Chromium Code Reviews| 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 685 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 696 | 696 |
| 697 # Show any remaining isolated outputs (such as logcats). | 697 # Show any remaining isolated outputs (such as logcats). |
| 698 # Note that collect_gtest_task.py uses the default summary.json, which | 698 # Note that collect_gtest_task.py uses the default summary.json, which |
| 699 # only has 'outputs_ref' instead of the deprecated 'isolated_out'. | 699 # only has 'outputs_ref' instead of the deprecated 'isolated_out'. |
| 700 for index, shard in enumerate(swarming_summary.get('shards', [])): | 700 for index, shard in enumerate(swarming_summary.get('shards', [])): |
| 701 outputs_ref = shard.get('outputs_ref') | 701 outputs_ref = shard.get('outputs_ref') |
| 702 if outputs_ref: | 702 if outputs_ref: |
| 703 link_name = 'shard #%d isolated out' % index | 703 link_name = 'shard #%d isolated out' % index |
| 704 p.links[link_name] = outputs_ref['view_url'] | 704 p.links[link_name] = outputs_ref['view_url'] |
| 705 | 705 |
| 706 | |
| 707 def _merge_isolated_script_shards(self, task, step_result): | |
| 708 # This code is unfortunately specialized to the "simplified" | |
| 709 # JSON format that used to be the standard for recipes. The | |
| 710 # isolated scripts should be changed to use the now-standard | |
| 711 # Chromium JSON test results format: | |
| 712 # https://www.chromium.org/developers/the-json-test-results-format | |
| 713 # . Note that gtests, above, don't seem to conform to this | |
| 714 # format yet, so it didn't seem like a good prerequisite to | |
| 715 # switch the isolated tests over when adding sharding support. | |
| 716 # | |
| 717 # These are the only keys we pay attention to in the output JSON. | |
| 718 merged_results = { | |
| 719 'successes': [], | |
| 720 'failures': [], | |
| 721 'valid': True, | |
| 722 } | |
| 723 for i in xrange(task.shards): | |
| 724 results_raw = step_result.raw_io.output_dir[ | |
|
Vadim Sh.
2016/06/17 00:31:11
I think at the very minimum we can acknowledge in
| |
| 725 self.m.path.join(str(i), 'output.json')] | |
| 726 results_json = self.m.json.loads(results_raw) | |
| 727 for key in merged_results: | |
| 728 if key in results_json: | |
| 729 if isinstance(merged_results[key], list): | |
| 730 merged_results[key].extend(results_json[key]) | |
| 731 elif isinstance(merged_results[key], bool): | |
| 732 merged_results[key] = merged_results[key] and results_json[key] | |
| 733 else: | |
| 734 raise recipe_api.InfraFailure( | |
| 735 'Unknown key type ' + type(merged_results[key]) + | |
| 736 ' when handling key ' + key + '.') # pragma: no cover | |
| 737 return merged_results | |
| 738 | |
| 706 def _isolated_script_collect_step(self, task, **kwargs): | 739 def _isolated_script_collect_step(self, task, **kwargs): |
| 707 step_test_data = kwargs.pop('step_test_data', None) | 740 step_test_data = kwargs.pop('step_test_data', None) |
| 708 if not step_test_data: | 741 if not step_test_data: |
| 709 step_test_data = self.m.test_utils.test_api.canned_isolated_script_output( | 742 step_test_data = self.m.test_utils.test_api.canned_isolated_script_output( |
| 710 passing=True, is_win=self.m.platform.is_win, swarming=True) | 743 passing=True, is_win=self.m.platform.is_win, swarming=True) |
| 711 | 744 |
| 712 args=self.get_collect_cmd_args(task) | 745 args=self.get_collect_cmd_args(task) |
| 713 args.extend(['--task-output-dir', self.m.raw_io.output_dir()]) | 746 args.extend(['--task-output-dir', self.m.raw_io.output_dir()]) |
| 714 | 747 |
| 715 try: | 748 try: |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 729 step_result = self.m.step.active_result | 762 step_result = self.m.step.active_result |
| 730 outdir_json = self.m.json.dumps(step_result.raw_io.output_dir, indent=2) | 763 outdir_json = self.m.json.dumps(step_result.raw_io.output_dir, indent=2) |
| 731 step_result.presentation.logs['outdir_json'] = outdir_json.splitlines() | 764 step_result.presentation.logs['outdir_json'] = outdir_json.splitlines() |
| 732 | 765 |
| 733 # Check if it's an internal failure. | 766 # Check if it's an internal failure. |
| 734 summary = self.m.json.loads( | 767 summary = self.m.json.loads( |
| 735 step_result.raw_io.output_dir['summary.json']) | 768 step_result.raw_io.output_dir['summary.json']) |
| 736 if any(shard['internal_failure'] for shard in summary['shards']): | 769 if any(shard['internal_failure'] for shard in summary['shards']): |
| 737 raise recipe_api.InfraFailure('Internal swarming failure.') | 770 raise recipe_api.InfraFailure('Internal swarming failure.') |
| 738 | 771 |
| 739 # TODO(nednguyen, kbr): Combine isolated script results from multiple | 772 # Always show the shards' links in the collect step. (It looks |
| 740 # shards rather than assuming that there is always just one shard. | 773 # like show_isolated_out_in_collect_step is false by default |
| 741 assert len(summary['shards']) == 1 | 774 # in recipe runs.) |
| 742 results_raw = step_result.raw_io.output_dir[ | 775 links = step_result.presentation.links |
| 743 self.m.path.join('0', 'output.json')] | 776 for index in xrange(task.shards): |
| 744 step_result.isolated_script_results = self.m.json.loads(results_raw) | 777 url = task.get_shard_view_url(index) |
| 778 if url: | |
| 779 links['shard #%d' % index] = url | |
| 780 | |
| 781 step_result.isolated_script_results = \ | |
| 782 self._merge_isolated_script_shards(task, step_result) | |
| 745 | 783 |
| 746 self._display_pending(summary, step_result.presentation) | 784 self._display_pending(summary, step_result.presentation) |
| 747 except Exception as e: | 785 except Exception as e: |
| 748 self.m.step.active_result.presentation.logs['no_results_exc'] = [str(e)] | 786 self.m.step.active_result.presentation.logs['no_results_exc'] = [str(e)] |
| 749 self.m.step.active_result.isolated_script_results = None | 787 self.m.step.active_result.isolated_script_results = None |
| 750 | 788 |
| 751 def _get_step_name(self, prefix, task): | 789 def _get_step_name(self, prefix, task): |
| 752 """SwarmingTask -> name of a step of a waterfall. | 790 """SwarmingTask -> name of a step of a waterfall. |
| 753 | 791 |
| 754 Will take a task title (+ step name prefix) and append OS dimension to it. | 792 Will take a task title (+ step name prefix) and append OS dimension to it. |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 928 | 966 |
| 929 def get_shard_view_url(self, index): | 967 def get_shard_view_url(self, index): |
| 930 """Returns URL of HTML page with shard details or None if not available. | 968 """Returns URL of HTML page with shard details or None if not available. |
| 931 | 969 |
| 932 Works only after the task has been successfully triggered. | 970 Works only after the task has been successfully triggered. |
| 933 """ | 971 """ |
| 934 if self._trigger_output and self._trigger_output.get('tasks'): | 972 if self._trigger_output and self._trigger_output.get('tasks'): |
| 935 for shard_dict in self._trigger_output['tasks'].itervalues(): | 973 for shard_dict in self._trigger_output['tasks'].itervalues(): |
| 936 if shard_dict['shard_index'] == index: | 974 if shard_dict['shard_index'] == index: |
| 937 return shard_dict['view_url'] | 975 return shard_dict['view_url'] |
| OLD | NEW |