Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1135)

Side by Side Diff: recipe_engine/recipe_test_api.py

Issue 1421843006: Add simple depends_on API. (Closed) Base URL: https://chromium.googlesource.com/external/github.com/luci/recipes-py@master
Patch Set: Fix small broken tests, add invoke tests, respond to nits. Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 # Copyright 2013-2015 The Chromium Authors. All rights reserved. 1 # Copyright 2013-2015 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 collections 5 import collections
6 6
7 from .util import ModuleInjectionSite, static_call, static_wraps 7 from .util import ModuleInjectionSite, static_call, static_wraps
8 from .types import freeze
8 9
9 def combineify(name, dest, a, b): 10 def combineify(name, dest, a, b):
10 """ 11 """
11 Combines dictionary members in two objects into a third one using addition. 12 Combines dictionary members in two objects into a third one using addition.
12 13
13 Args: 14 Args:
14 name - the name of the member 15 name - the name of the member
15 dest - the destination object 16 dest - the destination object
16 a - the first source object 17 a - the first source object
17 b - the second source object 18 b - the second source object
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 return "ModuleTestData(%r)" % super(ModuleTestData, self).__repr__() 153 return "ModuleTestData(%r)" % super(ModuleTestData, self).__repr__()
153 154
154 155
155 class TestData(BaseTestData): 156 class TestData(BaseTestData):
156 def __init__(self, name=None): 157 def __init__(self, name=None):
157 super(TestData, self).__init__() 158 super(TestData, self).__init__()
158 self.name = name 159 self.name = name
159 self.properties = {} # key -> val 160 self.properties = {} # key -> val
160 self.mod_data = collections.defaultdict(ModuleTestData) 161 self.mod_data = collections.defaultdict(ModuleTestData)
161 self.step_data = collections.defaultdict(StepTestData) 162 self.step_data = collections.defaultdict(StepTestData)
163 self.depend_on_data = {}
162 self.expected_exception = None 164 self.expected_exception = None
163 165
164 def __add__(self, other): 166 def __add__(self, other):
165 assert isinstance(other, TestData) 167 assert isinstance(other, TestData)
166 ret = TestData(self.name or other.name) 168 ret = TestData(self.name or other.name)
167 169
168 ret.properties.update(self.properties) 170 ret.properties.update(self.properties)
169 ret.properties.update(other.properties) 171 ret.properties.update(other.properties)
170 172
171 combineify('mod_data', ret, self, other) 173 combineify('mod_data', ret, self, other)
172 combineify('step_data', ret, self, other) 174 combineify('step_data', ret, self, other)
175 combineify('depend_on_data', ret, self, other)
173 ret.expected_exception = self.expected_exception 176 ret.expected_exception = self.expected_exception
174 if other.expected_exception: 177 if other.expected_exception:
175 ret.expected_exception = other.expected_exception 178 ret.expected_exception = other.expected_exception
176 179
177 return ret 180 return ret
178 181
179 def empty(self): 182 def empty(self):
180 return not self.step_data 183 return not self.step_data
181 184
182 def pop_step_test_data(self, step_name, step_test_data_fn): 185 def pop_step_test_data(self, step_name, step_test_data_fn):
183 step_test_data = step_test_data_fn() 186 step_test_data = step_test_data_fn()
184 if step_name in self.step_data: 187 if step_name in self.step_data:
185 step_test_data += self.step_data.pop(step_name) 188 step_test_data += self.step_data.pop(step_name)
186 return step_test_data 189 return step_test_data
187 190
188 def get_module_test_data(self, module_name): 191 def get_module_test_data(self, module_name):
189 return self.mod_data.get(module_name, ModuleTestData()) 192 return self.mod_data.get(module_name, ModuleTestData())
190 193
191 def expect_exception(self, exception): 194 def expect_exception(self, exception):
192 assert not self.expected_exception 195 assert not self.expected_exception
193 assert isinstance(exception, basestring), ( 196 assert isinstance(exception, basestring), (
194 'expect_exception expects a string containing the exception class name') 197 'expect_exception expects a string containing the exception class name')
195 self.expected_exception = exception 198 self.expected_exception = exception
196 199
197 def is_unexpected_exception(self, exception): 200 def is_unexpected_exception(self, exception):
198 name = exception.__class__.__name__ 201 name = exception.__class__.__name__
199 return not (self.enabled and name == self.expected_exception) 202 return not (self.enabled and name == self.expected_exception)
200 203
204 def depend_on(self, recipe, properties, result):
iannucci 2015/11/20 02:00:19 can we check that result conforms to the RETURN_SC
martiniss 2015/11/23 22:05:07 Yes. Did this in run.py since this file doesn't kn
205 tup = freeze((recipe, properties))
206 assert tup not in self.depend_on_data, (
207 'Already gave test data for recipe %s with properties %r' % tup)
208 self.depend_on_data[tup] = freeze(result)
iannucci 2015/11/20 02:00:19 Is there a way to distinguish the case where we re
martiniss 2015/11/23 22:05:07 Retrying the same job may partially be supported b
209
201 def __repr__(self): 210 def __repr__(self):
202 return "TestData(%r)" % ({ 211 return "TestData(%r)" % ({
203 'name': self.name, 212 'name': self.name,
204 'properties': self.properties, 213 'properties': self.properties,
205 'mod_data': dict(self.mod_data.iteritems()), 214 'mod_data': dict(self.mod_data.iteritems()),
206 'step_data': dict(self.step_data.iteritems()), 215 'step_data': dict(self.step_data.iteritems()),
207 'expected_exception': self.expected_exception, 216 'expected_exception': self.expected_exception,
217 'depend_on_data': self.depend_on_data,
208 },) 218 },)
209 219
210 220
211 class DisabledTestData(BaseTestData): 221 class DisabledTestData(BaseTestData):
212 def __init__(self): 222 def __init__(self):
213 super(DisabledTestData, self).__init__(False) 223 super(DisabledTestData, self).__init__(False)
214 224
215 def __getattr__(self, name): 225 def __getattr__(self, name):
216 return self 226 return self
217 227
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
455 def override_step_data(self, name, *data, **kwargs): 465 def override_step_data(self, name, *data, **kwargs):
456 """See _step_data()""" 466 """See _step_data()"""
457 kwargs['override'] = True 467 kwargs['override'] = True
458 return self._step_data(name, *data, **kwargs) 468 return self._step_data(name, *data, **kwargs)
459 override_step_data.__doc__ = _step_data.__doc__ 469 override_step_data.__doc__ = _step_data.__doc__
460 470
461 def expect_exception(self, exc_type): #pylint: disable=R0201 471 def expect_exception(self, exc_type): #pylint: disable=R0201
462 ret = TestData(None) 472 ret = TestData(None)
463 ret.expect_exception(exc_type) 473 ret.expect_exception(exc_type)
464 return ret 474 return ret
475
476 def depend_on(self, recipe, properties, result):
477 ret = TestData()
478 ret.depend_on(recipe, properties, result)
479 return ret
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698