[Piglit] [PATCH 06/13] framework: Split code out of framework.core

Dylan Baker baker.dylan.c at gmail.com
Sat Jun 21 05:06:07 PDT 2014


This splits results code out of core into its own module. This makes the
code cleaner and easier to understand, and is groundwork for coming
patches.

Signed-off-by: Dylan Baker <baker.dylan.c at gmail.com>
---
 framework/core.py                | 286 -----------------------------------
 framework/exectest.py            |   3 +-
 framework/programs/run.py        |  10 +-
 framework/programs/summary.py    |   3 +-
 framework/results.py             | 314 +++++++++++++++++++++++++++++++++++++++
 framework/summary.py             |   4 +-
 framework/tests/core_tests.py    |  43 +-----
 framework/tests/dmesg_tests.py   |   2 +-
 framework/tests/results_tests.py |  91 ++++++++++++
 9 files changed, 418 insertions(+), 338 deletions(-)
 create mode 100644 framework/results.py
 create mode 100644 framework/tests/results_tests.py

diff --git a/framework/core.py b/framework/core.py
index 2005a4e..de5afa0 100644
--- a/framework/core.py
+++ b/framework/core.py
@@ -28,163 +28,17 @@ import os
 import re
 import subprocess
 import sys
-from cStringIO import StringIO
 # TODO: ConfigParser is known as configparser in python3
 import ConfigParser
-try:
-    import simplejson as json
-except ImportError:
-    import json
-
-import framework.status as status
-from .threads import synchronized_self
 
 __all__ = ['PIGLIT_CONFIG',
            'Options',
-           'TestrunResult',
-           'TestResult',
-           'JSONWriter',
-           'checkDir',
            'collect_system_info',
-           'load_results',
            'parse_listfile']
 
 
 PIGLIT_CONFIG = ConfigParser.SafeConfigParser()
 
-class PiglitJSONEncoder(json.JSONEncoder):
-    def default(self, o):
-        if isinstance(o, status.Status):
-            return str(o)
-        elif isinstance(o, set):
-            return list(o)
-        return json.JSONEncoder.default(self, o)
-
-
-class JSONWriter:
-    '''
-    Writes to a JSON file stream
-
-    JSONWriter is threadsafe.
-
-    Example
-    -------
-
-    This call to ``json.dump``::
-        json.dump(
-            {
-                'a': [1, 2, 3],
-                'b': 4,
-                'c': {
-                    'x': 100,
-                },
-            }
-            file,
-            indent=JSONWriter.INDENT)
-
-    is equivalent to::
-        w = JSONWriter(file)
-        w.open_dict()
-        w.write_dict_item('a', [1, 2, 3])
-        w.write_dict_item('b', 4)
-        w.write_dict_item('c', {'x': 100})
-        w.close_dict()
-
-    which is also equivalent to::
-        w = JSONWriter(file)
-        w.open_dict()
-        w.write_dict_item('a', [1, 2, 3])
-        w.write_dict_item('b', 4)
-
-        w.write_dict_key('c')
-        w.open_dict()
-        w.write_dict_item('x', 100)
-        w.close_dict()
-
-        w.close_dict()
-    '''
-
-    INDENT = 4
-
-    def __init__(self, file):
-        self.file = file
-        self.__indent_level = 0
-        self.__inhibit_next_indent = False
-        self.__encoder = PiglitJSONEncoder(indent=self.INDENT)
-
-        # self.__is_collection_empty
-        #
-        # A stack that indicates if the currect collection is empty
-        #
-        # When open_dict is called, True is pushed onto the
-        # stack. When the first element is written to the newly
-        # opened dict, the top of the stack is set to False.
-        # When the close_dict is called, the stack is popped.
-        #
-        # The top of the stack is element -1.
-        #
-        # XXX: How does one attach docstrings to member variables?
-        #
-        self.__is_collection_empty = []
-
-    @synchronized_self
-    def __write_indent(self):
-        if self.__inhibit_next_indent:
-            self.__inhibit_next_indent = False
-            return
-        else:
-            i = ' ' * self.__indent_level * self.INDENT
-            self.file.write(i)
-
-    @synchronized_self
-    def __write(self, obj):
-        lines = list(self.__encoder.encode(obj).split('\n'))
-        n = len(lines)
-        for i in range(n):
-            self.__write_indent()
-            self.file.write(lines[i])
-            if i != n - 1:
-                self.file.write('\n')
-
-    @synchronized_self
-    def open_dict(self):
-        self.__write_indent()
-        self.file.write('{')
-
-        self.__indent_level += 1
-        self.__is_collection_empty.append(True)
-
-    @synchronized_self
-    def close_dict(self, comma=True):
-        self.__indent_level -= 1
-        self.__is_collection_empty.pop()
-
-        self.file.write('\n')
-        self.__write_indent()
-        self.file.write('}')
-
-    @synchronized_self
-    def write_dict_item(self, key, value):
-        # Write key.
-        self.write_dict_key(key)
-
-        # Write value.
-        self.__write(value)
-
-    @synchronized_self
-    def write_dict_key(self, key):
-        # Write comma if this is not the initial item in the dict.
-        if self.__is_collection_empty[-1]:
-            self.__is_collection_empty[-1] = False
-        else:
-            self.file.write(',')
-
-        self.file.write('\n')
-        self.__write(key)
-        self.file.write(': ')
-
-        self.__inhibit_next_indent = True
-
 
 # Ensure the given directory exists
 def checkDir(dirname, failifexists):
