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