Currently when the test dictionary is filtered the TestDict instance is replaced by a built-in-dict instance. This isn't ideal for a number of reasons, obviously the silent change in type isn't good. This is also groundwork for other patches in this series.
This also fixes a number of unit tests that I'm not exactly sure why they passed before this test. They were doing some invalid things, mainly mangling types. They also happened to be cloning data after destructively editing the data. They are fixed now. Signed-off-by: Dylan Baker <[email protected]> --- framework/profile.py | 31 ++++++++++++++++++++++++++----- unittests/profile_tests.py | 33 ++++++++++++++++----------------- 2 files changed, 42 insertions(+), 22 deletions(-) diff --git a/framework/profile.py b/framework/profile.py index 6342eae..4940b11 100644 --- a/framework/profile.py +++ b/framework/profile.py @@ -54,15 +54,22 @@ __all__ = [ class TestDict(collections.MutableMapping): """A special kind of dict for tests. - This dict lowers the names of keys by default + This dict lowers the names of keys by default. + + This class intentionally doesn't accept keyword arguments. This is + intentional to avoid breakages. """ - def __init__(self, *args, **kwargs): + def __init__(self): + # This is because it had special __setitem__ and __getitem__ protocol + # methods, and simply passing *args and **kwargs into self.__container + # will bypass these methods + # # This counter is incremented once when the allow_reassignment context # manager is opened, and decremented each time it is closed. This # allows stacking of the context manager self.__allow_reassignment = 0 - self.__container = dict(*args, **kwargs) + self.__container = dict() def __setitem__(self, key, value): """Enforce types on set operations. @@ -144,6 +151,21 @@ class TestDict(collections.MutableMapping): yield self.__allow_reassignment -= 1 + def filter(self, callable): + """Filter tests out of the testdict before running. + + This method destructively filters results out of the test test + dictionary list using the callable provided. + + Arguments: + callable -- a callable object that returns truthy if the item remains, + falsy if it should be removed + + """ + for k, v in list(six.iteritems(self)): + if not callable((k, v)): + del self[k] + class TestProfile(object): """ Class that holds a list of tests for execution @@ -217,8 +239,7 @@ class TestProfile(object): return True # Filter out unwanted tests - self.test_list = dict(item for item in six.iteritems(self.test_list) - if check_all(item)) + self.test_list.filter(check_all) if not self.test_list: raise exceptions.PiglitFatalError( diff --git a/unittests/profile_tests.py b/unittests/profile_tests.py index 20e4d37..19c859d 100644 --- a/unittests/profile_tests.py +++ b/unittests/profile_tests.py @@ -116,12 +116,11 @@ def test_testprofile_update_test_list(): class TestPrepareTestListMatches(object): """Create tests for TestProfile.prepare_test_list filtering""" def __init__(self): - self.data = { - grouptools.join('group1', 'test1'): 'thingy', - grouptools.join('group1', 'group3', 'test2'): 'thing', - grouptools.join('group3', 'test5'): 'other', - grouptools.join('group4', 'Test9'): 'is_caps', - } + self.data = profile.TestDict() + self.data[grouptools.join('group1', 'test1')] = utils.Test(['thingy']) + self.data[grouptools.join('group1', 'group3', 'test2')] = utils.Test(['thing']) + self.data[grouptools.join('group3', 'test5')] = utils.Test(['other']) + self.data[grouptools.join('group4', 'Test9')] = utils.Test(['is_caps']) self.opts = None self.__patcher = mock.patch('framework.profile.options.OPTIONS', new_callable=options._Options) @@ -142,7 +141,7 @@ class TestPrepareTestListMatches(object): profile_.test_list = self.data profile_._prepare_test_list() - nt.assert_dict_equal(profile_.test_list, self.data) + nt.assert_dict_equal(dict(profile_.test_list), dict(self.data)) def test_matches_filter_mar_2(self): """profile.TestProfile.prepare_test_list: 'not env.filter or matches_any_regex()' mar is False""" @@ -152,35 +151,35 @@ class TestPrepareTestListMatches(object): profile_.test_list = self.data profile_._prepare_test_list() - baseline = {grouptools.join('group3', 'test5'): 'other'} + baseline = {grouptools.join('group3', 'test5'): utils.Test(['other'])} - nt.assert_dict_equal(profile_.test_list, baseline) + nt.assert_dict_equal(dict(profile_.test_list), baseline) def test_matches_env_exclude(self): """profile.TestProfile.prepare_test_list: 'not path in env.exclude_tests'""" self.opts.exclude_tests.add(grouptools.join('group3', 'test5')) + baseline = copy.deepcopy(self.data) + del baseline[grouptools.join('group3', 'test5')] + profile_ = profile.TestProfile() profile_.test_list = self.data profile_._prepare_test_list() - baseline = copy.deepcopy(self.data) - del baseline[grouptools.join('group3', 'test5')] - - nt.assert_dict_equal(profile_.test_list, baseline) + nt.assert_dict_equal(dict(profile_.test_list), dict(baseline)) def test_matches_exclude_mar(self): """profile.TestProfile.prepare_test_list: 'not matches_any_regexp()'""" self.opts.exclude_filter = ['test5'] + baseline = copy.deepcopy(self.data) + del baseline[grouptools.join('group3', 'test5')] + profile_ = profile.TestProfile() profile_.test_list = self.data profile_._prepare_test_list() - baseline = copy.deepcopy(self.data) - del baseline[grouptools.join('group3', 'test5')] - - nt.assert_dict_equal(profile_.test_list, baseline) + nt.assert_dict_equal(dict(profile_.test_list), dict(baseline)) def test_matches_include_caps(self): """profile.TestProfile.prepare_test_list: matches capitalized tests""" -- 2.8.2 _______________________________________________ Piglit mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/piglit
