[Piglit] [PATCH 07/11] framework/test/shader_test.py: Add fast skipping support for extensions

baker.dylan.c at gmail.com baker.dylan.c at gmail.com
Thu Nov 5 14:16:45 PST 2015


From: Dylan Baker <baker.dylan.c at gmail.com>

This hooks up the new mixin from the previous patch in ShaderTest (the
class used to run shader_runner). This patch gives me a ~40 second
reduction in runtime for shader.py (a profile that runs only shader_test
files).

My setup is as follows:
HSW i7-4500U (4 logical cores)
running piglit with "-c -p gbm"

Signed-off-by: Dylan Baker <dylanx.c.baker at intel.com>
---
 framework/test/shader_test.py        | 76 +++++++++++++++++++++++-------------
 framework/tests/shader_test_tests.py | 67 +++++++++++++++++++++++++++++++
 2 files changed, 116 insertions(+), 27 deletions(-)

diff --git a/framework/test/shader_test.py b/framework/test/shader_test.py
index d06eb2d..e531f08 100644
--- a/framework/test/shader_test.py
+++ b/framework/test/shader_test.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2012, 2014 Intel Corporation
+# Copyright (C) 2012, 2014, 2015 Intel Corporation
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
@@ -27,6 +27,7 @@ from __future__ import print_function, absolute_import
 import re
 
 from framework import exceptions
