[Piglit] [Patch v2 13/13] exectest.py: update comments and docstrings

Dylan Baker baker.dylan.c at gmail.com
Tue May 13 11:38:46 PDT 2014


v2: - various cleanups and refactors

Signed-off-by: Dylan Baker <baker.dylan.c at gmail.com>
---
 framework/exectest.py | 124 +++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 97 insertions(+), 27 deletions(-)

diff --git a/framework/exectest.py b/framework/exectest.py
index 18448b7..8a4f4a9 100644
--- a/framework/exectest.py
+++ b/framework/exectest.py
@@ -1,4 +1,4 @@
-#
+
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
 # files (the "Software"), to deal in the Software without
@@ -20,6 +20,29 @@
 # OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 # DEALINGS IN THE SOFTWARE.
 
+""" Implements classes and helpers for running "native" piglit tests
+
+This module provides the abstract Test class which should be used as the base
+class for all tests for piglit integration. It provides two direct children
+PiglitTest and GleanTest, and two additional children of PiglitTest, ShaderTest
+and GLSLParserTest. Finally it provides custom exceptions for use with
+GLSLParesrTest and ShaderTest.
+
+In addition it provides helper methods for adding ShaderTest and
+GLSLParserTests to the profile modules.
+
+Test provides two methods for running tests, each one offering more features:
+
+Test.run() is a low frills method that runs the test, and sets the Test.results
+Attribute (running self._check_for_skip_scenario() and
+self._interpret_result())
+
+Test.execute() provides more features, it calls self.run() internally, but
+provides support for console logging, recording the results of the test into a
+json file, and support for dmesg checking.
+
+"""
+
 import errno
 import os
 import os.path as path
@@ -60,6 +83,30 @@ _GLEAN_EXECUTABLE = os.path.join(TEST_BIN_DIR, "glean")
 
 
 class Test(object):
+    """ Abstract base class for piglit tests
+
+    Test provides an API for running tests.
+
+    All inheriting classes will need to provide their own implementation of
+    _interpret_result, which transforms the raw output of the binary into a
+    TestResult object attached to Test._results
+
+    It may be useful to override the command property as well as the
+    _check_for_skip_scenario() method.
+
+    Overriding the Test.ENV method is not recomended, as that name is
+    overwritten by TestProfile.run. If a class or instance needs a specific ENV
+    setup, override ENV in the sublcass or in the instance.
+
+    Arguments:
+    command -- a command to run the test that will be passed to
+               subprocess.Popen
+
+    Keyword Arguments:
+    run_concurrent -- Set to True if the test is thread safe, otherwise False.
+                      Default: False
+
+    """
     ENV = Environment()
     __slots__ = ['ENV', 'run_concurrent', 'env', 'result', 'cwd', '_command',
                  '_test_hook_execute_run']
@@ -83,13 +130,20 @@ class Test(object):
         self._test_hook_execute_run = lambda: None
 
     def execute(self, path, log, json_writer, dmesg):
