// Copyright 2015 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/command_line.h"
#include "base/files/file.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/macros.h"
#include "base/test/multiprocess_test.h"
#include "base/test/test_timeouts.h"
#include "base/threading/platform_thread.h"
#include "base/time/time.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/multiprocess_func_list.h"

using base::File;
using base::FilePath;

namespace {

// Flag for the parent to share a temp dir to the child.
const char kTempDirFlag[] = "temp-dir";

// Flags to control how the subprocess unlocks the file.
const char kFileUnlock[] = "file-unlock";
const char kCloseUnlock[] = "close-unlock";
const char kExitUnlock[] = "exit-unlock";

// File to lock in temp dir.
const char kLockFile[] = "lockfile";

// Constants for various requests and responses, used as |signal_file| parameter
// to signal/wait helpers.
const char kSignalLockFileLocked[] = "locked.signal";
const char kSignalLockFileClose[] = "close.signal";
const char kSignalLockFileClosed[] = "closed.signal";
const char kSignalLockFileUnlock[] = "unlock.signal";
const char kSignalLockFileUnlocked[] = "unlocked.signal";
const char kSignalExit[] = "exit.signal";

// Signal an event by creating a file which didn't previously exist.
bool SignalEvent(const FilePath& signal_dir, const char* signal_file) {
  File file(signal_dir.AppendASCII(signal_file),
            File::FLAG_CREATE | File::FLAG_WRITE);
  return file.IsValid();
}

// Check whether an event was signaled.
bool CheckEvent(const FilePath& signal_dir, const char* signal_file) {
  File file(signal_dir.AppendASCII(signal_file),
            File::FLAG_OPEN | File::FLAG_READ);
  return file.IsValid();
}

// Busy-wait for an event to be signaled, returning false for timeout.
bool WaitForEventWithTimeout(const FilePath& signal_dir,
                             const char* signal_file,
                             const base::TimeDelta& timeout) {
  const base::Time finish_by = base::Time::Now() + timeout;
  while (!CheckEvent(signal_dir, signal_file)) {
    if (base::Time::Now() > finish_by)
      return false;
    base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
  }
  return true;
}

// Wait forever for the event to be signaled (should never return false).
bool WaitForEvent(const FilePath& signal_dir, const char* signal_file) {
  return WaitForEventWithTimeout(signal_dir, signal_file,
                                 base::TimeDelta::Max());
}

// Keep these in sync so StartChild*() can refer to correct test main.
#define ChildMain ChildLockUnlock
#define ChildMainString "ChildLockUnlock"

// Subprocess to test getting a file lock then releasing it.  |kTempDirFlag|
// must pass in an existing temporary directory for the lockfile and signal
// files.  One of the following flags must be passed to determine how to unlock
// the lock file:
// - |kFileUnlock| calls Unlock() to unlock.
// - |kCloseUnlock| calls Close() while the lock is held.
// - |kExitUnlock| exits while the lock is held.
MULTIPROCESS_TEST_MAIN(ChildMain) {
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  const FilePath temp_path = command_line->GetSwitchValuePath(kTempDirFlag);
  CHECK(base::DirectoryExists(temp_path));

  // Immediately lock the file.
  File file(temp_path.AppendASCII(kLockFile),
            File::FLAG_OPEN | File::FLAG_READ | File::FLAG_WRITE);
  CHECK(file.IsValid());
  CHECK_EQ(File::FILE_OK, file.Lock());
  CHECK(SignalEvent(temp_path, kSignalLockFileLocked));

  if (command_line->HasSwitch(kFileUnlock)) {
    // Wait for signal to unlock, then unlock the file.
    CHECK(WaitForEvent(temp_path, kSignalLockFileUnlock));
    CHECK_EQ(File::FILE_OK, file.Unlock());
    CHECK(SignalEvent(temp_path, kSignalLockFileUnlocked));
  } else if (command_line->HasSwitch(kCloseUnlock)) {
    // Wait for the signal to close, then close the file.
    CHECK(WaitForEvent(temp_path, kSignalLockFileClose));
    file.Close();
    CHECK(!file.IsValid());
    CHECK(SignalEvent(temp_path, kSignalLockFileClosed));
  } else {
    CHECK(command_line->HasSwitch(kExitUnlock));
  }

  // Wait for signal to exit, so that unlock or close can be distinguished from
  // exit.
  CHECK(WaitForEvent(temp_path, kSignalExit));
  return 0;
}

}  // namespace

