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

Ilia Mirkin imirkin at alum.mit.edu
Sat Jun 21 06:46:05 PDT 2014


On Sat, Jun 21, 2014 at 8:06 AM, Dylan Baker <baker.dylan.c at gmail.com> wrote:
> 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>

Acked-by: Ilia Mirkin <imirkin at alum.mit.edu>

Seems reasonable, but I won't pretend to have done a careful review
making sure that the code was properly moved...

> ---
>  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
>
> _______________________________________________
> Piglit mailing list
> Piglit at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/piglit


More information about the Piglit mailing list