-        '''
-        Run the test.
+        """ Run a Test with features
 
-        :path:
-            Fully qualified test name as a string.  For example,
-            ``spec/glsl-1.30/preprocessor/compiler/keywords/void.frag``.
-        '''
+        This method wraps self.run(), and adds some additional features. The
+        biggest of these features is console logging, recording results to a
+        JSON file, and dmesg checking.
+
+        Arguments:
+        path -- the name of the test to record in the json and send to the
+                logger
+        log -- a log.Log() instance
+        json_wrtier -- a core.JSONWriter instance
+        dmesg -- a dmesg instance
+
+        """
         log_current = log.pre_log(path if self.ENV.verbose else None)
 
         # Run the test
@@ -141,17 +195,27 @@ class Test(object):
 
     @abc.abstractmethod
     def interpret_result(self):
+        """ Transform the raw output of a test into a form piglit understands
+
+        Takes the raw output of the command that is recorded in
+        self._result['out'], self._result['err'], and
+        self._result['returncode'] and sets self._result['result'] and
+        self._result['subtest'] (if applicable). It is also free to modify the
+        other members of self._result. For example, to remove hints from the
+        raw output.
+
+        """
         pass
 
     def run(self):
-        """
-        Run a test.  The return value will be a dictionary with keys
-        including 'result', 'info', 'returncode' and 'command'.
-        * For 'result', the value may be one of 'pass', 'fail', 'skip',
-          'crash', or 'warn'.
-        * For 'info', the value will include stderr/out text.
-        * For 'returncode', the value will be the numeric exit code/value.
-        * For 'command', the value will be command line program and arguments.
+        """ Run the test and set the result
+
+        This method to ensure that the test should be run (via
+        self._check_for_skip_result()) and returns early if the test shouldn't
+        be run. Then it runs the test, runs self._interpret_result(), ensures
+        that the test shouldn't be a crash or warn based on returncode, and
+        finally does some result adjustment for valgrind.
+
         """
         self.result['command'] = ' '.join(self.command)
         self.result['environment'] = " ".join(
@@ -215,6 +279,12 @@ class Test(object):
         return False
 
     def _run_command(self):
+        """ Run the command
+
+        Runs the command from self.command, then converts the output to UTF-8
+        and sets the out, err, and returncode keys in self._result
+
+        """
         fullenv = os.environ.copy()
         for key, value in self.env.iteritems():
             fullenv[key] = str(value)
@@ -262,11 +332,11 @@ class Test(object):
 
 
 class PiglitTest(Test):
-    """
-    PiglitTest: Run a "native" piglit test executable
+    """ PiglitTest: Run a "native" piglit test executable
+
+    This is both the base for other native piglit tests, and used to directly
+    run piglit tests
 
-    Expect one line prefixed PIGLIT: in the output, which contains a result
-    dictionary. The plain output is appended to this dictionary
     """
     def __init__(self, *args, **kwargs):
         super(PiglitTest, self).__init__(*args, **kwargs)
@@ -277,7 +347,7 @@ class PiglitTest(Test):
     def check_for_skip_scenario(self):
         """ Native Piglit-test specific skip checking
 
-        If we are running on gbm don't run glean or glx- tests
+        If we are running on gbm don't run glx tests
 
         """
         if _PIGLIT_PLATFORM == 'gbm':
@@ -302,6 +372,7 @@ class PiglitTest(Test):
 
 
 class GleanTest(Test):
+    """ Run Glean tests """
     GLOBAL_PARAMS = []
 
     def __init__(self, name, *args, **kwargs):
@@ -330,7 +401,7 @@ class GLSLParserTest(PiglitTest):
 
     Specifically it is necessary to parse a glsl_parser_test to get information
     about it before actually creating a PiglitTest. Even though this could
-    be done with a funciton wrapper, making it a distinct class makes it easier
+    be done with a function wrapper, making it a distinct class makes it easier
     to sort in the profile.
 
     Arguments:
@@ -367,7 +438,7 @@ class GLSLParserTest(PiglitTest):
                 # Remove all leading whitespace
                 line = line.strip()
 
-                # If strip renendered '' that means we had a blank newline,
+                # If strip returned '' that means we had a blank newline,
                 # just go on
                 if line == '':
                     continue
@@ -439,7 +510,7 @@ class ShaderTest(PiglitTest):
             # Find the config section
             for line in lines:
                 # We need to find the first line of the configuration file, as
-                # soon as we do then we can move on to geting the
+                # soon as we do then we can move on to getting the
                 # configuration. The first line needs to be parsed by the next
                 # block.
                 if line.lstrip().startswith('[require]'):
@@ -456,7 +527,7 @@ class ShaderTest(PiglitTest):
                     elif line.endswith('2.0'):
                         prog = path.join(TEST_BIN_DIR, 'shader_runner_gles2')
                     # If we don't set gles2 or gles3 continue the loop,
-                    # probably htting the exception in the for/else
+                    # probably hitting the exception in the for/else
                     else:
                         raise ShaderTestParserException("No GL ES version set")
                     break
@@ -474,7 +545,7 @@ class ShaderTest(PiglitTest):
 
 
 class ShaderTestParserException(Exception):
-    """ An excpetion to be raised for errors in the ShaderTest parser """
+    """ An exception to be raised for errors in the ShaderTest parser """
     pass
 
 
@@ -506,8 +577,7 @@ def import_glsl_parser_tests(group, basepath, subdirectories):
                 ext = f.rsplit('.')[-1]
                 if ext in ['vert', 'geom', 'frag', 'comp']:
                     filepath = path.join(dirpath, f)
-                    # testname := filepath relative to
-                    # basepath.
+                    # testname := filepath relative to basepath.
                     testname = os.path.relpath(filepath, basepath)
                     if os.path.sep != '/':
                         testname = testname.replace(os.path.sep, '/', -1)
-- 
2.0.0.rc2



More information about the Piglit mailing list