Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(12)

Side by Side Diff: scripts/slave/recipe_modules/swarming/api.py

Issue 2375663003: Add json test results format support for SwarmingIsolatedScriptTest (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
(...skipping 752 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 def _merge_simplified_test_result_format(self, shard_results_list):
774 merged_results = {
775 'successes': [],
776 'failures': [],
777 'valid': True,
778 }
779 for results_json in shard_results_list:
780 for key in merged_results:
781 if key in results_json:
782 if isinstance(merged_results[key], list):
783 merged_results[key].extend(results_json[key])
784 elif isinstance(merged_results[key], bool):
785 merged_results[key] = merged_results[key] and results_json[key]
786 else:
787 raise recipe_api.InfraFailure(
788 'Unknown key type ' + type(merged_results[key]) +
789 ' when handling key ' + key + '.') # pragma: no cover
790 return merged_results
791
792 def _merge_json_test_result_format(self, shard_results_list):
793 merged_results = {
794 'tests': {},
795 'interrupted': false,
796 'path_delimiter': '',
797 'version': 3,
798 'seconds_since_epoch': float('inf'),
799 'num_failures_by_type': {
800 }
801 }
802 for result_json in shard_results_list:
803 if not ('tests' in result_json and
804 'interrupted' in result_json and
805 'path_delimiter' in result_json and
806 'version' in result_json and
807 'seconds_since_epoch' in result_json and
808 'num_failures_by_type' in result_json):
809 raise recipe_api.InfraFailure('Invalid json test results')
Sergiy Byelozyorov 2016/09/29 21:36:22 I would double-check if everybody implements the f
nednguyen 2016/10/04 00:10:11 Hmhh, the spec say these fields are required? htt
Sergiy Byelozyorov 2016/10/04 08:54:52 Sure. I just meant that you should make sure it do
Dirk Pranke 2016/10/04 20:04:02 We should try to follow the spec and update the sp
810
811 # Traverse the results_json's test trie & merged_results's test tries in
812 # DFS order & add the n to merged['tests'].
813 curr_result_nodes_queue = [results_json['tests']]
814 merged_results_nodes_queue = [merged_results['tests']]
815 while nodes_queue:
Sergiy Byelozyorov 2016/09/29 21:36:22 I don't see nodes_queue defined anywhere... does t
nednguyen 2016/10/04 00:10:11 Yeah, I wasn't sure how to test these. Done.
816 curr_node = curr_result_nodes_queue.pop()
817 merged_node = merged_results_nodes_queue.pop()
818 for k, v in curr_node.iteritems():
819 if k in merged_node:
820 curr_result_nodes_queue.push(v)
821 merged_results_nodes_queue.push(merged_node[k])
822 else:
823 merged_node[k] = v
824
825 # Update the rest of the fields for merged_results.
826 merged_results['interrupted'] |= results_json['interrupted']
827 if not merged_results['path_delimiter']:
828 merged_results['path_delimiter'] = results_json['path_delimiter']
829 elif merged_results['path_delimiter'] != results_json['path_delimiter']:
830 raise Exception(
831 'Incosistent path delimiter: %s %s' %
832 (merged_results['path_delimiter'],
833 results_json['path_delimiter']))
834 if results_json['version'] != 3:
835 raise recipe_api.InfraFailure(
836 'Only version 3 of json test result format is supported')
837 merged_results['seconds_since_epoch'] = min(
838 merged_results['seconds_since_epoch'],
839 results_json['seconds_since_epoch'])
Sergiy Byelozyorov 2016/09/29 21:36:22 Any particular reason to pick the smaller of the t
nednguyen 2016/10/04 00:10:11 I honestly not sure what is the reason for this fi
Sergiy Byelozyorov 2016/10/04 08:54:52 AFAIK, this is when the tests were run... probably
nednguyen 2016/10/04 13:30:29 Ah, I just think that the earliest seconds_since_e
840 for result_type, count in results_json['num_failures_by_type']:
841 if not result_type in merged_results['num_failures_by_type']:
Sergiy Byelozyorov 2016/09/29 21:36:22 IMHO this is more Pythonic: merged_results['num_f
nednguyen 2016/10/04 00:10:11 Done.
842 merged_results['num_failures_by_type'][result_type] = 0
843 merged_results['num_failures_by_type'][result_type] += count
773 844
774 def _merge_isolated_script_shards(self, task, step_result): 845 def _merge_isolated_script_shards(self, task, step_result):
775 # This code is unfortunately specialized to the "simplified" 846 # This code is unfortunately specialized to the "simplified"
776 # JSON format that used to be the standard for recipes. The 847 # JSON format that used to be the standard for recipes. The
777 # isolated scripts should be changed to use the now-standard 848 # isolated scripts should be changed to use the now-standard
778 # Chromium JSON test results format: 849 # Chromium JSON test results format:
779 # https://www.chromium.org/developers/the-json-test-results-format 850 # https://www.chromium.org/developers/the-json-test-results-format
780 # . Note that gtests, above, don't seem to conform to this 851 # . Note that gtests, above, don't seem to conform to this
781 # format yet, so it didn't seem like a good prerequisite to 852 # format yet, so it didn't seem like a good prerequisite to
782 # switch the isolated tests over when adding sharding support. 853 # switch the isolated tests over when adding sharding support.
783 # 854 #
784 # These are the only keys we pay attention to in the output JSON. 855 # These are the only keys we pay attention to in the output JSON.
Ken Russell (switch to Gerrit) 2016/09/30 23:37:53 Please move this comment to the top of _merge_simp
nednguyen 2016/10/04 00:10:11 Done.
785 merged_results = { 856 shard_results_list = []
786 'successes': [],
787 'failures': [],
788 'valid': True,
789 }
790 for i in xrange(task.shards): 857 for i in xrange(task.shards):
791 path = self.m.path.join(str(i), 'output.json') 858 path = self.m.path.join(str(i), 'output.json')
792 if path not in step_result.raw_io.output_dir: 859 if path not in step_result.raw_io.output_dir:
793 raise Exception('no results from shard #%d' % i) 860 raise Exception('no results from shard #%d' % i)
794 results_raw = step_result.raw_io.output_dir[path] 861 results_raw = step_result.raw_io.output_dir[path]
795 try: 862 try:
796 results_json = self.m.json.loads(results_raw) 863 results_json = self.m.json.loads(results_raw)
864 shard_results_list.append(results_json)
797 except Exception as e: 865 except Exception as e:
798 raise Exception('error decoding JSON results from shard #%d' % i) 866 raise Exception('error decoding JSON results from shard #%d' % i)
799 for key in merged_results: 867 if not shard_results_list:
eyaich1 2016/09/29 14:55:23 no need for this check you create it above
Sergiy Byelozyorov 2016/09/29 21:36:22 But it can be empty, can't it?
800 if key in results_json: 868 raise Exception('No shard results is created')
Ken Russell (switch to Gerrit) 2016/09/30 23:37:53 Grammar: remove "is".
nednguyen 2016/10/04 00:10:11 Done.
801 if isinstance(merged_results[key], list): 869 elif 'seconds_since_epoch' in shard_results_list[0]:
eyaich1 2016/09/29 14:55:23 is this the distinguishing factor between the resu
nednguyen 2016/10/04 00:10:11 This is the distinguished factor between the simpl
802 merged_results[key].extend(results_json[key]) 870 return self._merge_json_test_result_format[shard_results_list]
803 elif isinstance(merged_results[key], bool): 871 else:
804 merged_results[key] = merged_results[key] and results_json[key] 872 return self._merge_simplified_json_format(shard_results_list)
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 873
811 def _isolated_script_collect_step(self, task, **kwargs): 874 def _isolated_script_collect_step(self, task, **kwargs):
812 step_test_data = kwargs.pop('step_test_data', None) 875 step_test_data = kwargs.pop('step_test_data', None)
813 if not step_test_data: 876 if not step_test_data:
814 step_test_data = self.m.test_utils.test_api.canned_isolated_script_output( 877 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) 878 passing=True, is_win=self.m.platform.is_win, swarming=True)
816 879
817 args=self.get_collect_cmd_args(task) 880 args=self.get_collect_cmd_args(task)
818 args.extend(['--task-output-dir', self.m.raw_io.output_dir()]) 881 args.extend(['--task-output-dir', self.m.raw_io.output_dir()])
819 882
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
1052 1115
1053 def get_shard_view_url(self, index): 1116 def get_shard_view_url(self, index):
1054 """Returns URL of HTML page with shard details or None if not available. 1117 """Returns URL of HTML page with shard details or None if not available.
1055 1118
1056 Works only after the task has been successfully triggered. 1119 Works only after the task has been successfully triggered.
1057 """ 1120 """
1058 if self._trigger_output and self._trigger_output.get('tasks'): 1121 if self._trigger_output and self._trigger_output.get('tasks'):
1059 for shard_dict in self._trigger_output['tasks'].itervalues(): 1122 for shard_dict in self._trigger_output['tasks'].itervalues():
1060 if shard_dict['shard_index'] == index: 1123 if shard_dict['shard_index'] == index:
1061 return shard_dict['view_url'] 1124 return shard_dict['view_url']
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698