Changeset 276670 in webkit
- Timestamp:
- Apr 27, 2021, 3:09:45 PM (5 years ago)
- Location:
- trunk/Tools
- Files:
-
- 6 edited
-
ChangeLog (modified) (1 diff)
-
Scripts/webkitpy/layout_tests/controllers/layout_test_runner.py (modified) (2 diffs)
-
Scripts/webkitpy/layout_tests/controllers/manager.py (modified) (9 diffs)
-
Scripts/webkitpy/layout_tests/models/test.py (modified) (1 diff)
-
Scripts/webkitpy/layout_tests/models/test_input.py (modified) (3 diffs)
-
Scripts/webkitpy/port/base.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Tools/ChangeLog
r276669 r276670 1 2021-04-27 Sam Sneddon <gsnedders@apple.com> 2 3 Make TestInput immutable 4 https://bugs.webkit.org/show_bug.cgi?id=224989 5 6 Reviewed by Jonathan Bedard. 7 8 The main point here is moving computing reference_files and 9 should_run_pixel_test to when we initially construct TestInput, as at 10 this point this happens in the some process and thread (since bug 11 221577), hence there's no real reason for it to happen later. 12 13 In doing this, I've eliminated Port.should_run_as_pixel_test on the 14 basis that no port actually overrode this to apply any different logic, 15 especially given it seems unlikely that any port would want to use 16 different logic here. (Note that ports still have some control through 17 Port.default_pixel_tests.) 18 19 With this done, it should then be possible to make TestInput immutable, 20 which should help make things easier to understand. 21 22 Expect, as it happens, there was a reason for it to happen later: we 23 previously generated all the TestInputs twice, once to find out how 24 many workers we need and then another time to actually run them (plus 25 potentially a third time for retries!). There's no actual reason to do 26 this, so move the creation to Manager.run and pass that list around 27 instead of the Tests. 28 29 * Scripts/webkitpy/layout_tests/controllers/layout_test_runner.py: 30 (LayoutTestRunner.run_tests): Don't update TestInput. 31 (LayoutTestRunner._update_test_input): Deleted. 32 * Scripts/webkitpy/layout_tests/controllers/manager.py: 33 (Manager._test_input_for_file): Moved from _update_test_input and 34 Port.should_run_as_pixel_test. 35 (Manager._get_test_inputs): Deleted. 36 (Manager._multiply_test_inputs): Simplify code used to generated 37 repeated/rerun test inputs. 38 (Manager._update_worker_count): Don't create TestInputs; take 39 test_inputs as arg. 40 (Manager._set_up_run): Rename test_names to test_inputs. 41 (Manager.run): Create TestInput objects here. 42 (Manager._run_test_subset): Take TestInputs not Tests, generate new 43 TestInputs for retry if needed. 44 (Manager._run_tests): Don't create TestInputs; take test_inputs as arg. 45 * Scripts/webkitpy/layout_tests/models/test.py: Fly-by: use __slots__. 46 * Scripts/webkitpy/layout_tests/models/test_input.py: 47 (TestInput): Migrate to attrs. 48 (TestInput.__init__): Deleted. 49 (TestInput.__repr__): Deleted. 50 * Scripts/webkitpy/port/base.py: 51 (Port.should_run_as_pixel_test): Deleted. 52 (Port._should_run_as_pixel_test): Deleted. 53 1 54 2021-04-27 Sam Sneddon <gsnedders@apple.com> 2 55 -
trunk/Tools/Scripts/webkitpy/layout_tests/controllers/layout_test_runner.py
r275773 r276670 95 95 def run_tests(self, expectations, test_inputs, num_workers, retrying, device_type=None): 96 96 self._expectations = expectations 97 self._test_inputs = [] 98 for test_input in test_inputs: 99 self._update_test_input(test_input, device_type) 100 self._test_inputs.append(test_input) 97 self._test_inputs = list(test_inputs) 101 98 102 99 self._retrying = retrying … … 136 133 137 134 return run_results 138 139 def _update_test_input(self, test_input, device_type=None):140 if test_input.reference_files is None:141 # Lazy initialization.142 test_input.reference_files = self._port.reference_files(test_input.test_name, device_type=device_type)143 if test_input.reference_files:144 test_input.should_run_pixel_test = True145 else:146 test_input.should_run_pixel_test = self._port.should_run_as_pixel_test(test_input)147 135 148 136 def _worker_factory(self, worker_connection): -
trunk/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py
r275888 r276670 216 216 217 217 def _test_input_for_file(self, test_file, device_type): 218 reference_files = self._port.reference_files( 219 test_file.test_path, device_type=device_type 220 ) 221 timeout = ( 222 self._options.slow_time_out_ms 223 if self._test_is_slow(test_file.test_path, device_type=device_type) 224 else self._options.time_out_ms 225 ) 226 should_dump_jsconsolelog_in_stderr = ( 227 self._test_should_dump_jsconsolelog_in_stderr( 228 test_file.test_path, device_type=device_type 229 ) 230 ) 231 232 if reference_files: 233 should_run_pixel_test = True 234 elif not self._options.pixel_tests: 235 should_run_pixel_test = False 236 elif self._options.pixel_test_directories: 237 should_run_pixel_test = any( 238 test_file.test_path.startswith(directory) 239 for directory in self._options.pixel_test_directories 240 ) 241 else: 242 should_run_pixel_test = True 243 218 244 return TestInput( 219 245 test_file, 220 self._options.slow_time_out_ms if self._test_is_slow(test_file.test_path, device_type=device_type) else self._options.time_out_ms, 221 test_file.needs_any_server, 222 should_dump_jsconsolelog_in_stderr=self._test_should_dump_jsconsolelog_in_stderr(test_file.test_path, device_type=device_type)) 246 timeout=timeout, 247 needs_servers=test_file.needs_any_server, 248 should_dump_jsconsolelog_in_stderr=should_dump_jsconsolelog_in_stderr, 249 reference_files=reference_files, 250 should_run_pixel_test=should_run_pixel_test, 251 ) 223 252 224 253 def _test_is_slow(self, test_file, device_type): … … 230 259 return self._expectations[device_type].model().has_modifier(test_file, test_expectations.DUMPJSCONSOLELOGINSTDERR) 231 260 232 def _get_test_inputs(self, tests_to_run, repeat_each, iterations, device_type): 233 test_inputs = [] 234 for _ in range(iterations): 235 for test in tests_to_run: 236 for _ in range(repeat_each): 237 test_inputs.append(self._test_input_for_file(test, device_type=device_type)) 238 return test_inputs 239 240 def _update_worker_count(self, test_names, device_type): 241 test_inputs = self._get_test_inputs(test_names, self._options.repeat_each, self._options.iterations, device_type=device_type) 242 worker_count = self._runner.get_worker_count(test_inputs, int(self._options.child_processes)) 261 def _multiply_test_inputs(self, test_inputs, repeat_each, iterations): 262 if repeat_each == 1: 263 per_iteration = list(test_inputs)[:] 264 else: 265 per_iteration = [] 266 for test_input in test_inputs: 267 per_iteration.extend([test_input] * repeat_each) 268 269 return per_iteration * iterations 270 271 def _update_worker_count(self, test_inputs): 272 new_test_inputs = self._multiply_test_inputs(test_inputs, self._options.repeat_each, self._options.iterations) 273 worker_count = self._runner.get_worker_count(new_test_inputs, int(self._options.child_processes)) 243 274 self._options.child_processes = worker_count 244 275 245 def _set_up_run(self, test_ names, device_type):276 def _set_up_run(self, test_inputs, device_type): 246 277 # This must be started before we check the system dependencies, 247 278 # since the helper may do things to make the setup correct. … … 250 281 return False 251 282 252 self._update_worker_count(test_ names, device_type=device_type)283 self._update_worker_count(test_inputs) 253 284 self._port.reset_preferences() 254 285 … … 354 385 if not tests_to_run_by_device[device_type]: 355 386 continue 356 if not self._set_up_run(tests_to_run_by_device[device_type], device_type=device_type): 387 388 test_inputs = [self._test_input_for_file(test, device_type=device_type) 389 for test in tests_to_run_by_device[device_type]] 390 391 if not self._set_up_run(test_inputs, device_type=device_type): 357 392 return test_run_results.RunDetails(exit_code=-1) 358 393 … … 360 395 if not configuration.get('flavor', None): # The --result-report-flavor argument should override wk1/wk2 361 396 configuration['flavor'] = 'wk2' if self._options.webkit_test_runner else 'wk1' 362 temp_initial_results, temp_retry_results, temp_enabled_pixel_tests_in_retry = self._run_test_subset(test s_to_run_by_device[device_type], device_type=device_type)397 temp_initial_results, temp_retry_results, temp_enabled_pixel_tests_in_retry = self._run_test_subset(test_inputs, device_type=device_type) 363 398 364 399 skipped_results = TestRunResults(self._expectations[device_type], len(aggregate_tests_to_skip)) … … 429 464 430 465 def _run_test_subset(self, 431 test s_to_run, # type: List[Test]466 test_inputs, # type: List[TestInput] 432 467 device_type, # type: Optional[DeviceType] 433 468 ): 434 469 try: 435 470 enabled_pixel_tests_in_retry = False 436 initial_results = self._run_tests(test s_to_run, self._options.repeat_each, self._options.iterations, int(self._options.child_processes), retrying=False, device_type=device_type)471 initial_results = self._run_tests(test_inputs, self._options.repeat_each, self._options.iterations, int(self._options.child_processes), retrying=False, device_type=device_type) 437 472 438 473 tests_to_retry = self._tests_to_retry(initial_results, include_crashes=self._port.should_retry_crashes()) … … 441 476 if retry_failures and tests_to_retry: 442 477 enabled_pixel_tests_in_retry = self._force_pixel_tests_if_needed() 478 if enabled_pixel_tests_in_retry: 479 retry_test_inputs = [self._test_input_for_file(test_input.test, device_type=device_type) 480 for test_input in test_inputs 481 if test_input.test.test_path in tests_to_retry] 482 else: 483 retry_test_inputs = [test_input 484 for test_input in test_inputs 485 if test_input.test.test_path in tests_to_retry] 443 486 444 487 _log.info('') 445 488 _log.info("Retrying %s ..." % pluralize(len(tests_to_retry), "unexpected failure")) 446 489 _log.info('') 447 retry_results = self._run_tests( [test for test in tests_to_run if test.test_path in tests_to_retry],490 retry_results = self._run_tests(retry_test_inputs, 448 491 repeat_each=1, 449 492 iterations=1, … … 495 538 496 539 def _run_tests(self, 497 test s_to_run, # type: List[Test]540 test_inputs, # type: List[TestInput] 498 541 repeat_each, # type: int 499 542 iterations, # type: int … … 502 545 device_type, # type: Optional[DeviceType] 503 546 ): 504 test_inputs = self._get_test_inputs(tests_to_run, repeat_each, iterations, device_type=device_type)547 new_test_inputs = self._multiply_test_inputs(test_inputs, repeat_each, iterations) 505 548 506 549 assert self._runner is not None 507 return self._runner.run_tests(self._expectations[device_type], test_inputs, num_workers, retrying, device_type)550 return self._runner.run_tests(self._expectations[device_type], new_test_inputs, num_workers, retrying, device_type) 508 551 509 552 def _clean_up_run(self): -
trunk/Tools/Scripts/webkitpy/layout_tests/models/test.py
r275888 r276670 31 31 32 32 33 @attr.s(frozen=True )33 @attr.s(frozen=True, slots=True) 34 34 class Test(object): 35 35 """Data about a test and its expectations. -
trunk/Tools/Scripts/webkitpy/layout_tests/models/test_input.py
r275773 r276670 1 1 # Copyright (C) 2010 Google Inc. All rights reserved. 2 2 # Copyright (C) 2010 Gabor Rapcsanyi (rgabor@inf.u-szeged.hu), University of Szeged 3 # Copyright (C) 2021 Apple Inc. All rights reserved. 3 4 # 4 5 # Redistribution and use in source and binary forms, with or without … … 29 30 30 31 32 import attr 33 31 34 from .test import Test 32 35 36 37 @attr.s(frozen=True, slots=True) 33 38 class TestInput(object): 34 39 """Information about a test needed to run it. … … 37 42 derived from TestExpectations/test execution options (e.g., timeout). 38 43 """ 39 40 def __init__(self, 41 test, # type: Test 42 timeout=None, # type: Union[None, int, str] 43 needs_servers=None, # type: Optional[bool] 44 should_dump_jsconsolelog_in_stderr=None, # type: Optional[bool] 45 ): 46 # TestInput objects are normally constructed by the manager and passed 47 # to the workers, but these some fields are set lazily in the workers where possible 48 # because they require us to look at the filesystem and we want to be able to do that in parallel. 49 self.test = test 50 self.timeout = timeout # in msecs; should rename this for consistency 51 self.needs_servers = needs_servers 52 self.should_dump_jsconsolelog_in_stderr = should_dump_jsconsolelog_in_stderr 53 self.reference_files = None 44 test = attr.ib(type=Test) 45 timeout = attr.ib(default=None) # type: Union[None, int, str] 46 needs_servers = attr.ib(default=None) # type: Optional[bool] 47 should_dump_jsconsolelog_in_stderr = attr.ib(default=None) # type: Optional[bool] 48 reference_files = attr.ib(default=None) # type: Optional[List[Tuple[str str]]] 49 should_run_pixel_test = attr.ib(default=None) # type: Optional[bool] 54 50 55 51 @property 56 52 def test_name(self): 57 53 return self.test.test_path 58 59 def __repr__(self):60 return "TestInput('%s', timeout=%s, needs_servers=%s, reference_files=%s, should_dump_jsconsolelog_in_stderr=%s)" % (self.test_name, self.timeout, self.needs_servers, self.reference_files, self.should_dump_jsconsolelog_in_stderr) -
trunk/Tools/Scripts/webkitpy/port/base.py
r276669 r276670 1362 1362 pass 1363 1363 1364 def should_run_as_pixel_test(self, test_input):1365 if not self._options.pixel_tests:1366 return False1367 if self._options.pixel_test_directories:1368 return any(test_input.test_name.startswith(directory) for directory in self._options.pixel_test_directories)1369 return self._should_run_as_pixel_test(test_input)1370 1371 def _should_run_as_pixel_test(self, test_input):1372 # Default behavior is to allow all test to run as pixel tests if --pixel-tests is on and1373 # --pixel-test-directory is not specified.1374 return True1375 1376 1364 def _in_flatpak_sandbox(self): 1377 1365 return self._filesystem.exists("/.flatpak-info")
Note:
See TracChangeset
for help on using the changeset viewer.