Chromium Code Reviews| Index: scripts/slave/recipe_modules/swarming/api.py |
| diff --git a/scripts/slave/recipe_modules/swarming/api.py b/scripts/slave/recipe_modules/swarming/api.py |
| index 75a4df3290862aa64d5c1bcb36be48702d7808e3..c015fc75159c02315176796f24fb2e0f374f6dc8 100644 |
| --- a/scripts/slave/recipe_modules/swarming/api.py |
| +++ b/scripts/slave/recipe_modules/swarming/api.py |
| @@ -346,6 +346,35 @@ class SwarmingApi(recipe_api.RecipeApi): |
| task.collect_step = self._telemetry_gpu_collect_step |
| return task |
| + def isolated_script_task(self, title, isolated_hash, extra_args=None, |
| + idempotent=False, **kwargs): |
|
nednguyen
2015/10/27 00:58:09
Pawel: changing the default of this from False to
Paweł Hajdan Jr.
2015/10/27 11:12:52
False makes sense to me. I don't see any _existing
|
| + """Returns a new SwarmingTask to run an isolated script test on Swarming. |
| + |
| + Swarming recipe module knows how collect JSON file with test execution |
| + summary produced by isolated script tests launcher. Since isolated script |
| + tests do not support sharding, no merging of the results is performed. |
| + Parsed JSON summary is returned from the collect step. |
| + |
| + For meaning of the rest of the arguments see 'task' method. |
| + """ |
| + extra_args = list(extra_args or []) |
| + |
| + # Ensure --isolated-script-test-output is not already passed. We are going |
| + # to overwrite it. |
| + bad_args = any( |
| + x.startswith('--isolated-script-test-output=') for x in extra_args) |
| + if bad_args: # pragma: no cover |
| + raise ValueError('--isolated-script-test-output should not be used.') |
| + |
| + # Append it. output.json name is expected by collect_gtest_task.py. |
| + extra_args.append( |
| + '--isolated-script-test-output=${ISOLATED_OUTDIR}/output.json') |
| + |
| + task = self.task(title, isolated_hash, extra_args=extra_args, |
| + idempotent=idempotent, **kwargs) |
| + task.collect_step = self._isolated_script_collect_step |
| + return task |
| + |
| def check_client_version(self, step_test_data=None): |
| """Yields steps to verify compatibility with swarming_client version.""" |
| return self.m.swarming_client.ensure_script_version( |
| @@ -654,6 +683,51 @@ class SwarmingApi(recipe_api.RecipeApi): |
| self.m.step.active_result.presentation.logs['no_results_exc'] = [str(e)] |
| self.m.step.active_result.telemetry_results = None |
| + def _isolated_script_collect_step(self, task, **kwargs): |
| + step_test_data = kwargs.pop('step_test_data', None) |
| + if not step_test_data: |
| + step_test_data = self.m.test_utils.test_api.canned_isolated_script_output( |
| + passing=True, is_win=self.m.platform.is_win, swarming=True) |
| + |
| + args=self.get_collect_cmd_args(task) |
| + args.extend(['--task-output-dir', self.m.raw_io.output_dir()]) |
| + |
| + try: |
| + self.m.python( |
| + name=self._get_step_name('', task), |
| + script=self.m.swarming_client.path.join('swarming.py'), |
| + args=args, step_test_data=lambda: step_test_data, |
| + **kwargs) |
| + finally: |
| + # Regardless of the outcome of the test (pass or fail), we try to parse |
| + # the results. If any error occurs while parsing results, then we set them |
| + # to None, which will be treated as invalid test results by |
| + # SwarmingIsolatedScriptTest class in recipe_modules/chromium/steps.py. |
| + # Note that try-except block below will not mask the |
| + # recipe_api.StepFailure exception from the collect step above. Instead |
| + # it is being allowed to propagate after the results have been parsed. |
| + try: |
| + step_result = self.m.step.active_result |
| + outdir_json = self.m.json.dumps(step_result.raw_io.output_dir, indent=2) |
| + step_result.presentation.logs['outdir_json'] = outdir_json.splitlines() |
| + |
| + # Check if it's an internal failure. |
| + summary = self.m.json.loads( |
| + step_result.raw_io.output_dir['summary.json']) |
| + if any(shard['internal_failure'] for shard in summary['shards']): |
| + raise recipe_api.InfraFailure('Internal swarming failure.') |
| + |
| + # TODO(nednguyen, kbr): Combine isolated script results from multiple |
| + # shards rather than assuming that there is always just one shard. |
| + assert len(summary['shards']) == 1 |
| + results_raw = step_result.raw_io.output_dir[ |
| + self.m.path.join('0', 'output.json')] |
| + step_result.isolated_script_results = self.m.json.loads(results_raw) |
| + |
| + self._display_pending(summary, step_result.presentation) |
| + except Exception as e: |
| + self.m.step.active_result.presentation.logs['no_results_exc'] = [str(e)] |
| + self.m.step.active_result.telemetry_results = None |
| def _get_step_name(self, prefix, task): |
| """SwarmingTask -> name of a step of a waterfall. |