// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/basictypes.h"
#include "base/environment.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/rand_util.h"
#include "base/stringprintf.h"
#include "base/test/multiprocess_test.h"
#include "base/time.h"
#include "chrome/common/multi_process_lock.h"
#include "testing/multiprocess_func_list.h"

class MultiProcessLockTest : public base::MultiProcessTest {
 public:
  static const char kLockEnviromentVarName[];

  class ScopedEnvironmentVariable {
   public:
    ScopedEnvironmentVariable(const std::string &name,
                              const std::string &value)
        : name_(name), environment_(base::Environment::Create()) {
      environment_->SetVar(name_.c_str(), value);
    }
    ~ScopedEnvironmentVariable() {
      environment_->UnSetVar(name_.c_str());
    }

   private:
    std::string name_;
    scoped_ptr<base::Environment> environment_;
    DISALLOW_COPY_AND_ASSIGN(ScopedEnvironmentVariable);
  };

  std::string GenerateLockName();
  void ExpectLockIsLocked(const std::string &name);
  void ExpectLockIsUnlocked(const std::string &name);
};

const char MultiProcessLockTest::kLockEnviromentVarName[]
    = "MULTI_PROCESS_TEST_LOCK_NAME";

std::string MultiProcessLockTest::GenerateLockName() {
  base::Time now = base::Time::NowFromSystemTime();
  return base::StringPrintf("multi_process_test_lock %lf%lf",
                            now.ToDoubleT(), base::RandDouble());
}

void MultiProcessLockTest::ExpectLockIsLocked(const std::string &name) {
  ScopedEnvironmentVariable var(kLockEnviromentVarName, name);
  base::ProcessHandle handle = SpawnChild("MultiProcessLockTryFailMain", false);
  ASSERT_TRUE(handle);
  int exit_code = 0;
  EXPECT_TRUE(base::WaitForExitCode(handle, &exit_code));
  EXPECT_EQ(exit_code, 0);
}

void MultiProcessLockTest::ExpectLockIsUnlocked(
    const std::string &name) {
  ScopedEnvironmentVariable var(kLockEnviromentVarName, name);
  base::ProcessHandle handle = SpawnChild("MultiProcessLockTrySucceedMain",
                                          false);
  ASSERT_TRUE(handle);
  int exit_code = 0;
  EXPECT_TRUE(base::WaitForExitCode(handle, &exit_code));
  EXPECT_EQ(exit_code, 0);
}

TEST_F(MultiProcessLockTest, BasicCreationTest) {
  // Test basic creation/destruction with no lock taken
  std::string name = GenerateLockName();
  scoped_ptr<MultiProcessLock> scoped(MultiProcessLock::Create(name));
  ExpectLockIsUnlocked(name);
  scoped.reset(NULL);
}

TEST_F(MultiProcessLockTest, LongNameTest) {
  // Every platform has has it's own max path name size,
  // so different checks are needed for them.
  // POSIX: sizeof(address.sun_path) - 2
  // Mac OS X: BOOTSTRAP_MAX_NAME_LEN
  // Windows: MAX_PATH
  LOG(INFO) << "Following error log due to long name is expected";
#if defined(OS_MACOSX)
  std::string name("This is a name that is longer than one hundred and "
      "twenty-eight characters to make sure that we fail appropriately on "
      "Mac OS X when we have a path that is too long for Mac OS X to handle");
#elif defined(OS_POSIX)
  std::string name("This is a name that is longer than one hundred and eight "
      "characters to make sure that we fail appropriately on POSIX systems "
      "when we have a path that is too long for the system to handle");
#elif defined(OS_WIN)
  std::string name("This is a name that is longer than two hundred and sixty "
      "characters to make sure that we fail appropriately on Windows when we "
      "have a path that is too long for Windows to handle "
      "This limitation comes from the MAX_PATH definition which is obviously "
      "defined to be a maximum of two hundred and sixty characters ");
#endif
  scoped_ptr<MultiProcessLock> test_lock(MultiProcessLock::Create(name));
  EXPECT_FALSE(test_lock->TryLock());
}

TEST_F(MultiProcessLockTest, SimpleLock) {
  std::string name = GenerateLockName();
  scoped_ptr<MultiProcessLock> test_lock(MultiProcessLock::Create(name));
  EXPECT_TRUE(test_lock->TryLock());
  ExpectLockIsLocked(name);
  test_lock->Unlock();
  ExpectLockIsUnlocked(name);
}

TEST_F(MultiProcessLockTest, RecursiveLock) {
  std::string name = GenerateLockName();
  scoped_ptr<MultiProcessLock> test_lock(MultiProcessLock::Create(name));
  EXPECT_TRUE(test_lock->TryLock());
  ExpectLockIsLocked(name);
  LOG(INFO) << "Following error log "
            << "'MultiProcessLock is already locked' is expected";
  EXPECT_TRUE(test_lock->TryLock());
  ExpectLockIsLocked(name);
  test_lock->Unlock();
  ExpectLockIsUnlocked(name);
  LOG(INFO) << "Following error log "
            << "'Over-unlocked MultiProcessLock' is expected";
  test_lock->Unlock();
  ExpectLockIsUnlocked(name);
  test_lock.reset();
}

TEST_F(MultiProcessLockTest, LockScope) {
  // Check to see that lock is released when it goes out of scope.
  std::string name = GenerateLockName();
  {
    scoped_ptr<MultiProcessLock> test_lock(MultiProcessLock::Create(name));
    EXPECT_TRUE(test_lock->TryLock());
    ExpectLockIsLocked(name);
  }
  ExpectLockIsUnlocked(name);
}

MULTIPROCESS_TEST_MAIN(MultiProcessLockTryFailMain) {
  std::string name;
  scoped_ptr<base::Environment> environment(base::Environment::Create());
  EXPECT_TRUE(environment->GetVar(MultiProcessLockTest::kLockEnviromentVarName,
                                  &name));
#if defined(OS_MACOSX)
  // OS X sends out a log if a lock fails.
  // Hopefully this will keep people from panicking about it when they
  // are perusing the build logs.
  LOG(INFO) << "Following error log "
            << "\"CFMessagePort: bootstrap_register(): failed 1100 (0x44c) "
            << "'Permission denied'\" is expected";
#endif  // defined(OS_MACOSX)
  scoped_ptr<MultiProcessLock> test_lock(
      MultiProcessLock::Create(name));
  EXPECT_FALSE(test_lock->TryLock());
  return 0;
}

MULTIPROCESS_TEST_MAIN(MultiProcessLockTrySucceedMain) {
  std::string name;
  scoped_ptr<base::Environment> environment(base::Environment::Create());
  EXPECT_TRUE(environment->GetVar(MultiProcessLockTest::kLockEnviromentVarName,
                                  &name));
  scoped_ptr<MultiProcessLock> test_lock(
      MultiProcessLock::Create(name));
  EXPECT_TRUE(test_lock->TryLock());
  return 0;
}