+from .opengl import FastSkipMixin
 from .piglit_test import PiglitBaseTest
 
 __all__ = [
@@ -34,22 +35,25 @@ __all__ = [
 ]
 
 
-class ShaderTest(PiglitBaseTest):
+class ShaderTest(FastSkipMixin, PiglitBaseTest):
     """ Parse a shader test file and return a PiglitTest instance
 
     This function parses a shader test to determine if it's a GL, GLES2 or
     GLES3 test, and then returns a PiglitTest setup properly.
 
     """
+    _is_gl = re.compile(r'GL (<|<=|=|>=|>) \d\.\d')
+
     def __init__(self, filename):
-        is_gl = re.compile(r'GL (<|<=|=|>=|>) \d\.\d')
+        self.gl_required = set()
+
         # Iterate over the lines in shader file looking for the config section.
         # By using a generator this can be split into two for loops at minimal
         # cost. The first one looks for the start of the config block or raises
         # an exception. The second looks for the GL version or raises an
         # exception
         with open(filename, 'r') as shader_file:
-            lines = (l for l in shader_file)
+            lines = (l for l in shader_file.readlines())
 
             # Find the config section
             for line in lines:
@@ -63,32 +67,50 @@ class ShaderTest(PiglitBaseTest):
                 raise exceptions.PiglitFatalError(
                     "In file {}: Config block not found".format(filename))
 
-            # Find the OpenGL API to use
-            for line in lines:
-                line = line.strip()
-                if line.startswith('GL ES'):
-                    if line.endswith('3.0'):
-                        prog = 'shader_runner_gles3'
-                    elif line.endswith('2.0'):
-                        prog = 'shader_runner_gles2'
-                    # If we don't set gles2 or gles3 continue the loop,
-                    # probably htting the exception in the for/else
-                    else:
-                        raise exceptions.PiglitFatalError(
-                            "In File {}: No GL ES version set".format(filename))
-                    break
-                elif line.startswith('[') or is_gl.match(line):
-                    # In the event that we reach the end of the config black
-                    # and an API hasn't been found, it's an old test and uses
-                    # "GL"
-                    prog = 'shader_runner'
-                    break
-            else:
-                raise exceptions.PiglitFatalError(
-                    "In file {}: No GL version set".format(filename))
+            lines = list(lines)
+
+        prog = self.__find_gl(lines, filename)
 
         super(ShaderTest, self).__init__([prog, filename], run_concurrent=True)
 
+        # This needs to be run after super or gl_required will be reset
+        self.__find_requirements(lines)
+
+    def __find_gl(self, lines, filename):
+        """Find the OpenGL API to use."""
+        for line in lines:
+            line = line.strip()
+            if line.startswith('GL ES'):
+                if line.endswith('3.0'):
+                    prog = 'shader_runner_gles3'
+                elif line.endswith('2.0'):
+                    prog = 'shader_runner_gles2'
+                # If we don't set gles2 or gles3 continue the loop,
+                # probably htting the exception in the for/else
+                else:
+                    raise exceptions.PiglitFatalError(
+                        "In File {}: No GL ES version set".format(filename))
+                break
+            elif line.startswith('[') or self._is_gl.match(line):
+                # In the event that we reach the end of the config black
+                # and an API hasn't been found, it's an old test and uses
+                # "GL"
+                prog = 'shader_runner'
+                break
+        else:
+            raise exceptions.PiglitFatalError(
+                "In file {}: No GL version set".format(filename))
+
+        return prog
+
+    def __find_requirements(self, lines):
+        """Find any requirements in the test and record them."""
+        for line in lines:
+            if line.startswith('GL_') and not line.startswith('GL_MAX'):
+                self.gl_required.add(line.strip())
+            elif line.startswith('['):
+                break
+
     @PiglitBaseTest.command.getter
     def command(self):
         """ Add -auto to the test command """
diff --git a/framework/tests/shader_test_tests.py b/framework/tests/shader_test_tests.py
index 1c10385..ebc76b3 100644
--- a/framework/tests/shader_test_tests.py
+++ b/framework/tests/shader_test_tests.py
@@ -23,12 +23,36 @@
 from __future__ import print_function, absolute_import
 import os
 
+import mock
 import nose.tools as nt
 
 from framework import exceptions
 import framework.test as testm
 import framework.tests.utils as utils
 
+# pylint: disable=invalid-name
+
+
+class _Setup(object):
+    def __init__(self):
+        self.__patchers = []
+        self.__patchers.append(mock.patch.dict(
+            'framework.test.base.options.OPTIONS.env',
+            {'PIGLIT_PLATFORM': 'foo'}))
+
+    def setup(self):
+        for patcher in self.__patchers:
+            patcher.start()
+
+    def teardown(self):
+        for patcher in self.__patchers:
+            patcher.stop()
+
+
+_setup = _Setup()
+setup = _setup.setup
+teardown = _setup.teardown
+
 
 def test_initialize_shader_test():
     """test.shader_test.ShaderTest: class initializes"""
@@ -80,3 +104,46 @@ def test_add_auto():
     """test.shader_test.ShaderTest: -auto is added to the command"""
     test = testm.ShaderTest('tests/spec/glsl-es-1.00/execution/sanity.shader_test')
     nt.assert_in('-auto', test.command)
+
+
+def test_find_requirements():
+    """test.shader_test.ShaderTest: populates gl_requirements properly"""
+
+    data = ('[require]\n'
+            'GL = 2.0\n'
+            'GL_ARB_ham_sandwhich\n')
+
+    with utils.tempfile(data) as temp:
+        test = testm.ShaderTest(temp)
+
+    nt.eq_(test.gl_required, set(['GL_ARB_ham_sandwhich']))
+
+
+ at utils.nose_generator
+def test_ignore_shader_runner_directives():
+    """test.shader_test.ShaderTest: Doesn't add shader_runner command to gl_required list"""
+    should_ignore = [
+        'GL_MAX_VERTEX_OUTPUT_COMPONENTS',
+        'GL_MAX_FRAGMENT_UNIFORM_COMPONENTS',
+        'GL_MAX_VERTEX_UNIFORM_COMPONENTS',
+        'GL_MAX_VARYING_COMPONENTS',
+    ]
+
+    def test(config):
+        with mock.patch('framework.test.shader_test.open',
+                        mock.mock_open(read_data=config)):
+            test = testm.ShaderTest('null')
+        nt.eq_(test.gl_required, {'GL_foobar'})
+
+    for ignore in should_ignore:
+        config = '\n'.join([
+            '[require]',
+            'GL >= 1.0',
+            'GL_foobar',
+            ignore,
+        ])
+        test.description = ('test.shader_test.ShaderTest: doesn\'t add '
+                            'shader_runner command {} to gl_required'.format(
+                                ignore))
+
+        yield test, config
-- 
2.6.2



More information about the Piglit mailing list