[Piglit] [PATCH 3/15] framework: Split FastSkipMixin.

Dylan Baker dylan at pnwbakers.com
Fri Sep 9 19:18:41 UTC 2016


This splits the FastSkipMixin into two classes. One that actually does
the fast skipping, and one that provides a mixin for Test.

This split will allow the class to be used in the traditional way, but
also in shader_test.MultiShaderTest.

Signed-off-by: Dylan Baker <dylanx.c.baker at intel.com>
---
 framework/test/opengl.py                | 182 ++++++++++++++++++------
 unittests/framework/test/test_opengl.py | 192 ++++++++++++++-----------
 2 files changed, 251 insertions(+), 123 deletions(-)

diff --git a/framework/test/opengl.py b/framework/test/opengl.py
index 6fe8670..e19e437 100644
--- a/framework/test/opengl.py
+++ b/framework/test/opengl.py
@@ -37,6 +37,7 @@ from .base import TestIsSkip
 # pylint: disable=too-few-public-methods
 
 __all__ = [
+    'FastSkip',
     'FastSkipMixin',
 ]
 
@@ -287,23 +288,11 @@ class WflInfo(object):
         return ret
 
 
-class FastSkipMixin(object):
-    """Fast test skipping for OpenGL based suites.
-
-    This provides an is_skip() method which will skip the test if an of it's
-    requirements are not met.
+class FastSkip(object):
+    """A class for testing OpenGL requirements.
 
-    It also provides new attributes:
-    gl_reqruied -- This is a set of extensions that are required for running
-                   the extension.
-    gl_version -- A float that is the required version number for an OpenGL
-                  test.
-    gles_version -- A float that is the required version number for an OpenGL
-                    ES test
-    glsl_version -- A float that is the required version number of OpenGL
-                    Shader Language for a test
-    glsl_ES_version -- A float that is the required version number of OpenGL ES
-                       Shader Language for a test
+    This class provides a mechanism for testing OpenGL requirements, and
+    skipping tests that have unmet requirements
 
     This requires wflinfo to be installed and accessible to provide it's
     functionality, however, it will no-op if wflinfo is not accessible.
@@ -312,75 +301,186 @@ class FastSkipMixin(object):
     it is better to run a few tests that could have been skipped, than to skip
     all the tests that could have, but also a few that should have run.
 
