| 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 datetime | 5 import datetime |
| 6 import functools | 6 import functools |
| 7 | 7 |
| 8 from recipe_engine.types import freeze | 8 from recipe_engine.types import freeze |
| 9 from recipe_engine import recipe_api | 9 from recipe_engine import recipe_api |
| 10 | 10 |
| (...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 391 # Append it. output.json name is expected by collect_gtest_task.py. | 391 # Append it. output.json name is expected by collect_gtest_task.py. |
| 392 extra_args.append( | 392 extra_args.append( |
| 393 '--test-launcher-summary-output=${ISOLATED_OUTDIR}/output.json') | 393 '--test-launcher-summary-output=${ISOLATED_OUTDIR}/output.json') |
| 394 | 394 |
| 395 # Make a task, configure it to be collected through shim script. | 395 # Make a task, configure it to be collected through shim script. |
| 396 task = self.task(title, isolated_hash, extra_args=extra_args, **kwargs) | 396 task = self.task(title, isolated_hash, extra_args=extra_args, **kwargs) |
| 397 task.collect_step = lambda *args, **kw: ( | 397 task.collect_step = lambda *args, **kw: ( |
| 398 self._gtest_collect_step(test_launcher_summary_output, *args, **kw)) | 398 self._gtest_collect_step(test_launcher_summary_output, *args, **kw)) |
| 399 return task | 399 return task |
| 400 | 400 |
| 401 def telemetry_gpu_task(self, title, isolated_hash, extra_args=None, **kwargs): |
| 402 """Returns a new SwarmingTask to run an isolated telemetry test on Swarming. |
| 403 |
| 404 Swarming recipe module knows how collect JSON file with test execution |
| 405 summary produced by telemetry test launcher. Since telemetry tests do not |
| 406 support sharding, no merging of the results is performed. Parsed JSON |
| 407 summary is returned from the collect step. |
| 408 |
| 409 For meaning of the rest of the arguments see 'task' method. |
| 410 """ |
| 411 extra_args = list(extra_args or []) |
| 412 |
| 413 # Ensure --output-dir is not already passed. We are going to overwrite it. |
| 414 bad_args = any(x.startswith('--output-dir') for x in extra_args) |
| 415 if bad_args: # pragma: no cover |
| 416 raise ValueError('--output-dir should not be used.') |
| 417 |
| 418 extra_args.extend(['--output-format', 'json', |
| 419 '--output-dir', '${ISOLATED_OUTDIR}']) |
| 420 |
| 421 # For the time being, assume that all Telemetry tests are not |
| 422 # idempotent. As of this writing, Telemetry itself downloads some |
| 423 # data from remote servers; additionally, some tests like the |
| 424 # pixel_tests download reference images from cloud storage. It's |
| 425 # safest to assume that these tests aren't idempotent, though we |
| 426 # should work toward making them so. |
| 427 task = self.task(title, isolated_hash, extra_args=extra_args, |
| 428 idempotent=False, **kwargs) |
| 429 task.collect_step = self._telemetry_gpu_collect_step |
| 430 return task |
| 431 |
| 401 def isolated_script_task(self, title, isolated_hash, extra_args=None, | 432 def isolated_script_task(self, title, isolated_hash, extra_args=None, |
| 402 idempotent=False, **kwargs): | 433 idempotent=False, **kwargs): |
| 403 """Returns a new SwarmingTask to run an isolated script test on Swarming. | 434 """Returns a new SwarmingTask to run an isolated script test on Swarming. |
| 404 | 435 |
| 405 Swarming recipe module knows how collect JSON file with test execution | 436 Swarming recipe module knows how collect JSON file with test execution |
| 406 summary produced by isolated script tests launcher. Since isolated script | 437 summary produced by isolated script tests launcher. Since isolated script |
| 407 tests do not support sharding, no merging of the results is performed. | 438 tests do not support sharding, no merging of the results is performed. |
| 408 Parsed JSON summary is returned from the collect step. | 439 Parsed JSON summary is returned from the collect step. |
| 409 | 440 |
| 410 For meaning of the rest of the arguments see 'task' method. | 441 For meaning of the rest of the arguments see 'task' method. |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 673 for index in missing_shards: | 704 for index in missing_shards: |
| 674 p.links['missing shard #%d' % index] = \ | 705 p.links['missing shard #%d' % index] = \ |
| 675 task.get_shard_view_url(index) | 706 task.get_shard_view_url(index) |
| 676 if gtest_results.valid: | 707 if gtest_results.valid: |
| 677 p.step_text += self.m.test_utils.format_step_text([ | 708 p.step_text += self.m.test_utils.format_step_text([ |
| 678 ['failures:', gtest_results.failures] | 709 ['failures:', gtest_results.failures] |
| 679 ]) | 710 ]) |
| 680 self._display_pending(gtest_results.raw.get('swarming_summary', {}), | 711 self._display_pending(gtest_results.raw.get('swarming_summary', {}), |
| 681 step_result.presentation) | 712 step_result.presentation) |
| 682 | 713 |
| 714 def _telemetry_gpu_collect_step(self, task, **kwargs): |
| 715 step_test_data = kwargs.pop('step_test_data', None) |
| 716 if not step_test_data: |
| 717 step_test_data = self.m.test_utils.test_api.canned_telemetry_gpu_output( |
| 718 passing=True, is_win=self.m.platform.is_win, swarming=True) |
| 719 |
| 720 args=self.get_collect_cmd_args(task) |
| 721 args.extend(['--task-output-dir', self.m.raw_io.output_dir()]) |
| 722 |
| 723 try: |
| 724 self.m.python( |
| 725 name=self._get_step_name('', task), |
| 726 script=self.m.swarming_client.path.join('swarming.py'), |
| 727 args=args, step_test_data=lambda: step_test_data, |
| 728 **kwargs) |
| 729 finally: |
| 730 # Regardless of the outcome of the test (pass or fail), we try to parse |
| 731 # the results. If any error occurs while parsing results, then we set them |
| 732 # to None, which will be treated as invalid test results by |
| 733 # SwarmingTelemetryGPUTest class in recipe_modules/chromium/steps.py. Note |
| 734 # that try-except block below will not mask the recipe_api.StepFailure |
| 735 # exception from the collect step above. Instead it is being allowed to |
| 736 # propagate after the results have been parsed. |
| 737 try: |
| 738 step_result = self.m.step.active_result |
| 739 outdir_json = self.m.json.dumps(step_result.raw_io.output_dir, indent=2) |
| 740 step_result.presentation.logs['outdir_json'] = outdir_json.splitlines() |
| 741 |
| 742 # Check if it's an internal failure. |
| 743 summary = self.m.json.loads( |
| 744 step_result.raw_io.output_dir['summary.json']) |
| 745 if any(shard['internal_failure'] for shard in summary['shards']): |
| 746 raise recipe_api.InfraFailure('Internal swarming failure.') |
| 747 |
| 748 # TODO(sergiyb): Combine telemetry results from multiple shards rather |
| 749 # than assuming that there is always just one shard. |
| 750 assert len(summary['shards']) == 1 |
| 751 results_raw = step_result.raw_io.output_dir[ |
| 752 self.m.path.join('0', 'results.json')] |
| 753 |
| 754 # GPU test launcher may bail out early with return code 0 and empty |
| 755 # results file if there were no tests to run, e.g. when all tests are |
| 756 # disabled on current platform. |
| 757 # TODO(sergiyb): We should instead rewrite run_gpu_test.py to always |
| 758 # write valid results.json regardless of the return code. |
| 759 if step_result.retcode == 0 and results_raw == '': |
| 760 step_result.telemetry_results = {'per_page_values': [], 'pages': []} |
| 761 else: |
| 762 step_result.telemetry_results = self.m.json.loads(results_raw) |
| 763 |
| 764 self._display_pending(summary, step_result.presentation) |
| 765 except Exception as e: |
| 766 self.m.step.active_result.presentation.logs['no_results_exc'] = [str(e)] |
| 767 self.m.step.active_result.telemetry_results = None |
| 768 |
| 683 def _isolated_script_collect_step(self, task, **kwargs): | 769 def _isolated_script_collect_step(self, task, **kwargs): |
| 684 step_test_data = kwargs.pop('step_test_data', None) | 770 step_test_data = kwargs.pop('step_test_data', None) |
| 685 if not step_test_data: | 771 if not step_test_data: |
| 686 step_test_data = self.m.test_utils.test_api.canned_isolated_script_output( | 772 step_test_data = self.m.test_utils.test_api.canned_isolated_script_output( |
| 687 passing=True, is_win=self.m.platform.is_win, swarming=True) | 773 passing=True, is_win=self.m.platform.is_win, swarming=True) |
| 688 | 774 |
| 689 args=self.get_collect_cmd_args(task) | 775 args=self.get_collect_cmd_args(task) |
| 690 args.extend(['--task-output-dir', self.m.raw_io.output_dir()]) | 776 args.extend(['--task-output-dir', self.m.raw_io.output_dir()]) |
| 691 | 777 |
| 692 try: | 778 try: |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 906 | 992 |
| 907 def get_shard_view_url(self, index): | 993 def get_shard_view_url(self, index): |
| 908 """Returns URL of HTML page with shard details or None if not available. | 994 """Returns URL of HTML page with shard details or None if not available. |
| 909 | 995 |
| 910 Works only after the task has been successfully triggered. | 996 Works only after the task has been successfully triggered. |
| 911 """ | 997 """ |
| 912 if self._trigger_output and self._trigger_output.get('tasks'): | 998 if self._trigger_output and self._trigger_output.get('tasks'): |
| 913 for shard_dict in self._trigger_output['tasks'].itervalues(): | 999 for shard_dict in self._trigger_output['tasks'].itervalues(): |
| 914 if shard_dict['shard_index'] == index: | 1000 if shard_dict['shard_index'] == index: |
| 915 return shard_dict['view_url'] | 1001 return shard_dict['view_url'] |
| OLD | NEW |