Chromium Code Reviews| Index: chromecast/crash/minidump_manager_unittest.cc |
| diff --git a/chromecast/crash/minidump_manager_unittest.cc b/chromecast/crash/minidump_manager_unittest.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..c571fd760395b28a36e2da0eba69d4d8335fd1f5 |
| --- /dev/null |
| +++ b/chromecast/crash/minidump_manager_unittest.cc |
| @@ -0,0 +1,170 @@ |
| +// 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 <stdlib.h> |
| +#include <sys/stat.h> // mkdir |
| +#include <stdio.h> // perror |
| +#include <time.h> |
| + |
| +#include "base/base_paths.h" |
| +#include "base/files/file.h" |
| +#include "base/files/file_util.h" |
| +#include "base/memory/scoped_ptr.h" |
| +#include "base/process/launch.h" |
| +#include "base/test/scoped_path_override.h" |
| +#include "base/threading/platform_thread.h" |
| + |
|
gunsch
2015/06/09 18:46:19
nit: remove blank line
slan
2015/06/10 01:49:13
Done.
|
| +#include "chromecast/crash/minidump_manager.h" |
| +#include "testing/gtest/include/gtest/gtest.h" |
| + |
| +namespace chromecast { |
| +namespace { |
| + |
| +const char kLockfileName[] = "lockfile"; |
| +const char kMinidumpSubdir[] = "minidumps"; |
| + |
| +// A trivial implementation of MinidumpManager, which does no work to the |
| +// minidump and exposes its protected members for testing. |
| +class MinidumpManagerSimple : public MinidumpManager { |
| + public: |
| + MinidumpManagerSimple() : MinidumpManager(), work_done_(false) {} |
| + ~MinidumpManagerSimple() override {} |
| + |
| + // MinidumpManager implementation: |
| + int DoWork() override { |
| + work_done_ = true; |
| + return 0; |
| + } |
| + |
| + // Accessors for testing. |
| + const std::string& dump_path() { return dump_path_; } |
| + const std::string& lockfile_path() { return lockfile_path_; } |
| + bool work_done() { return work_done_; } |
| + |
| + private: |
| + bool work_done_; |
| +}; |
| + |
| +class MinidumpManagerTest : public testing::Test { |
| + public: |
| + MinidumpManagerTest() {} |
| + ~MinidumpManagerTest() override {} |
| + |
| + void SetUp() override { |
| + // Set up a temporary directory which will be used as our fake home dir. |
| + ASSERT_TRUE(base::CreateNewTempDirectory("", &fake_home_dir_)); |
| + path_override_.reset( |
| + new base::ScopedPathOverride(base::DIR_HOME, fake_home_dir_)); |
| + minidump_dir_ = fake_home_dir_.Append(kMinidumpSubdir); |
| + } |
| + |
| + void TearDown() override { |
| + // Remove the temp directory. |
| + path_override_.reset(); |
| + ASSERT_TRUE(base::DeleteFile(fake_home_dir_, true)); |
| + } |
| + |
| + protected: |
| + base::FilePath |
| + fake_home_dir_; // Path to the home directory used for the test. |
| + base::FilePath minidump_dir_; // Path the the minidump directory. |
| + |
| + private: |
| + scoped_ptr<base::ScopedPathOverride> path_override_; |
| +}; |
| + |
| +} // namespace |
| + |
| +TEST_F(MinidumpManagerTest, FilePathsAreCorrect) { |
| + MinidumpManagerSimple manager; |
| + |
| + // Verify file paths for directory and lock file. |
| + ASSERT_EQ(minidump_dir_.value(), manager.dump_path()); |
| + ASSERT_EQ(minidump_dir_.Append(kLockfileName).value(), |
| + manager.lockfile_path()); |
| +} |
| + |
| +TEST_F(MinidumpManagerTest, AcquireLockOnNonExistentDirectory) { |
| + // Create the manager and do the minidump work. |
| + MinidumpManagerSimple manager; |
| + ASSERT_EQ(0, manager.DoWorkLocked()); |
| + ASSERT_TRUE(manager.work_done()); |
| + |
| + // Verify the directory and the lockfile both exist. |
| + ASSERT_TRUE(base::DirectoryExists(minidump_dir_)); |
| + ASSERT_TRUE(base::PathExists(minidump_dir_.Append(kLockfileName))); |
| +} |
| + |
| +TEST_F(MinidumpManagerTest, AcquireLockOnExistingEmptyDirectory) { |
| + // Create the empty minidump directory. |
| + ASSERT_TRUE(base::CreateDirectory(minidump_dir_)); |
| + ASSERT_TRUE(base::IsDirectoryEmpty(minidump_dir_)); |
| + |
| + MinidumpManagerSimple manager; |
| + ASSERT_EQ(0, manager.DoWorkLocked()); |
| + ASSERT_TRUE(manager.work_done()); |
| + |
| + // Verify the directory and the lockfile both exist. |
| + ASSERT_TRUE(base::DirectoryExists(minidump_dir_)); |
| + ASSERT_TRUE(base::PathExists(minidump_dir_.Append(kLockfileName))); |
| +} |
| + |
| +TEST_F(MinidumpManagerTest, AcquireLockOnExistingDirectoryWithLockfile) { |
| + // Create a minidump directory. |
| + ASSERT_TRUE(base::CreateDirectory(minidump_dir_)); |
| + ASSERT_TRUE(base::IsDirectoryEmpty(minidump_dir_)); |
| + |
| + // Create a lockfile in that directory. |
| + base::File lockfile(minidump_dir_.Append(kLockfileName), |
| + base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE); |
| + ASSERT_TRUE(lockfile.IsValid()); |
| + |
| + MinidumpManagerSimple manager; |
| + ASSERT_EQ(0, manager.DoWorkLocked()); |
| + ASSERT_TRUE(manager.work_done()); |
| + |
| + // Verify the directory and the lockfile both exist. |
| + ASSERT_TRUE(base::DirectoryExists(minidump_dir_)); |
| + ASSERT_TRUE(base::PathExists(minidump_dir_.Append(kLockfileName))); |
| +} |
| + |
| +TEST_F(MinidumpManagerTest, DoNotBlockOnAcquiringLock) { |
|
gunsch
2015/06/09 18:46:19
You can rename the test as DISABLED_DoNotBlockOnAc
slan
2015/06/10 01:49:13
Done.
|
| + // TODO(slan): Determine how to lock the lockfile before attempting to |
| + // aquire lock on it from this process, and test that this thread does not |
| + // block. |
| + |
| + //// Create a minidump directory. |
| + // ASSERT_TRUE(base::CreateDirectory(minidump_dir_)); |
| + // ASSERT_TRUE(base::IsDirectoryEmpty(minidump_dir_)); |
| + |
| + //// Create a lockfile in that directory. |
| + // base::File lockfile(minidump_dir_.Append(kLockfileName), |
| + // base::File::FLAG_CREATE_ALWAYS|base::File::FLAG_WRITE); |
| + // ASSERT_TRUE(lockfile.IsValid()); |
| + |
| + //// Fork the process. |
| + // pid_t pid = base::ForkWithFlags(0u, nullptr, nullptr); |
| + // if (pid != 0) { |
| + // // The child process should hold a lock on the file for 20ms then exit. |
| + // lockfile.Lock(); |
| + // base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1000)); |
| + // lockfile.Unlock(); |
| + // return; |
| + //} else { |
| + // // The parent process should attempt to grab the lock after 10ms, fail |
| + // // immediately, and exit imediately. |
| + // base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(500)); |
| + |
| + // MinidumpManagerSimple manager; |
| + // manager.SetNonblocking(true); |
| + // ASSERT_EQ(-1, manager.DoWorkLocked()); |
| + // ASSERT_FALSE(manager.work_done()); |
| + |
| + // // Verify the directory and the lockfile both exist. |
| + // ASSERT_TRUE(base::DirectoryExists(minidump_dir_)); |
| + // ASSERT_TRUE(base::PathExists(minidump_dir_.Append(kLockfileName))); |
| + //} |
| +} |
| + |
| +} // namespace chromecast |