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

Unified Diff: scripts/slave/recipe_modules/json/api.py

Issue 23889036: Refactor the way that TestApi works so that it is actually useful. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: rebase Created 7 years, 3 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
Index: scripts/slave/recipe_modules/json/api.py
diff --git a/scripts/slave/recipe_modules/json/api.py b/scripts/slave/recipe_modules/json/api.py
index 487f0320b40f99e22b2ae033e9f992d2b35d6d5b..4656e51ab5e10b7c11689f7dd6ffacf6ac521897 100644
--- a/scripts/slave/recipe_modules/json/api.py
+++ b/scripts/slave/recipe_modules/json/api.py
@@ -3,6 +3,7 @@
# found in the LICENSE file.
import functools
+import contextlib
import json
import os
import tempfile
@@ -10,6 +11,9 @@ import tempfile
from cStringIO import StringIO
from slave import recipe_api
+from slave import recipe_util
+
+from .util import TestResults
class StringListIO(object):
def __init__(self):
@@ -31,55 +35,7 @@ class StringListIO(object):
self.lines[-1] = self.lines[-1].getvalue()
-def convert_trie_to_flat_paths(trie, prefix=None):
- # Cloned from webkitpy.layout_tests.layout_package.json_results_generator
- # so that this code can stand alone.
- result = {}
- for name, data in trie.iteritems():
- if prefix:
- name = prefix + "/" + name
-
- if len(data) and not "actual" in data and not "expected" in data:
- result.update(convert_trie_to_flat_paths(data, name))
- else:
- result[name] = data
-
- return result
-
-
-class TestResults(object):
- def __init__(self, jsonish):
- self.raw = jsonish
-
- self.tests = convert_trie_to_flat_paths(jsonish.get('tests', {}))
- self.passes = {}
- self.unexpected_passes = {}
- self.failures = {}
- self.unexpected_failures = {}
- self.flakes = {}
- self.unexpected_flakes = {}
-
- for (test, result) in self.tests.iteritems():
- key = 'unexpected_' if result.get('is_unexpected') else ''
- actual_result = result['actual']
- data = actual_result
- if ' PASS' in actual_result:
- key += 'flakes'
- elif actual_result == 'PASS':
- key += 'passes'
- data = result
- else:
- key += 'failures'
- getattr(self, key)[test] = data
-
- def __getattr__(self, key):
- if key in self.raw:
- return self.raw[key]
- raise AttributeError("'%s' object has no attribute '%s'" %
- (self.__class__, key)) # pragma: no cover
-
-
-class JsonOutputPlaceholder(recipe_api.Placeholder):
+class JsonOutputPlaceholder(recipe_util.Placeholder):
"""JsonOutputPlaceholder is meant to be a placeholder object which, when added
to a step's cmd list, will be replaced by annotated_run with the command
parameters --output-json /path/to/file during the evaluation of your recipe
@@ -95,15 +51,14 @@ class JsonOutputPlaceholder(recipe_api.Placeholder):
# TODO(iannucci): The --output-json was a shortsighted bug. It should be
# --json-output to generalize to '--<module>-<method>' convention, which is
# used in multiple places in the recipe ecosystem.
- def __init__(self, name='output', flag='--output-json'):
- self.name = name
+ def __init__(self, mod_name, name='output', flag='--output-json'):
self.flag = flag
self.output_file = None
- super(JsonOutputPlaceholder, self).__init__()
+ super(JsonOutputPlaceholder, self).__init__(name, mod_name)
- def render(self, test_data):
+ def render(self, test):
items = [self.flag]
- if test_data is not None:
+ if test.enabled:
items.append('/path/to/tmp/json')
else: # pragma: no cover
json_output_fd, self.output_file = tempfile.mkstemp()
@@ -111,10 +66,9 @@ class JsonOutputPlaceholder(recipe_api.Placeholder):
items.append(self.output_file)
return items
- def step_finished(self, presentation, result_data, test_data):
- assert not hasattr(result_data, self.name)
- if test_data is not None:
- raw_data = json.dumps(test_data.pop(self.name, None))
+ def result(self, presentation, test):
+ if test.enabled:
+ raw_data = json.dumps(test.data)
else: # pragma: no cover
assert self.output_file is not None
with open(self.output_file, 'r') as f:
@@ -122,28 +76,29 @@ class JsonOutputPlaceholder(recipe_api.Placeholder):
os.unlink(self.output_file)
valid = False
+ ret = None
try:
- setattr(result_data, self.name, json.loads(raw_data))
+ ret = json.loads(raw_data)
valid = True
except ValueError: # pragma: no cover
pass
- key = 'json.' + self.name + ('' if valid else ' (invalid)')
- listio = StringListIO()
- json.dump(getattr(result_data, self.name), listio, indent=2, sort_keys=True)
- listio.close()
+ key = self.name + ('' if valid else ' (invalid)')
+ with contextlib.closing(StringListIO()) as listio:
+ json.dump(ret, listio, indent=2, sort_keys=True)
presentation.logs[key] = listio.lines
+ return ret
+
class TestResultsOutputPlaceholder(JsonOutputPlaceholder):
- def __init__(self):
+ def __init__(self, mod_name):
super(TestResultsOutputPlaceholder, self).__init__(
- name='test_results', flag='--json-test-results')
+ mod_name, name='test_results', flag='--json-test-results')
- def step_finished(self, presentation, result_data, test_data):
- super(TestResultsOutputPlaceholder, self).step_finished(
- presentation, result_data, test_data)
- result_data.test_results = TestResults(result_data.test_results)
+ def result(self, presentation, test):
+ ret = super(TestResultsOutputPlaceholder, self).result(presentation, test)
+ return TestResults(ret)
class JsonApi(recipe_api.RecipeApi):
@@ -158,20 +113,18 @@ class JsonApi(recipe_api.RecipeApi):
def input(self, data):
"""A placeholder which will expand to a file path containing <data>."""
- return recipe_api.InputDataPlaceholder(self.dumps(data), '.json')
+ return self.m.raw.input(self.dumps(data), '.json', self.name)
- @staticmethod
- def output():
+ def output(self):
"""A placeholder which will expand to '--output-json /tmp/file'."""
- return JsonOutputPlaceholder()
+ return JsonOutputPlaceholder(self.name)
- @staticmethod
- def test_results():
+ def test_results(self):
"""A placeholder which will expand to '--json-test-results /tmp/file'.
The test_results will be an instance of the TestResults class.
"""
- return TestResultsOutputPlaceholder()
+ return TestResultsOutputPlaceholder(self.name)
def property_args(self):
"""Return --build-properties and --factory-properties arguments. LEGACY!
@@ -188,4 +141,3 @@ class JsonApi(recipe_api.RecipeApi):
'--factory-properties', prop_str,
'--build-properties', prop_str
]
-

Powered by Google App Engine
This is Rietveld 408576698