[Piglit] [PATCH 2/5] framework/profile: don't replace TestDict instance with regular dict

Dylan Baker dylan at pnwbakers.com
Mon May 2 21:21:11 UTC 2016


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 <dylanx.c.baker at intel.com>
---
 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



More information about the Piglit mailing list