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

Unified Diff: recipe_engine/recipe_test_api.py

Issue 1773273003: Make output placeholders like json.output index-able by name. (Closed) Base URL: https://chromium.googlesource.com/external/github.com/luci/recipes-py@master
Patch Set: Created 4 years, 9 months 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | recipe_engine/step_runner.py » ('j') | recipe_engine/step_runner.py » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: recipe_engine/recipe_test_api.py
diff --git a/recipe_engine/recipe_test_api.py b/recipe_engine/recipe_test_api.py
index 9015267afb6ebfe730a8bb84ead952205403c470..d316cbfe23c645c6ee028b37049f7c74b1a884c2 100644
--- a/recipe_engine/recipe_test_api.py
+++ b/recipe_engine/recipe_test_api.py
@@ -5,10 +5,10 @@
import collections
import contextlib
-from .util import ModuleInjectionSite, static_call, static_wraps
+from .util import ModuleInjectionSite, Placeholder, static_call, static_wraps
from .types import freeze
-def combineify(name, dest, a, b):
+def combineify(name, dest, a, b, overwrite=False):
"""
Combines dictionary members in two objects into a third one using addition.
@@ -17,12 +17,16 @@ def combineify(name, dest, a, b):
dest - the destination object
a - the first source object
b - the second source object
+ overwrite - whether to over write the value from a with the same key.
iannucci 2016/03/10 03:17:42 So I think that now they're all named, there's no
stgao 2016/03/10 20:34:22 Unfortunately, we still have to do it this way, be
"""
dest_dict = getattr(dest, name)
dest_dict.update(getattr(a, name))
for k, v in getattr(b, name).iteritems():
if k in dest_dict:
- dest_dict[k] += v
+ if not overwrite:
+ dest_dict[k] += v
+ else:
+ dest_dict[k] = v
else:
dest_dict[k] = v
@@ -38,9 +42,10 @@ class BaseTestData(object):
class PlaceholderTestData(BaseTestData):
- def __init__(self, data=None):
+ def __init__(self, data=None, id=None):
super(PlaceholderTestData, self).__init__()
self.data = data
+ self.id = id or Placeholder.DEFAULT_ID
def __repr__(self):
return "PlaceholderTestData(%r)" % (self.data,)
@@ -55,8 +60,8 @@ class StepTestData(BaseTestData):
"""
def __init__(self):
super(StepTestData, self).__init__()
- # { (module, placeholder) -> [data] }
- self.placeholder_data = collections.defaultdict(list)
+ # { (module, placeholder, id) -> data }
+ self.placeholder_data = {}
self.override = False
self._stdout = None
self._stderr = None
@@ -70,7 +75,7 @@ class StepTestData(BaseTestData):
ret = StepTestData()
- combineify('placeholder_data', ret, self, other)
+ combineify('placeholder_data', ret, self, other, overwrite=True)
# pylint: disable=W0212
ret._stdout = other._stdout or self._stdout
@@ -83,18 +88,13 @@ class StepTestData(BaseTestData):
return ret
def unwrap_placeholder(self):
- # {(module, placeholder): [data]} => data.
+ # {(module, placeholder, id): data} => data.
assert len(self.placeholder_data) == 1
- data_list = self.placeholder_data.items()[0][1]
- assert len(data_list) == 1
- return data_list[0]
-
- def pop_placeholder(self, name_pieces):
- l = self.placeholder_data[name_pieces]
- if l:
- return l.pop(0)
- else:
- return PlaceholderTestData()
+ return self.placeholder_data.values()[0]
+
+ def pop_placeholder(self, module_name, placeholder_name, id):
+ return self.placeholder_data.pop((module_name, placeholder_name, id),
+ PlaceholderTestData())
@property
def retcode(self): # pylint: disable=E0202
@@ -257,7 +257,7 @@ class DisabledTestData(BaseTestData):
def __getattr__(self, name):
return self
- def pop_placeholder(self, _name_pieces):
+ def pop_placeholder(self, _module_name, _placeholder_name, _id):
return self
def pop_step_test_data(self, _step_name, _step_test_data_fn):
@@ -288,42 +288,40 @@ def placeholder_step_data(func):
StepTestData() object.
The wrapped function may return either:
- * <placeholder data>, <retcode or None>
+ * <placeholder data>, <retcode or None>, <id or None>
* StepTestData containing exactly one PlaceholderTestData and possible a
retcode. This is useful for returning the result of another method which
is wrapped with placeholder_step_data.
In either case, the wrapper function will return a StepTestData object with
the retcode and placeholder datum inserted with a name of:
- (<Test module name>, <wrapped function name>)
+ (<Test module name>, <wrapped function name>, <id>)
Say you had a 'foo_module' with the following RecipeTestApi:
class FooTestApi(RecipeTestApi):
@placeholder_step_data
@staticmethod
- def cool_method(data, retcode=None):
- return ("Test data (%s)" % data), retcode
+ def cool_method(data, retcode=None, id=None):
+ return ("Test data (%s)" % data), retcode, id
@placeholder_step_data
- def other_method(self, retcode=None):
- return self.cool_method('hammer time', retcode)
+ def other_method(self, retcode=None, id=None):
+ return self.cool_method('hammer time', retcode=retcode, id=id)
- Code calling cool_method('hello') would get a StepTestData:
+ Code calling cool_method('hello', id='cool1') would get a StepTestData:
StepTestData(
placeholder_data = {
- ('foo_module', 'cool_method'): [
+ ('foo_module', 'cool_method', 'cool1') :
PlaceholderTestData('Test data (hello)')
- ]
},
retcode = None
)
- Code calling other_method(50) would get a StepTestData:
+ Code calling other_method(retcode=50, id='other1') would get a StepTestData:
StepTestData(
placeholder_data = {
- ('foo_module', 'other_method'): [
+ ('foo_module', 'other_method', 'other1'):
PlaceholderTestData('Test data (hammer time)')
- ]
},
retcode = 50
)
@@ -343,11 +341,12 @@ def placeholder_step_data(func):
)
placeholder_data, retcode = all_data[0], data.retcode
else:
- placeholder_data, retcode = data
- placeholder_data = PlaceholderTestData(placeholder_data)
+ placeholder_data, retcode, id = data
+ placeholder_data = PlaceholderTestData(placeholder_data, id=id)
ret = StepTestData()
- ret.placeholder_data[(mod_name, inner.__name__)].append(placeholder_data)
+ key = (mod_name, inner.__name__, placeholder_data.id)
+ ret.placeholder_data[key] = placeholder_data
ret.retcode = retcode
return ret
return inner
@@ -374,7 +373,7 @@ class RecipeTestApi(object):
the platform module's test_api for a good example of this.
step_data - Step-specific data. There are two major components to this.
retcode - The return code of the step
- placeholder_data - A mapping from placeholder name to the a list of
+ placeholder_data - A mapping from placeholder name to the list of
PlaceholderTestData objects, one for each instance
of that kind of Placeholder in the step.
stdout, stderr - PlaceholderTestData objects for stdout and stderr.
« no previous file with comments | « no previous file | recipe_engine/step_runner.py » ('j') | recipe_engine/step_runner.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698