[Piglit] [PATCH 1/2] framework: change 'regressions' to mean 'regressions in the last test run'
Nicolai Hähnle
nhaehnle at gmail.com
Mon Oct 24 15:04:08 UTC 2016
On 24.10.2016 16:57, Ilia Mirkin wrote:
> So is the idea that now regressions shows regressions compared to an
> initial "golden" run?
No, it's the dual of that: the latest run is compared to everything
before, i.e. it answers the question: what's failing _now_ that used to
work at some point in the past?
> I don't like the idea of only changing regressions. These things were
> previously pretty consistent...
>
> fixes + regressions + new + disabled = changes
But this "sums" isn't disjoint: a test can appear in all of fixes,
regressions, and new (and in some unusual cases even disabled)
simultaneously. That makes the status quo pretty useless IMO.
Maybe 'fixes' should get a similar do-over to 'regressions', but I'm not
sure what that would look like.
Let me turn this around and ask: (a) are you using the regressions page
today, and (b) if so, how? Also, the same questions for the fixes page,
because I have no use for that at all :)
Nicolai
>
> Now regressions is some weird other thing not part of that taxonomy.
> I'd rather that invariant remain - if you change one, you change all.
>
> On Mon, Oct 24, 2016 at 10:02 AM, Nicolai Hähnle <nhaehnle at gmail.com> wrote:
>> From: Nicolai Hähnle <nicolai.haehnle at amd.com>
>>
>> The idea is that 'regressions' can be useful when a summary is generated
>> for a sequence of chronologically sorted runs of the same configuration.
>> In that case, what's interesting is the state of the driver in the latest
>> run. With this change, 'regressions' now shows those tests that fail (or
>> crash etc.) in the latest run but have had a better result in at least one
>> earlier run.
>>
>> In particular, this no longer shows tests that regressed in an earlier
>> test but have been fixed again since then.
>> ---
>> framework/summary/common.py | 29 +++++++++++++++++++++++------
>> 1 file changed, 23 insertions(+), 6 deletions(-)
>>
>> diff --git a/framework/summary/common.py b/framework/summary/common.py
>> index 8c7e2c7..d3a7b31 100644
>> --- a/framework/summary/common.py
>> +++ b/framework/summary/common.py
>> @@ -23,20 +23,21 @@
>> """Shared functions for summary generation."""
>>
>> from __future__ import (
>> absolute_import, division, print_function, unicode_literals
>> )
>> import re
>> import operator
>>
>> import six
>> from six.moves import zip
>> +from itertools import repeat
>>
>> # a local variable status exists, prevent accidental overloading by renaming
>> # the module
>> import framework.status as so
>> from framework.core import lazy_property
>> from framework import grouptools
>>
>>
>> class Results(object): # pylint: disable=too-few-public-methods
>> """Container object for results.
>> @@ -69,28 +70,29 @@ class Names(object):
>> """Class containing names of tests for various statuses.
>>
>> Members contain lists of sets of names that have a status.
>>
>> Each status is lazily evaluated and cached.
>>
>> """
>> def __init__(self, tests):
>> self.__results = tests.results
>>
>> - def __diff(self, comparator, handler=None):
>> + def __diff(self, comparator, handler=None, lhs=None, rhs=None):
>> """Helper for simplifying comparators using find_diffs."""
>> ret = ['']
>> if handler is None:
>> - ret.extend(find_diffs(self.__results, self.all, comparator))
>> + ret.extend(find_diffs(self.__results, self.all, comparator,
>> + lhs=lhs, rhs=rhs))
>> else:
>> ret.extend(find_diffs(self.__results, self.all, comparator,
>> - handler=handler))
>> + handler=handler, lhs=lhs, rhs=rhs))
>> return ret
>>
>> def __single(self, comparator):
>> """Helper for simplifying comparators using find_single."""
>> return find_single(self.__results, self.all, comparator)
>>
>> @lazy_property
>> def all(self):
>> """A set of all tests in all runs."""
>> all_ = set()
>> @@ -133,21 +135,22 @@ class Names(object):
>> @lazy_property
>> def skips(self):
>> # It is critical to use is not == here, otherwise so.NOTRUN will also
>> # be added to this list
>> return self.__single(lambda x: x is so.SKIP)
>>
>> @lazy_property
>> def regressions(self):
>> # By ensureing tha min(x, y) is >= so.PASS we eleminate NOTRUN and SKIP
>> # from these pages
>> - return self.__diff(lambda x, y: x < y and min(x, y) >= so.PASS)
>> + return self.__diff(lambda x, y: x < y and min(x, y) >= so.PASS,
>> + rhs=self.__results[-1])
>>
>> @lazy_property
>> def fixes(self):
>> # By ensureing tha min(x, y) is >= so.PASS we eleminate NOTRUN and SKIP
>> # from these pages
>> return self.__diff(lambda x, y: x > y and min(x, y) >= so.PASS)
>>
>> @lazy_property
>> def enabled(self):
>> def handler(names, name, prev, cur):
>> @@ -285,41 +288,55 @@ def _result_in(name, result):
>> """If a result (or a subtest result) exists return True, else False."""
>> try:
>> # This is a little hacky, but I don't know of a better way where we
>> # ensure the value is truthy
>> _ = result.get_result(name)
>> return True
>> except KeyError:
>> return False
>>
>>
>> -def find_diffs(results, tests, comparator, handler=lambda *a: None):
>> +def find_diffs(results, tests, comparator, handler=lambda *a: None, lhs=None, rhs=None):
>> """Generate diffs between two or more sets of results.
>>
>> Arguments:
>> results -- a list of results.TestrunResult instances
>> tests -- an iterable of test names. Must be iterable more than once
>> comparator -- a function with the signautre f(x, y), that returns True when
>> the test should be added to the set of diffs
>> + lhs -- the left-hand-side result for calls to comparator.
>> + If not specified, results from the range results[:-1] will be used.
>> + rhs -- the right-hand-side result for calls to comparator.
>> + If not specified, results from the range results[1:] will be used.
>> + Note that at least one of lhs and rhs must be unspecified.
>>
>> Keyword Arguemnts:
>> handler -- a function with the signature f(names, name, prev, cur). in the
>> event of a KeyError while comparing the results with comparator,
>> handler will be passed the (<the set of names>, <the current
>> test name>, <the previous result>, <the current result>). This
>> can be used to add name even when a KeyError is expected (ie,
>> enabled tests).
>> Default: pass
>>
>> """
>> + assert (lhs is None) or (rhs is None)
>> diffs = [] # There can't be changes from nil -> 0
>> - for prev, cur in zip(results[:-1], results[1:]):
>> + if lhs is None:
>> + lhs = results[:-1]
>> + else:
>> + lhs = repeat(lhs)
>> + if rhs is None:
>> + rhs = results[1:]
>> + else:
>> + rhs = repeat(rhs)
>> + for prev, cur in zip(lhs, rhs):
>> names = set()
>> for name in tests:
>> try:
>> if comparator(prev.get_result(name), cur.get_result(name)):
>> names.add(name)
>> except KeyError:
>> handler(names, name, prev, cur)
>> diffs.append(names)
>> return diffs
>>
>> --
>> 2.7.4
>>
>> _______________________________________________
>> Piglit mailing list
>> Piglit at lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/piglit
More information about the Piglit
mailing list