+    Keyword Arguments:
+    gl_reqruied     -- This is a set of extensions that are required for
+                       running the extension.
+    gl_version      -- A float that is the required version number for an
+                       OpenGL test.
+    gles_version    -- A float that is the required version number for an
+                       OpenGL ES test
+    glsl_version    -- A float that is the required version number of OpenGL
+                       Shader Language for a test
+    glsl_es_version -- A float that is the required version number of OpenGL ES
+                       Shader Language for a test
     """
-    # XXX: This still gets called once for each thread. (4 times with 4
-    # threads), this is a synchronization issue and I don't know how to stop it
-    # other than querying each value before starting the thread pool.
-    __info = WflInfo()
+    __slots__ = ['gl_required', 'gl_version', 'gles_version', 'glsl_version',
+                 'glsl_es_version']
 
-    def __init__(self, command, gl_required=None, gl_version=None,
-                 gles_version=None, glsl_version=None, glsl_es_version=None,
-                 **kwargs):  # pylint: disable=too-many-arguments
-        super(FastSkipMixin, self).__init__(command, **kwargs)
+    info = WflInfo()
+
+    def __init__(self, gl_required=None, gl_version=None, gles_version=None,
+                 glsl_version=None, glsl_es_version=None):
         self.gl_required = gl_required or set()
         self.gl_version = gl_version
         self.gles_version = gles_version
         self.glsl_version = glsl_version
         self.glsl_es_version = glsl_es_version
 
-    def is_skip(self):
+    def test(self):
         """Skip this test if any of it's feature requirements are unmet.
 
         If no extensions were calculated (if wflinfo isn't installed) then run
         all tests.
 
+        Raises:
+        TestIsSkip   -- if any of the conditions passed to self are false
         """
-        if self.__info.gl_extensions:
+        if self.info.gl_extensions:
             for extension in self.gl_required:
-                if extension not in self.__info.gl_extensions:
+                if extension not in self.info.gl_extensions:
                     raise TestIsSkip(
                         'Test requires extension {} '
                         'which is not available'.format(extension))
 
         # TODO: Be able to handle any operator
-        if (self.__info.gl_version is not None
+        if (self.info.gl_version is not None
                 and self.gl_version is not None
-                and self.gl_version > self.__info.gl_version):
+                and self.gl_version > self.info.gl_version):
             raise TestIsSkip(
                 'Test requires OpenGL version {}, '
                 'but only {} is available'.format(
-                    self.gl_version, self.__info.gl_version))
+                    self.gl_version, self.info.gl_version))
 
         # TODO: Be able to handle any operator
-        if (self.__info.gles_version is not None
+        if (self.info.gles_version is not None
                 and self.gles_version is not None
-                and self.gles_version > self.__info.gles_version):
+                and self.gles_version > self.info.gles_version):
             raise TestIsSkip(
                 'Test requires OpenGL ES version {}, '
                 'but only {} is available'.format(
-                    self.gles_version, self.__info.gles_version))
+                    self.gles_version, self.info.gles_version))
 
         # TODO: Be able to handle any operator
-        if (self.__info.glsl_version is not None
+        if (self.info.glsl_version is not None
                 and self.glsl_version is not None
-                and self.glsl_version > self.__info.glsl_version):
+                and self.glsl_version > self.info.glsl_version):
             raise TestIsSkip(
                 'Test requires OpenGL Shader Language version {}, '
                 'but only {} is available'.format(
-                    self.glsl_version, self.__info.glsl_version))
+                    self.glsl_version, self.info.glsl_version))
 
         # TODO: Be able to handle any operator
-        if (self.__info.glsl_es_version is not None
+        if (self.info.glsl_es_version is not None
                 and self.glsl_es_version is not None
-                and self.glsl_es_version > self.__info.glsl_es_version):
+                and self.glsl_es_version > self.info.glsl_es_version):
             raise TestIsSkip(
                 'Test requires OpenGL ES Shader Language version {}, '
                 'but only {} is available'.format(
-                    self.glsl_es_version, self.__info.glsl_es_version))
+                    self.glsl_es_version, self.info.glsl_es_version))
+
+
+class FastSkipMixin(object):
+    """Fast test skipping for OpenGL based suites.
+
+    This provides an is_skip() method which will skip the test if an of it's
+    requirements are not met.
+
+    This is a wrapper around the FastSkip object which makes it easier to
+    integrate into existing classes (and maintains API compatibility). It thus
+    has all of the same requirements as that class.
+
+    It also provides new attributes:
+    gl_reqruied     -- This is a set of extensions that are required for
+                       running the extension.
+    gl_version      -- A float that is the required version number for an
+                       OpenGL test.
+    gles_version    -- A float that is the required version number for an
+                       OpenGL ES test
+    glsl_version    -- A float that is the required version number of OpenGL
+                       Shader Language for a test
+    glsl_es_version -- A float that is the required version number of OpenGL ES
+                       Shader Language for a test
+    """
+
+    def __init__(self, command, gl_required=None, gl_version=None,
+                 gles_version=None, glsl_version=None, glsl_es_version=None,
+                 **kwargs):  # pylint: disable=too-many-arguments
+        super(FastSkipMixin, self).__init__(command, **kwargs)
+        self.__skiper = FastSkip(gl_required=gl_required,
+                                 gl_version=gl_version,
+                                 gles_version=gles_version,
+                                 glsl_version=glsl_version,
+                                 glsl_es_version=glsl_es_version)
+
+    @property
+    def gl_required(self):
+        return self.__skiper.gl_required
+
+    @gl_required.setter
+    def gl_required(self, new):
+        self.__skiper.gl_required = new
+
+    @property
+    def gl_version(self):
+        return self.__skiper.gl_version
+
+    @gl_version.setter
+    def gl_version(self, new):
+        self.__skiper.gl_version = new
+
+    @property
+    def gles_version(self):
+        return self.__skiper.gles_version
+
+    @gles_version.setter
+    def gles_version(self, new):
+        self.__skiper.gles_version = new
+
+    @property
+    def glsl_version(self):
+        return self.__skiper.glsl_version
+
+    @glsl_version.setter
+    def glsl_version(self, new):
+        self.__skiper.glsl_version = new
+
+    @property
+    def glsl_es_version(self):
+        return self.__skiper.glsl_es_version
+
+    @glsl_es_version.setter
+    def glsl_es_version(self, new):
+        self.__skiper.glsl_es_version = new
+
+    def is_skip(self):
+        """Skip this test if any of it's feature requirements are unmet.
+
+        If no extensions were calculated (if wflinfo isn't installed) then run
+        all tests.
+        """
+        self.__skiper.test()
 
         super(FastSkipMixin, self).is_skip()
 
 
+class FastSkipDisabled(object):
+    """A no-op version of FastSkip."""
+
+    __slots__ = ['gl_required', 'gl_version', 'gles_version', 'glsl_version',
+                 'glsl_es_version']
+
+    def __init__(self, gl_required=None, gl_version=None, gles_version=None,
+                 glsl_version=None, glsl_es_version=None):
+        self.gl_required = gl_required or set()
+        self.gl_version = gl_version
+        self.gles_version = gles_version
+        self.glsl_version = glsl_version
+        self.glsl_es_version = glsl_es_version
+
+    def test(self):
+        pass
+
+
 class FastSkipMixinDisabled(object):
     def __init__(self, command, gl_required=None, gl_version=None,
                  gles_version=None, glsl_version=None, glsl_es_version=None,
@@ -400,4 +500,8 @@ class FastSkipMixinDisabled(object):
 # PIGLIT_NO_FAST_SKIP is truthy
 if _DISABLED:
     warnings.warn('Fast Skipping Disabled')
+    # TODO: we can probably get rid of the FastSkipMixinDisabled and just rely
+    # on the FastSkipDisabled
+    # pylint: disable=invalid-name
     FastSkipMixin = FastSkipMixinDisabled
+    FastSkip = FastSkipDisabled
diff --git a/unittests/framework/test/test_opengl.py b/unittests/framework/test/test_opengl.py
index 6381373..a397408 100644
--- a/unittests/framework/test/test_opengl.py
+++ b/unittests/framework/test/test_opengl.py
@@ -38,7 +38,6 @@ from framework.test.base import TestIsSkip as _TestIsSkip
 from .. import utils
 
 # pylint: disable=no-self-use,attribute-defined-outside-init,protected-access
-# pylint: disable=invalid-name
 
 
 def _has_wflinfo():
@@ -396,9 +395,6 @@ class TestWflInfo(object):
 class TestFastSkipMixin(object):  # pylint: disable=too-many-public-methods
     """Tests for the FastSkipMixin class."""
 
-    class _Test(opengl.FastSkipMixin, utils.Test):
-        pass
-
     @pytest.yield_fixture(autouse=True, scope='class')
     def patch(self):
         """Create a Class with FastSkipMixin, but patch various bits."""
@@ -409,13 +405,11 @@ class TestFastSkipMixin(object):  # pylint: disable=too-many-public-methods
         _mock_wflinfo.glsl_es_version = 2.0
         _mock_wflinfo.gl_extensions = set(['bar'])
 
-        with mock.patch.object(self._Test, '_FastSkipMixin__info',
-                               _mock_wflinfo):
+        with mock.patch('framework.test.opengl.FastSkip.info', _mock_wflinfo):
             yield
 
-    @pytest.fixture
-    def inst(self):
-        return self._Test(['foo'])
+    class _Test(opengl.FastSkipMixin, utils.Test):
+        pass
 
     def test_api(self):
         """Tests that the api works.
@@ -427,143 +421,174 @@ class TestFastSkipMixin(object):  # pylint: disable=too-many-public-methods
         self._Test(['foo'], gl_required={'foo'}, gles_version=3,
                    glsl_es_version=2)
 
+
+class TestFastSkip(object):
+    """Tests for the FastSkip class."""
+
+    @pytest.yield_fixture(autouse=True, scope='class')
+    def patch(self):
+        """Create a Class with FastSkipMixin, but patch various bits."""
+        _mock_wflinfo = mock.Mock(spec=opengl.WflInfo)
+        _mock_wflinfo.gl_version = 3.3
+        _mock_wflinfo.gles_version = 3.0
+        _mock_wflinfo.glsl_version = 3.3
+        _mock_wflinfo.glsl_es_version = 2.0
+        _mock_wflinfo.gl_extensions = set(['bar'])
+
+        with mock.patch('framework.test.opengl.FastSkip.info', _mock_wflinfo):
+            yield
+
+    @pytest.fixture
+    def inst(self):
+        return opengl.FastSkip()
+
     def test_should_skip(self, inst):
-        """test.opengl.FastSkipMixin.is_skip: Skips when requires is missing
+        """test.opengl.FastSkipMixin.test: Skips when requires is missing
         from extensions.
         """
         inst.gl_required.add('foobar')
         with pytest.raises(_TestIsSkip):
-            inst.is_skip()
+            inst.test()
 
     def test_should_not_skip(self, inst):
-        """test.opengl.FastSkipMixin.is_skip: runs when requires is in
+        """test.opengl.FastSkipMixin.test: runs when requires is in
         extensions.
         """
         inst.gl_required.add('bar')
-        inst.is_skip()
-
-    def test_extension_empty(self, inst):
-        """test.opengl.FastSkipMixin.is_skip: if extensions are empty test
-        runs.
-        """
-        inst.gl_required.add('foobar')
-        with mock.patch.object(inst._FastSkipMixin__info, 'gl_extensions',  # pylint: disable=no-member
-                               None):
-            inst.is_skip()
-
-    def test_requires_empty(self, inst):
-        """test.opengl.FastSkipMixin.is_skip: if gl_requires is empty test
-        runs.
-        """
-        inst.is_skip()
+        inst.test()
 
     def test_max_gl_version_lt(self, inst):
-        """test.opengl.FastSkipMixin.is_skip: skips if gl_version >
+        """test.opengl.FastSkipMixin.test: skips if gl_version >
         __max_gl_version.
         """
         inst.gl_version = 4.0
         with pytest.raises(_TestIsSkip):
-            inst.is_skip()
+            inst.test()
 
     def test_max_gl_version_gt(self, inst):
-        """test.opengl.FastSkipMixin.is_skip: runs if gl_version <
+        """test.opengl.FastSkipMixin.test: runs if gl_version <
         __max_gl_version.
         """
         inst.gl_version = 1.0
 
-    def test_max_gl_version_unset(self, inst):
-        """test.opengl.FastSkipMixin.is_skip: runs if __max_gl_version is
-        None.
-        """
-        inst.gl_version = 1.0
-        with mock.patch.object(inst._FastSkipMixin__info, 'gl_version',  # pylint: disable=no-member
-                               None):
-            inst.is_skip()
-
     def test_max_gl_version_set(self, inst):
-        """test.opengl.FastSkipMixin.is_skip: runs if gl_version is None"""
-        inst.is_skip()
+        """test.opengl.FastSkipMixin.test: runs if gl_version is None"""
+        inst.test()
 
     def test_max_gles_version_lt(self, inst):
-        """test.opengl.FastSkipMixin.is_skip: skips if gles_version >
+        """test.opengl.FastSkipMixin.test: skips if gles_version >
         __max_gles_version.
         """
         inst.gles_version = 4.0
         with pytest.raises(_TestIsSkip):
-            inst.is_skip()
+            inst.test()
 
     def test_max_gles_version_gt(self, inst):
-        """test.opengl.FastSkipMixin.is_skip: runs if gles_version <
+        """test.opengl.FastSkipMixin.test: runs if gles_version <
         __max_gles_version.
         """
         inst.gles_version = 1.0
 
-    def test_max_gles_version_unset(self, inst):
-        """test.opengl.FastSkipMixin.is_skip: runs if __max_gles_version is
-        None.
-        """
-        inst.gles_version = 1.0
-        with mock.patch.object(inst._FastSkipMixin__info, 'gles_version',  # pylint: disable=no-member
-                               None):
-            inst.is_skip()
-
     def test_max_gles_version_set(self, inst):
-        """test.opengl.FastSkipMixin.is_skip: runs if gles_version is None"""
-        inst.is_skip()
+        """test.opengl.FastSkipMixin.test: runs if gles_version is None"""
+        inst.test()
 
     def test_max_glsl_version_lt(self, inst):
-        """test.opengl.FastSkipMixin.is_skip: skips if glsl_version >
+        """test.opengl.FastSkipMixin.test: skips if glsl_version >
         __max_glsl_version.
         """
         inst.glsl_version = 4.0
         with pytest.raises(_TestIsSkip):
-            inst.is_skip()
+            inst.test()
 
     def test_max_glsl_version_gt(self, inst):
-        """test.opengl.FastSkipMixin.is_skip: runs if glsl_version <
+        """test.opengl.FastSkipMixin.test: runs if glsl_version <
         __max_glsl_version.
         """
         inst.glsl_version = 1.0
 
-    def test_max_glsl_version_unset(self, inst):
-        """test.opengl.FastSkipMixin.is_skip: runs if __max_glsl_version is
-        None.
-        """
-        inst.glsl_version = 1.0
-        with mock.patch.object(inst._FastSkipMixin__info, 'glsl_version',  # pylint: disable=no-member
-                               None):
-            inst.is_skip()
-
     def test_max_glsl_version_set(self, inst):
-        """test.opengl.FastSkipMixin.is_skip: runs if glsl_version is None"""
-        inst.is_skip()
+        """test.opengl.FastSkipMixin.test: runs if glsl_version is None"""
+        inst.test()
 
     def test_max_glsl_es_version_lt(self, inst):
-        """test.opengl.FastSkipMixin.is_skip: skips if glsl_es_version >
+        """test.opengl.FastSkipMixin.test: skips if glsl_es_version >
         __max_glsl_es_version.
         """
         inst.glsl_es_version = 4.0
         with pytest.raises(_TestIsSkip):
-            inst.is_skip()
+            inst.test()
 
     def test_max_glsl_es_version_gt(self, inst):
-        """test.opengl.FastSkipMixin.is_skip: runs if glsl_es_version <
+        """test.opengl.FastSkipMixin.test: runs if glsl_es_version <
         __max_glsl_es_version.
         """
         inst.glsl_es_version = 1.0
 
-    def test_max_glsl_es_version_unset(self, inst):
-        """test.opengl.FastSkipMixin.is_skip: runs if __max_glsl_es_version is
+    def test_max_glsl_es_version_set(self, inst):
+        """test.opengl.FastSkipMixin.test: runs if glsl_es_version is None"""
+        inst.test()
+
+    class TestEmpty(object):
+        """Tests for the FastSkip class when values are unset."""
+
+        @pytest.yield_fixture(autouse=True, scope='class')
+        def patch(self):
+            """Create a Class with FastSkipMixin, but patch various bits."""
+            _mock_wflinfo = mock.Mock(spec=opengl.WflInfo)
+            _mock_wflinfo.gl_version = None
+            _mock_wflinfo.gles_version = None
+            _mock_wflinfo.glsl_version = None
+            _mock_wflinfo.glsl_es_version = None
+            _mock_wflinfo.gl_extensions = set()
+
+            with mock.patch('framework.test.opengl.FastSkip.info', _mock_wflinfo):
+                yield
+
+        @pytest.fixture
+        def inst(self):
+            return opengl.FastSkip()
+
+        def test_extension_empty(self, inst):
+            """test.opengl.FastSkipMixin.test: if extensions are empty test
+            runs.
+            """
+            inst.gl_required.add('foobar')
+            inst.test()
+
+        def test_requires_empty(self, inst):
+            """test.opengl.FastSkipMixin.test: if gl_requires is empty test
+            runs.
+            """
+            inst.test()
+
+        def test_max_gl_version_unset(self, inst):
+            """test.opengl.FastSkipMixin.test: runs if __max_gl_version is
+            None.
+            """
+            inst.gl_version = 1.0
+            inst.test()
+
+        def test_max_glsl_es_version_unset(self, inst):
+            """test.opengl.FastSkipMixin.test: runs if __max_glsl_es_version is
+            None.
+            """
+            inst.glsl_es_version = 1.0
+            inst.test()
+
+    def test_max_glsl_version_unset(self, inst):
+        """test.opengl.FastSkipMixin.test: runs if __max_glsl_version is
         None.
         """
-        inst.glsl_es_version = 1.0
-        with mock.patch.object(inst._FastSkipMixin__info, 'glsl_es_version',  # pylint: disable=no-member
-                               None):
-            inst.is_skip()
+        inst.glsl_version = 1.0
+        inst.test()
 
-    def test_max_glsl_es_version_set(self, inst):
-        """test.opengl.FastSkipMixin.is_skip: runs if glsl_es_version is None"""
-        inst.is_skip()
+    def test_max_gles_version_unset(self, inst):
+        """test.opengl.FastSkipMixin.test: runs if __max_gles_version is
+        None.
+        """
+        inst.gles_version = 1.0
+        inst.test()
 
 
 class TestFastSkipMixinDisabled(object):
@@ -579,8 +604,7 @@ class TestFastSkipMixinDisabled(object):
         _mock_wflinfo.glsl_es_version = 2.0
         _mock_wflinfo.gl_extensions = set(['bar'])
 
-        with mock.patch.object(self._Test, '_FastSkipMixin__info',
-                               _mock_wflinfo):
+        with mock.patch('framework.test.opengl.FastSkip.info', _mock_wflinfo):
             yield
 
     class _Test(opengl.FastSkipMixin, utils.Test):
-- 
git-series 0.8.10


More information about the Piglit mailing list