diff options
author | Paweł Hajdan, Jr <phajdan.jr@chromium.org> | 2015-01-14 11:06:52 +0100 |
---|---|---|
committer | Paweł Hajdan, Jr <phajdan.jr@chromium.org> | 2015-01-14 10:09:12 +0000 |
commit | 49adb29e8bb25a51b5dc01d692a3acad717553e6 (patch) | |
tree | 63e22f8b1d067082a522ef21e7cdd0a66eabed1c /base | |
parent | 3cb31c320b8970c192c2baf32c35a73932911adb (diff) | |
download | chromium_src-49adb29e8bb25a51b5dc01d692a3acad717553e6.zip chromium_src-49adb29e8bb25a51b5dc01d692a3acad717553e6.tar.gz chromium_src-49adb29e8bb25a51b5dc01d692a3acad717553e6.tar.bz2 |
Extract UnitTestLauncherDelegate declaration to a header
This is a preparation for defining some methods in an ios-specific
.cc file.
BUG=426870
R=sky@chromium.org
Review URL: https://codereview.chromium.org/848903002
Cr-Commit-Position: refs/heads/master@{#311440}
Diffstat (limited to 'base')
-rw-r--r-- | base/test/launcher/unit_test_launcher.cc | 334 | ||||
-rw-r--r-- | base/test/launcher/unit_test_launcher.h | 70 |
2 files changed, 230 insertions, 174 deletions
diff --git a/base/test/launcher/unit_test_launcher.cc b/base/test/launcher/unit_test_launcher.cc index 6309cde..719c498 100644 --- a/base/test/launcher/unit_test_launcher.cc +++ b/base/test/launcher/unit_test_launcher.cc @@ -100,34 +100,153 @@ CommandLine GetCommandLineForChildGTestProcess( return new_cmd_line; } -class UnitTestLauncherDelegate : public TestLauncherDelegate { - public: - explicit UnitTestLauncherDelegate(size_t batch_limit, bool use_job_objects) - : batch_limit_(batch_limit), - use_job_objects_(use_job_objects) { +bool GetSwitchValueAsInt(const std::string& switch_name, int* result) { + if (!CommandLine::ForCurrentProcess()->HasSwitch(switch_name)) + return true; + + std::string switch_value = + CommandLine::ForCurrentProcess()->GetSwitchValueASCII(switch_name); + if (!StringToInt(switch_value, result) || *result < 1) { + LOG(ERROR) << "Invalid value for " << switch_name << ": " << switch_value; + return false; } - ~UnitTestLauncherDelegate() override { - DCHECK(thread_checker_.CalledOnValidThread()); + return true; +} + +int LaunchUnitTestsInternal(const RunTestSuiteCallback& run_test_suite, + int default_jobs, + bool use_job_objects, + const Closure& gtest_init) { +#if defined(OS_ANDROID) + // We can't easily fork on Android, just run the test suite directly. + return run_test_suite.Run(); +#else + bool force_single_process = false; + if (CommandLine::ForCurrentProcess()->HasSwitch( + switches::kTestLauncherDebugLauncher)) { + fprintf(stdout, "Forcing test launcher debugging mode.\n"); + fflush(stdout); + } else { + if (base::debug::BeingDebugged()) { + fprintf(stdout, + "Debugger detected, switching to single process mode.\n" + "Pass --test-launcher-debug-launcher to debug the launcher " + "itself.\n"); + fflush(stdout); + force_single_process = true; + } + } + + if (CommandLine::ForCurrentProcess()->HasSwitch(kGTestHelpFlag) || + CommandLine::ForCurrentProcess()->HasSwitch(kGTestListTestsFlag) || + CommandLine::ForCurrentProcess()->HasSwitch(kSingleProcessTestsFlag) || + force_single_process) { + return run_test_suite.Run(); + } +#endif + + if (CommandLine::ForCurrentProcess()->HasSwitch(kHelpFlag)) { + PrintUsage(); + return 0; } - private: - struct GTestCallbackState { - TestLauncher* test_launcher; - std::vector<std::string> test_names; - FilePath output_file; - }; + base::TimeTicks start_time(base::TimeTicks::Now()); + + gtest_init.Run(); + TestTimeouts::Initialize(); + + int batch_limit = kDefaultTestBatchLimit; + if (!GetSwitchValueAsInt(switches::kTestLauncherBatchLimit, &batch_limit)) + return 1; + + fprintf(stdout, + "IMPORTANT DEBUGGING NOTE: batches of tests are run inside their\n" + "own process. For debugging a test inside a debugger, use the\n" + "--gtest_filter=<your_test_name> flag along with\n" + "--single-process-tests.\n"); + fflush(stdout); + + MessageLoopForIO message_loop; + + UnitTestLauncherDelegate delegate(batch_limit, use_job_objects); + base::TestLauncher launcher(&delegate, default_jobs); + bool success = launcher.Run(); + + fprintf(stdout, "Tests took %" PRId64 " seconds.\n", + (base::TimeTicks::Now() - start_time).InSeconds()); + fflush(stdout); + + return (success ? 0 : 1); +} - bool ShouldRunTest(const std::string& test_case_name, - const std::string& test_name) override { +void InitGoogleTestChar(int* argc, char** argv) { + testing::InitGoogleTest(argc, argv); +} + +#if defined(OS_WIN) +void InitGoogleTestWChar(int* argc, wchar_t** argv) { + testing::InitGoogleTest(argc, argv); +} +#endif // defined(OS_WIN) + +} // namespace + +int LaunchUnitTests(int argc, + char** argv, + const RunTestSuiteCallback& run_test_suite) { + CommandLine::Init(argc, argv); + return LaunchUnitTestsInternal(run_test_suite, SysInfo::NumberOfProcessors(), + true, Bind(&InitGoogleTestChar, &argc, argv)); +} + +int LaunchUnitTestsSerially(int argc, + char** argv, + const RunTestSuiteCallback& run_test_suite) { + CommandLine::Init(argc, argv); + return LaunchUnitTestsInternal(run_test_suite, 1, true, + Bind(&InitGoogleTestChar, &argc, argv)); +} + +#if defined(OS_WIN) +int LaunchUnitTests(int argc, + wchar_t** argv, + bool use_job_objects, + const RunTestSuiteCallback& run_test_suite) { + // Windows CommandLine::Init ignores argv anyway. + CommandLine::Init(argc, NULL); + return LaunchUnitTestsInternal(run_test_suite, SysInfo::NumberOfProcessors(), + use_job_objects, + Bind(&InitGoogleTestWChar, &argc, argv)); +} +#endif // defined(OS_WIN) + +UnitTestLauncherDelegate::UnitTestLauncherDelegate(size_t batch_limit, + bool use_job_objects) + : batch_limit_(batch_limit), use_job_objects_(use_job_objects) { +} + +UnitTestLauncherDelegate::~UnitTestLauncherDelegate() { + DCHECK(thread_checker_.CalledOnValidThread()); +} + +UnitTestLauncherDelegate::GTestCallbackState::GTestCallbackState() { +} + +UnitTestLauncherDelegate::GTestCallbackState::~GTestCallbackState() { +} + +bool UnitTestLauncherDelegate::ShouldRunTest(const std::string& test_case_name, + const std::string& test_name) { DCHECK(thread_checker_.CalledOnValidThread()); // There is no additional logic to disable specific tests. return true; } - size_t RunTests(TestLauncher* test_launcher, - const std::vector<std::string>& test_names) override { + size_t UnitTestLauncherDelegate::RunTests( + TestLauncher* test_launcher, + const std::vector<std::string>& test_names) { DCHECK(thread_checker_.CalledOnValidThread()); std::vector<std::string> batch; @@ -145,8 +264,9 @@ class UnitTestLauncherDelegate : public TestLauncherDelegate { return test_names.size(); } - size_t RetryTests(TestLauncher* test_launcher, - const std::vector<std::string>& test_names) override { + size_t UnitTestLauncherDelegate::RetryTests( + TestLauncher* test_launcher, + const std::vector<std::string>& test_names) { MessageLoop::current()->PostTask( FROM_HERE, Bind(&UnitTestLauncherDelegate::RunSerially, @@ -156,8 +276,9 @@ class UnitTestLauncherDelegate : public TestLauncherDelegate { return test_names.size(); } - void RunSerially(TestLauncher* test_launcher, - const std::vector<std::string>& test_names) { + void UnitTestLauncherDelegate::RunSerially( + TestLauncher* test_launcher, + const std::vector<std::string>& test_names) { if (test_names.empty()) return; @@ -193,8 +314,9 @@ class UnitTestLauncherDelegate : public TestLauncherDelegate { new_test_names)); } - void RunBatch(TestLauncher* test_launcher, - const std::vector<std::string>& test_names) { + void UnitTestLauncherDelegate::RunBatch( + TestLauncher* test_launcher, + const std::vector<std::string>& test_names) { DCHECK(thread_checker_.CalledOnValidThread()); if (test_names.empty()) @@ -234,11 +356,12 @@ class UnitTestLauncherDelegate : public TestLauncherDelegate { callback_state)); } - void GTestCallback(const GTestCallbackState& callback_state, - int exit_code, - const TimeDelta& elapsed_time, - bool was_timeout, - const std::string& output) { + void UnitTestLauncherDelegate::GTestCallback( + const GTestCallbackState& callback_state, + int exit_code, + const TimeDelta& elapsed_time, + bool was_timeout, + const std::string& output) { DCHECK(thread_checker_.CalledOnValidThread()); std::vector<std::string> tests_to_relaunch; ProcessTestResults(callback_state.test_launcher, @@ -262,12 +385,13 @@ class UnitTestLauncherDelegate : public TestLauncherDelegate { DeleteFile(callback_state.output_file.DirName(), true); } - void SerialGTestCallback(const GTestCallbackState& callback_state, - const std::vector<std::string>& test_names, - int exit_code, - const TimeDelta& elapsed_time, - bool was_timeout, - const std::string& output) { + void UnitTestLauncherDelegate::SerialGTestCallback( + const GTestCallbackState& callback_state, + const std::vector<std::string>& test_names, + int exit_code, + const TimeDelta& elapsed_time, + bool was_timeout, + const std::string& output) { DCHECK(thread_checker_.CalledOnValidThread()); std::vector<std::string> tests_to_relaunch; bool called_any_callbacks = @@ -297,7 +421,8 @@ class UnitTestLauncherDelegate : public TestLauncherDelegate { test_names)); } - static bool ProcessTestResults( + // static + bool UnitTestLauncherDelegate::ProcessTestResults( TestLauncher* test_launcher, const std::vector<std::string>& test_names, const base::FilePath& output_file, @@ -434,143 +559,4 @@ class UnitTestLauncherDelegate : public TestLauncherDelegate { return called_any_callback; } - ThreadChecker thread_checker_; - - // Maximum number of tests to run in a single batch. - size_t batch_limit_; - - // Determines whether we use job objects on Windows. - bool use_job_objects_; -}; - -bool GetSwitchValueAsInt(const std::string& switch_name, int* result) { - if (!CommandLine::ForCurrentProcess()->HasSwitch(switch_name)) - return true; - - std::string switch_value = - CommandLine::ForCurrentProcess()->GetSwitchValueASCII(switch_name); - if (!StringToInt(switch_value, result) || *result < 1) { - LOG(ERROR) << "Invalid value for " << switch_name << ": " << switch_value; - return false; - } - - return true; -} - -int LaunchUnitTestsInternal(const RunTestSuiteCallback& run_test_suite, - int default_jobs, - bool use_job_objects, - const Closure& gtest_init) { -#if defined(OS_ANDROID) - // We can't easily fork on Android, just run the test suite directly. - return run_test_suite.Run(); -#else - bool force_single_process = false; - if (CommandLine::ForCurrentProcess()->HasSwitch( - switches::kTestLauncherDebugLauncher)) { - fprintf(stdout, "Forcing test launcher debugging mode.\n"); - fflush(stdout); - } else { - if (base::debug::BeingDebugged()) { - fprintf(stdout, - "Debugger detected, switching to single process mode.\n" - "Pass --test-launcher-debug-launcher to debug the launcher " - "itself.\n"); - fflush(stdout); - force_single_process = true; - } - } - - if (CommandLine::ForCurrentProcess()->HasSwitch(kGTestHelpFlag) || - CommandLine::ForCurrentProcess()->HasSwitch(kGTestListTestsFlag) || - CommandLine::ForCurrentProcess()->HasSwitch(kSingleProcessTestsFlag) || - force_single_process) { - return run_test_suite.Run(); - } -#endif - - if (CommandLine::ForCurrentProcess()->HasSwitch(kHelpFlag)) { - PrintUsage(); - return 0; - } - - base::TimeTicks start_time(base::TimeTicks::Now()); - - gtest_init.Run(); - TestTimeouts::Initialize(); - - int batch_limit = kDefaultTestBatchLimit; - if (!GetSwitchValueAsInt(switches::kTestLauncherBatchLimit, &batch_limit)) - return 1; - - fprintf(stdout, - "IMPORTANT DEBUGGING NOTE: batches of tests are run inside their\n" - "own process. For debugging a test inside a debugger, use the\n" - "--gtest_filter=<your_test_name> flag along with\n" - "--single-process-tests.\n"); - fflush(stdout); - - MessageLoopForIO message_loop; - - UnitTestLauncherDelegate delegate(batch_limit, use_job_objects); - base::TestLauncher launcher(&delegate, default_jobs); - bool success = launcher.Run(); - - fprintf(stdout, - "Tests took %" PRId64 " seconds.\n", - (base::TimeTicks::Now() - start_time).InSeconds()); - fflush(stdout); - - return (success ? 0 : 1); -} - -void InitGoogleTestChar(int* argc, char** argv) { - testing::InitGoogleTest(argc, argv); -} - -#if defined(OS_WIN) -void InitGoogleTestWChar(int* argc, wchar_t** argv) { - testing::InitGoogleTest(argc, argv); -} -#endif // defined(OS_WIN) - -} // namespace - -int LaunchUnitTests(int argc, - char** argv, - const RunTestSuiteCallback& run_test_suite) { - CommandLine::Init(argc, argv); - return LaunchUnitTestsInternal( - run_test_suite, - SysInfo::NumberOfProcessors(), - true, - Bind(&InitGoogleTestChar, &argc, argv)); -} - -int LaunchUnitTestsSerially(int argc, - char** argv, - const RunTestSuiteCallback& run_test_suite) { - CommandLine::Init(argc, argv); - return LaunchUnitTestsInternal( - run_test_suite, - 1, - true, - Bind(&InitGoogleTestChar, &argc, argv)); -} - -#if defined(OS_WIN) -int LaunchUnitTests(int argc, - wchar_t** argv, - bool use_job_objects, - const RunTestSuiteCallback& run_test_suite) { - // Windows CommandLine::Init ignores argv anyway. - CommandLine::Init(argc, NULL); - return LaunchUnitTestsInternal( - run_test_suite, - SysInfo::NumberOfProcessors(), - use_job_objects, - Bind(&InitGoogleTestWChar, &argc, argv)); -} -#endif // defined(OS_WIN) - } // namespace base diff --git a/base/test/launcher/unit_test_launcher.h b/base/test/launcher/unit_test_launcher.h index 5682ed9..7264e41 100644 --- a/base/test/launcher/unit_test_launcher.h +++ b/base/test/launcher/unit_test_launcher.h @@ -6,6 +6,8 @@ #define BASE_TEST_LAUNCHER_UNIT_TEST_LAUNCHER_H_ #include "base/callback.h" +#include "base/files/file_path.h" +#include "base/test/launcher/test_launcher.h" namespace base { @@ -31,6 +33,74 @@ int LaunchUnitTests(int argc, const RunTestSuiteCallback& run_test_suite); #endif // defined(OS_WIN) +// Test launcher delegate for unit tests (mostly to support batching). +class UnitTestLauncherDelegate : public TestLauncherDelegate { + public: + explicit UnitTestLauncherDelegate(size_t batch_limit, bool use_job_objects); + ~UnitTestLauncherDelegate() override; + + private: + struct GTestCallbackState { + GTestCallbackState(); + ~GTestCallbackState(); + + TestLauncher* test_launcher; + std::vector<std::string> test_names; + FilePath output_file; + }; + + // TestLauncherDelegate: + bool ShouldRunTest(const std::string& test_case_name, + const std::string& test_name) override; + size_t RunTests(TestLauncher* test_launcher, + const std::vector<std::string>& test_names) override; + size_t RetryTests(TestLauncher* test_launcher, + const std::vector<std::string>& test_names) override; + + // Runs tests serially, each in its own process. + void RunSerially(TestLauncher* test_launcher, + const std::vector<std::string>& test_names); + + // Runs tests in batches (each batch in its own process). + void RunBatch(TestLauncher* test_launcher, + const std::vector<std::string>& test_names); + + // Callback for batched tests. + void GTestCallback(const GTestCallbackState& callback_state, + int exit_code, + const TimeDelta& elapsed_time, + bool was_timeout, + const std::string& output); + + // Callback for serialized tests. + void SerialGTestCallback(const GTestCallbackState& callback_state, + const std::vector<std::string>& test_names, + int exit_code, + const TimeDelta& elapsed_time, + bool was_timeout, + const std::string& output); + + // Interprets test results and reports to the test launcher. Returns true + // on success. + static bool ProcessTestResults(TestLauncher* test_launcher, + const std::vector<std::string>& test_names, + const base::FilePath& output_file, + const std::string& output, + int exit_code, + bool was_timeout, + std::vector<std::string>* tests_to_relaunch); + + ThreadChecker thread_checker_; + + // Maximum number of tests to run in a single batch. + size_t batch_limit_; + + // Determines whether we use job objects on Windows. + bool use_job_objects_; + + DISALLOW_COPY_AND_ASSIGN(UnitTestLauncherDelegate); +}; + } // namespace base #endif // BASE_TEST_LAUNCHER_UNIT_TEST_LAUNCHER_H_ |