2013-05-21 16:06:40 +00:00
|
|
|
#!/usr/bin/env python
|
|
|
|
# Copyright (c) 2013 The Chromium Authors. All rights reserved.
|
|
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
|
|
# found in the LICENSE file.
|
|
|
|
|
|
|
|
"""Utility to display a summary of JSON-format GM results, and exit with
|
|
|
|
a nonzero errorcode if there were non-ignored failures in the GM results.
|
|
|
|
|
|
|
|
Usage:
|
|
|
|
python display_json_results.py <filename>
|
|
|
|
|
|
|
|
TODO(epoger): We may want to add flags to set the following:
|
|
|
|
- which error types cause a nonzero return code
|
|
|
|
- maximum number of tests to list for any one ResultAccumulator
|
|
|
|
(to keep the output reasonably short)
|
|
|
|
"""
|
|
|
|
|
|
|
|
__author__ = 'Elliot Poger'
|
|
|
|
|
|
|
|
|
2013-05-28 15:25:38 +00:00
|
|
|
# system-level imports
|
2013-05-21 16:06:40 +00:00
|
|
|
import sys
|
|
|
|
|
2013-05-28 15:25:38 +00:00
|
|
|
# local imports
|
|
|
|
import gm_json
|
2013-05-21 16:06:40 +00:00
|
|
|
|
|
|
|
|
|
|
|
class ResultAccumulator(object):
|
|
|
|
"""Object that accumulates results of a given type, and can generate a
|
|
|
|
summary upon request."""
|
|
|
|
|
|
|
|
def __init__(self, name, do_list, do_fail):
|
|
|
|
"""name: name of the category this result type falls into
|
|
|
|
do_list: whether to list all of the tests with this results type
|
|
|
|
do_fail: whether to return with nonzero exit code if there are any
|
|
|
|
results of this type
|
|
|
|
"""
|
|
|
|
self._name = name
|
|
|
|
self._do_list = do_list
|
|
|
|
self._do_fail = do_fail
|
|
|
|
self._testnames = []
|
|
|
|
|
|
|
|
def AddResult(self, testname):
|
|
|
|
"""Adds a result of this particular type.
|
|
|
|
testname: (string) name of the test"""
|
|
|
|
self._testnames.append(testname)
|
|
|
|
|
|
|
|
def ShouldSignalFailure(self):
|
|
|
|
"""Returns true if this result type is serious (self._do_fail is True)
|
|
|
|
and there were any results of this type."""
|
|
|
|
if self._do_fail and self._testnames:
|
|
|
|
return True
|
|
|
|
else:
|
|
|
|
return False
|
|
|
|
|
|
|
|
def GetSummaryLine(self):
|
|
|
|
"""Returns a single-line string summary of all results added to this
|
|
|
|
accumulator so far."""
|
|
|
|
summary = ''
|
|
|
|
if self._do_fail:
|
|
|
|
summary += '[*] '
|
|
|
|
else:
|
|
|
|
summary += '[ ] '
|
|
|
|
summary += str(len(self._testnames))
|
|
|
|
summary += ' '
|
|
|
|
summary += self._name
|
|
|
|
if self._do_list:
|
|
|
|
summary += ': '
|
|
|
|
for testname in self._testnames:
|
|
|
|
summary += testname
|
|
|
|
summary += ' '
|
|
|
|
return summary
|
|
|
|
|
|
|
|
|
|
|
|
def Display(filepath):
|
|
|
|
"""Displays a summary of the results in a JSON file.
|
|
|
|
Returns True if the results are free of any significant failures.
|
|
|
|
filepath: (string) path to JSON file"""
|
|
|
|
|
|
|
|
# Map labels within the JSON file to the ResultAccumulator for each label.
|
|
|
|
results_map = {
|
2013-05-28 15:25:38 +00:00
|
|
|
gm_json.JSONKEY_ACTUALRESULTS_FAILED:
|
2013-05-21 16:06:40 +00:00
|
|
|
ResultAccumulator(name='ExpectationsMismatch',
|
|
|
|
do_list=True, do_fail=True),
|
2013-05-28 15:25:38 +00:00
|
|
|
gm_json.JSONKEY_ACTUALRESULTS_FAILUREIGNORED:
|
2013-05-21 16:06:40 +00:00
|
|
|
ResultAccumulator(name='IgnoredExpectationsMismatch',
|
|
|
|
do_list=True, do_fail=False),
|
2013-05-28 15:25:38 +00:00
|
|
|
gm_json.JSONKEY_ACTUALRESULTS_NOCOMPARISON:
|
2013-05-21 16:06:40 +00:00
|
|
|
ResultAccumulator(name='MissingExpectations',
|
|
|
|
do_list=False, do_fail=False),
|
2013-05-28 15:25:38 +00:00
|
|
|
gm_json.JSONKEY_ACTUALRESULTS_SUCCEEDED:
|
2013-05-21 16:06:40 +00:00
|
|
|
ResultAccumulator(name='Passed',
|
|
|
|
do_list=False, do_fail=False),
|
|
|
|
}
|
|
|
|
|
|
|
|
success = True
|
2013-06-04 17:50:36 +00:00
|
|
|
json_dict = gm_json.LoadFromFile(filepath)
|
2013-05-28 15:25:38 +00:00
|
|
|
actual_results = json_dict[gm_json.JSONKEY_ACTUALRESULTS]
|
2013-05-21 16:06:40 +00:00
|
|
|
for label, accumulator in results_map.iteritems():
|
|
|
|
results = actual_results[label]
|
|
|
|
if results:
|
|
|
|
for result in results:
|
|
|
|
accumulator.AddResult(result)
|
|
|
|
print accumulator.GetSummaryLine()
|
|
|
|
if accumulator.ShouldSignalFailure():
|
|
|
|
success = False
|
|
|
|
print '(results marked with [*] will cause nonzero return value)'
|
|
|
|
return success
|
|
|
|
|
|
|
|
|
|
|
|
if '__main__' == __name__:
|
|
|
|
if len(sys.argv) != 2:
|
|
|
|
raise Exception('usage: %s <input-json-filepath>' % sys.argv[0])
|
|
|
|
sys.exit(0 if Display(sys.argv[1]) else 1)
|