Index: telemetry/telemetry/testing/browser_test_runner.py |
diff --git a/telemetry/telemetry/testing/browser_test_runner.py b/telemetry/telemetry/testing/browser_test_runner.py |
index 8b419dc59862b12162f6821c380de11a6f820b28..0769724efb1ad650cde6560cc363ffc1178e5936 100644 |
--- a/telemetry/telemetry/testing/browser_test_runner.py |
+++ b/telemetry/telemetry/testing/browser_test_runner.py |
@@ -94,7 +94,21 @@ def _TestTime(test, test_times, default_test_time): |
return test_times.get(test.shortName()) or default_test_time |
-def _SplitShardsByTime(test_cases, total_shards, test_times): |
+def _DebugShardDistributions(shards, test_times): |
+ for i, s in enumerate(shards): |
+ num_tests = len(s) |
+ if test_times: |
+ median = _MedianTestTime(test_times) |
+ shard_time = 0.0 |
+ for t in s: |
+ shard_time += _TestTime(t, test_times, median) |
+ print 'shard %d: %d seconds (%d tests)' % (i, shard_time, num_tests) |
+ else: |
+ print 'shard %d: %d tests (unknown duration)' % (i, num_tests) |
+ |
+ |
+def _SplitShardsByTime(test_cases, total_shards, test_times, |
+ debug_shard_distributions): |
median = _MedianTestTime(test_times) |
shards = [] |
for i in xrange(total_shards): |
@@ -121,13 +135,18 @@ def _SplitShardsByTime(test_cases, total_shards, test_times): |
shards[min_shard_index]['tests'].append(t) |
shards[min_shard_index]['total_time'] += _TestTime(t, test_times, median) |
- return [s['tests'] for s in shards] |
+ res = [s['tests'] for s in shards] |
+ if debug_shard_distributions: |
+ _DebugShardDistributions(res, test_times) |
+ |
+ return res |
_TEST_GENERATOR_PREFIX = 'GenerateTestCases_' |
def _LoadTests(test_class, finder_options, filter_regex_str, |
- total_shards, shard_index, opt_test_times=None): |
+ total_shards, shard_index, test_times, |
+ debug_shard_distributions): |
test_cases = [] |
filter_regex = re.compile(filter_regex_str) |
for name, method in inspect.getmembers( |
@@ -153,13 +172,22 @@ def _LoadTests(test_class, finder_options, filter_regex_str, |
setattr(test_class, generated_test_name, _GenerateTestMethod( |
based_method, args)) |
test_cases.append(test_class(generated_test_name)) |
- if opt_test_times: |
+ if test_times: |
# Assign tests to shards. |
- shards = _SplitShardsByTime(test_cases, total_shards, opt_test_times) |
+ shards = _SplitShardsByTime(test_cases, total_shards, test_times, |
+ debug_shard_distributions) |
return shards[shard_index] |
else: |
test_cases.sort(key=lambda t: t.shortName()) |
test_range = _TestRangeForShard(total_shards, shard_index, len(test_cases)) |
+ if debug_shard_distributions: |
+ tmp_shards = [] |
+ for i in xrange(total_shards): |
+ tmp_range = _TestRangeForShard(total_shards, i, len(test_cases)) |
+ tmp_shards.append(test_cases[tmp_range[0]:tmp_range[1]]) |
+ # Can edit the code to get 'test_times' passed in here for |
+ # debugging and comparison purposes. |
+ _DebugShardDistributions(tmp_shards, None) |
return test_cases[test_range[0]:test_range[1]] |
@@ -209,6 +237,10 @@ def Run(project_config, test_run_options, args): |
'The file format is that written by ' |
'--write-abbreviated-json-results-to. This information is used to more ' |
'evenly distribute tests among shards.')) |
+ parser.add_argument('--debug-shard-distributions', |
+ action='store_true', default=False, |
+ help='Print debugging information about the shards\' test distributions') |
+ |
option, extra_args = parser.parse_known_args(args) |
for start_dir in project_config.start_dirs: |
@@ -243,7 +275,7 @@ def Run(project_config, test_run_options, args): |
suite = unittest.TestSuite() |
for test in _LoadTests(test_class, options, option.test_filter, |
option.total_shards, option.shard_index, |
- test_times): |
+ test_times, option.debug_shard_distributions): |
suite.addTest(test) |
results = unittest.TextTestRunner( |