// 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/environment.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/process/kill.h"
#include "base/rand_util.h"
#include "base/strings/stringprintf.h"
#include "base/test/multiprocess_test.h"
#include "base/time/time.h"
#include "build/build_config.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::Process process = SpawnChild("MultiProcessLockTryFailMain");
  ASSERT_TRUE(process.IsValid());
  int exit_code = -1;
  EXPECT_TRUE(process.WaitForExit(&exit_code));
  EXPECT_EQ(0, exit_code);
}

void MultiProcessLockTest::ExpectLockIsUnlocked(
    const std::string &name) {
  ScopedEnvironmentVariable var(kLockEnviromentVarName, name);
  base::Process process = SpawnChild("MultiProcessLockTrySucceedMain");
  ASSERT_TRUE(process.IsValid());
  int exit_code = -1;
  EXPECT_TRUE(process.WaitForExit(&exit_code));
  EXPECT_EQ(0, exit_code);
}

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 locking to fail because it is claimed by another process.
  bool locked_successfully = test_lock->TryLock();
  EXPECT_FALSE(locked_successfully);
  return locked_successfully;
}

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 locking to succeed because it is not claimed yet.
  bool locked_successfully = test_lock->TryLock();
  EXPECT_TRUE(locked_successfully);
  return !locked_successfully;
}
