| Index: chrome/test/out_of_proc_test_runner.cc
|
| diff --git a/chrome/test/out_of_proc_test_runner.cc b/chrome/test/out_of_proc_test_runner.cc
|
| index 4d70e17f2953b22a011c77843add432833d10719..1b169eb0ab3dce31fdeb2d364663c453a1473614 100644
|
| --- a/chrome/test/out_of_proc_test_runner.cc
|
| +++ b/chrome/test/out_of_proc_test_runner.cc
|
| @@ -6,6 +6,7 @@
|
| #include <vector>
|
|
|
| #include "base/command_line.h"
|
| +#include "base/environment.h"
|
| #include "base/file_util.h"
|
| #include "base/hash_tables.h"
|
| #include "base/linked_ptr.h"
|
| @@ -66,6 +67,11 @@ const char kHelpFlag[] = "help";
|
|
|
| const char kTestTerminateTimeoutFlag[] = "test-terminate-timeout";
|
|
|
| +// The environment variable name for the total number of test shards.
|
| +static const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS";
|
| +// The environment variable name for the test shard index.
|
| +static const char kTestShardIndex[] = "GTEST_SHARD_INDEX";
|
| +
|
| // How long we wait for the subprocess to exit (with a success/failure code).
|
| // See http://crbug.com/43862 for some discussion of the value.
|
| const int kDefaultTestTimeoutMs = 20000;
|
| @@ -74,6 +80,67 @@ const int kDefaultTestTimeoutMs = 20000;
|
| static const FilePath::CharType kDefaultOutputFile[] = FILE_PATH_LITERAL(
|
| "test_detail.xml");
|
|
|
| +// Parses the environment variable var as an Int32. If it is unset, returns
|
| +// default_val. If it is set, unsets it then converts it to Int32 before
|
| +// returning it. If unsetting or converting to an Int32 fails, print an
|
| +// error and exit with failure.
|
| +int32 Int32FromEnvOrDie(const char* const var, int32 default_val) {
|
| + scoped_ptr<base::Environment> env(base::Environment::Create());
|
| + std::string str_val;
|
| + int32 result;
|
| + if (!env->GetVar(var, &str_val))
|
| + return default_val;
|
| + if (!env->UnSetVar(var)) {
|
| + LOG(ERROR) << "Invalid environment: we could not unset " << var << ".\n";
|
| + exit(EXIT_FAILURE);
|
| + }
|
| + if (!base::StringToInt(str_val, &result)) {
|
| + LOG(ERROR) << "Invalid environment: " << var << " is not an integer.\n";
|
| + exit(EXIT_FAILURE);
|
| + }
|
| + return result;
|
| +}
|
| +
|
| +// Checks whether sharding is enabled by examining the relevant
|
| +// environment variable values. If the variables are present,
|
| +// but inconsistent (i.e., shard_index >= total_shards), prints
|
| +// an error and exits.
|
| +bool ShouldShard(int32* total_shards, int32* shard_index) {
|
| + *total_shards = Int32FromEnvOrDie(kTestTotalShards, -1);
|
| + *shard_index = Int32FromEnvOrDie(kTestShardIndex, -1);
|
| +
|
| + if (*total_shards == -1 && *shard_index == -1) {
|
| + return false;
|
| + } else if (*total_shards == -1 && *shard_index != -1) {
|
| + LOG(ERROR) << "Invalid environment variables: you have "
|
| + << kTestShardIndex << " = " << *shard_index
|
| + << ", but have left " << kTestTotalShards << " unset.\n";
|
| + exit(EXIT_FAILURE);
|
| + } else if (*total_shards != -1 && *shard_index == -1) {
|
| + LOG(ERROR) << "Invalid environment variables: you have "
|
| + << kTestTotalShards << " = " << *total_shards
|
| + << ", but have left " << kTestShardIndex << " unset.\n";
|
| + exit(EXIT_FAILURE);
|
| + } else if (*shard_index < 0 || *shard_index >= *total_shards) {
|
| + LOG(ERROR) << "Invalid environment variables: we require 0 <= "
|
| + << kTestShardIndex << " < " << kTestTotalShards
|
| + << ", but you have " << kTestShardIndex << "=" << *shard_index
|
| + << ", " << kTestTotalShards << "=" << *total_shards << ".\n";
|
| + exit(EXIT_FAILURE);
|
| + }
|
| +
|
| + return *total_shards > 1;
|
| +}
|
| +
|
| +// Given the total number of shards, the shard index, and the test id, returns
|
| +// true iff the test should be run on this shard. The test id is some arbitrary
|
| +// but unique non-negative integer assigned by this launcher to each test
|
| +// method. Assumes that 0 <= shard_index < total_shards, which is first
|
| +// verified in ShouldShard().
|
| +bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) {
|
| + return (test_id % total_shards) == shard_index;
|
| +}
|
| +
|
| // A helper class to output results.
|
| // Note: as currently XML is the only supported format by gtest, we don't
|
| // check output format (e.g. "xml:" prefix) here and output an XML file
|
| @@ -364,10 +431,15 @@ bool RunTests() {
|
| negative_filter = filter.substr(dash_pos + 1); // Everything after the dash.
|
| }
|
|
|
| + int num_runnable_tests = 0;
|
| int test_run_count = 0;
|
| int ignored_failure_count = 0;
|
| std::vector<std::string> failed_tests;
|
|
|
| + int32 total_shards;
|
| + int32 shard_index;
|
| + bool should_shard = ShouldShard(&total_shards, &shard_index);
|
| +
|
| ResultsPrinter printer(*command_line);
|
| for (int i = 0; i < unit_test->total_test_case_count(); ++i) {
|
| const testing::TestCase* test_case = unit_test->GetTestCase(i);
|
| @@ -393,6 +465,17 @@ bool RunTests() {
|
| false, false, false, 0);
|
| continue;
|
| }
|
| + // Decide if this test should be run.
|
| + bool should_run = true;
|
| + if (should_shard) {
|
| + should_run = ShouldRunTestOnShard(total_shards, shard_index,
|
| + num_runnable_tests);
|
| + }
|
| + num_runnable_tests += 1;
|
| + // If sharding is enabled and the test should not be run, skip it.
|
| + if (!should_run) {
|
| + continue;
|
| + }
|
| base::Time start_time = base::Time::Now();
|
| ++test_run_count;
|
| int exit_code = RunTest(test_name);
|
|
|