// 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 "chrome/common/multi_process_lock.h"

#include <memory>

#include "base/environment.h"
#include "base/logging.h"
#include "base/macros.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 "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_;
    std::unique_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();
  std::unique_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
  std::unique_ptr<MultiProcessLock> test_lock(MultiProcessLock::Create(name));
  EXPECT_FALSE(test_lock->TryLock());
}

TEST_F(MultiProcessLockTest, SimpleLock) {
  std::string name = GenerateLockName();
  std::unique_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();
  std::unique_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();
  {
    std::unique_ptr<MultiProcessLock> test_lock(MultiProcessLock::Create(name));
    EXPECT_TRUE(test_lock->TryLock());
    ExpectLockIsLocked(name);
  }
  ExpectLockIsUnlocked(name);
}

MULTIPROCESS_TEST_MAIN(MultiProcessLockTryFailMain) {
  std::string name;
  std::unique_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)
  std::unique_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;
  std::unique_ptr<base::Environment> environment(base::Environment::Create());
  EXPECT_TRUE(environment->GetVar(MultiProcessLockTest::kLockEnviromentVarName,
                                  &name));
  std::unique_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;
}
