WebKit Bugzilla
Attachment 356439 Details for
Bug 192161
: webkitpy: Sort tests by associated device type
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-192161-20181203170357.patch (text/plain), 19.51 KB, created by
Jonathan Bedard
on 2018-12-03 17:03:58 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Jonathan Bedard
Created:
2018-12-03 17:03:58 PST
Size:
19.51 KB
patch
obsolete
>Index: Tools/ChangeLog >=================================================================== >--- Tools/ChangeLog (revision 238831) >+++ Tools/ChangeLog (working copy) >@@ -1,3 +1,50 @@ >+2018-12-03 Jonathan Bedard <jbedard@apple.com> >+ >+ webkitpy: Sort tests by associated device type >+ https://bugs.webkit.org/show_bug.cgi?id=192161 >+ <rdar://problem/46345392> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Sort tests by device type and make an effort to run each specified device type. >+ Do not run tests if their specified device is not available. >+ >+ * Scripts/webkitpy/common/memoized.py: >+ (memoized.__call__): Support kwargs in memoized function. >+ * Scripts/webkitpy/layout_tests/controllers/manager.py: >+ (Manager.run): Assign each test a device type. Then, generate a list of >+ device types to sequentially iterate through. Note that a test will run >+ on the first device which matches, so if and iPhone 7 is available and >+ the test requires an iPhone, the test will be run on the iPhone 7. >+ * Scripts/webkitpy/port/base.py: >+ (Port): >+ (Port.default_child_processes): Accept additional arguments. >+ * Scripts/webkitpy/port/device_port.py: >+ (DevicePort): >+ (DevicePort._device_type_with_version): Adds version to the DeviceType. >+ (DevicePort.default_child_processes): Allows default_child_processes to be >+ attached to a device type. >+ (DevicePort.setup_test_run): Use _device_type_with_version. >+ * Scripts/webkitpy/port/ios_device.py: >+ (IOSDevicePort): >+ (IOSDevicePort.default_child_processes): Deleted. >+ * Scripts/webkitpy/port/ios_simulator.py: >+ (IOSSimulatorPort.default_child_processes): Deleted. >+ (IOSSimulatorPort.check_sys_deps): Deleted. >+ * Scripts/webkitpy/port/mac.py: >+ (MacPort.default_child_processes): Accept additional arguments. >+ * Scripts/webkitpy/port/test.py: >+ * Scripts/webkitpy/port/watch_device.py: >+ (WatchDevicePort): >+ (WatchDevicePort.default_child_processes): Deleted. >+ * Scripts/webkitpy/port/watch_simulator.py: >+ (WatchSimulatorPort.default_child_processes): Deleted. >+ (WatchSimulatorPort.check_sys_deps): Deleted. >+ * Scripts/webkitpy/xcode/simulated_device.py: >+ (SimulatedDeviceManager): >+ (SimulatedDeviceManager.device_count_for_type): Count the number of devices >+ available for a specific device type. >+ > 2018-12-03 Chris Dumez <cdumez@apple.com> > > Regression(PSON) Google OAuth is broken in private sessions >Index: Tools/Scripts/webkitpy/common/memoized.py >=================================================================== >--- Tools/Scripts/webkitpy/common/memoized.py (revision 238808) >+++ Tools/Scripts/webkitpy/common/memoized.py (working copy) >@@ -37,12 +37,12 @@ class memoized(object): > self._function = function > self._results_cache = {} > >- def __call__(self, *args): >+ def __call__(self, *args, **kwargs): > try: > return self._results_cache[args] > except KeyError: > # If we didn't find the args in our cache, call and save the results. >- result = self._function(*args) >+ result = self._function(*args, **kwargs) > self._results_cache[args] = result > return result > # FIXME: We may need to handle TypeError here in the case >Index: Tools/Scripts/webkitpy/layout_tests/controllers/manager.py >=================================================================== >--- Tools/Scripts/webkitpy/layout_tests/controllers/manager.py (revision 238808) >+++ Tools/Scripts/webkitpy/layout_tests/controllers/manager.py (working copy) >@@ -206,24 +206,23 @@ class Manager(object): > _log.critical('No tests to run.') > return test_run_results.RunDetails(exit_code=-1) > >- default_device_tests = [] >- > # Look for tests with custom device requirements. >- custom_device_tests = defaultdict(list) >+ test_device_mapping = defaultdict(list) > for test_file in tests_to_run: >- custom_device = self._custom_device_for_test(test_file) >- if custom_device: >- custom_device_tests[custom_device].append(test_file) >- else: >- default_device_tests.append(test_file) >+ test_device_mapping[self._custom_device_for_test(test_file) or self._port.DEFAULT_DEVICE_TYPE].append(test_file) > >- if custom_device_tests: >- for device_type, tests in custom_device_tests.iteritems(): >- _log.debug('{} tests use device {}'.format(len(tests), device_type)) >- >- initial_results = None >- retry_results = None >- enabled_pixel_tests_in_retry = False >+ # Partial device types might actually match more descriptive device types, in which case we can boot fewer simulators. >+ device_type_order = [] >+ types_with_family = [] >+ remaining_types = [] >+ for device_type in test_device_mapping.iterkeys(): >+ if device_type and device_type.hardware_family and device_type.hardware_type: >+ device_type_order.append(device_type) >+ elif device_type and device_type.hardware_family: >+ types_with_family.append(device_type) >+ else: >+ remaining_types.append(device_type) >+ device_type_order.extend(types_with_family + remaining_types) > > needs_http = any((self._is_http_test(test) and not self._needs_web_platform_test(test)) for test in tests_to_run) > needs_web_platform_test_server = any(self._needs_web_platform_test(test) for test in tests_to_run) >@@ -242,31 +241,37 @@ class Manager(object): > # Create the output directory if it doesn't already exist. > self._port.host.filesystem.maybe_make_directory(self._results_directory) > >- if default_device_tests: >- _log.info('') >- _log.info("Running %s", pluralize(len(tests_to_run), "test")) >- _log.info('') >- if not self._set_up_run(tests_to_run): >- return test_run_results.RunDetails(exit_code=-1) >+ initial_results = None >+ retry_results = None >+ enabled_pixel_tests_in_retry = False > >- initial_results, retry_results, enabled_pixel_tests_in_retry = self._run_test_subset(default_device_tests, tests_to_skip) >+ while device_type_order: >+ _log.info('') >+ device_type = device_type_order[0] > >- # Only use a single worker for custom device classes >- self._options.child_processes = 1 >- for device_type in custom_device_tests: >- device_tests = custom_device_tests[device_type] >- if device_tests: >+ if not self._port.default_child_processes(device_type=device_type): >+ _log.info('Skipping {} because {} is not available'.format(pluralize(len(test_device_mapping[device_type]), 'test'), str(device_type))) > _log.info('') >- _log.info('Running %s for %s', pluralize(len(device_tests), "test"), device_type) >- _log.info('') >- if not self._set_up_run(device_tests, device_type): >- return test_run_results.RunDetails(exit_code=-1) >+ continue > >- device_initial_results, device_retry_results, device_enabled_pixel_tests_in_retry = self._run_test_subset(device_tests, tests_to_skip) >+ tests = [] >+ index = 0 >+ while index < len(device_type_order): >+ if device_type_order[index] == device_type: >+ tests.extend(test_device_mapping[device_type_order[index]]) >+ del device_type_order[index] >+ else: >+ index += 1 >+ >+ _log.info('Running {}{}'.format(pluralize(len(tests), 'test'), ' for {}'.format(str(device_type)) if device_type else '')) >+ _log.info('') >+ if not self._set_up_run(tests, device_type): >+ return test_run_results.RunDetails(exit_code=-1) > >- initial_results = initial_results.merge(device_initial_results) if initial_results else device_initial_results >- retry_results = retry_results.merge(device_retry_results) if retry_results else device_retry_results >- enabled_pixel_tests_in_retry |= device_enabled_pixel_tests_in_retry >+ temp_initial_results, temp_retry_results, temp_enabled_pixel_tests_in_retry = self._run_test_subset(tests, tests_to_skip) >+ initial_results = initial_results.merge(temp_initial_results) if initial_results else temp_initial_results >+ retry_results = retry_results.merge(temp_retry_results) if retry_results else temp_retry_results >+ enabled_pixel_tests_in_retry |= temp_enabled_pixel_tests_in_retry > > self._runner.stop_servers() > end_time = time.time() >Index: Tools/Scripts/webkitpy/port/base.py >=================================================================== >--- Tools/Scripts/webkitpy/port/base.py (revision 238808) >+++ Tools/Scripts/webkitpy/port/base.py (working copy) >@@ -81,6 +81,7 @@ class Port(object): > > DEFAULT_ARCHITECTURE = 'x86' > >+ DEFAULT_DEVICE_TYPE = None > CUSTOM_DEVICE_TYPES = [] > > @classmethod >@@ -176,7 +177,7 @@ class Port(object): > def should_retry_crashes(self): > return False > >- def default_child_processes(self): >+ def default_child_processes(self, **kwargs): > """Return the number of DumpRenderTree instances to use for this port.""" > return self._executive.cpu_count() > >Index: Tools/Scripts/webkitpy/port/device_port.py >=================================================================== >--- Tools/Scripts/webkitpy/port/device_port.py (revision 238808) >+++ Tools/Scripts/webkitpy/port/device_port.py (working copy) >@@ -37,7 +37,6 @@ _log = logging.getLogger(__name__) > class DevicePort(DarwinPort): > > DEVICE_MANAGER = None >- DEFAULT_DEVICE_TYPE = None > NO_DEVICE_MANAGER = 'No device manager found for port' > > def __init__(self, *args, **kwargs): >@@ -106,17 +105,31 @@ class DevicePort(DarwinPort): > if not device.install_dylibs(self._build_path()): > raise RuntimeError('Failed to install dylibs at {} on device {}'.format(self._build_path(), device.udid)) > >- def setup_test_run(self, device_type=None): >- if not self.DEVICE_MANAGER: >- raise RuntimeError(self.NO_DEVICE_MANAGER) >- >+ def _device_type_with_version(self, device_type=None): > device_type = device_type if device_type else self.DEFAULT_DEVICE_TYPE >- device_type = DeviceType( >+ return DeviceType( > hardware_family=device_type.hardware_family, > hardware_type=device_type.hardware_type, > software_version=self.device_version(), > software_variant=device_type.software_variant, > ) >+ >+ def default_child_processes(self, device_type=None): >+ if not self.DEVICE_MANAGER: >+ raise RuntimeError(self.NO_DEVICE_MANAGER) >+ if self.DEVICE_MANAGER.INITIALIZED_DEVICES: >+ return len(self.DEVICE_MANAGER.INITIALIZED_DEVICES) >+ return self.DEVICE_MANAGER.device_count_for_type( >+ self._device_type_with_version(device_type), >+ host=self.host, >+ dedicated_simulators=not self.get_option('dedicated_simulators', False), >+ ) >+ >+ def setup_test_run(self, device_type=None): >+ if not self.DEVICE_MANAGER: >+ raise RuntimeError(self.NO_DEVICE_MANAGER) >+ >+ device_type = self._device_type_with_version(device_type) > _log.debug('\nCreating devices for {}'.format(device_type)) > > request = DeviceRequest( >Index: Tools/Scripts/webkitpy/port/ios_device.py >=================================================================== >--- Tools/Scripts/webkitpy/port/ios_device.py (revision 238808) >+++ Tools/Scripts/webkitpy/port/ios_device.py (working copy) >@@ -44,12 +44,6 @@ class IOSDevicePort(IOSPort): > NO_ON_DEVICE_TESTING = 'On-device testing is not supported in this configuration' > NO_DEVICE_MANAGER = NO_ON_DEVICE_TESTING > >- @memoized >- def default_child_processes(self): >- if apple_additions(): >- return apple_additions().ios_device_default_child_processes(self) >- return 1 >- > def _driver_class(self): > if apple_additions(): > return apple_additions().ios_device_driver() >Index: Tools/Scripts/webkitpy/port/ios_simulator.py >=================================================================== >--- Tools/Scripts/webkitpy/port/ios_simulator.py (revision 238808) >+++ Tools/Scripts/webkitpy/port/ios_simulator.py (working copy) >@@ -58,19 +58,6 @@ class IOSSimulatorPort(IOSPort): > return Version.from_string(self.get_option('version')) > return IOSSimulatorPort._version_from_name(self._name) if IOSSimulatorPort._version_from_name(self._name) else self.host.platform.xcode_sdk_version('iphonesimulator') > >- @memoized >- def default_child_processes(self): >- def booted_ios_devices_filter(device): >- if not device.platform_device.is_booted_or_booting(): >- return False >- return device.platform_device.device_type in DeviceType(software_variant='iOS', software_version=self.device_version()) >- >- if not self.get_option('dedicated_simulators', False): >- num_booted_sims = len(SimulatedDeviceManager.device_by_filter(booted_ios_devices_filter, host=self.host)) >- if num_booted_sims: >- return num_booted_sims >- return SimulatedDeviceManager.max_supported_simulators(self.host) >- > def clean_up_test_run(self): > super(IOSSimulatorPort, self).clean_up_test_run() > _log.debug("clean_up_test_run") >@@ -102,14 +89,6 @@ class IOSSimulatorPort(IOSPort): > def operating_system(self): > return 'ios-simulator' > >- def check_sys_deps(self): >- target_device_type = DeviceType(software_variant='iOS', software_version=self.device_version()) >- for device in SimulatedDeviceManager.available_devices(self.host): >- if device.platform_device.device_type in target_device_type: >- return super(IOSSimulatorPort, self).check_sys_deps() >- _log.error('No Simulated device matching "{}" defined in Xcode iOS SDK'.format(str(target_device_type))) >- return False >- > def reset_preferences(self): > _log.debug("reset_preferences") > SimulatedDeviceManager.tear_down(self.host) >Index: Tools/Scripts/webkitpy/port/mac.py >=================================================================== >--- Tools/Scripts/webkitpy/port/mac.py (revision 238808) >+++ Tools/Scripts/webkitpy/port/mac.py (working copy) >@@ -188,7 +188,7 @@ class MacPort(DarwinPort): > def is_mavericks(self): > return self._version == 'mavericks' > >- def default_child_processes(self): >+ def default_child_processes(self, **kwargs): > default_count = super(MacPort, self).default_child_processes() > > # FIXME: https://bugs.webkit.org/show_bug.cgi?id=95906 With too many WebProcess WK2 tests get stuck in resource contention. >Index: Tools/Scripts/webkitpy/port/test.py >=================================================================== >--- Tools/Scripts/webkitpy/port/test.py (revision 238808) >+++ Tools/Scripts/webkitpy/port/test.py (working copy) >@@ -418,7 +418,7 @@ class TestPort(Port): > } > return [self._webkit_baseline_path(d) for d in search_paths[self.name()]] > >- def default_child_processes(self): >+ def default_child_processes(self, **kwargs): > return 1 > > def worker_startup_delay_secs(self): >Index: Tools/Scripts/webkitpy/port/watch_device.py >=================================================================== >--- Tools/Scripts/webkitpy/port/watch_device.py (revision 238808) >+++ Tools/Scripts/webkitpy/port/watch_device.py (working copy) >@@ -42,12 +42,6 @@ class WatchDevicePort(WatchPort): > NO_ON_DEVICE_TESTING = 'On-device testing is not supported in this configuration' > NO_DEVICE_MANAGER = NO_ON_DEVICE_TESTING > >- @memoized >- def default_child_processes(self): >- if apple_additions(): >- return len(apple_additions().device_for_worker_number_map(self, software_variant='watchOS')) >- return 1 >- > def _driver_class(self): > if apple_additions(): > return apple_additions().device_driver() >Index: Tools/Scripts/webkitpy/port/watch_simulator.py >=================================================================== >--- Tools/Scripts/webkitpy/port/watch_simulator.py (revision 238808) >+++ Tools/Scripts/webkitpy/port/watch_simulator.py (working copy) >@@ -71,30 +71,9 @@ class WatchSimulatorPort(WatchPort): > new_environment[value] = inherited_env[value] > return new_environment > >- @memoized >- def default_child_processes(self): >- def filter_booted_watchos_devices(device): >- if not device.platform_device.is_booted_or_booting(): >- return False >- return device.platform_device.device_type in DeviceType(software_variant='watchOS', software_version=self.device_version()) >- >- if not self.get_option('dedicated_simulators', False): >- num_booted_sims = len(SimulatedDeviceManager.device_by_filter(filter_booted_watchos_devices, host=self.host)) >- if num_booted_sims: >- return num_booted_sims >- return SimulatedDeviceManager.max_supported_simulators(self.host) >- > def operating_system(self): > return 'watchos-simulator' > >- def check_sys_deps(self): >- target_device_type = DeviceType(software_variant='watchOS', software_version=self.device_version()) >- for device in SimulatedDeviceManager.available_devices(self.host): >- if device.platform_device.device_type in target_device_type: >- return super(WatchSimulatorPort, self).check_sys_deps() >- _log.error('No simulated device matching "{}" found in watchOS SDK'.format(str(target_device_type))) >- return False >- > def setup_environ_for_server(self, server_name=None): > _log.debug('Setting up environment for server on {}'.format(self.operating_system())) > env = super(WatchSimulatorPort, self).setup_environ_for_server(server_name) >Index: Tools/Scripts/webkitpy/xcode/simulated_device.py >=================================================================== >--- Tools/Scripts/webkitpy/xcode/simulated_device.py (revision 238808) >+++ Tools/Scripts/webkitpy/xcode/simulated_device.py (working copy) >@@ -325,6 +325,21 @@ class SimulatedDeviceManager(object): > SimulatedDeviceManager.INITIALIZED_DEVICES.append(device) > > @staticmethod >+ @memoized >+ def device_count_for_type(device_type, host=SystemHost(), use_booted_simulator=True, **kwargs): >+ if not host.platform.is_mac(): >+ return 0 >+ >+ if SimulatedDeviceManager.available_devices(host) and use_booted_simulator: >+ filter = lambda device: device.platform_device.is_booted_or_booting() and device.platform_device.device_type in device_type >+ return len(SimulatedDeviceManager.device_by_filter(filter, host=host)) >+ >+ for name in SimulatedDeviceManager._device_identifier_to_name.itervalues(): >+ if DeviceType.from_string(name) in device_type: >+ return SimulatedDeviceManager.max_supported_simulators(host) >+ return 0 >+ >+ @staticmethod > def initialize_devices(requests, host=SystemHost(), name_base='Managed', simulator_ui=True, timeout=SIMULATOR_BOOT_TIMEOUT, **kwargs): > if SimulatedDeviceManager.INITIALIZED_DEVICES is not None: > return SimulatedDeviceManager.INITIALIZED_DEVICES
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 192161
:
356439
|
356514
|
356550
|
356587
|
356608
|
356618