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

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

Issue 2073923002: Support sharding for swarmed isolated script tests. (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/build.git@master
Patch Set: Explicitly handle missing shards' output. Created 4 years, 6 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 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
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 path = self.m.path.join(str(i), 'output.json')
725 if path not in step_result.raw_io.output_dir:
726 raise Exception('no results from shard #%d' % i)
727 results_raw = step_result.raw_io.output_dir[path]
728 results_json = self.m.json.loads(results_raw)
729 for key in merged_results:
730 if key in results_json:
731 if isinstance(merged_results[key], list):
732 merged_results[key].extend(results_json[key])
733 elif isinstance(merged_results[key], bool):
734 merged_results[key] = merged_results[key] and results_json[key]
735 else:
736 raise recipe_api.InfraFailure(
737 'Unknown key type ' + type(merged_results[key]) +
738 ' when handling key ' + key + '.') # pragma: no cover
739 return merged_results
740
706 def _isolated_script_collect_step(self, task, **kwargs): 741 def _isolated_script_collect_step(self, task, **kwargs):
707 step_test_data = kwargs.pop('step_test_data', None) 742 step_test_data = kwargs.pop('step_test_data', None)
708 if not step_test_data: 743 if not step_test_data:
709 step_test_data = self.m.test_utils.test_api.canned_isolated_script_output( 744 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) 745 passing=True, is_win=self.m.platform.is_win, swarming=True)
711 746
712 args=self.get_collect_cmd_args(task) 747 args=self.get_collect_cmd_args(task)
713 args.extend(['--task-output-dir', self.m.raw_io.output_dir()]) 748 args.extend(['--task-output-dir', self.m.raw_io.output_dir()])
714 749
715 try: 750 try:
(...skipping 13 matching lines...) Expand all
729 step_result = self.m.step.active_result 764 step_result = self.m.step.active_result
730 outdir_json = self.m.json.dumps(step_result.raw_io.output_dir, indent=2) 765 outdir_json = self.m.json.dumps(step_result.raw_io.output_dir, indent=2)
731 step_result.presentation.logs['outdir_json'] = outdir_json.splitlines() 766 step_result.presentation.logs['outdir_json'] = outdir_json.splitlines()
732 767
733 # Check if it's an internal failure. 768 # Check if it's an internal failure.
734 summary = self.m.json.loads( 769 summary = self.m.json.loads(
735 step_result.raw_io.output_dir['summary.json']) 770 step_result.raw_io.output_dir['summary.json'])
736 if any(shard['internal_failure'] for shard in summary['shards']): 771 if any(shard['internal_failure'] for shard in summary['shards']):
737 raise recipe_api.InfraFailure('Internal swarming failure.') 772 raise recipe_api.InfraFailure('Internal swarming failure.')
738 773
739 # TODO(nednguyen, kbr): Combine isolated script results from multiple 774 # Always show the shards' links in the collect step. (It looks
740 # shards rather than assuming that there is always just one shard. 775 # like show_isolated_out_in_collect_step is false by default
741 assert len(summary['shards']) == 1 776 # in recipe runs.)
742 results_raw = step_result.raw_io.output_dir[ 777 links = step_result.presentation.links
743 self.m.path.join('0', 'output.json')] 778 for index in xrange(task.shards):
744 step_result.isolated_script_results = self.m.json.loads(results_raw) 779 url = task.get_shard_view_url(index)
780 if url:
781 links['shard #%d' % index] = url
782
783 step_result.isolated_script_results = \
784 self._merge_isolated_script_shards(task, step_result)
745 785
746 self._display_pending(summary, step_result.presentation) 786 self._display_pending(summary, step_result.presentation)
747 except Exception as e: 787 except Exception as e:
748 self.m.step.active_result.presentation.logs['no_results_exc'] = [str(e)] 788 self.m.step.active_result.presentation.logs['no_results_exc'] = [str(e)]
749 self.m.step.active_result.isolated_script_results = None 789 self.m.step.active_result.isolated_script_results = None
750 790
751 def _get_step_name(self, prefix, task): 791 def _get_step_name(self, prefix, task):
752 """SwarmingTask -> name of a step of a waterfall. 792 """SwarmingTask -> name of a step of a waterfall.
753 793
754 Will take a task title (+ step name prefix) and append OS dimension to it. 794 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
928 968
929 def get_shard_view_url(self, index): 969 def get_shard_view_url(self, index):
930 """Returns URL of HTML page with shard details or None if not available. 970 """Returns URL of HTML page with shard details or None if not available.
931 971
932 Works only after the task has been successfully triggered. 972 Works only after the task has been successfully triggered.
933 """ 973 """
934 if self._trigger_output and self._trigger_output.get('tasks'): 974 if self._trigger_output and self._trigger_output.get('tasks'):
935 for shard_dict in self._trigger_output['tasks'].itervalues(): 975 for shard_dict in self._trigger_output['tasks'].itervalues():
936 if shard_dict['shard_index'] == index: 976 if shard_dict['shard_index'] == index:
937 return shard_dict['view_url'] 977 return shard_dict['view_url']
OLDNEW
« no previous file with comments | « scripts/slave/recipe_modules/chromium_tests/steps.py ('k') | scripts/slave/recipe_modules/test_utils/test_api.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698