OLD | NEW |
---|---|
1 # Copyright 2013 The Chromium Authors. All rights reserved. | 1 # Copyright 2013 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 from slave import recipe_util | 6 from slave import recipe_util |
7 | 7 |
8 from .util import GTestResults, TestResults | 8 from .util import GTestResults, TestResults |
9 | 9 |
10 from RECIPE_MODULES.json.api import JsonOutputPlaceholder | 10 from RECIPE_MODULES.json.api import JsonOutputPlaceholder |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
47 # simplifies caller code. | 47 # simplifies caller code. |
48 if section[1]: | 48 if section[1]: |
49 step_text.append('<br/>%s<br/>' % section[0]) | 49 step_text.append('<br/>%s<br/>' % section[0]) |
50 step_text.extend(('%s<br/>' % line for line in section[1])) | 50 step_text.extend(('%s<br/>' % line for line in section[1])) |
51 else: # pragma: no cover | 51 else: # pragma: no cover |
52 raise ValueError( | 52 raise ValueError( |
53 'Expected a one or two-element list, got %r instead.' % section) | 53 'Expected a one or two-element list, got %r instead.' % section) |
54 return ''.join(step_text) | 54 return ''.join(step_text) |
55 | 55 |
56 # TODO(martinis) rewrite this. can be written better using 1.5 syntax. | 56 # TODO(martinis) rewrite this. can be written better using 1.5 syntax. |
57 def determine_new_failures(self, caller_api, tests, deapply_patch_fn): | 57 def determine_new_failures(self, caller_api, tests, deapply_patch_fn, |
58 amp_tests=[]): | |
58 """ | 59 """ |
59 Utility function for running steps with a patch applied, and retrying | 60 Utility function for running steps with a patch applied, and retrying |
60 failing steps without the patch. Failures from the run without the patch are | 61 failing steps without the patch. Failures from the run without the patch are |
61 ignored. | 62 ignored. |
62 | 63 |
63 Args: | 64 Args: |
64 caller_api - caller's recipe API; this is needed because self.m here | 65 caller_api - caller's recipe API; this is needed because self.m here |
65 is different than in the caller (different recipe modules | 66 is different than in the caller (different recipe modules |
66 get injected depending on caller's DEPS vs. this module's | 67 get injected depending on caller's DEPS vs. this module's |
67 DEPS) | 68 DEPS) |
69 amp_tests - iterable of objects of type AMPGTestTest | |
Paweł Hajdan Jr.
2015/04/22 16:25:09
This shouldn't be needed - see my comment in steps
| |
68 tests - iterable of objects implementing the Test interface above | 70 tests - iterable of objects implementing the Test interface above |
69 deapply_patch_fn - function that takes a list of failing tests | 71 deapply_patch_fn - function that takes a list of failing tests |
70 and undoes any effect of the previously applied patch | 72 and undoes any effect of the previously applied patch |
71 """ | 73 """ |
72 # Convert iterable to list, since it is enumerated multiple times. | 74 # Convert iterable to list, since it is enumerated multiple times. |
75 amp_tests = list(amp_tests) | |
73 tests = list(tests) | 76 tests = list(tests) |
74 | 77 |
75 failing_tests = [] | 78 failing_tests = [] |
76 #TODO(martiniss) convert loop | 79 #TODO(martiniss) convert loop |
77 def run(prefix, tests): | 80 def run(prefix, tests): |
78 for t in tests: | 81 for t in tests: |
79 try: | 82 try: |
80 t.pre_run(caller_api, prefix) | 83 t.pre_run(caller_api, prefix) |
81 # TODO(iannucci): Write a test. | 84 # TODO(iannucci): Write a test. |
82 except caller_api.step.StepFailure: # pragma: no cover | 85 except caller_api.step.StepFailure: # pragma: no cover |
83 pass | 86 pass |
84 for t in tests: | 87 for t in tests: |
85 try: | 88 try: |
86 t.run(caller_api, prefix) | 89 t.run(caller_api, prefix) |
87 # TODO(iannucci): How should exceptions be accumulated/handled here? | 90 # TODO(iannucci): How should exceptions be accumulated/handled here? |
88 except caller_api.step.StepFailure: | 91 except caller_api.step.StepFailure: |
89 pass | 92 pass |
90 for t in tests: | 93 for t in tests: |
91 try: | 94 try: |
92 t.post_run(caller_api, prefix) | 95 t.post_run(caller_api, prefix) |
93 # TODO(iannucci): Write a test. | 96 # TODO(iannucci): Write a test. |
94 except caller_api.step.StepFailure: # pragma: no cover | 97 except caller_api.step.StepFailure: # pragma: no cover |
95 pass | 98 pass |
96 | 99 |
97 run('with patch', tests) | 100 with_patch_prefix = 'with patch' |
101 for t in amp_tests: | |
102 t.trigger(caller_api, with_patch_prefix) | |
103 | |
104 run(with_patch_prefix, tests) | |
105 | |
106 for t in amp_tests: | |
107 t.collect(caller_api, with_patch_prefix) | |
98 | 108 |
99 with self.m.step.defer_results(): | 109 with self.m.step.defer_results(): |
100 for t in tests: | 110 for t in (amp_tests + tests): |
101 if not t.has_valid_results(caller_api, 'with patch'): | 111 if not t.has_valid_results(caller_api, with_patch_prefix): |
102 self.m.tryserver.maybe_set_transient_failure_tryjob_result() | 112 self.m.tryserver.maybe_set_transient_failure_tryjob_result() |
103 self.m.python.failing_step(t.name, 'TEST RESULTS WERE INVALID') | 113 self.m.python.failing_step(t.name, 'TEST RESULTS WERE INVALID') |
104 elif t.failures(caller_api, 'with patch'): | 114 elif t.failures(caller_api, with_patch_prefix): |
105 failing_tests.append(t) | 115 failing_tests.append(t) |
106 if not failing_tests: | 116 if not failing_tests: |
107 return | 117 return |
108 | 118 |
109 try: | 119 try: |
110 return deapply_patch_fn(failing_tests) | 120 return deapply_patch_fn(failing_tests) |
111 except self.m.step.StepFailure: | 121 except self.m.step.StepFailure: |
112 self.m.tryserver.set_transient_failure_tryjob_result() | 122 self.m.tryserver.set_transient_failure_tryjob_result() |
113 raise | 123 raise |
114 finally: | 124 finally: |
125 # Failing AMP tests will be run locally without the patch | |
115 run('without patch', failing_tests) | 126 run('without patch', failing_tests) |
116 with self.m.step.defer_results(): | 127 with self.m.step.defer_results(): |
117 for t in failing_tests: | 128 for t in failing_tests: |
118 self._summarize_retried_test(caller_api, t) | 129 self._summarize_retried_test(caller_api, t) |
119 | 130 |
120 def _summarize_retried_test(self, caller_api, test): | 131 def _summarize_retried_test(self, caller_api, test): |
121 if not test.has_valid_results(caller_api, 'without patch'): | 132 if not test.has_valid_results(caller_api, 'without patch'): |
122 self.m.tryserver.maybe_set_transient_failure_tryjob_result() | 133 self.m.tryserver.maybe_set_transient_failure_tryjob_result() |
123 self.m.python.failing_step(test.name, 'TEST RESULTS WERE INVALID') | 134 self.m.python.failing_step(test.name, 'TEST RESULTS WERE INVALID') |
124 | 135 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
188 """A placeholder which will expand to | 199 """A placeholder which will expand to |
189 '--test-launcher-summary-output=/tmp/file'. | 200 '--test-launcher-summary-output=/tmp/file'. |
190 | 201 |
191 Provides the --test-launcher-summary-output flag since --flag=value | 202 Provides the --test-launcher-summary-output flag since --flag=value |
192 (i.e. a single token in the command line) is the required format. | 203 (i.e. a single token in the command line) is the required format. |
193 | 204 |
194 The test_results will be an instance of the GTestResults class. | 205 The test_results will be an instance of the GTestResults class. |
195 """ | 206 """ |
196 return GTestResultsOutputPlaceholder(self, add_json_log) | 207 return GTestResultsOutputPlaceholder(self, add_json_log) |
197 | 208 |
OLD | NEW |