[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