Chromium Code Reviews| Index: scripts/slave/recipe_modules/chromium_tests/steps.py |
| diff --git a/scripts/slave/recipe_modules/chromium_tests/steps.py b/scripts/slave/recipe_modules/chromium_tests/steps.py |
| index ada6e28c6f88f28886990d2876b19604ae799a66..cd864849ab8beae4e83a61ffdf123d0b24ccf1da 100644 |
| --- a/scripts/slave/recipe_modules/chromium_tests/steps.py |
| +++ b/scripts/slave/recipe_modules/chromium_tests/steps.py |
| @@ -805,6 +805,136 @@ class AMPInstrumentationTest(AMPTest): |
| isolate_file_path=isolate_file_path).run(api, suffix) |
| +class IsolatedScriptTest(Test): |
| + def __init__(self, name, args=None, target_name=None, revision=None, |
| + webkit_revision=None, override_compile_targets=None, |
| + **runtest_kwargs): |
| + """Constructs an instance of IsolatedScriptTest. |
| + |
| + An IsolatedScriptTest knows how to invoke an isolate which obeys a certain |
| + contract. The isolate's main target must be a wrapper script which must |
| + interpret certain command line arguments as follows: |
| + |
| + --test-launcher-summary-output [FILENAME] |
| + |
| + The wrapper script must write the simplified json output that the recipes |
| + consume (similar to GTestTest and ScriptTest) into |FILENAME|. |
| + |
| + The contract may be expanded later to support functionality like sharding |
| + and retries of specific failed tests. Currently the examples of such wrapper |
| + scripts live in src/testing/scripts/ in the Chromium workspace. |
| + |
| + Args: |
| + name: Displayed name of the test. May be modified by suffixes. |
| + args: Arguments to be passed to the test. |
| + target_name: Actual name of the test. Defaults to name. |
| + revision: Revision of the Chrome checkout. |
| + webkit_revision: Revision of the WebKit checkout. |
| + override_compile_targets: List of compile targets for this test |
| + (for tests that don't follow target naming conventions). |
| + runtest_kwargs: Additional keyword args forwarded to the runtest. |
| + """ |
| + super(IsolatedScriptTest, self).__init__() |
| + self._name = name |
| + self._args = args or [] |
| + self._target_name = target_name |
| + self._revision = revision |
| + self._webkit_revision = webkit_revision |
| + self._override_compile_targets = override_compile_targets |
| + self._runtest_kwargs = runtest_kwargs |
| + |
| + @property |
| + def name(self): |
| + return self._name |
| + |
| + @property |
| + def target_name(self): |
| + return self._target_name or self._name |
| + |
| + @property |
| + def isolate_target(self): |
|
Ken Russell (switch to Gerrit)
2015/09/15 01:41:16
I think we need to override the "uses_swarming" pr
|
| + return self.target_name # pragma: no cover |
| + |
| + # TODO(nednguyen, kbr): figure out what to do with Android. |
| + def compile_targets(self, api): |
| + if self._override_compile_targets: |
| + return self._override_compile_targets |
| + |
| + if api.chromium.c.TARGET_PLATFORM == 'android': |
| + return [self.target_name + '_apk'] |
| + |
| + return [self.target_name] |
| + |
| + def run(self, api, suffix): |
| + # Copy the list because run can be invoked multiple times and we modify |
| + # the local copy. |
| + args = self._args[:] |
| + is_android = api.chromium.c.TARGET_PLATFORM == 'android' |
| + |
| + # TODO(nednguyen, kbr): figure out what to do with Android. |
| + if is_android: |
| + raise UnimplementedError |
| + |
| + kwargs = {} |
| + # TODO(nednguyen, kbr): define contract with the wrapper script to rerun |
| + # a subset of the tests. |
| + # if suffix == 'without patch': |
| + # failures = self.failures(api, 'with patch') |
| + # if is_android: |
| + # kwargs['gtest_filter'] = ':'.join(failures) # pragma: no cover |
| + # else: |
| + # args.append(api.chromium.test_launcher_filter(failures)) |
| + |
| + gtest_results_file = api.test_utils.gtest_results(add_json_log=False) |
|
Ken Russell (switch to Gerrit)
2015/09/17 01:19:31
We should use api.json.output() here and a similar
|
| + step_test_data = lambda: api.test_utils.test_api.canned_gtest_output(True) |
| + |
| + kwargs['name'] = self._step_name(suffix) |
| + kwargs['args'] = args |
| + kwargs['step_test_data'] = step_test_data |
| + kwargs['xvfb'] = True |
| + kwargs['test_type'] = self.name |
| + kwargs['annotate'] = 'gtest' |
| + kwargs['test_launcher_summary_output'] = gtest_results_file |
| + kwargs.update(self._runtest_kwargs) |
| + |
| + try: |
| + api.isolate.runtest(self.target_name, self._revision, |
| + self._webkit_revision, **kwargs) |
| + finally: |
| + self._test_runs[suffix] = api.step.active_result |
|
iannucci
2015/09/17 00:49:48
talked to kbr. I think what you want to do is swit
|
| + if self.has_valid_results(api, suffix): |
| + self._test_runs[suffix].presentation.step_text += ( |
| + api.test_utils.format_step_text([ |
| + ['failures:', self.failures(api, suffix)] |
| + ])) |
| + return self._test_runs[suffix] |
| + |
| + def has_valid_results(self, api, suffix): |
| + try: |
| + # Make sure the JSON includes all necessary data. |
| + self.failures(api, suffix) |
| + |
| + return self._test_runs[suffix].json.output['valid'] |
| + except Exception: # pragma: no cover |
| + return False |
| + |
| + def failures(self, api, suffix): |
| + return self._test_runs[suffix].json.output['failures'] |
| + |
| + |
| +def generate_isolated_script(api, mastername, buildername, test_spec, |
| + enable_swarming=False, |
| + scripts_compile_targets=None): |
| + for spec in test_spec.get(buildername, {}).get( |
| + 'isolated_scripts', []): |
| + # TODO(kbr, nednguyen): figure out where revision & webkit_revision come |
| + # from. |
| + yield IsolatedScriptTest( |
| + str(spec['name']), |
| + args=spec.get('args', []), |
| + target_name=spec['isolate_name']) |
| + |
| + |
| class GTestTest(Test): |
| def __init__(self, name, args=None, target_name=None, enable_swarming=False, |
| swarming_shards=1, swarming_dimensions=None, swarming_tags=None, |