class FileLockingTest : public testing::Test {
 public:
  FileLockingTest() {}

 protected:
  void SetUp() override {
    testing::Test::SetUp();

    // Setup the temp dir and the lock file.
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
    lock_file_.Initialize(
        temp_dir_.path().AppendASCII(kLockFile),
        File::FLAG_CREATE | File::FLAG_READ | File::FLAG_WRITE);
    ASSERT_TRUE(lock_file_.IsValid());
  }

  bool SignalEvent(const char* signal_file) {
    return ::SignalEvent(temp_dir_.path(), signal_file);
  }

  bool WaitForEventOrTimeout(const char* signal_file) {
    return ::WaitForEventWithTimeout(temp_dir_.path(), signal_file,
                                     TestTimeouts::action_timeout());
  }

  // Start a child process set to use the specified unlock action, and wait for
  // it to lock the file.
  void StartChildAndSignalLock(const char* unlock_action) {
    // Create a temporary dir and spin up a ChildLockExit subprocess against it.
    const FilePath temp_path = temp_dir_.path();
    base::CommandLine child_command_line(
        base::GetMultiProcessTestChildBaseCommandLine());
    child_command_line.AppendSwitchPath(kTempDirFlag, temp_path);
    child_command_line.AppendSwitch(unlock_action);
    lock_child_ =
        base::SpawnMultiProcessTestChild(ChildMainString, child_command_line,
                                         base::LaunchOptions());
    ASSERT_TRUE(lock_child_.IsValid());

    // Wait for the child to lock the file.
    ASSERT_TRUE(WaitForEventOrTimeout(kSignalLockFileLocked));
  }

  // Signal the child to exit cleanly.
  void ExitChildCleanly() {
    ASSERT_TRUE(SignalEvent(kSignalExit));
    int rv = -1;
    ASSERT_TRUE(lock_child_.WaitForExitWithTimeout(
        TestTimeouts::action_timeout(), &rv));
    ASSERT_EQ(0, rv);
  }

  base::ScopedTempDir temp_dir_;
  base::File lock_file_;
  base::Process lock_child_;

 private:
  DISALLOW_COPY_AND_ASSIGN(FileLockingTest);
};

// Test that locks are released by Unlock().
TEST_F(FileLockingTest, LockAndUnlock) {
  StartChildAndSignalLock(kFileUnlock);

  ASSERT_NE(File::FILE_OK, lock_file_.Lock());
  ASSERT_TRUE(SignalEvent(kSignalLockFileUnlock));
  ASSERT_TRUE(WaitForEventOrTimeout(kSignalLockFileUnlocked));
  ASSERT_EQ(File::FILE_OK, lock_file_.Lock());
  ASSERT_EQ(File::FILE_OK, lock_file_.Unlock());

  ExitChildCleanly();
}

// Test that locks are released on Close().
TEST_F(FileLockingTest, UnlockOnClose) {
  StartChildAndSignalLock(kCloseUnlock);

  ASSERT_NE(File::FILE_OK, lock_file_.Lock());
  ASSERT_TRUE(SignalEvent(kSignalLockFileClose));
  ASSERT_TRUE(WaitForEventOrTimeout(kSignalLockFileClosed));
  ASSERT_EQ(File::FILE_OK, lock_file_.Lock());
  ASSERT_EQ(File::FILE_OK, lock_file_.Unlock());

  ExitChildCleanly();
}

// Test that locks are released on exit.
TEST_F(FileLockingTest, UnlockOnExit) {
  StartChildAndSignalLock(kExitUnlock);

  ASSERT_NE(File::FILE_OK, lock_file_.Lock());
  ExitChildCleanly();
  ASSERT_EQ(File::FILE_OK, lock_file_.Lock());
  ASSERT_EQ(File::FILE_OK, lock_file_.Unlock());
}

// Test that killing the process releases the lock.  This should cover crashing.
TEST_F(FileLockingTest, UnlockOnTerminate) {
  // The child will wait for an exit which never arrives.
  StartChildAndSignalLock(kExitUnlock);

  ASSERT_NE(File::FILE_OK, lock_file_.Lock());
  ASSERT_TRUE(lock_child_.Terminate(0, true));
  ASSERT_EQ(File::FILE_OK, lock_file_.Lock());
  ASSERT_EQ(File::FILE_OK, lock_file_.Unlock());
}
