This patch produces the exact same output as the previous approach, just in a much simpler way. It also moves some more of the status information out of if branches and into the Status class in the status module.
Signed-off-by: Dylan Baker <[email protected]> --- framework/status.py | 6 ++- framework/summary.py | 143 ++++++++++++++------------------------------------- 2 files changed, 45 insertions(+), 104 deletions(-) diff --git a/framework/status.py b/framework/status.py index a265317..2fe153e 100644 --- a/framework/status.py +++ b/framework/status.py @@ -104,10 +104,11 @@ class Status(object): # Using __slots__ allows us to implement the flyweight pattern, limiting # the memory consumed for creating tens of thousands of these objects. - __slots__ = ['name', 'value'] + __slots__ = ['name', 'value', 'fraction'] name = None value = None + fraction = (0, 1) def __init__(self): raise NotImplementedError @@ -149,6 +150,7 @@ class Status(object): class NotRun(Status): name = 'Not Run' value = 0 + fraction = (0, 0) def __init__(self): pass @@ -157,6 +159,7 @@ class NotRun(Status): class Pass(Status): name = 'pass' value = 10 + fraction = (1, 1) def __init__(self): pass @@ -205,6 +208,7 @@ class Crash(Status): class Skip(Status): name = 'skip' value = 50 + fraction = (0, 0) def __init__(self): pass diff --git a/framework/summary.py b/framework/summary.py index 31c1c26..4f983bf 100644 --- a/framework/summary.py +++ b/framework/summary.py @@ -25,12 +25,14 @@ import string from itertools import izip_longest from shutil import copy from json import loads +import collections from mako.template import Template -import core # a local variable status exists, prevent accidental overloading by renaming # the module import status as so +import core + __all__ = [ 'Summary', @@ -265,98 +267,6 @@ class Summary: piglit-run. """ - def buildDictionary(summary): - # Build a dictionary from test name to pass count/total count, i.e. - # counts['spec/glsl/foo'] == (456, 800) - counts = {} - - if not summary.tests: - return {} - - lastGroup = '' - - # Build a dictionary of group stati, passing groupname = status. - # This is the "worst" status of the group in descending order: - # crash, skip, fail, warn, pass - status = {} - - # currentStack is a stack containing numerical values that that - # relate to a status output, 5 for crash, 4 for skip, 3 for fail, 2 - # for warn, 1 for pass - currentStatus = [] - - # Stack contains tuples like: (pass count, total count) - stack = [] - - def openGroup(name): - stack.append((0, 0)) - - # Since NotRun is the "lowest" status for HTML generation, if - # there is another status it will replace skip - currentStatus.append(so.NotRun()) - - def closeGroup(group_name): - # We're done with this group, record the number of pass/total - # in the dictionary. - (nr_pass, nr_total) = stack.pop() - counts[group_name] = (nr_pass, nr_total) - - # Also add our pass/total count to the parent group's counts - # (which are still being computed) - (parent_pass, parent_total) = stack[-1] - stack[-1] = (parent_pass + nr_pass, parent_total + nr_total) - - # Add the status back to the group hierarchy - if currentStatus[-2] < currentStatus[-1]: - currentStatus[-2] = currentStatus[-1] - status[group_name] = currentStatus.pop() - - openGroup('fake') - openGroup('all') - - # fulltest is a full test name, - # i.e. tests/shaders/glsl-algebraic-add-zero - for fulltest in sorted(summary.tests): - # same as fulltest.rpartition('/') - group, test = path.split(fulltest) - - if group != lastGroup: - # We're in a different group now. Close the old ones - # and open the new ones. - for x in path.relpath(group, lastGroup).split('/'): - if x != '..': - openGroup(x) - else: - closeGroup(lastGroup) - lastGroup = path.normpath(path.join(lastGroup, - "..")) - - lastGroup = group - - # Add the current test - (pass_so_far, total_so_far) = stack[-1] - if summary.tests[fulltest]['result'] == so.Pass(): - pass_so_far += 1 - if summary.tests[fulltest]['result'] != so.Skip(): - total_so_far += 1 - stack[-1] = (pass_so_far, total_so_far) - - # compare the status - if summary.tests[fulltest]['result'] > currentStatus[-1]: - currentStatus[-1] = summary.tests[fulltest]['result'] - - # Work back up the stack closing groups as we go until we reach the - # top, where we need to manually close this as "all" - while len(stack) > 2: - closeGroup(lastGroup) - lastGroup = path.dirname(lastGroup) - closeGroup("all") - - assert(len(stack) == 1) - assert(len(currentStatus) == 1) - - return counts, status - # Create a Result object for each piglit result and append it to the # results list self.results = [Result(i) for i in resultfiles] @@ -366,16 +276,43 @@ class Summary: self.tests = {'all': set(), 'changes': set(), 'problems': set(), 'skipped': set(), 'regressions': set(), 'fixes': set()} - for each in self.results: - # Build a dict of the status output of all of the tests, with the - # name of the test run as the key for that result, this will be - # used to write pull the statuses later - fraction, status = buildDictionary(each) - self.fractions.update({each.name: fraction}) - self.status.update({each.name: status}) - - # Create a list with all the test names in it - self.tests['all'] = set(self.tests['all']) | set(each.tests) + for results in self.results: + # Create a set of all of the tset names across all of the runs + self.tests['all'] = set(self.tests['all'] | set(results.tests)) + + # Create two dictionaries that have a default factory: they return + # a default value instead of a key error. + # This default key must be callable + self.fractions[results.name] = collections.defaultdict(lambda: (0, 0)) + self.status[results.name] = collections.defaultdict(so.NotRun) + + # short names + fraction = self.fractions[results.name] + status = self.status[results.name] + + for test, value in results.tests.iteritems(): + result = value['result'] + #FIXME: Add subtest support + + # Walk the test name as if it was a path, at each level update + # the tests passed over the total number of tests (fractions), + # and update the status of the current level if the status of + # the previous level was worse + while True: + fraction[test] = tuple([sum(i) for i in zip(fraction[test], + result.fraction)]) + if result > status[test]: + status[test] = result + + test = path.dirname(test) + # when we hit the root update the 'all' group and break + if test == '': + fraction['all'] = \ + tuple([sum(i) for i in + zip(fraction['all'], result.fraction)]) + if status['all'] < result: + status['all'] = result + break # Create the lists of statuses like problems, regressions, fixes, # changes and skips -- 1.8.1.5 _______________________________________________ Piglit mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/piglit
