chromium/base/files/file_locking_unittest.cc

// Copyright 2015 The Chromium Authors
// 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/test/multiprocess_test.h"
#include "base/test/test_timeouts.h"
#include "base/threading/platform_thread.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/multiprocess_func_list.h"

File;
FilePath;

namespace {

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

// Flags to control how the process locks the file.
const char kFileLockShared[] =;
const char kFileLockExclusive[] =;

// Flags to control how the subprocess unlocks the file.
const char kFileUnlock[] =;
const char kCloseUnlock[] =;
const char kExitUnlock[] =;

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

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

// Signal an event by creating a file which didn't previously exist.
bool SignalEvent(const FilePath& signal_dir, const char* signal_file) {}

// Check whether an event was signaled.
bool CheckEvent(const FilePath& signal_dir, const char* signal_file) {}

// 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) {}

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

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

// 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) {}

}  // namespace

class FileLockingTest : public testing::Test {};

// Test that locks are released by Unlock().
TEST_F(FileLockingTest, LockAndUnlockExclusive) {}
TEST_F(FileLockingTest, LockAndUnlockShared) {}

// Test that locks are released on Close().
TEST_F(FileLockingTest, UnlockOnCloseExclusive) {}
TEST_F(FileLockingTest, UnlockOnCloseShared) {}

// Test that locks are released on exit.
TEST_F(FileLockingTest, UnlockOnExitExclusive) {}
TEST_F(FileLockingTest, UnlockOnExitShared) {}

// Test that killing the process releases the lock.  This should cover crashing.
// Flaky on Android (http://crbug.com/747518)
#if BUILDFLAG(IS_ANDROID)
#define MAYBE_UnlockOnTerminate
#else
#define MAYBE_UnlockOnTerminate
#endif
TEST_F(FileLockingTest, MAYBE_UnlockOnTerminate) {}