Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(462)

Side by Side Diff: third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py

Issue 2082653004: blink/run-webkit-tests: Allow seeding the random test run order and write out value. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixing tests. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (C) 2010 Google Inc. All rights reserved. 1 # Copyright (C) 2010 Google Inc. All rights reserved.
2 # Copyright (C) 2010 Gabor Rapcsanyi (rgabor@inf.u-szeged.hu), University of Sze ged 2 # Copyright (C) 2010 Gabor Rapcsanyi (rgabor@inf.u-szeged.hu), University of Sze ged
3 # 3 #
4 # Redistribution and use in source and binary forms, with or without 4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions are 5 # modification, are permitted provided that the following conditions are
6 # met: 6 # met:
7 # 7 #
8 # * Redistributions of source code must retain the above copyright 8 # * Redistributions of source code must retain the above copyright
9 # notice, this list of conditions and the following disclaimer. 9 # notice, this list of conditions and the following disclaimer.
10 # * Redistributions in binary form must reproduce the above 10 # * Redistributions in binary form must reproduce the above
(...skipping 22 matching lines...) Expand all
33 starting the required helper servers, deciding the order and way to 33 starting the required helper servers, deciding the order and way to
34 run the tests, retrying fails tests and collecting the test results, 34 run the tests, retrying fails tests and collecting the test results,
35 including crash logs, and mismatches with expectations. 35 including crash logs, and mismatches with expectations.
36 36
37 The Manager object has a constructor and one main method called run. 37 The Manager object has a constructor and one main method called run.
38 """ 38 """
39 39
40 import json 40 import json
41 import logging 41 import logging
42 import random 42 import random
43 import re
43 import sys 44 import sys
44 import time 45 import time
45 46
46 from webkitpy.common.net.file_uploader import FileUploader 47 from webkitpy.common.net.file_uploader import FileUploader
47 from webkitpy.layout_tests.controllers.layout_test_finder import LayoutTestFinde r 48 from webkitpy.layout_tests.controllers.layout_test_finder import LayoutTestFinde r
48 from webkitpy.layout_tests.controllers.layout_test_runner import LayoutTestRunne r 49 from webkitpy.layout_tests.controllers.layout_test_runner import LayoutTestRunne r
49 from webkitpy.layout_tests.controllers.test_result_writer import TestResultWrite r 50 from webkitpy.layout_tests.controllers.test_result_writer import TestResultWrite r
50 from webkitpy.layout_tests.layout_package import json_results_generator 51 from webkitpy.layout_tests.layout_package import json_results_generator
51 from webkitpy.layout_tests.models import test_expectations 52 from webkitpy.layout_tests.models import test_expectations
52 from webkitpy.layout_tests.models import test_failures 53 from webkitpy.layout_tests.models import test_failures
(...skipping 29 matching lines...) Expand all
82 self.HTTP_SUBDIR = 'http' + port.TEST_PATH_SEPARATOR 83 self.HTTP_SUBDIR = 'http' + port.TEST_PATH_SEPARATOR
83 self.INSPECTOR_SUBDIR = 'inspector' + port.TEST_PATH_SEPARATOR 84 self.INSPECTOR_SUBDIR = 'inspector' + port.TEST_PATH_SEPARATOR
84 self.PERF_SUBDIR = 'perf' 85 self.PERF_SUBDIR = 'perf'
85 self.WEBSOCKET_SUBDIR = 'websocket' + port.TEST_PATH_SEPARATOR 86 self.WEBSOCKET_SUBDIR = 'websocket' + port.TEST_PATH_SEPARATOR
86 self.LAYOUT_TESTS_DIRECTORY = 'LayoutTests' 87 self.LAYOUT_TESTS_DIRECTORY = 'LayoutTests'
87 self.ARCHIVED_RESULTS_LIMIT = 25 88 self.ARCHIVED_RESULTS_LIMIT = 25
88 self._http_server_started = False 89 self._http_server_started = False
89 self._wptserve_started = False 90 self._wptserve_started = False
90 self._websockets_server_started = False 91 self._websockets_server_started = False
91 92
93 self._random_seed = None
92 self._results_directory = self._port.results_directory() 94 self._results_directory = self._port.results_directory()
93 self._finder = LayoutTestFinder(self._port, self._options) 95 self._finder = LayoutTestFinder(self._port, self._options)
94 self._runner = LayoutTestRunner(self._options, self._port, self._printer , self._results_directory, self._test_is_slow) 96 self._runner = LayoutTestRunner(self._options, self._port, self._printer , self._results_directory, self._test_is_slow)
95 97
96 def run(self, args): 98 def run(self, args):
97 """Run the tests and return a RunDetails object with the results.""" 99 """Run the tests and return a RunDetails object with the results."""
98 start_time = time.time() 100 start_time = time.time()
99 self._printer.write_update("Collecting tests ...") 101 self._printer.write_update("Collecting tests ...")
100 running_all_tests = False 102 running_all_tests = False
101 try: 103 try:
(...skipping 10 matching lines...) Expand all
112 114
113 # Check to make sure we're not skipping every test. 115 # Check to make sure we're not skipping every test.
114 if not tests_to_run: 116 if not tests_to_run:
115 _log.critical('No tests to run.') 117 _log.critical('No tests to run.')
116 return test_run_results.RunDetails(exit_code=test_run_results.NO_TES TS_EXIT_STATUS) 118 return test_run_results.RunDetails(exit_code=test_run_results.NO_TES TS_EXIT_STATUS)
117 119
118 exit_code = self._set_up_run(tests_to_run) 120 exit_code = self._set_up_run(tests_to_run)
119 if exit_code: 121 if exit_code:
120 return test_run_results.RunDetails(exit_code=exit_code) 122 return test_run_results.RunDetails(exit_code=exit_code)
121 123
124 # Write out the random seed and the order we are running the tests in.
125 if not self._options.dry_run:
126 if self._random_seed:
127 self._filesystem.write_text_file(
128 self._filesystem.join(self._results_directory, "random-seed. txt"),
129 "%s\n" % self._random_seed)
130 self._filesystem.write_text_file(
131 self._filesystem.join(self._results_directory, "tests-run-order. txt"),
132 "\n".join(tests_to_run))
Dirk Pranke 2016/06/21 23:47:13 How does this relate to your "write a json file ou
mithro 2016/06/22 08:40:08 Logging the random seed into the json environment
133
122 # Don't retry failures if an explicit list of tests was passed in. 134 # Don't retry failures if an explicit list of tests was passed in.
123 if self._options.retry_failures is None: 135 if self._options.retry_failures is None:
124 should_retry_failures = len(paths) < len(test_names) 136 should_retry_failures = len(paths) < len(test_names)
125 else: 137 else:
126 should_retry_failures = self._options.retry_failures 138 should_retry_failures = self._options.retry_failures
127 139
128 enabled_pixel_tests_in_retry = False 140 enabled_pixel_tests_in_retry = False
129 try: 141 try:
130 self._start_servers(tests_to_run) 142 self._start_servers(tests_to_run)
131 143
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 tests_to_skip = self._finder.skip_tests(paths, test_names, self._expecta tions, self._http_tests(test_names)) 257 tests_to_skip = self._finder.skip_tests(paths, test_names, self._expecta tions, self._http_tests(test_names))
246 tests_to_run = [test for test in test_names if test not in tests_to_skip ] 258 tests_to_run = [test for test in test_names if test not in tests_to_skip ]
247 259
248 if not tests_to_run: 260 if not tests_to_run:
249 return tests_to_run, tests_to_skip 261 return tests_to_run, tests_to_skip
250 262
251 # Create a sorted list of test files so the subset chunk, 263 # Create a sorted list of test files so the subset chunk,
252 # if used, contains alphabetically consecutive tests. 264 # if used, contains alphabetically consecutive tests.
253 if self._options.order == 'natural': 265 if self._options.order == 'natural':
254 tests_to_run.sort(key=self._port.test_key) 266 tests_to_run.sort(key=self._port.test_key)
255 elif self._options.order == 'random': 267 elif self._options.order.startswith('random'):
256 random.shuffle(tests_to_run)
257 elif self._options.order == 'random-seeded':
258 rnd = random.Random() 268 rnd = random.Random()
qyearsley 2016/06/22 17:30:16 This line could be removed (it appears below).
259 rnd.seed(4) # http://xkcd.com/221/ 269
270 groups = re.match('random-seeded(=([0-9]+))?', self._options.order)
qyearsley 2016/06/22 17:30:16 Instead of specifying seeds with an option like `-
Dirk Pranke 2016/06/24 01:53:40 +1 to splitting it into a separate argument.
271 if not groups:
272 seed = int(time.time())
273 elif not groups.group(2):
274 seed = 4 # http://xkcd.com/221/
qyearsley 2016/06/22 17:30:16 It's probably not necessary to necessary to keep t
275 else:
276 seed = int(groups.group(2))
277 _log.info("Test random order seed: %i", seed)
278 self._random_seed = seed
279
280 # Make sure the tests are in sorted before we randomize them.
281 tests_to_run.sort()
282 rnd = random.Random()
283 rnd.seed(seed)
260 rnd.shuffle(tests_to_run) 284 rnd.shuffle(tests_to_run)
261 285
262 tests_to_run, tests_in_other_chunks = self._finder.split_into_chunks(tes ts_to_run) 286 tests_to_run, tests_in_other_chunks = self._finder.split_into_chunks(tes ts_to_run)
263 self._expectations.add_extra_skipped_tests(tests_in_other_chunks) 287 self._expectations.add_extra_skipped_tests(tests_in_other_chunks)
264 tests_to_skip.update(tests_in_other_chunks) 288 tests_to_skip.update(tests_in_other_chunks)
265 289
266 return tests_to_run, tests_to_skip 290 return tests_to_run, tests_to_skip
267 291
268 def _test_input_for_file(self, test_file): 292 def _test_input_for_file(self, test_file):
269 return TestInput(test_file, 293 return TestInput(test_file,
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
553 577
554 stats = {} 578 stats = {}
555 for result in initial_results.results_by_name.values(): 579 for result in initial_results.results_by_name.values():
556 if result.type != test_expectations.SKIP: 580 if result.type != test_expectations.SKIP:
557 stats[result.test_name] = {'results': (_worker_number(result.wor ker_name), result.test_number, result.pid, int( 581 stats[result.test_name] = {'results': (_worker_number(result.wor ker_name), result.test_number, result.pid, int(
558 result.test_run_time * 1000), int(result.total_run_time * 10 00))} 582 result.test_run_time * 1000), int(result.total_run_time * 10 00))}
559 stats_trie = {} 583 stats_trie = {}
560 for name, value in stats.iteritems(): 584 for name, value in stats.iteritems():
561 json_results_generator.add_path_to_trie(name, value, stats_trie) 585 json_results_generator.add_path_to_trie(name, value, stats_trie)
562 return stats_trie 586 return stats_trie
OLDNEW
« no previous file with comments | « no previous file | third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698