@@ -207,125 +61,6 @@ def checkDir(dirname, failifexists):
             raise
 
 
-class TestResult(dict):
-    def __init__(self, *args):
-        dict.__init__(self, *args)
-
-        # Replace the result with a status object
-        try:
-            self['result'] = status.status_lookup(self['result'])
-        except KeyError:
-            # If there isn't a result (like when used by piglit-run), go on
-            # normally
-            pass
-
-
-class TestrunResult:
-    def __init__(self, resultfile=None):
-        self.serialized_keys = ['options',
-                                'name',
-                                'tests',
-                                'uname',
-                                'wglinfo',
-                                'glxinfo',
-                                'lspci',
-                                'time_elapsed']
-        self.name = None
-        self.uname = None
-        self.options = None
-        self.glxinfo = None
-        self.lspci = None
-        self.time_elapsed = None
-        self.tests = {}
-
-        if resultfile:
-            # Attempt to open the json file normally, if it fails then attempt
-            # to repair it.
-            try:
-                raw_dict = json.load(resultfile)
-            except ValueError:
-                raw_dict = json.load(self.__repairFile(resultfile))
-
-            # Check that only expected keys were unserialized.
-            for key in raw_dict:
-                if key not in self.serialized_keys:
-                    raise Exception('unexpected key in results file: ', str(key))
-
-            self.__dict__.update(raw_dict)
-
-            # Replace each raw dict in self.tests with a TestResult.
-            for (path, result) in self.tests.items():
-                self.tests[path] = TestResult(result)
-
-    def __repairFile(self, file):
-        '''
-        Reapair JSON file if necessary
-
-        If the JSON file is not closed properly, perhaps due a system
-        crash during a test run, then the JSON is repaired by
-        discarding the trailing, incomplete item and appending braces
-        to the file to close the JSON object.
-
-        The repair is performed on a string buffer, and the given file
-        is never written to. This allows the file to be safely read
-        during a test run.
-
-        :return: If no repair occured, then ``file`` is returned.
-                Otherwise, a new file object containing the repaired JSON
-                is returned.
-        '''
-
-        file.seek(0)
-        lines = file.readlines()
-
-        # JSON object was not closed properly.
-        #
-        # To repair the file, we execute these steps:
-        #   1. Find the closing brace of the last, properly written
-        #      test result.
-        #   2. Discard all subsequent lines.
-        #   3. Remove the trailing comma of that test result.
-        #   4. Append enough closing braces to close the json object.
-        #   5. Return a file object containing the repaired JSON.
-
-        # Each non-terminal test result ends with this line:
-        safe_line = 2 * JSONWriter.INDENT * ' ' + '},\n'
-
-        # Search for the last occurence of safe_line.
-        safe_line_num = None
-        for i in range(-1, - len(lines), -1):
-            if lines[i] == safe_line:
-                safe_line_num = i
-                break
-
-        if safe_line_num is None:
-            raise Exception('failed to repair corrupt result file: ' +
-                            file.name)
-
-        # Remove corrupt lines.
-        lines = lines[0:(safe_line_num + 1)]
-
-        # Remove trailing comma.
-        lines[-1] = 2 * JSONWriter.INDENT * ' ' + '}\n'
-
-        # Close json object.
-        lines.append(JSONWriter.INDENT * ' ' + '}\n')
-        lines.append('}')
-
-        # Return new file object containing the repaired JSON.
-        new_file = StringIO()
-        new_file.writelines(lines)
-        new_file.flush()
-        new_file.seek(0)
-        return new_file
-
-    def write(self, file):
-        # Serialize only the keys in serialized_keys.
-        keys = set(self.__dict__.keys()).intersection(self.serialized_keys)
-        raw_dict = dict([(k, self.__dict__[k]) for k in keys])
-        json.dump(raw_dict, file, indent=JSONWriter.INDENT)
-
-
 class Options(object):
     """ Contains options for a piglit run
 
@@ -399,27 +134,6 @@ def collect_system_info():
     return result
 
 
-def load_results(filename):
-    """ Loader function for TestrunResult class
-
-    This function takes a single argument of a results file.
-
-    It makes quite a few assumptions, first it assumes that it has been passed
-    a folder, if that fails then it looks for a plain text json file called
-    "main"
-
-    """
-    try:
-        with open(filename, 'r') as resultsfile:
-            testrun = TestrunResult(resultsfile)
-    except IOError:
-        with open(os.path.join(filename, "main"), 'r') as resultsfile:
-            testrun = TestrunResult(resultsfile)
-
-    assert(testrun.name is not None)
-    return testrun
-
-
 def parse_listfile(filename):
     """
     Parses a newline-seperated list in a text file and returns a python list
