OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/test/launcher/test_launcher.h" | 5 #include "base/test/launcher/test_launcher.h" |
6 | 6 |
7 #include "base/at_exit.h" | 7 #include "base/at_exit.h" |
| 8 #include "base/base_paths.h" |
8 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/command_line.h" |
| 11 #include "base/files/file_path.h" |
| 12 #include "base/files/file_util.h" |
| 13 #include "base/files/scoped_temp_dir.h" |
| 14 #include "base/format_macros.h" |
| 15 #include "base/message_loop/message_loop.h" |
| 16 #include "base/path_service.h" |
| 17 #include "base/process/launch.h" |
9 #include "base/test/launcher/unit_test_launcher.h" | 18 #include "base/test/launcher/unit_test_launcher.h" |
| 19 #include "base/test/test_switches.h" |
| 20 #include "base/test/test_timeouts.h" |
10 | 21 |
11 namespace { | 22 namespace { |
12 | 23 |
13 int DummyRunTestSuite(void) { | 24 const char kHelpFlag[] = "help"; |
14 return -1; | 25 |
| 26 void PrintUsage() { |
| 27 fprintf(stdout, |
| 28 "Runs tests using the gtest framework, each batch of tests being\n" |
| 29 "run in their own process. Supported command-line flags:\n" |
| 30 "\n" |
| 31 " Common flags:\n" |
| 32 " --gtest_filter=...\n" |
| 33 " Runs a subset of tests (see --gtest_help for more info).\n" |
| 34 "\n" |
| 35 " --help\n" |
| 36 " Shows this message.\n" |
| 37 "\n" |
| 38 " Other flags:\n" |
| 39 " --test-launcher-retry-limit=N\n" |
| 40 " Sets the limit of test retries on failures to N.\n" |
| 41 "\n" |
| 42 " --test-launcher-summary-output=PATH\n" |
| 43 " Saves a JSON machine-readable summary of the run.\n" |
| 44 "\n" |
| 45 " --test-launcher-print-test-stdio=auto|always|never\n" |
| 46 " Controls when full test output is printed.\n" |
| 47 " auto means to print it when the test failed.\n" |
| 48 "\n" |
| 49 " --test-launcher-total-shards=N\n" |
| 50 " Sets the total number of shards to N.\n" |
| 51 "\n" |
| 52 " --test-launcher-shard-index=N\n" |
| 53 " Sets the shard index to run to N (from 0 to TOTAL - 1).\n"); |
| 54 fflush(stdout); |
15 } | 55 } |
16 | 56 |
| 57 class IOSUnitTestLauncherDelegate : public base::UnitTestLauncherDelegate { |
| 58 public: |
| 59 IOSUnitTestLauncherDelegate() : base::UnitTestLauncherDelegate(0, false) { |
| 60 } |
| 61 |
| 62 bool Init() WARN_UNUSED_RESULT { |
| 63 if (!PathService::Get(base::DIR_EXE, &dir_exe_)) { |
| 64 LOG(ERROR) << "Failed to get directory of current executable."; |
| 65 return false; |
| 66 } |
| 67 |
| 68 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); |
| 69 std::vector<std::string> args(command_line->GetArgs()); |
| 70 if (args.size() < 1) { |
| 71 LOG(ERROR) << "Arguments expected."; |
| 72 return false; |
| 73 } |
| 74 test_name_ = args[0]; |
| 75 |
| 76 base::CommandLine cmd_line(dir_exe_.AppendASCII(test_name_ + ".app")); |
| 77 cmd_line.AppendSwitch(switches::kTestLauncherPrintWritablePath); |
| 78 cmd_line.PrependWrapper(dir_exe_.AppendASCII("iossim").value()); |
| 79 |
| 80 std::string raw_output; |
| 81 if (!base::GetAppOutput(cmd_line, &raw_output)) { |
| 82 LOG(ERROR) << "GetAppOutput failed."; |
| 83 return false; |
| 84 } |
| 85 writable_path_ = base::FilePath(raw_output); |
| 86 |
| 87 return true; |
| 88 } |
| 89 |
| 90 bool GetTests(std::vector<base::SplitTestName>* output) override { |
| 91 base::ScopedTempDir temp_dir; |
| 92 if (!temp_dir.CreateUniqueTempDirUnderPath(writable_path_)) |
| 93 return false; |
| 94 base::FilePath test_list_path( |
| 95 temp_dir.path().AppendASCII("test_list.json")); |
| 96 |
| 97 base::CommandLine cmd_line(dir_exe_.AppendASCII(test_name_ + ".app")); |
| 98 cmd_line.AppendSwitchPath(switches::kTestLauncherListTests, test_list_path); |
| 99 cmd_line.PrependWrapper(dir_exe_.AppendASCII("iossim").value()); |
| 100 |
| 101 base::LaunchOptions launch_options; |
| 102 launch_options.wait = true; |
| 103 |
| 104 if (!base::LaunchProcess(cmd_line, launch_options).IsValid()) |
| 105 return false; |
| 106 |
| 107 return base::ReadTestNamesFromFile(test_list_path, output); |
| 108 } |
| 109 |
| 110 private: |
| 111 // Directory containing test launcher's executable. |
| 112 base::FilePath dir_exe_; |
| 113 |
| 114 // Name of the test executable to run. |
| 115 std::string test_name_; |
| 116 |
| 117 // Path that launched test binary can write to. |
| 118 base::FilePath writable_path_; |
| 119 |
| 120 DISALLOW_COPY_AND_ASSIGN(IOSUnitTestLauncherDelegate); |
| 121 }; |
| 122 |
17 } // namespace | 123 } // namespace |
18 | 124 |
19 int main(int argc, char** argv) { | 125 int main(int argc, char** argv) { |
20 base::AtExitManager at_exit; | 126 base::AtExitManager at_exit; |
21 return base::LaunchUnitTests(argc, argv, base::Bind(&DummyRunTestSuite)); | 127 |
| 128 base::CommandLine::Init(argc, argv); |
| 129 |
| 130 if (base::CommandLine::ForCurrentProcess()->HasSwitch(kHelpFlag)) { |
| 131 PrintUsage(); |
| 132 return 0; |
| 133 } |
| 134 |
| 135 base::TimeTicks start_time(base::TimeTicks::Now()); |
| 136 |
| 137 TestTimeouts::Initialize(); |
| 138 |
| 139 base::MessageLoopForIO message_loop; |
| 140 |
| 141 IOSUnitTestLauncherDelegate delegate; |
| 142 if (!delegate.Init()) { |
| 143 fprintf(stderr, "Failed to intialize test launcher delegate.\n"); |
| 144 fflush(stderr); |
| 145 return 1; |
| 146 } |
| 147 // Force one job since we can't run multiple simulators in parallel. |
| 148 base::TestLauncher launcher(&delegate, 1); |
| 149 bool success = launcher.Run(); |
| 150 |
| 151 fprintf(stdout, "Tests took %" PRId64 " seconds.\n", |
| 152 (base::TimeTicks::Now() - start_time).InSeconds()); |
| 153 fflush(stdout); |
| 154 |
| 155 return (success ? 0 : 1); |
22 } | 156 } |
OLD | NEW |