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 logging | 5 import logging |
| 6 import datetime | 6 import datetime |
| 7 import functools | 7 import functools |
| 8 | 8 |
| 9 from recipe_engine import recipe_api | 9 from recipe_engine import recipe_api |
| 10 | 10 |
| 11 from resources import results_merger | |
|
eyaich1
2016/10/10 13:51:28
Are you sure this is possible? Similar to my swar
nednguyen
2016/10/10 14:26:26
Yes, this is possible because I added resources/__
| |
| 11 | 12 |
| 12 # Minimally supported version of swarming.py script (reported by --version). | 13 # Minimally supported version of swarming.py script (reported by --version). |
| 13 MINIMAL_SWARMING_VERSION = (0, 8, 6) | 14 MINIMAL_SWARMING_VERSION = (0, 8, 6) |
| 14 | 15 |
| 15 | 16 |
| 16 def parse_time(value): | 17 def parse_time(value): |
| 17 """Converts serialized time from the API to datetime.datetime.""" | 18 """Converts serialized time from the API to datetime.datetime.""" |
| 18 # When microseconds are 0, the '.123456' suffix is elided. This means the | 19 # When microseconds are 0, the '.123456' suffix is elided. This means the |
| 19 # serialized format is not consistent, which confuses the hell out of python. | 20 # serialized format is not consistent, which confuses the hell out of python. |
| 20 # TODO(maruel): Remove third format once we enforce version >=0.8.2. | 21 # TODO(maruel): Remove third format once we enforce version >=0.8.2. |
| (...skipping 702 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 723 | 724 |
| 724 # Show any remaining isolated outputs (such as logcats). | 725 # Show any remaining isolated outputs (such as logcats). |
| 725 # Note that collect_gtest_task.py uses the default summary.json, which | 726 # Note that collect_gtest_task.py uses the default summary.json, which |
| 726 # only has 'outputs_ref' instead of the deprecated 'isolated_out'. | 727 # only has 'outputs_ref' instead of the deprecated 'isolated_out'. |
| 727 for index, shard in enumerate(swarming_summary.get('shards', [])): | 728 for index, shard in enumerate(swarming_summary.get('shards', [])): |
| 728 outputs_ref = shard.get('outputs_ref') | 729 outputs_ref = shard.get('outputs_ref') |
| 729 if outputs_ref: | 730 if outputs_ref: |
| 730 link_name = 'shard #%d isolated out' % index | 731 link_name = 'shard #%d isolated out' % index |
| 731 p.links[link_name] = outputs_ref['view_url'] | 732 p.links[link_name] = outputs_ref['view_url'] |
| 732 | 733 |
| 733 | |
| 734 def _merge_isolated_script_chartjson_ouput_shards(self, task, step_result): | 734 def _merge_isolated_script_chartjson_ouput_shards(self, task, step_result): |
| 735 # Taken from third_party/catapult/telemetry/telemetry/internal/results/ | 735 # Taken from third_party/catapult/telemetry/telemetry/internal/results/ |
| 736 # chart_json_output_formatter.py, the json entries are as follows: | 736 # chart_json_output_formatter.py, the json entries are as follows: |
| 737 # result_dict = { | 737 # result_dict = { |
| 738 # 'format_version': '0.1', | 738 # 'format_version': '0.1', |
| 739 # 'next_version': '0.2', | 739 # 'next_version': '0.2', |
| 740 # 'benchmark_name': benchmark_metadata.name, | 740 # 'benchmark_name': benchmark_metadata.name, |
| 741 # 'benchmark_description': benchmark_metadata.description, | 741 # 'benchmark_description': benchmark_metadata.description, |
| 742 # 'trace_rerun_options': benchmark_metadata.rerun_options, | 742 # 'trace_rerun_options': benchmark_metadata.rerun_options, |
| 743 # 'benchmark_metadata': benchmark_metadata.AsDict(), | 743 # 'benchmark_metadata': benchmark_metadata.AsDict(), |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 763 merged_results = chartjson_results_json | 763 merged_results = chartjson_results_json |
| 764 seen_first_shard = True | 764 seen_first_shard = True |
| 765 continue | 765 continue |
| 766 for key in chartjson_results_json: | 766 for key in chartjson_results_json: |
| 767 if key == 'charts': | 767 if key == 'charts': |
| 768 # Append each additional chart to our merged results | 768 # Append each additional chart to our merged results |
| 769 for add_key in chartjson_results_json[key]: | 769 for add_key in chartjson_results_json[key]: |
| 770 merged_results[key][add_key] = chartjson_results_json[key][add_key] | 770 merged_results[key][add_key] = chartjson_results_json[key][add_key] |
| 771 return merged_results | 771 return merged_results |
| 772 | 772 |
| 773 | |
| 774 def _merge_isolated_script_shards(self, task, step_result): | 773 def _merge_isolated_script_shards(self, task, step_result): |
| 775 # This code is unfortunately specialized to the "simplified" | 774 shard_results_list = [] |
| 776 # JSON format that used to be the standard for recipes. The | |
| 777 # isolated scripts should be changed to use the now-standard | |
| 778 # Chromium JSON test results format: | |
| 779 # https://www.chromium.org/developers/the-json-test-results-format | |
| 780 # . Note that gtests, above, don't seem to conform to this | |
| 781 # format yet, so it didn't seem like a good prerequisite to | |
| 782 # switch the isolated tests over when adding sharding support. | |
| 783 # | |
| 784 # These are the only keys we pay attention to in the output JSON. | |
| 785 merged_results = { | |
| 786 'successes': [], | |
| 787 'failures': [], | |
| 788 'valid': True, | |
| 789 } | |
| 790 for i in xrange(task.shards): | 775 for i in xrange(task.shards): |
| 791 path = self.m.path.join(str(i), 'output.json') | 776 path = self.m.path.join(str(i), 'output.json') |
| 792 if path not in step_result.raw_io.output_dir: | 777 if path not in step_result.raw_io.output_dir: |
| 793 raise Exception('no results from shard #%d' % i) | 778 raise Exception('no results from shard #%d' % i) |
| 794 results_raw = step_result.raw_io.output_dir[path] | 779 results_raw = step_result.raw_io.output_dir[path] |
| 795 try: | 780 try: |
| 796 results_json = self.m.json.loads(results_raw) | 781 results_json = self.m.json.loads(results_raw) |
| 782 shard_results_list.append(results_json) | |
| 797 except Exception as e: | 783 except Exception as e: |
| 798 raise Exception('error decoding JSON results from shard #%d' % i) | 784 raise Exception('error decoding JSON results from shard #%d' % i) |
| 799 for key in merged_results: | 785 return results_merger.merge_test_results(shard_results_list) |
| 800 if key in results_json: | |
| 801 if isinstance(merged_results[key], list): | |
| 802 merged_results[key].extend(results_json[key]) | |
| 803 elif isinstance(merged_results[key], bool): | |
| 804 merged_results[key] = merged_results[key] and results_json[key] | |
| 805 else: | |
| 806 raise recipe_api.InfraFailure( | |
| 807 'Unknown key type ' + type(merged_results[key]) + | |
| 808 ' when handling key ' + key + '.') # pragma: no cover | |
| 809 return merged_results | |
| 810 | 786 |
| 811 def _isolated_script_collect_step(self, task, **kwargs): | 787 def _isolated_script_collect_step(self, task, **kwargs): |
| 812 step_test_data = kwargs.pop('step_test_data', None) | 788 step_test_data = kwargs.pop('step_test_data', None) |
| 813 if not step_test_data: | 789 if not step_test_data: |
| 814 step_test_data = self.m.test_utils.test_api.canned_isolated_script_output( | 790 step_test_data = self.m.test_utils.test_api.canned_isolated_script_output( |
| 815 passing=True, is_win=self.m.platform.is_win, swarming=True) | 791 passing=True, is_win=self.m.platform.is_win, swarming=True) |
| 816 | 792 |
| 817 args=self.get_collect_cmd_args(task) | 793 args=self.get_collect_cmd_args(task) |
| 818 args.extend(['--task-output-dir', self.m.raw_io.output_dir()]) | 794 args.extend(['--task-output-dir', self.m.raw_io.output_dir()]) |
| 819 | 795 |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1052 | 1028 |
| 1053 def get_shard_view_url(self, index): | 1029 def get_shard_view_url(self, index): |
| 1054 """Returns URL of HTML page with shard details or None if not available. | 1030 """Returns URL of HTML page with shard details or None if not available. |
| 1055 | 1031 |
| 1056 Works only after the task has been successfully triggered. | 1032 Works only after the task has been successfully triggered. |
| 1057 """ | 1033 """ |
| 1058 if self._trigger_output and self._trigger_output.get('tasks'): | 1034 if self._trigger_output and self._trigger_output.get('tasks'): |
| 1059 for shard_dict in self._trigger_output['tasks'].itervalues(): | 1035 for shard_dict in self._trigger_output['tasks'].itervalues(): |
| 1060 if shard_dict['shard_index'] == index: | 1036 if shard_dict['shard_index'] == index: |
| 1061 return shard_dict['view_url'] | 1037 return shard_dict['view_url'] |
| OLD | NEW |