Chromium Code Reviews| 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 from slave import recipe_api | 5 from slave import recipe_api |
| 6 | 6 |
| 7 | 7 |
| 8 class IsolateApi(recipe_api.RecipeApi): | 8 class IsolateApi(recipe_api.RecipeApi): |
| 9 """APIs for interacting with isolates.""" | 9 """APIs for interacting with isolates.""" |
| 10 | 10 |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 31 server during the build. This must be called early in your recipe; | 31 server during the build. This must be called early in your recipe; |
| 32 definitely before the checkout and runhooks steps. | 32 definitely before the checkout and runhooks steps. |
| 33 | 33 |
| 34 Uses current values of self.isolate_server. It should be property configured | 34 Uses current values of self.isolate_server. It should be property configured |
| 35 before calling this method if the default value (production instance of | 35 before calling this method if the default value (production instance of |
| 36 Isolate service) is not ok. | 36 Isolate service) is not ok. |
| 37 """ | 37 """ |
| 38 config.gyp_env.GYP_DEFINES['test_isolation_mode'] = 'archive' | 38 config.gyp_env.GYP_DEFINES['test_isolation_mode'] = 'archive' |
| 39 config.gyp_env.GYP_DEFINES['test_isolation_outdir'] = self._isolate_server | 39 config.gyp_env.GYP_DEFINES['test_isolation_outdir'] = self._isolate_server |
| 40 | 40 |
| 41 def find_isolated_tests(self, build_dir, targets=None): | 41 def find_isolated_tests(self, build_dir, targets=None, **kwargs): |
|
M-A Ruel
2014/06/04 00:52:53
Side note: it's interesting because in the last CL
Vadim Sh.
2014/06/04 02:58:26
I've realized I need to pass crapload of additiona
| |
| 42 """Returns a step which finds all *.isolated files in a build directory. | 42 """Returns a step which finds all *.isolated files in a build directory. |
| 43 | 43 |
| 44 Assigns the dict {target name -> *.isolated file hash} to the swarm_hashes | 44 Assigns the dict {target name -> *.isolated file hash} to the swarm_hashes |
| 45 build property. This implies this step can currently only be run once | 45 build property. This implies this step can currently only be run once |
| 46 per recipe. | 46 per recipe. |
| 47 | 47 |
| 48 If |targets| is None, the step will use all *.isolated files it finds. | 48 If |targets| is None, the step will use all *.isolated files it finds. |
| 49 Otherwise, it will verify that all |targets| are found and will use only | 49 Otherwise, it will verify that all |targets| are found and will use only |
| 50 them. If some expected targets are missing, will abort the build. | 50 them. If some expected targets are missing, will abort the build. |
| 51 | |
| 52 Also accepts step execution controlling flags (always_run, can_fail_build, | |
| 53 etc. via kwargs). | |
| 51 """ | 54 """ |
| 55 # Failure is fatal by default. | |
| 56 if 'abort_on_failure' not in kwargs: | |
|
M-A Ruel
2014/06/04 00:52:53
What you want is:
kwargs.setdefault('abort_on_fail
Vadim Sh.
2014/06/04 02:58:26
Done.
| |
| 57 kwargs['abort_on_failure'] = True | |
| 58 | |
| 52 def followup_fn(step_result): | 59 def followup_fn(step_result): |
| 53 assert isinstance(step_result.json.output, dict) | 60 assert isinstance(step_result.json.output, dict) |
| 54 self._isolated_tests = step_result.json.output | 61 self._isolated_tests = step_result.json.output |
| 55 if targets is not None and step_result.presentation.status != 'FAILURE': | 62 if targets is not None and step_result.presentation.status != 'FAILURE': |
| 56 found = set(step_result.json.output) | 63 found = set(step_result.json.output) |
| 57 expected = set(targets) | 64 expected = set(targets) |
| 58 if found >= expected: | 65 if found >= expected: |
| 59 # Limit result only to |expected|. | 66 # Limit result only to |expected|. |
| 60 self._isolated_tests = { | 67 self._isolated_tests = { |
| 61 target: step_result.json.output[target] for target in expected | 68 target: step_result.json.output[target] for target in expected |
| 62 } | 69 } |
| 63 else: | 70 else: |
| 64 # Some expected targets are missing? Fail the step. | 71 # Some expected targets are missing? Fail the step. |
| 65 step_result.presentation.status = 'FAILURE' | 72 step_result.presentation.status = 'FAILURE' |
| 66 step_result.presentation.logs['missing.isolates'] = ( | 73 step_result.presentation.logs['missing.isolates'] = ( |
| 67 ['Failed to find *.isolated files:'] + list(expected - found)) | 74 ['Failed to find *.isolated files:'] + list(expected - found)) |
| 68 step_result.presentation.properties['swarm_hashes'] = self._isolated_tests | 75 step_result.presentation.properties['swarm_hashes'] = self._isolated_tests |
| 69 # No isolated files found? That looks suspicious, emit warning. | 76 # No isolated files found? That looks suspicious, emit warning. |
| 70 if (not self._isolated_tests and | 77 if (not self._isolated_tests and |
| 71 step_result.presentation.status != 'FAILURE'): | 78 step_result.presentation.status != 'FAILURE'): |
| 72 step_result.presentation.status = 'WARNING' | 79 step_result.presentation.status = 'WARNING' |
| 80 | |
| 73 return self.m.python( | 81 return self.m.python( |
| 74 'find isolated tests', | 82 'find isolated tests', |
| 75 self.resource('find_isolated_tests.py'), | 83 self.resource('find_isolated_tests.py'), |
| 76 [ | 84 [ |
| 77 '--build-dir', build_dir, | 85 '--build-dir', build_dir, |
| 78 '--output-json', self.m.json.output(), | 86 '--output-json', self.m.json.output(), |
| 79 ], | 87 ], |
| 80 abort_on_failure=True, | |
| 81 followup_fn=followup_fn, | 88 followup_fn=followup_fn, |
| 82 step_test_data=lambda: (self.test_api.output_json(targets))) | 89 step_test_data=lambda: (self.test_api.output_json(targets)), |
| 90 **kwargs) | |
| 83 | 91 |
| 84 @property | 92 @property |
| 85 def isolated_tests(self): | 93 def isolated_tests(self): |
| 86 """The dictionary of 'target name -> isolated hash' for this run. | 94 """The dictionary of 'target name -> isolated hash' for this run. |
| 87 | 95 |
| 88 These come either from the incoming swarm_hashes build property, | 96 These come either from the incoming swarm_hashes build property, |
| 89 or from calling find_isolated_tests, above, at some point during the run. | 97 or from calling find_isolated_tests, above, at some point during the run. |
| 90 """ | 98 """ |
| 91 hashes = self.m.properties.get('swarm_hashes', self._isolated_tests) | 99 hashes = self.m.properties.get('swarm_hashes', self._isolated_tests) |
| 92 return { | 100 return { |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 149 # When running the Telemetry test via an isolate we need to tell | 157 # When running the Telemetry test via an isolate we need to tell |
| 150 # run_isolated.py the hash and isolate server first, and then give | 158 # run_isolated.py the hash and isolate server first, and then give |
| 151 # the isolate the test name and other arguments separately. | 159 # the isolate the test name and other arguments separately. |
| 152 prefix_args=self.runtest_args_list(isolate_name) + ['--'], | 160 prefix_args=self.runtest_args_list(isolate_name) + ['--'], |
| 153 args=args, | 161 args=args, |
| 154 name=name, | 162 name=name, |
| 155 revision=revision, | 163 revision=revision, |
| 156 webkit_revision=webkit_revision, | 164 webkit_revision=webkit_revision, |
| 157 master_class_name=master_class_name, | 165 master_class_name=master_class_name, |
| 158 **runtest_kwargs) | 166 **runtest_kwargs) |
| OLD | NEW |