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

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: License headers 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
« no previous file with comments | « scripts/slave/recipe_modules/json/__init__.py ('k') | scripts/slave/recipe_modules/json/test_api.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..e891d4b6a4c035a03c7074d36bedf3c4724c8f7e 100644
--- a/scripts/slave/recipe_modules/json/api.py
+++ b/scripts/slave/recipe_modules/json/api.py
@@ -3,13 +3,15 @@
# found in the LICENSE file.
import functools
+import contextlib
import json
-import os
-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 +33,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
@@ -92,58 +46,36 @@ class JsonOutputPlaceholder(recipe_api.Placeholder):
JSON document, which will be set as the json_output for that step in the
step_history OrderedDict passed to your recipe generator.
"""
- # 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
- self.flag = flag
- self.output_file = None
+ def __init__(self, api):
+ self.raw = api.m.raw_io.output('.json')
super(JsonOutputPlaceholder, self).__init__()
- def render(self, test_data):
- items = [self.flag]
- if test_data is not None:
- items.append('/path/to/tmp/json')
- else: # pragma: no cover
- json_output_fd, self.output_file = tempfile.mkstemp()
- os.close(json_output_fd)
- 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))
- else: # pragma: no cover
- assert self.output_file is not None
- with open(self.output_file, 'r') as f:
- raw_data = f.read()
- os.unlink(self.output_file)
+ def render(self, test):
+ return self.raw.render(test)
+
+ def result(self, presentation, test):
+ raw_data = self.raw.result(presentation, test)
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):
- super(TestResultsOutputPlaceholder, self).__init__(
- 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)
+class TestResultsOutputPlaceholder(JsonOutputPlaceholder):
+ def result(self, presentation, test):
+ ret = super(TestResultsOutputPlaceholder, self).result(presentation, test)
+ return TestResults(ret)
class JsonApi(recipe_api.RecipeApi):
@@ -156,22 +88,23 @@ class JsonApi(recipe_api.RecipeApi):
return json.dumps(*args, **kwargs)
self.dumps = dumps
+ @recipe_util.returns_placeholder
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_io.input(self.dumps(data), '.json')
- @staticmethod
- def output():
+ @recipe_util.returns_placeholder
+ def output(self):
"""A placeholder which will expand to '--output-json /tmp/file'."""
- return JsonOutputPlaceholder()
+ return JsonOutputPlaceholder(self)
- @staticmethod
- def test_results():
+ @recipe_util.returns_placeholder
+ 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)
def property_args(self):
"""Return --build-properties and --factory-properties arguments. LEGACY!
@@ -188,4 +121,3 @@ class JsonApi(recipe_api.RecipeApi):
'--factory-properties', prop_str,
'--build-properties', prop_str
]
-
« no previous file with comments | « scripts/slave/recipe_modules/json/__init__.py ('k') | scripts/slave/recipe_modules/json/test_api.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698