| 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
|
| ]
|
| -
|
|
|