| 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. |
| 1031 browser_config = api.chromium.c.build_config_fs.lower() | 1032 browser_config = api.chromium.c.build_config_fs.lower() |
| 1032 args = self._args[:] | 1033 args = self._args[:] |
| 1033 | 1034 |
| 1034 # TODO(nednguyen): only rerun the tests that failed for the "without patch" | 1035 # TODO(nednguyen): only rerun the tests that failed for the "without patch" |
| 1035 # suffix. | 1036 # suffix. |
| 1036 | 1037 |
| 1037 # For the time being, we assume all isolated_script_test are not idempotent | 1038 # For the time being, we assume all isolated_script_test are not idempotent |
| 1038 # TODO(nednguyen): make this configurable in isolated_scripts's spec. | 1039 # TODO(nednguyen): make this configurable in isolated_scripts's spec. |
| 1039 return api.swarming.isolated_script_task( | 1040 return api.swarming.isolated_script_task( |
| 1040 title=self._step_name(suffix), isolated_hash=isolated_hash, | 1041 title=self._step_name(suffix), isolated_hash=isolated_hash, |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1202 name = 'print_preview_tests' | 1203 name = 'print_preview_tests' |
| 1203 | 1204 |
| 1204 def run_step(self, api, suffix, cmd_args, **kwargs): | 1205 def run_step(self, api, suffix, cmd_args, **kwargs): |
| 1205 platform_arg = '.'.join(['browser_test', | 1206 platform_arg = '.'.join(['browser_test', |
| 1206 api.platform.normalize_platform_name(api.platform.name)]) | 1207 api.platform.normalize_platform_name(api.platform.name)]) |
| 1207 args = cmd_args | 1208 args = cmd_args |
| 1208 path = api.path['checkout'].join( | 1209 path = api.path['checkout'].join( |
| 1209 'third_party', 'WebKit', 'Tools', 'Scripts', 'run-webkit-tests') | 1210 'third_party', 'WebKit', 'Tools', 'Scripts', 'run-webkit-tests') |
| 1210 args.extend(['--platform', platform_arg]) | 1211 args.extend(['--platform', platform_arg]) |
| 1211 | 1212 |
| 1213 # This is similar to how api.chromium.run_telemetry_test() sets the |
| 1214 # environment variable for the sandbox. |
| 1212 env = {} | 1215 env = {} |
| 1213 if api.platform.is_linux: | 1216 if api.platform.is_linux: |
| 1214 env['CHROME_DEVEL_SANDBOX'] = api.path.join( | 1217 env['CHROME_DEVEL_SANDBOX'] = api.path.join( |
| 1215 '/opt', 'chromium', 'chrome_sandbox') | 1218 '/opt', 'chromium', 'chrome_sandbox') |
| 1216 | 1219 |
| 1217 return api.chromium.runtest( | 1220 return api.chromium.runtest( |
| 1218 test=path, | 1221 test=path, |
| 1219 args=args, | 1222 args=args, |
| 1220 xvfb=True, | 1223 xvfb=True, |
| 1221 name=self._step_name(suffix), | 1224 name=self._step_name(suffix), |
| 1222 python_mode=True, | 1225 python_mode=True, |
| 1223 env=env, | 1226 env=env, |
| 1224 **kwargs) | 1227 **kwargs) |
| 1225 | 1228 |
| 1226 @staticmethod | 1229 @staticmethod |
| 1227 def compile_targets(api): | 1230 def compile_targets(api): |
| 1228 targets = ['browser_tests', 'blink_tests'] | 1231 targets = ['browser_tests', 'blink_tests'] |
| 1229 if api.platform.is_win: | 1232 if api.platform.is_win: |
| 1230 targets.append('crash_service') | 1233 targets.append('crash_service') |
| 1231 | 1234 |
| 1232 return targets | 1235 return targets |
| 1233 | 1236 |
| 1234 | 1237 |
| 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 |
| 1235 class BisectTest(Test): # pylint: disable=W0232 | 1282 class BisectTest(Test): # pylint: disable=W0232 |
| 1236 name = 'bisect_test' | 1283 name = 'bisect_test' |
| 1237 | 1284 |
| 1238 @property | 1285 @property |
| 1239 def abort_on_failure(self): | 1286 def abort_on_failure(self): |
| 1240 return True # pragma: no cover | 1287 return True # pragma: no cover |
| 1241 | 1288 |
| 1242 @property | 1289 @property |
| 1243 def uses_local_devices(self): | 1290 def uses_local_devices(self): |
| 1244 return True | 1291 return True |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1261 api.bisect_tester.upload_results(self.test_output, self.values, | 1308 api.bisect_tester.upload_results(self.test_output, self.values, |
| 1262 self.retcodes) | 1309 self.retcodes) |
| 1263 | 1310 |
| 1264 def has_valid_results(self, *_): | 1311 def has_valid_results(self, *_): |
| 1265 return len(getattr(self, 'values', [])) > 0 # pragma: no cover | 1312 return len(getattr(self, 'values', [])) > 0 # pragma: no cover |
| 1266 | 1313 |
| 1267 def failures(self, *_): | 1314 def failures(self, *_): |
| 1268 return self._failures # pragma: no cover | 1315 return self._failures # pragma: no cover |
| 1269 | 1316 |
| 1270 | 1317 |
| 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 |
| 1271 class AndroidTest(Test): | 1455 class AndroidTest(Test): |
| 1272 def __init__(self, name, compile_target, isolate_file_path=None): | 1456 def __init__(self, name, compile_target, isolate_file_path=None): |
| 1273 super(AndroidTest, self).__init__() | 1457 super(AndroidTest, self).__init__() |
| 1274 | 1458 |
| 1275 self._name = name | 1459 self._name = name |
| 1276 self.compile_target = compile_target | 1460 self.compile_target = compile_target |
| 1277 | 1461 |
| 1278 self.isolate_file_path = isolate_file_path | 1462 self.isolate_file_path = isolate_file_path |
| 1279 | 1463 |
| 1280 @property | 1464 @property |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1538 "https://storage.googleapis.com/chromium-layout-test-archives/%s/%s" | 1722 "https://storage.googleapis.com/chromium-layout-test-archives/%s/%s" |
| 1539 % (sanitized_buildername, buildnumber)) | 1723 % (sanitized_buildername, buildnumber)) |
| 1540 | 1724 |
| 1541 archive_result.presentation.links['layout_test_results'] = ( | 1725 archive_result.presentation.links['layout_test_results'] = ( |
| 1542 base + '/layout-test-results/results.html') | 1726 base + '/layout-test-results/results.html') |
| 1543 archive_result.presentation.links['(zip)'] = ( | 1727 archive_result.presentation.links['(zip)'] = ( |
| 1544 base + '/layout-test-results.zip') | 1728 base + '/layout-test-results.zip') |
| 1545 | 1729 |
| 1546 def has_valid_results(self, api, suffix): | 1730 def has_valid_results(self, api, suffix): |
| 1547 if suffix not in self._test_runs: | 1731 if suffix not in self._test_runs: |
| 1548 # TODO(kbr): crbug.com/553925 - this line is flakily failing to | 1732 return False |
| 1549 # be covered. | |
| 1550 return False # pragma: no cover | |
| 1551 step = self._test_runs[suffix] | 1733 step = self._test_runs[suffix] |
| 1552 # TODO(dpranke): crbug.com/357866 - note that all comparing against | 1734 # TODO(dpranke): crbug.com/357866 - note that all comparing against |
| 1553 # MAX_FAILURES_EXIT_STATUS tells us is that we did not exit early | 1735 # MAX_FAILURES_EXIT_STATUS tells us is that we did not exit early |
| 1554 # or abnormally; it does not tell us how many failures there actually | 1736 # or abnormally; it does not tell us how many failures there actually |
| 1555 # were, which might be much higher (up to 5000 diffs, where we | 1737 # were, which might be much higher (up to 5000 diffs, where we |
| 1556 # would bail out early with --exit-after-n-failures) or lower | 1738 # would bail out early with --exit-after-n-failures) or lower |
| 1557 # if we bailed out after 100 crashes w/ -exit-after-n-crashes, in | 1739 # if we bailed out after 100 crashes w/ -exit-after-n-crashes, in |
| 1558 # which case the retcode is actually 130 | 1740 # which case the retcode is actually 130 |
| 1559 return (step.test_utils.test_results.valid and | 1741 return (step.test_utils.test_results.valid and |
| 1560 step.retcode <= step.test_utils.test_results.MAX_FAILURES_EXIT_STATU
S) | 1742 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... |
| 1625 def run(self, api, suffix): | 1807 def run(self, api, suffix): |
| 1626 api.chromium_android.coverage_report(upload=False) | 1808 api.chromium_android.coverage_report(upload=False) |
| 1627 api.chromium_android.get_changed_lines_for_revision() | 1809 api.chromium_android.get_changed_lines_for_revision() |
| 1628 api.chromium_android.incremental_coverage_report() | 1810 api.chromium_android.incremental_coverage_report() |
| 1629 | 1811 |
| 1630 | 1812 |
| 1631 GOMA_TESTS = [ | 1813 GOMA_TESTS = [ |
| 1632 GTestTest('base_unittests'), | 1814 GTestTest('base_unittests'), |
| 1633 GTestTest('content_unittests'), | 1815 GTestTest('content_unittests'), |
| 1634 ] | 1816 ] |
| OLD | NEW |