diff --git a/framework/exectest.py b/framework/exectest.py
index d7cad6e..3c38c97 100644
--- a/framework/exectest.py
+++ b/framework/exectest.py
@@ -28,7 +28,8 @@ import time
 import sys
 import traceback
 
-from .core import TestResult, Options
+from framework.core import Options
+from framework.results import TestResult
 
 
 __all__ = ['Test',
diff --git a/framework/programs/run.py b/framework/programs/run.py
index 6008eb5..298f1e1 100644
--- a/framework/programs/run.py
+++ b/framework/programs/run.py
@@ -28,6 +28,7 @@ import os.path as path
 import time
 
 import framework.core as core
+import framework.results
 import framework.profile
 
 __all__ = ['run',
@@ -142,13 +143,12 @@ def run(input_):
     if args.platform:
         env.env['PIGLIT_PLATFORM'] = args.platform
 
-
     # Change working directory to the root of the piglit directory
     piglit_dir = path.dirname(path.realpath(sys.argv[0]))
     os.chdir(piglit_dir)
     core.checkDir(args.results_path, False)
 
-    results = core.TestrunResult()
+    results = framework.results.TestrunResult()
 
     # Set results.name
     if args.name is not None:
@@ -159,7 +159,7 @@ def run(input_):
     # Begin json.
     result_filepath = path.join(args.results_path, 'main')
     result_file = open(result_filepath, 'w')
-    json_writer = core.JSONWriter(result_file)
+    json_writer = framework.results.JSONWriter(result_file)
     json_writer.open_dict()
 
     # Write out command line options for use in resuming.
@@ -210,7 +210,7 @@ def resume(input_):
                         help="Path to results folder")
     args = parser.parse_args(input_)
 
-    results = core.load_results(args.results_path)
+    results = framework.results.load_results(args.results_path)
     env = core.Options(concurrent=results.options['concurrent'],
                        exclude_filter=results.options['exclude_filter'],
                        include_filter=results.options['filter'],
@@ -223,7 +223,7 @@ def resume(input_):
         env.env['PIGLIT_PLATFORM'] = results.options['platform']
 
     results_path = path.join(args.results_path, "main")
-    json_writer = core.JSONWriter(open(results_path, 'w+'))
+    json_writer = framework.results.JSONWriter(open(results_path, 'w+'))
     json_writer.open_dict()
     json_writer.write_dict_key("options")
     json_writer.open_dict()
diff --git a/framework/programs/summary.py b/framework/programs/summary.py
index da4e040..81f6d3d 100644
--- a/framework/programs/summary.py
+++ b/framework/programs/summary.py
@@ -26,6 +26,7 @@ import os.path as path
 import framework.summary as summary
 import framework.status as status
 import framework.core as core
+import framework.results
 import framework.junit 
 
 __all__ = ['html',
@@ -104,7 +105,7 @@ class _Writer:
         self.path = []
 
     def write(self, arg):
-        testrun = core.load_results(arg)
+        testrun = framework.results.load_results(arg)
 
         self.report.start()
         self.report.startSuite('piglit')
diff --git a/framework/results.py b/framework/results.py
new file mode 100644
index 0000000..c9831f7
--- /dev/null
+++ b/framework/results.py
@@ -0,0 +1,314 @@
+# 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
+# restriction, including without limitation the rights to use,
+# copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following
+# conditions:
+#
+# This permission notice shall be included in all copies or
+# substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+# PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHOR(S) BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+
+""" Module for results generation """
+
+from __future__ import print_function
+import os
+from cStringIO import StringIO
+try:
+    import simplejson as json
+except ImportError:
+    import json
+
+import framework.status as status
+from framework.threads import synchronized_self
+
+__all__ = [
+    'TestrunResult',
+    'TestResult',
+    'JSONWriter',
+    'load_results',
+]
+
+
+class PiglitJSONEncoder(json.JSONEncoder):
+    def default(self, o):
+        if isinstance(o, status.Status):
+            return str(o)
+        elif isinstance(o, set):
+            return list(o)
+        return json.JSONEncoder.default(self, o)
+
+
+class JSONWriter:
+    '''
+    Writes to a JSON file stream
+
+    JSONWriter is threadsafe.
+
+    Example
+    -------
+
+    This call to ``json.dump``::
+        json.dump(
+            {
+                'a': [1, 2, 3],
+                'b': 4,
+                'c': {
+                    'x': 100,
+                },
+            }
+            file,
+            indent=JSONWriter.INDENT)
+
+    is equivalent to::
+        w = JSONWriter(file)
+        w.open_dict()
+        w.write_dict_item('a', [1, 2, 3])
+        w.write_dict_item('b', 4)
+        w.write_dict_item('c', {'x': 100})
+        w.close_dict()
+
+    which is also equivalent to::
+        w = JSONWriter(file)
+        w.open_dict()
+        w.write_dict_item('a', [1, 2, 3])
+        w.write_dict_item('b', 4)
+
+        w.write_dict_key('c')
+        w.open_dict()
+        w.write_dict_item('x', 100)
+        w.close_dict()
+
+        w.close_dict()
+    '''
+
+    INDENT = 4
+
+    def __init__(self, file):
+        self.file = file
+        self.__indent_level = 0
+        self.__inhibit_next_indent = False
+        self.__encoder = PiglitJSONEncoder(indent=self.INDENT)
+
+        # self.__is_collection_empty
+        #
+        # A stack that indicates if the currect collection is empty
+        #
+        # When open_dict is called, True is pushed onto the
+        # stack. When the first element is written to the newly
+        # opened dict, the top of the stack is set to False.
+        # When the close_dict is called, the stack is popped.
+        #
+        # The top of the stack is element -1.
+        #
+        # XXX: How does one attach docstrings to member variables?
+        #
+        self.__is_collection_empty = []
+
+    @synchronized_self
+    def __write_indent(self):
+        if self.__inhibit_next_indent:
+            self.__inhibit_next_indent = False
+            return
+        else:
+            i = ' ' * self.__indent_level * self.INDENT
+            self.file.write(i)
+
+    @synchronized_self
+    def __write(self, obj):
+        lines = list(self.__encoder.encode(obj).split('\n'))
+        n = len(lines)
+        for i in range(n):
+            self.__write_indent()
+            self.file.write(lines[i])
+            if i != n - 1:
+                self.file.write('\n')
+
+    @synchronized_self
+    def open_dict(self):
+        self.__write_indent()
+        self.file.write('{')
+
+        self.__indent_level += 1
+        self.__is_collection_empty.append(True)
+
+    @synchronized_self
+    def close_dict(self, comma=True):
+        self.__indent_level -= 1
+        self.__is_collection_empty.pop()
+
+        self.file.write('\n')
+        self.__write_indent()
+        self.file.write('}')
+
+    @synchronized_self
+    def write_dict_item(self, key, value):
+        # Write key.
+        self.write_dict_key(key)
+
+        # Write value.
+        self.__write(value)
+
+    @synchronized_self
+    def write_dict_key(self, key):
+        # Write comma if this is not the initial item in the dict.
+        if self.__is_collection_empty[-1]:
+            self.__is_collection_empty[-1] = False
+        else:
+            self.file.write(',')
+
+        self.file.write('\n')
+        self.__write(key)
+        self.file.write(': ')
+
+        self.__inhibit_next_indent = True
+
+
+class TestResult(dict):
+    def __init__(self, *args):
+        dict.__init__(self, *args)
+
+        # Replace the result with a status object
+        try:
+            self['result'] = status.status_lookup(self['result'])
+        except KeyError:
+            # If there isn't a result (like when used by piglit-run), go on
+            # normally
+            pass
+
+
+class TestrunResult:
+    def __init__(self, resultfile=None):
+        self.serialized_keys = ['options',
+                                'name',
+                                'tests',
+                                'uname',
+                                'wglinfo',
+                                'glxinfo',
+                                'lspci',
+                                'time_elapsed']
+        self.name = None
+        self.uname = None
+        self.options = None
+        self.glxinfo = None
+        self.lspci = None
+        self.time_elapsed = None
+        self.tests = {}
+
+        if resultfile:
+            # Attempt to open the json file normally, if it fails then attempt
+            # to repair it.
+            try:
+                raw_dict = json.load(resultfile)
+            except ValueError:
+                raw_dict = json.load(self.__repairFile(resultfile))
+
+            # Check that only expected keys were unserialized.
+            for key in raw_dict:
+                if key not in self.serialized_keys:
+                    raise Exception('unexpected key in results file: ', str(key))
+
+            self.__dict__.update(raw_dict)
+
+            # Replace each raw dict in self.tests with a TestResult.
+            for (path, result) in self.tests.items():
+                self.tests[path] = TestResult(result)
+
+    def __repairFile(self, file):
+        '''
+        Reapair JSON file if necessary
+
+        If the JSON file is not closed properly, perhaps due a system
+        crash during a test run, then the JSON is repaired by
+        discarding the trailing, incomplete item and appending braces
+        to the file to close the JSON object.
+
+        The repair is performed on a string buffer, and the given file
+        is never written to. This allows the file to be safely read
+        during a test run.
+
+        :return: If no repair occured, then ``file`` is returned.
+                Otherwise, a new file object containing the repaired JSON
+                is returned.
+        '''
+
+        file.seek(0)
+        lines = file.readlines()
+
+        # JSON object was not closed properly.
+        #
+        # To repair the file, we execute these steps:
+        #   1. Find the closing brace of the last, properly written
+        #      test result.
+        #   2. Discard all subsequent lines.
+        #   3. Remove the trailing comma of that test result.
+        #   4. Append enough closing braces to close the json object.
+        #   5. Return a file object containing the repaired JSON.
+
+        # Each non-terminal test result ends with this line:
+        safe_line = 2 * JSONWriter.INDENT * ' ' + '},\n'
+
+        # Search for the last occurence of safe_line.
+        safe_line_num = None
+        for i in range(-1, - len(lines), -1):
+            if lines[i] == safe_line:
+                safe_line_num = i
+                break
+
+        if safe_line_num is None:
+            raise Exception('failed to repair corrupt result file: ' +
+                            file.name)
+
+        # Remove corrupt lines.
+        lines = lines[0:(safe_line_num + 1)]
+
+        # Remove trailing comma.
+        lines[-1] = 2 * JSONWriter.INDENT * ' ' + '}\n'
+
+        # Close json object.
+        lines.append(JSONWriter.INDENT * ' ' + '}\n')
+        lines.append('}')
+
+        # Return new file object containing the repaired JSON.
+        new_file = StringIO()
+        new_file.writelines(lines)
+        new_file.flush()
+        new_file.seek(0)
+        return new_file
+
+    def write(self, file):
+        # Serialize only the keys in serialized_keys.
+        keys = set(self.__dict__.keys()).intersection(self.serialized_keys)
+        raw_dict = dict([(k, self.__dict__[k]) for k in keys])
+        json.dump(raw_dict, file, indent=JSONWriter.INDENT)
+
+
+def load_results(filename):
+    """ Loader function for TestrunResult class
+
+    This function takes a single argument of a results file.
+
+    It makes quite a few assumptions, first it assumes that it has been passed
+    a folder, if that fails then it looks for a plain text json file called
+    "main"
+
+    """
+    try:
+        with open(filename, 'r') as resultsfile:
+            testrun = TestrunResult(resultsfile)
+    except IOError:
+        with open(os.path.join(filename, "main"), 'r') as resultsfile:
+            testrun = TestrunResult(resultsfile)
+
+    assert(testrun.name is not None)
+    return testrun
diff --git a/framework/summary.py b/framework/summary.py
index 7b88c96..fa98267 100644
--- a/framework/summary.py
+++ b/framework/summary.py
@@ -34,7 +34,7 @@ from mako.template import Template
 # a local variable status exists, prevent accidental overloading by renaming
 # the module
 import framework.status as so
-import framework.core as core
+import framework.results
 
 
 __all__ = [
@@ -287,7 +287,7 @@ class Summary:
 
         # Create a Result object for each piglit result and append it to the
         # results list
-        self.results = [core.load_results(i) for i in resultfiles]
+        self.results = [framework.results.load_results(i) for i in resultfiles]
 
         self.status = {}
         self.fractions = {}
diff --git a/framework/tests/core_tests.py b/framework/tests/core_tests.py
index 15858b8..e6ff5ec 100644
--- a/framework/tests/core_tests.py
+++ b/framework/tests/core_tests.py
@@ -22,12 +22,9 @@
 
 
 import os
-import tempfile
 import collections
-import json
 import framework.tests.utils as utils
 import framework.core as core
-import framework.status as status
 
 
 def check_initialize(target):
@@ -49,25 +46,12 @@ def test_generate_initialize():
     """
     yieldable = check_initialize
 
-    for target in [core.Options, core.TestrunResult, core.TestResult,
-                   core.PiglitJSONEncoder]:
+    for target in [core.Options]:
         yieldable.description = "Test that {} initializes".format(
             target.__name__)
         yield yieldable, target
 
 
-def test_initialize_jsonwriter():
-    """ Test that JSONWriter initializes
-
-    This needs to be handled separately from the others because it requires
-    arguments
-
-    """
-    with tempfile.TemporaryFile() as tfile:
-        func = core.JSONWriter(tfile)
-        assert isinstance(func, core.JSONWriter)
-
-
 def test_parse_listfile_return():
     """ Test that parse_listfile returns a container
 
@@ -126,28 +110,3 @@ def test_parse_listfile_tilde():
         results = core.parse_listfile(tfile)
 
     assert results[0] == os.path.expandvars("$HOME/foo")
-
-
-def test_load_results_folder():
-    """ Test that load_results takes a folder with a file named main in it """
-    with utils.tempdir() as tdir:
-        with open(os.path.join(tdir, 'main'), 'w') as tfile:
-            tfile.write(json.dumps(utils.JSON_DATA))
-
-        results = core.load_results(tdir)
-        assert results
-
-
-def test_load_results_file():
-    """ Test that load_results takes a file """
-    with utils.resultfile() as tfile:
-        results = core.load_results(tfile.name)
-        assert results
-
-
-def test_testresult_to_status():
-    """ TestResult initialized with result key converts the value to a Status
-    """
-    result = core.TestResult({'result': 'pass'})
-    assert isinstance(result['result'], status.Status), \
-        "Result key not converted to a status object"
diff --git a/framework/tests/dmesg_tests.py b/framework/tests/dmesg_tests.py
index ccc3144..ff70e2d 100644
--- a/framework/tests/dmesg_tests.py
+++ b/framework/tests/dmesg_tests.py
@@ -27,7 +27,7 @@ import re
 import nose.tools as nt
 from nose.plugins.skip import SkipTest
 from framework.dmesg import DummyDmesg, LinuxDmesg, get_dmesg
-from framework.core import TestResult, PiglitJSONEncoder
+from framework.results import TestResult, PiglitJSONEncoder
 from framework.exectest import PiglitTest
 from framework.gleantest import GleanTest
 from framework.shader_test import ShaderTest
diff --git a/framework/tests/results_tests.py b/framework/tests/results_tests.py
new file mode 100644
index 0000000..d4be74c
--- /dev/null
+++ b/framework/tests/results_tests.py
@@ -0,0 +1,91 @@
+# Copyright (c) 2014 Intel Corporation
+
+# 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 restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+""" Module providing tests for the core module """
+
+
+import os
+import tempfile
+import json
+import framework.tests.utils as utils
+import framework.results as results
+import framework.status as status
+
+
+def check_initialize(target):
+    """ Check that a class initializes without error """
+    func = target()
+    # Asserting that func exists will fail for Group and TestrunResult which
+    # are dict subclasses
+    assert isinstance(func, target)
+
+
+def test_generate_initialize():
+    """ Generator that creates tests to initialize all of the classes in core
+
+    In a compiled language the compiler provides this kind of checking, but in
+    an interpreted language like python you don't have a compiler test. The
+    unit tests generated by this function serve as a similar test, does this
+    even work?
+
+    """
+    yieldable = check_initialize
+
+    for target in [results.TestrunResult, results.TestResult]:
+        yieldable.description = "Test that {} initializes".format(
+            target.__name__)
+        yield yieldable, target
+
+
+def test_initialize_jsonwriter():
+    """ Test that JSONWriter initializes
+
+    This needs to be handled separately from the others because it requires
+    arguments
+
+    """
+    with tempfile.TemporaryFile() as tfile:
+        func = results.JSONWriter(tfile)
+        assert isinstance(func, results.JSONWriter)
+
+
+def test_load_results_folder():
+    """ Test that load_results takes a folder with a file named main in it """
+    with utils.tempdir() as tdir:
+        with open(os.path.join(tdir, 'main'), 'w') as tfile:
+            tfile.write(json.dumps(utils.JSON_DATA))
+
+        results_ = results.load_results(tdir)
+        assert results_
+
+
+def test_load_results_file():
+    """ Test that load_results takes a file """
+    with utils.resultfile() as tfile:
+        results_ = results.load_results(tfile.name)
+        assert results_
+
+
+def test_testresult_to_status():
+    """ TestResult initialized with result key converts the value to a Status
+    """
+    result = results.TestResult({'result': 'pass'})
+    assert isinstance(result['result'], status.Status), \
+        "Result key not converted to a status object"
-- 
2.0.0



More information about the Piglit mailing list