| OLD | NEW |
| 1 # Copyright 2014 The Chromium Authors. All rights reserved. | 1 # Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 import re | 5 import re |
| 6 import string | 6 import string |
| 7 | 7 |
| 8 | 8 |
| 9 class Test(object): | 9 class Test(object): |
| 10 """ | 10 """ |
| (...skipping 1010 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1021 def compile_targets(self, _): | 1021 def compile_targets(self, _): |
| 1022 if self._override_compile_targets: | 1022 if self._override_compile_targets: |
| 1023 return self._override_compile_targets | 1023 return self._override_compile_targets |
| 1024 return [self.target_name] | 1024 return [self.target_name] |
| 1025 | 1025 |
| 1026 @property | 1026 @property |
| 1027 def uses_swarming(self): | 1027 def uses_swarming(self): |
| 1028 return True | 1028 return True |
| 1029 | 1029 |
| 1030 def create_task(self, api, suffix, isolated_hash): | 1030 def create_task(self, api, suffix, isolated_hash): |
| 1031 # For local tests args are added inside api.chromium.run_telemetry_test. | |
| 1032 browser_config = api.chromium.c.build_config_fs.lower() | 1031 browser_config = api.chromium.c.build_config_fs.lower() |
| 1033 args = self._args[:] | 1032 args = self._args[:] |
| 1034 | 1033 |
| 1035 # TODO(nednguyen): only rerun the tests that failed for the "without patch" | 1034 # TODO(nednguyen): only rerun the tests that failed for the "without patch" |
| 1036 # suffix. | 1035 # suffix. |
| 1037 | 1036 |
| 1038 # For the time being, we assume all isolated_script_test are not idempotent | 1037 # For the time being, we assume all isolated_script_test are not idempotent |
| 1039 # TODO(nednguyen): make this configurable in isolated_scripts's spec. | 1038 # TODO(nednguyen): make this configurable in isolated_scripts's spec. |
| 1040 return api.swarming.isolated_script_task( | 1039 return api.swarming.isolated_script_task( |
| 1041 title=self._step_name(suffix), isolated_hash=isolated_hash, | 1040 title=self._step_name(suffix), isolated_hash=isolated_hash, |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1203 name = 'print_preview_tests' | 1202 name = 'print_preview_tests' |
| 1204 | 1203 |
| 1205 def run_step(self, api, suffix, cmd_args, **kwargs): | 1204 def run_step(self, api, suffix, cmd_args, **kwargs): |
| 1206 platform_arg = '.'.join(['browser_test', | 1205 platform_arg = '.'.join(['browser_test', |
| 1207 api.platform.normalize_platform_name(api.platform.name)]) | 1206 api.platform.normalize_platform_name(api.platform.name)]) |
| 1208 args = cmd_args | 1207 args = cmd_args |
| 1209 path = api.path['checkout'].join( | 1208 path = api.path['checkout'].join( |
| 1210 'third_party', 'WebKit', 'Tools', 'Scripts', 'run-webkit-tests') | 1209 'third_party', 'WebKit', 'Tools', 'Scripts', 'run-webkit-tests') |
| 1211 args.extend(['--platform', platform_arg]) | 1210 args.extend(['--platform', platform_arg]) |
| 1212 | 1211 |
| 1213 # This is similar to how api.chromium.run_telemetry_test() sets the | |
| 1214 # environment variable for the sandbox. | |
| 1215 env = {} | 1212 env = {} |
| 1216 if api.platform.is_linux: | 1213 if api.platform.is_linux: |
| 1217 env['CHROME_DEVEL_SANDBOX'] = api.path.join( | 1214 env['CHROME_DEVEL_SANDBOX'] = api.path.join( |
| 1218 '/opt', 'chromium', 'chrome_sandbox') | 1215 '/opt', 'chromium', 'chrome_sandbox') |
| 1219 | 1216 |
| 1220 return api.chromium.runtest( | 1217 return api.chromium.runtest( |
| 1221 test=path, | 1218 test=path, |
| 1222 args=args, | 1219 args=args, |
| 1223 xvfb=True, | 1220 xvfb=True, |
| 1224 name=self._step_name(suffix), | 1221 name=self._step_name(suffix), |
| 1225 python_mode=True, | 1222 python_mode=True, |
| 1226 env=env, | 1223 env=env, |
| 1227 **kwargs) | 1224 **kwargs) |
| 1228 | 1225 |
| 1229 @staticmethod | 1226 @staticmethod |
| 1230 def compile_targets(api): | 1227 def compile_targets(api): |
| 1231 targets = ['browser_tests', 'blink_tests'] | 1228 targets = ['browser_tests', 'blink_tests'] |
| 1232 if api.platform.is_win: | 1229 if api.platform.is_win: |
| 1233 targets.append('crash_service') | 1230 targets.append('crash_service') |
| 1234 | 1231 |
| 1235 return targets | 1232 return targets |
| 1236 | 1233 |
| 1237 | 1234 |
| 1238 class TelemetryGPUTest(Test): # pylint: disable=W0232 | |
| 1239 def __init__(self, name, revision=None, webkit_revision=None, | |
| 1240 target_name=None, args=None, enable_swarming=False, | |
| 1241 swarming_dimensions=None, swarming_extra_suffix=None, | |
| 1242 **runtest_kwargs): | |
| 1243 if enable_swarming: | |
| 1244 self._test = SwarmingTelemetryGPUTest( | |
| 1245 name, args=args, dimensions=swarming_dimensions, | |
| 1246 target_name=target_name, extra_suffix=swarming_extra_suffix) | |
| 1247 else: | |
| 1248 self._test = LocalTelemetryGPUTest( | |
| 1249 name, revision, webkit_revision, args=args, target_name=target_name, | |
| 1250 **runtest_kwargs) | |
| 1251 | |
| 1252 @property | |
| 1253 def name(self): | |
| 1254 return self._test.name | |
| 1255 | |
| 1256 def isolate_target(self, api): | |
| 1257 return self._test.isolate_target(api) | |
| 1258 | |
| 1259 def compile_targets(self, api): | |
| 1260 return self._test.compile_targets(api) | |
| 1261 | |
| 1262 def pre_run(self, api, suffix): | |
| 1263 return self._test.pre_run(api, suffix) | |
| 1264 | |
| 1265 def run(self, api, suffix): | |
| 1266 return self._test.run(api, suffix) | |
| 1267 | |
| 1268 def post_run(self, api, suffix): | |
| 1269 return self._test.post_run(api, suffix) | |
| 1270 | |
| 1271 def has_valid_results(self, api, suffix): | |
| 1272 return self._test.has_valid_results(api, suffix) | |
| 1273 | |
| 1274 def failures(self, api, suffix): | |
| 1275 return self._test.failures(api, suffix) | |
| 1276 | |
| 1277 @property | |
| 1278 def uses_swarming(self): | |
| 1279 return self._test.uses_swarming | |
| 1280 | |
| 1281 | |
| 1282 class BisectTest(Test): # pylint: disable=W0232 | 1235 class BisectTest(Test): # pylint: disable=W0232 |
| 1283 name = 'bisect_test' | 1236 name = 'bisect_test' |
| 1284 | 1237 |
| 1285 @property | 1238 @property |
| 1286 def abort_on_failure(self): | 1239 def abort_on_failure(self): |
| 1287 return True # pragma: no cover | 1240 return True # pragma: no cover |
| 1288 | 1241 |
| 1289 @property | 1242 @property |
| 1290 def uses_local_devices(self): | 1243 def uses_local_devices(self): |
| 1291 return True | 1244 return True |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1308 api.bisect_tester.upload_results(self.test_output, self.values, | 1261 api.bisect_tester.upload_results(self.test_output, self.values, |
| 1309 self.retcodes) | 1262 self.retcodes) |
| 1310 | 1263 |
| 1311 def has_valid_results(self, *_): | 1264 def has_valid_results(self, *_): |
| 1312 return len(getattr(self, 'values', [])) > 0 # pragma: no cover | 1265 return len(getattr(self, 'values', [])) > 0 # pragma: no cover |
| 1313 | 1266 |
| 1314 def failures(self, *_): | 1267 def failures(self, *_): |
| 1315 return self._failures # pragma: no cover | 1268 return self._failures # pragma: no cover |
| 1316 | 1269 |
| 1317 | 1270 |
| 1318 class LocalTelemetryGPUTest(Test): # pylint: disable=W0232 | |
| 1319 def __init__(self, name, revision, webkit_revision, | |
| 1320 target_name=None, **runtest_kwargs): | |
| 1321 """Constructs an instance of LocalTelemetryGPUTest. | |
| 1322 | |
| 1323 Args: | |
| 1324 name: Displayed name of the test. May be modified by suffixes. | |
| 1325 revision: Revision of the Chrome checkout. | |
| 1326 webkit_revision: Revision of the WebKit checkout. | |
| 1327 target_name: Actual name of the test. Defaults to name. | |
| 1328 runtest_kwargs: Additional keyword args forwarded to the runtest. | |
| 1329 """ | |
| 1330 super(LocalTelemetryGPUTest, self).__init__() | |
| 1331 self._name = name | |
| 1332 self._target_name = target_name | |
| 1333 self._revision = revision | |
| 1334 self._webkit_revision = webkit_revision | |
| 1335 self._failures = {} | |
| 1336 self._valid = {} | |
| 1337 self._runtest_kwargs = runtest_kwargs | |
| 1338 | |
| 1339 @property | |
| 1340 def name(self): | |
| 1341 return self._name | |
| 1342 | |
| 1343 @property | |
| 1344 def target_name(self): | |
| 1345 return self._target_name or self._name | |
| 1346 | |
| 1347 def isolate_target(self, _api): | |
| 1348 return self.target_name # pragma: no cover | |
| 1349 | |
| 1350 def compile_targets(self, _): | |
| 1351 # TODO(sergiyb): Build 'chrome_public_apk' instead of 'chrome' on Android. | |
| 1352 return ['chrome', 'telemetry_gpu_test_run'] # pragma: no cover | |
| 1353 | |
| 1354 def run(self, api, suffix): # pylint: disable=R0201 | |
| 1355 kwargs = self._runtest_kwargs.copy() | |
| 1356 kwargs['args'].extend(['--output-format', 'json', | |
| 1357 '--output-dir', api.raw_io.output_dir()]) | |
| 1358 step_test_data=lambda: api.test_utils.test_api.canned_telemetry_gpu_output( | |
| 1359 passing=True, is_win=api.platform.is_win) | |
| 1360 try: | |
| 1361 api.isolate.run_telemetry_test( | |
| 1362 'telemetry_gpu_test', | |
| 1363 self.target_name, | |
| 1364 self._revision, | |
| 1365 self._webkit_revision, | |
| 1366 name=self._step_name(suffix), | |
| 1367 spawn_dbus=True, | |
| 1368 step_test_data=step_test_data, | |
| 1369 **self._runtest_kwargs) | |
| 1370 finally: | |
| 1371 step_result = api.step.active_result | |
| 1372 self._test_runs[suffix] = step_result | |
| 1373 | |
| 1374 try: | |
| 1375 res = api.json.loads(step_result.raw_io.output_dir['results.json']) | |
| 1376 failures = [res['pages'][str(value['page_id'])]['name'] | |
| 1377 for value in res['per_page_values'] | |
| 1378 if value['type'] == 'failure'] | |
| 1379 if not failures and step_result.retcode != 0: | |
| 1380 failures = ['%s (entire test suite)' % self.name] | |
| 1381 | |
| 1382 self._failures[suffix] = failures | |
| 1383 self._valid[suffix] = True | |
| 1384 except (ValueError, KeyError, AttributeError): # pragma: no cover | |
| 1385 self._valid[suffix] = False | |
| 1386 | |
| 1387 if self._valid[suffix]: | |
| 1388 step_result.presentation.step_text += api.test_utils.format_step_text([ | |
| 1389 ['failures:', self._failures[suffix]] | |
| 1390 ]) | |
| 1391 | |
| 1392 def has_valid_results(self, api, suffix): | |
| 1393 return suffix in self._valid and self._valid[suffix] # pragma: no cover | |
| 1394 | |
| 1395 def failures(self, api, suffix): # pragma: no cover | |
| 1396 assert self.has_valid_results(api, suffix) | |
| 1397 assert suffix in self._failures | |
| 1398 return self._failures[suffix] | |
| 1399 | |
| 1400 | |
| 1401 class SwarmingTelemetryGPUTest(SwarmingTest): | |
| 1402 def __init__(self, name, args=None, dimensions=None, target_name=None, | |
| 1403 extra_suffix=None): | |
| 1404 super(SwarmingTelemetryGPUTest, self).__init__( | |
| 1405 name, dimensions, {'gpu_test:1'}, 'telemetry_gpu_test', extra_suffix) | |
| 1406 self._args = args | |
| 1407 self._telemetry_target_name = target_name or name | |
| 1408 | |
| 1409 def compile_targets(self, _): | |
| 1410 # TODO(sergiyb): Build 'chrome_public_apk' instead of 'chrome' on Android. | |
| 1411 return ['chrome', 'telemetry_gpu_test_run'] | |
| 1412 | |
| 1413 def create_task(self, api, suffix, isolated_hash): | |
| 1414 # For local tests args are added inside api.chromium.run_telemetry_test. | |
| 1415 browser_config = api.chromium.c.build_config_fs.lower() | |
| 1416 args = [self._telemetry_target_name, '--show-stdout', | |
| 1417 '--browser=%s' % browser_config] + self._args | |
| 1418 | |
| 1419 # If rerunning without a patch, run only tests that failed. | |
| 1420 if suffix == 'without patch': | |
| 1421 failed_tests = sorted(self.failures(api, 'with patch')) | |
| 1422 # Telemetry test launcher uses re.compile to parse --story-filter argument
, | |
| 1423 # therefore we escape any special characters in test names. | |
| 1424 failed_tests = [re.escape(test_name) for test_name in failed_tests] | |
| 1425 args.append('--story-filter=%s' % '|'.join(failed_tests)) | |
| 1426 | |
| 1427 return api.swarming.telemetry_gpu_task( | |
| 1428 title=self._step_name(suffix), isolated_hash=isolated_hash, | |
| 1429 extra_args=args) | |
| 1430 | |
| 1431 def validate_task_results(self, api, step_result): | |
| 1432 results = getattr(step_result, 'telemetry_results', None) or {} | |
| 1433 | |
| 1434 try: | |
| 1435 failures = [results['pages'][str(value['page_id'])]['name'] | |
| 1436 for value in results['per_page_values'] | |
| 1437 if value['type'] == 'failure'] | |
| 1438 if not failures and step_result.retcode != 0: | |
| 1439 failures = ['%s (entire test suite)' % self.name] | |
| 1440 | |
| 1441 valid = True | |
| 1442 except (ValueError, KeyError) as e: # pragma: no cover | |
| 1443 step_result.presentation.logs['invalid_results_exc'] = [str(e)] | |
| 1444 valid = False | |
| 1445 failures = None | |
| 1446 | |
| 1447 if valid: | |
| 1448 step_result.presentation.step_text += api.test_utils.format_step_text([ | |
| 1449 ['failures:', failures] | |
| 1450 ]) | |
| 1451 | |
| 1452 return valid, failures | |
| 1453 | |
| 1454 | |
| 1455 class AndroidTest(Test): | 1271 class AndroidTest(Test): |
| 1456 def __init__(self, name, compile_target, isolate_file_path=None): | 1272 def __init__(self, name, compile_target, isolate_file_path=None): |
| 1457 super(AndroidTest, self).__init__() | 1273 super(AndroidTest, self).__init__() |
| 1458 | 1274 |
| 1459 self._name = name | 1275 self._name = name |
| 1460 self.compile_target = compile_target | 1276 self.compile_target = compile_target |
| 1461 | 1277 |
| 1462 self.isolate_file_path = isolate_file_path | 1278 self.isolate_file_path = isolate_file_path |
| 1463 | 1279 |
| 1464 @property | 1280 @property |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1722 "https://storage.googleapis.com/chromium-layout-test-archives/%s/%s" | 1538 "https://storage.googleapis.com/chromium-layout-test-archives/%s/%s" |
| 1723 % (sanitized_buildername, buildnumber)) | 1539 % (sanitized_buildername, buildnumber)) |
| 1724 | 1540 |
| 1725 archive_result.presentation.links['layout_test_results'] = ( | 1541 archive_result.presentation.links['layout_test_results'] = ( |
| 1726 base + '/layout-test-results/results.html') | 1542 base + '/layout-test-results/results.html') |
| 1727 archive_result.presentation.links['(zip)'] = ( | 1543 archive_result.presentation.links['(zip)'] = ( |
| 1728 base + '/layout-test-results.zip') | 1544 base + '/layout-test-results.zip') |
| 1729 | 1545 |
| 1730 def has_valid_results(self, api, suffix): | 1546 def has_valid_results(self, api, suffix): |
| 1731 if suffix not in self._test_runs: | 1547 if suffix not in self._test_runs: |
| 1732 return False | 1548 # TODO(kbr): crbug.com/553925 - this line is flakily failing to |
| 1549 # be covered. |
| 1550 return False # pragma: no cover |
| 1733 step = self._test_runs[suffix] | 1551 step = self._test_runs[suffix] |
| 1734 # TODO(dpranke): crbug.com/357866 - note that all comparing against | 1552 # TODO(dpranke): crbug.com/357866 - note that all comparing against |
| 1735 # MAX_FAILURES_EXIT_STATUS tells us is that we did not exit early | 1553 # MAX_FAILURES_EXIT_STATUS tells us is that we did not exit early |
| 1736 # or abnormally; it does not tell us how many failures there actually | 1554 # or abnormally; it does not tell us how many failures there actually |
| 1737 # were, which might be much higher (up to 5000 diffs, where we | 1555 # were, which might be much higher (up to 5000 diffs, where we |
| 1738 # would bail out early with --exit-after-n-failures) or lower | 1556 # would bail out early with --exit-after-n-failures) or lower |
| 1739 # if we bailed out after 100 crashes w/ -exit-after-n-crashes, in | 1557 # if we bailed out after 100 crashes w/ -exit-after-n-crashes, in |
| 1740 # which case the retcode is actually 130 | 1558 # which case the retcode is actually 130 |
| 1741 return (step.test_utils.test_results.valid and | 1559 return (step.test_utils.test_results.valid and |
| 1742 step.retcode <= step.test_utils.test_results.MAX_FAILURES_EXIT_STATU
S) | 1560 step.retcode <= step.test_utils.test_results.MAX_FAILURES_EXIT_STATU
S) |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1807 def run(self, api, suffix): | 1625 def run(self, api, suffix): |
| 1808 api.chromium_android.coverage_report(upload=False) | 1626 api.chromium_android.coverage_report(upload=False) |
| 1809 api.chromium_android.get_changed_lines_for_revision() | 1627 api.chromium_android.get_changed_lines_for_revision() |
| 1810 api.chromium_android.incremental_coverage_report() | 1628 api.chromium_android.incremental_coverage_report() |
| 1811 | 1629 |
| 1812 | 1630 |
| 1813 GOMA_TESTS = [ | 1631 GOMA_TESTS = [ |
| 1814 GTestTest('base_unittests'), | 1632 GTestTest('base_unittests'), |
| 1815 GTestTest('content_unittests'), | 1633 GTestTest('content_unittests'), |
| 1816 ] | 1634 ] |
| OLD | NEW |