diff options
author | Paweł Hajdan <phajdan.jr@chromium.org> | 2015-01-23 14:33:49 +0100 |
---|---|---|
committer | Paweł Hajdan <phajdan.jr@chromium.org> | 2015-01-23 13:34:27 +0000 |
commit | 19368c060c5a43ef85c00087661bffe88a09293c (patch) | |
tree | 4f3b09fcdbd14b1c42b0bbe30391d3ba8913aef2 /base/test | |
parent | 86b29d845dbb28a0bbd7dcd114447234ce641e0a (diff) | |
download | chromium_src-19368c060c5a43ef85c00087661bffe88a09293c.zip chromium_src-19368c060c5a43ef85c00087661bffe88a09293c.tar.gz chromium_src-19368c060c5a43ef85c00087661bffe88a09293c.tar.bz2 |
iOS gtest launcher: make simple unit tests like base_unittests work
BUG=426870
R=lliabraa@chromium.org, sky@chromium.org
Review URL: https://codereview.chromium.org/861093004
Cr-Commit-Position: refs/heads/master@{#312829}
Diffstat (limited to 'base/test')
-rw-r--r-- | base/test/gtest_util.cc | 5 | ||||
-rw-r--r-- | base/test/gtest_util.h | 5 | ||||
-rw-r--r-- | base/test/gtest_xml_util.cc | 4 | ||||
-rw-r--r-- | base/test/launcher/test_launcher.cc | 6 | ||||
-rw-r--r-- | base/test/launcher/test_launcher.h | 4 | ||||
-rw-r--r-- | base/test/launcher/test_launcher_ios.cc | 35 | ||||
-rw-r--r-- | base/test/launcher/unit_test_launcher.cc | 90 | ||||
-rw-r--r-- | base/test/launcher/unit_test_launcher.h | 32 | ||||
-rw-r--r-- | base/test/test_suite.cc | 4 |
9 files changed, 133 insertions, 52 deletions
diff --git a/base/test/gtest_util.cc b/base/test/gtest_util.cc index f98320c..c0bc04a 100644 --- a/base/test/gtest_util.cc +++ b/base/test/gtest_util.cc @@ -11,6 +11,11 @@ namespace base { +std::string FormatFullTestName(const std::string& test_case_name, + const std::string& test_name) { + return test_case_name + "." + test_name; +} + std::vector<SplitTestName> GetCompiledInTests() { testing::UnitTest* const unit_test = testing::UnitTest::GetInstance(); diff --git a/base/test/gtest_util.h b/base/test/gtest_util.h index d10c72f..77cc924 100644 --- a/base/test/gtest_util.h +++ b/base/test/gtest_util.h @@ -18,6 +18,11 @@ class FilePath; // First value is test case name, second one is test name. typedef std::pair<std::string, std::string> SplitTestName; +// Constructs a full test name given a test case name and a test name, +// e.g. for test case "A" and test name "B" returns "A.B". +std::string FormatFullTestName(const std::string& test_case_name, + const std::string& test_name); + // Returns a vector of gtest-based tests compiled into // current executable. std::vector<SplitTestName> GetCompiledInTests(); diff --git a/base/test/gtest_xml_util.cc b/base/test/gtest_xml_util.cc index 7a5ba8a..db8cc2d 100644 --- a/base/test/gtest_xml_util.cc +++ b/base/test/gtest_xml_util.cc @@ -7,6 +7,7 @@ #include "base/files/file_util.h" #include "base/logging.h" #include "base/strings/stringprintf.h" +#include "base/test/gtest_util.h" #include "base/test/launcher/test_launcher.h" #include "third_party/libxml/chromium/libxml_utils.h" @@ -146,8 +147,7 @@ bool ProcessGTestOutput(const base::FilePath& output_file, std::string test_name; if (!xml_reader.NodeAttribute("name", &test_name)) return false; - result.full_name = TestLauncher::FormatFullTestName(test_case_name, - test_name); + result.full_name = FormatFullTestName(test_case_name, test_name); result.elapsed_time = TimeDelta(); diff --git a/base/test/launcher/test_launcher.cc b/base/test/launcher/test_launcher.cc index b5316ad..667d1eb 100644 --- a/base/test/launcher/test_launcher.cc +++ b/base/test/launcher/test_launcher.cc @@ -686,12 +686,6 @@ void TestLauncher::OnTestFinished(const TestResult& result) { test_started_count_ += retry_started_count; } -// static -std::string TestLauncher::FormatFullTestName(const std::string& test_case_name, - const std::string& test_name) { - return test_case_name + "." + test_name; -} - bool TestLauncher::Init() { const CommandLine* command_line = CommandLine::ForCurrentProcess(); diff --git a/base/test/launcher/test_launcher.h b/base/test/launcher/test_launcher.h index 27909d4..544df63 100644 --- a/base/test/launcher/test_launcher.h +++ b/base/test/launcher/test_launcher.h @@ -115,10 +115,6 @@ class TestLauncher { // Called when a test has finished running. void OnTestFinished(const TestResult& result); - // Constructs a full test name given a test case name and a test name. - static std::string FormatFullTestName(const std::string& test_case_name, - const std::string& test_name); - private: bool Init() WARN_UNUSED_RESULT; diff --git a/base/test/launcher/test_launcher_ios.cc b/base/test/launcher/test_launcher_ios.cc index 82353cc..7028133 100644 --- a/base/test/launcher/test_launcher_ios.cc +++ b/base/test/launcher/test_launcher_ios.cc @@ -15,6 +15,7 @@ #include "base/message_loop/message_loop.h" #include "base/path_service.h" #include "base/process/launch.h" +#include "base/strings/string_util.h" #include "base/test/launcher/unit_test_launcher.h" #include "base/test/test_switches.h" #include "base/test/test_timeouts.h" @@ -54,9 +55,9 @@ void PrintUsage() { fflush(stdout); } -class IOSUnitTestLauncherDelegate : public base::UnitTestLauncherDelegate { +class IOSUnitTestPlatformDelegate : public base::UnitTestPlatformDelegate { public: - IOSUnitTestLauncherDelegate() : base::UnitTestLauncherDelegate(0, false) { + IOSUnitTestPlatformDelegate() { } bool Init() WARN_UNUSED_RESULT { @@ -107,6 +108,27 @@ class IOSUnitTestLauncherDelegate : public base::UnitTestLauncherDelegate { return base::ReadTestNamesFromFile(test_list_path, output); } + bool CreateTemporaryFile(base::FilePath* path) override { + if (!CreateTemporaryDirInDir(writable_path_, std::string(), path)) + return false; + *path = path->AppendASCII("test_results.xml"); + return true; + } + + base::CommandLine GetCommandLineForChildGTestProcess( + const std::vector<std::string>& test_names, + const base::FilePath& output_file) override { + base::CommandLine cmd_line(dir_exe_.AppendASCII(test_name_ + ".app")); + cmd_line.AppendSwitchPath(switches::kTestLauncherOutput, output_file); + cmd_line.AppendSwitchASCII(base::kGTestFilterFlag, + JoinString(test_names, ":")); + return cmd_line; + } + + std::string GetWrapperForChildGTestProcess() override { + return dir_exe_.AppendASCII("iossim").value(); + } + private: // Directory containing test launcher's executable. base::FilePath dir_exe_; @@ -117,7 +139,7 @@ class IOSUnitTestLauncherDelegate : public base::UnitTestLauncherDelegate { // Path that launched test binary can write to. base::FilePath writable_path_; - DISALLOW_COPY_AND_ASSIGN(IOSUnitTestLauncherDelegate); + DISALLOW_COPY_AND_ASSIGN(IOSUnitTestPlatformDelegate); }; } // namespace @@ -138,12 +160,13 @@ int main(int argc, char** argv) { base::MessageLoopForIO message_loop; - IOSUnitTestLauncherDelegate delegate; - if (!delegate.Init()) { - fprintf(stderr, "Failed to intialize test launcher delegate.\n"); + IOSUnitTestPlatformDelegate platform_delegate; + if (!platform_delegate.Init()) { + fprintf(stderr, "Failed to intialize test launcher platform delegate.\n"); fflush(stderr); return 1; } + base::UnitTestLauncherDelegate delegate(&platform_delegate, 0, false); // Force one job since we can't run multiple simulators in parallel. base::TestLauncher launcher(&delegate, 1); bool success = launcher.Run(); diff --git a/base/test/launcher/unit_test_launcher.cc b/base/test/launcher/unit_test_launcher.cc index a31b6db..2a4e748 100644 --- a/base/test/launcher/unit_test_launcher.cc +++ b/base/test/launcher/unit_test_launcher.cc @@ -85,20 +85,44 @@ void PrintUsage() { fflush(stdout); } -// Returns command line for child GTest process based on the command line -// of current process. |test_names| is a vector of test full names -// (e.g. "A.B"), |output_file| is path to the GTest XML output file. -CommandLine GetCommandLineForChildGTestProcess( - const std::vector<std::string>& test_names, - const base::FilePath& output_file) { - CommandLine new_cmd_line(*CommandLine::ForCurrentProcess()); +class DefaultUnitTestPlatformDelegate : public UnitTestPlatformDelegate { + public: + DefaultUnitTestPlatformDelegate() { + } - new_cmd_line.AppendSwitchPath(switches::kTestLauncherOutput, output_file); - new_cmd_line.AppendSwitchASCII(kGTestFilterFlag, JoinString(test_names, ":")); - new_cmd_line.AppendSwitch(kSingleProcessTestsFlag); + private: + // UnitTestPlatformDelegate: + bool GetTests(std::vector<SplitTestName>* output) override { + *output = GetCompiledInTests(); + return true; + } - return new_cmd_line; -} + bool CreateTemporaryFile(base::FilePath* path) override { + if (!CreateNewTempDirectory(FilePath::StringType(), path)) + return false; + *path = path->AppendASCII("test_results.xml"); + return true; + } + + CommandLine GetCommandLineForChildGTestProcess( + const std::vector<std::string>& test_names, + const base::FilePath& output_file) override { + CommandLine new_cmd_line(*CommandLine::ForCurrentProcess()); + + new_cmd_line.AppendSwitchPath(switches::kTestLauncherOutput, output_file); + new_cmd_line.AppendSwitchASCII(kGTestFilterFlag, + JoinString(test_names, ":")); + new_cmd_line.AppendSwitch(kSingleProcessTestsFlag); + + return new_cmd_line; + } + + std::string GetWrapperForChildGTestProcess() override { + return std::string(); + } + + DISALLOW_COPY_AND_ASSIGN(DefaultUnitTestPlatformDelegate); +}; bool GetSwitchValueAsInt(const std::string& switch_name, int* result) { if (!CommandLine::ForCurrentProcess()->HasSwitch(switch_name)) @@ -169,7 +193,9 @@ int LaunchUnitTestsInternal(const RunTestSuiteCallback& run_test_suite, MessageLoopForIO message_loop; - UnitTestLauncherDelegate delegate(batch_limit, use_job_objects); + DefaultUnitTestPlatformDelegate platform_delegate; + UnitTestLauncherDelegate delegate( + &platform_delegate, batch_limit, use_job_objects); base::TestLauncher launcher(&delegate, default_jobs); bool success = launcher.Run(); @@ -221,9 +247,13 @@ int LaunchUnitTests(int argc, } #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( + UnitTestPlatformDelegate* platform_delegate, + size_t batch_limit, + bool use_job_objects) + : platform_delegate_(platform_delegate), + batch_limit_(batch_limit), + use_job_objects_(use_job_objects) { } UnitTestLauncherDelegate::~UnitTestLauncherDelegate() { @@ -238,8 +268,7 @@ UnitTestLauncherDelegate::GTestCallbackState::~GTestCallbackState() { bool UnitTestLauncherDelegate::GetTests(std::vector<SplitTestName>* output) { DCHECK(thread_checker_.CalledOnValidThread()); - *output = GetCompiledInTests(); - return true; + return platform_delegate_->GetTests(output); } bool UnitTestLauncherDelegate::ShouldRunTest(const std::string& test_case_name, @@ -259,7 +288,8 @@ size_t UnitTestLauncherDelegate::RunTests( for (size_t i = 0; i < test_names.size(); i++) { batch.push_back(test_names[i]); - if (batch.size() >= batch_limit_) { + // Use 0 to indicate unlimited batch size. + if (batch.size() >= batch_limit_ && batch_limit_ != 0) { RunBatch(test_launcher, batch); batch.clear(); } @@ -293,13 +323,12 @@ void UnitTestLauncherDelegate::RunSerially( // per run to ensure clean state and make it possible to launch multiple // processes in parallel. base::FilePath output_file; - CHECK(CreateNewTempDirectory(FilePath::StringType(), &output_file)); - output_file = output_file.AppendASCII("test_results.xml"); + CHECK(platform_delegate_->CreateTemporaryFile(&output_file)); std::vector<std::string> current_test_names; current_test_names.push_back(test_name); - CommandLine cmd_line( - GetCommandLineForChildGTestProcess(current_test_names, output_file)); + CommandLine cmd_line(platform_delegate_->GetCommandLineForChildGTestProcess( + current_test_names, output_file)); GTestCallbackState callback_state; callback_state.test_launcher = test_launcher; @@ -307,7 +336,9 @@ void UnitTestLauncherDelegate::RunSerially( callback_state.output_file = output_file; test_launcher->LaunchChildGTestProcess( - cmd_line, std::string(), TestTimeouts::test_launcher_timeout(), + cmd_line, + platform_delegate_->GetWrapperForChildGTestProcess(), + TestTimeouts::test_launcher_timeout(), use_job_objects_ ? TestLauncher::USE_JOB_OBJECTS : 0, Bind(&UnitTestLauncherDelegate::SerialGTestCallback, Unretained(this), callback_state, new_test_names)); @@ -325,11 +356,10 @@ void UnitTestLauncherDelegate::RunBatch( // per run to ensure clean state and make it possible to launch multiple // processes in parallel. base::FilePath output_file; - CHECK(CreateNewTempDirectory(FilePath::StringType(), &output_file)); - output_file = output_file.AppendASCII("test_results.xml"); + CHECK(platform_delegate_->CreateTemporaryFile(&output_file)); - CommandLine cmd_line( - GetCommandLineForChildGTestProcess(test_names, output_file)); + CommandLine cmd_line(platform_delegate_->GetCommandLineForChildGTestProcess( + test_names, output_file)); // Adjust the timeout depending on how many tests we're running // (note that e.g. the last batch of tests will be smaller). @@ -346,7 +376,9 @@ void UnitTestLauncherDelegate::RunBatch( callback_state.output_file = output_file; test_launcher->LaunchChildGTestProcess( - cmd_line, std::string(), timeout, + cmd_line, + platform_delegate_->GetWrapperForChildGTestProcess(), + timeout, use_job_objects_ ? TestLauncher::USE_JOB_OBJECTS : 0, Bind(&UnitTestLauncherDelegate::GTestCallback, Unretained(this), callback_state)); diff --git a/base/test/launcher/unit_test_launcher.h b/base/test/launcher/unit_test_launcher.h index 0f661db..e4997a0 100644 --- a/base/test/launcher/unit_test_launcher.h +++ b/base/test/launcher/unit_test_launcher.h @@ -33,10 +33,38 @@ int LaunchUnitTests(int argc, const RunTestSuiteCallback& run_test_suite); #endif // defined(OS_WIN) +// Delegate to abstract away platform differences for unit tests. +class UnitTestPlatformDelegate { + public: + // Called to get names of tests available for running. The delegate + // must put the result in |output| and return true on success. + virtual bool GetTests(std::vector<SplitTestName>* output) = 0; + + // Called to create a temporary file. The delegate must put the resulting + // path in |path| and return true on success. + virtual bool CreateTemporaryFile(base::FilePath* path) = 0; + + // Returns command line for child GTest process based on the command line + // of current process. |test_names| is a vector of test full names + // (e.g. "A.B"), |output_file| is path to the GTest XML output file. + virtual CommandLine GetCommandLineForChildGTestProcess( + const std::vector<std::string>& test_names, + const base::FilePath& output_file) = 0; + + // Returns wrapper to use for child GTest process. Empty string means + // no wrapper. + virtual std::string GetWrapperForChildGTestProcess() = 0; + + protected: + ~UnitTestPlatformDelegate() {} +}; + // 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(UnitTestPlatformDelegate* delegate, + size_t batch_limit, + bool use_job_objects); ~UnitTestLauncherDelegate() override; private: @@ -93,6 +121,8 @@ class UnitTestLauncherDelegate : public TestLauncherDelegate { ThreadChecker thread_checker_; + UnitTestPlatformDelegate* platform_delegate_; + // Maximum number of tests to run in a single batch. size_t batch_limit_; diff --git a/base/test/test_suite.cc b/base/test/test_suite.cc index a6fc201..903e93e 100644 --- a/base/test/test_suite.cc +++ b/base/test/test_suite.cc @@ -171,7 +171,6 @@ void TestSuite::ResetCommandLine() { listeners.Append(new TestClientInitializer); } -#if !defined(OS_IOS) void TestSuite::AddTestLauncherResultPrinter() { // Only add the custom printer if requested. if (!base::CommandLine::ForCurrentProcess()->HasSwitch( @@ -197,7 +196,6 @@ void TestSuite::AddTestLauncherResultPrinter() { testing::UnitTest::GetInstance()->listeners(); listeners.Append(printer); } -#endif // !defined(OS_IOS) // Don't add additional code to this method. Instead add it to // Initialize(). See bug 6436. @@ -326,9 +324,7 @@ void TestSuite::Initialize() { CatchMaybeTests(); ResetCommandLine(); -#if !defined(OS_IOS) AddTestLauncherResultPrinter(); -#endif // !defined(OS_IOS) TestTimeouts::Initialize(); |