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 datetime | 6 import datetime |
6 import functools | 7 import functools |
7 | 8 |
8 from recipe_engine import recipe_api | 9 from recipe_engine import recipe_api |
9 | 10 |
10 | 11 |
11 # Minimally supported version of swarming.py script (reported by --version). | 12 # Minimally supported version of swarming.py script (reported by --version). |
12 MINIMAL_SWARMING_VERSION = (0, 8, 6) | 13 MINIMAL_SWARMING_VERSION = (0, 8, 6) |
13 | 14 |
14 | 15 |
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
400 extra_args.append( | 401 extra_args.append( |
401 '--test-launcher-summary-output=${ISOLATED_OUTDIR}/output.json') | 402 '--test-launcher-summary-output=${ISOLATED_OUTDIR}/output.json') |
402 | 403 |
403 # Make a task, configure it to be collected through shim script. | 404 # Make a task, configure it to be collected through shim script. |
404 task = self.task(title, isolated_hash, extra_args=extra_args, | 405 task = self.task(title, isolated_hash, extra_args=extra_args, |
405 cipd_packages=cipd_packages, **kwargs) | 406 cipd_packages=cipd_packages, **kwargs) |
406 task.collect_step = lambda *args, **kw: ( | 407 task.collect_step = lambda *args, **kw: ( |
407 self._gtest_collect_step(test_launcher_summary_output, *args, **kw)) | 408 self._gtest_collect_step(test_launcher_summary_output, *args, **kw)) |
408 return task | 409 return task |
409 | 410 |
411 def _check_and_set_output_flag(self, extra_args, flag, output_file_name): | |
412 extra_args = list(extra_args or []) | |
413 # Ensure flag is not already passed. We are going to overwrite it. | |
414 flag_value = '--%s=' % flag | |
415 bad_args = any(x.startswith(flag_value) for x in extra_args) | |
416 if bad_args: # pragma: no cover | |
417 error = '--%s should not be used' % flag | |
418 raise ValueError(error) | |
419 | |
420 # Append it. | |
421 output_arg = '--%s=${ISOLATED_OUTDIR}/%s' % (flag, output_file_name) | |
422 return extra_args.append(output_arg) | |
423 | |
410 def isolated_script_task(self, title, isolated_hash, extra_args=None, | 424 def isolated_script_task(self, title, isolated_hash, extra_args=None, |
411 idempotent=False, **kwargs): | 425 idempotent=False, **kwargs): |
412 """Returns a new SwarmingTask to run an isolated script test on Swarming. | 426 """Returns a new SwarmingTask to run an isolated script test on Swarming. |
413 | 427 |
414 Swarming recipe module knows how collect JSON file with test execution | 428 Swarming recipe module knows how collect JSON file with test execution |
415 summary produced by isolated script tests launcher. Since isolated script | 429 summary produced by isolated script tests launcher. Since isolated script |
416 tests do not support sharding, no merging of the results is performed. | 430 tests do not support sharding, no merging of the results is performed. |
417 Parsed JSON summary is returned from the collect step. | 431 Parsed JSON summary is returned from the collect step. |
418 | 432 |
419 For meaning of the rest of the arguments see 'task' method. | 433 For meaning of the rest of the arguments see 'task' method. |
420 """ | 434 """ |
421 extra_args = list(extra_args or []) | |
422 | 435 |
423 # Ensure --isolated-script-test-output is not already passed. We are going | 436 # Ensure output flags are not already passed. We are going |
424 # to overwrite it. | 437 # to overwrite them. |
425 bad_args = any( | 438 # output.json name is expected by collect_gtest_task.py. |
426 x.startswith('--isolated-script-test-output=') for x in extra_args) | 439 extra_args = self._check_and_set_output_flag( \ |
427 if bad_args: # pragma: no cover | 440 extra_args, 'isolated-script-test-output', 'output.json') |
428 raise ValueError('--isolated-script-test-output should not be used.') | 441 # chart-output.json name is expected by benchmarks generating chartjson |
429 | 442 # output |
430 # Append it. output.json name is expected by collect_gtest_task.py. | 443 extra_args = self._check_and_set_output_flag( \ |
Ken Russell (switch to Gerrit)
2016/09/13 19:34:47
Should the addition of this command line argument
eyaich1
2016/09/14 18:14:27
This code is not requiring the command line, it is
| |
431 extra_args.append( | 444 extra_args, 'isolated-script-test-chart-output', 'chart-output.json') |
Ken Russell (switch to Gerrit)
2016/09/13 19:34:46
I'd like to suggest using "isolated-script-test-ch
eyaich1
2016/09/14 18:14:28
Done.
| |
432 '--isolated-script-test-output=${ISOLATED_OUTDIR}/output.json') | |
433 | 445 |
434 task = self.task(title, isolated_hash, extra_args=extra_args, | 446 task = self.task(title, isolated_hash, extra_args=extra_args, |
435 idempotent=idempotent, **kwargs) | 447 idempotent=idempotent, **kwargs) |
436 task.collect_step = self._isolated_script_collect_step | 448 task.collect_step = self._isolated_script_collect_step |
437 return task | 449 return task |
438 | 450 |
439 def check_client_version(self, step_test_data=None): | 451 def check_client_version(self, step_test_data=None): |
440 """Yields steps to verify compatibility with swarming_client version.""" | 452 """Yields steps to verify compatibility with swarming_client version.""" |
441 return self.m.swarming_client.ensure_script_version( | 453 return self.m.swarming_client.ensure_script_version( |
442 'swarming.py', MINIMAL_SWARMING_VERSION, step_test_data) | 454 'swarming.py', MINIMAL_SWARMING_VERSION, step_test_data) |
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
710 # Show any remaining isolated outputs (such as logcats). | 722 # Show any remaining isolated outputs (such as logcats). |
711 # Note that collect_gtest_task.py uses the default summary.json, which | 723 # Note that collect_gtest_task.py uses the default summary.json, which |
712 # only has 'outputs_ref' instead of the deprecated 'isolated_out'. | 724 # only has 'outputs_ref' instead of the deprecated 'isolated_out'. |
713 for index, shard in enumerate(swarming_summary.get('shards', [])): | 725 for index, shard in enumerate(swarming_summary.get('shards', [])): |
714 outputs_ref = shard.get('outputs_ref') | 726 outputs_ref = shard.get('outputs_ref') |
715 if outputs_ref: | 727 if outputs_ref: |
716 link_name = 'shard #%d isolated out' % index | 728 link_name = 'shard #%d isolated out' % index |
717 p.links[link_name] = outputs_ref['view_url'] | 729 p.links[link_name] = outputs_ref['view_url'] |
718 | 730 |
719 | 731 |
732 def _merge_isolated_script_chart_ouput_shards(self, task, step_result): | |
Ken Russell (switch to Gerrit)
2016/09/13 19:34:46
chart -> chartjson?
eyaich1
2016/09/14 18:14:28
Done.
| |
733 # Taken from third_party/catapult/telemetry/telemetry/internal/results/ | |
734 # chart_json_output_formatter.py, the json entries are as follows: | |
735 # result_dict = { | |
736 # 'format_version': '0.1', | |
737 # 'next_version': '0.2', | |
738 # 'benchmark_name': benchmark_metadata.name, | |
739 # 'benchmark_description': benchmark_metadata.description, | |
740 # 'trace_rerun_options': benchmark_metadata.rerun_options, | |
741 # 'benchmark_metadata': benchmark_metadata.AsDict(), | |
742 # 'charts': charts, | |
743 # } | |
744 # | |
745 # Therefore, all entries should be the same and we should only need to merge | |
746 # the chat from each shard. | |
Ken Russell (switch to Gerrit)
2016/09/13 19:34:46
chat -> chart
eyaich1
2016/09/14 18:14:27
Done.
| |
747 merged_results = {} | |
748 seen_first_shard = False | |
749 for i in xrange(task.shards): | |
750 path = self.m.path.join(str(i), 'chart-output.json') | |
751 if path not in step_result.raw_io.output_dir: | |
752 logging.info("No chart json present, isolated_script_chart_results " + | |
753 " will be unset.") | |
754 results_raw = step_result.raw_io.output_dir[path] | |
755 try: | |
756 chart_results_json = self.m.json.loads(results_raw) | |
757 except Exception as e: | |
758 raise Exception('error decoding JSON results from shard #%d' % i) | |
759 if not seen_first_shard: | |
760 merged_results = chart_results_json | |
761 seen_first_shard = True | |
762 continue | |
763 for key in chart_results_json: | |
764 if key == 'charts': | |
765 merged_results[key].extend(results_json[key]) | |
766 break | |
767 return merged_results | |
768 | |
769 | |
720 def _merge_isolated_script_shards(self, task, step_result): | 770 def _merge_isolated_script_shards(self, task, step_result): |
721 # This code is unfortunately specialized to the "simplified" | 771 # This code is unfortunately specialized to the "simplified" |
722 # JSON format that used to be the standard for recipes. The | 772 # JSON format that used to be the standard for recipes. The |
723 # isolated scripts should be changed to use the now-standard | 773 # isolated scripts should be changed to use the now-standard |
724 # Chromium JSON test results format: | 774 # Chromium JSON test results format: |
725 # https://www.chromium.org/developers/the-json-test-results-format | 775 # https://www.chromium.org/developers/the-json-test-results-format |
726 # . Note that gtests, above, don't seem to conform to this | 776 # . Note that gtests, above, don't seem to conform to this |
727 # format yet, so it didn't seem like a good prerequisite to | 777 # format yet, so it didn't seem like a good prerequisite to |
728 # switch the isolated tests over when adding sharding support. | 778 # switch the isolated tests over when adding sharding support. |
729 # | 779 # |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
792 # in recipe runs.) | 842 # in recipe runs.) |
793 links = step_result.presentation.links | 843 links = step_result.presentation.links |
794 for index in xrange(task.shards): | 844 for index in xrange(task.shards): |
795 url = task.get_shard_view_url(index) | 845 url = task.get_shard_view_url(index) |
796 if url: | 846 if url: |
797 links['shard #%d' % index] = url | 847 links['shard #%d' % index] = url |
798 | 848 |
799 step_result.isolated_script_results = \ | 849 step_result.isolated_script_results = \ |
800 self._merge_isolated_script_shards(task, step_result) | 850 self._merge_isolated_script_shards(task, step_result) |
801 | 851 |
852 # Obtain chart json results if present | |
853 step_result.isolated_script_chart_results = \ | |
Ken Russell (switch to Gerrit)
2016/09/13 19:34:46
chart_results -> chartjson_results?
eyaich1
2016/09/14 18:14:27
Done.
| |
854 self._merge_isolated_script_chart_ouput_shards(task, step_result) | |
Ken Russell (switch to Gerrit)
2016/09/13 19:34:46
Is this sufficient to test the above code paths? H
eyaich1
2016/09/14 18:14:28
wow thanks for pointing me at the test_api.py file
| |
855 | |
802 self._display_pending(summary, step_result.presentation) | 856 self._display_pending(summary, step_result.presentation) |
803 except Exception as e: | 857 except Exception as e: |
804 self.m.step.active_result.presentation.logs['no_results_exc'] = [str(e)] | 858 self.m.step.active_result.presentation.logs['no_results_exc'] = [str(e)] |
805 self.m.step.active_result.isolated_script_results = None | 859 self.m.step.active_result.isolated_script_results = None |
806 | 860 |
807 def _get_step_name(self, prefix, task): | 861 def _get_step_name(self, prefix, task): |
808 """SwarmingTask -> name of a step of a waterfall. | 862 """SwarmingTask -> name of a step of a waterfall. |
809 | 863 |
810 Will take a task title (+ step name prefix) and append OS dimension to it. | 864 Will take a task title (+ step name prefix) and append OS dimension to it. |
811 | 865 |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
989 | 1043 |
990 def get_shard_view_url(self, index): | 1044 def get_shard_view_url(self, index): |
991 """Returns URL of HTML page with shard details or None if not available. | 1045 """Returns URL of HTML page with shard details or None if not available. |
992 | 1046 |
993 Works only after the task has been successfully triggered. | 1047 Works only after the task has been successfully triggered. |
994 """ | 1048 """ |
995 if self._trigger_output and self._trigger_output.get('tasks'): | 1049 if self._trigger_output and self._trigger_output.get('tasks'): |
996 for shard_dict in self._trigger_output['tasks'].itervalues(): | 1050 for shard_dict in self._trigger_output['tasks'].itervalues(): |
997 if shard_dict['shard_index'] == index: | 1051 if shard_dict['shard_index'] == index: |
998 return shard_dict['view_url'] | 1052 return shard_dict['view_url'] |
OLD | NEW |