On Sat, Jun 21, 2014 at 8:06 AM, Dylan Baker <[email protected]> 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 <[email protected]>
Acked-by: Ilia Mirkin <[email protected]> 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 > [email protected] > http://lists.freedesktop.org/mailman/listinfo/piglit _______________________________________________ Piglit mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/piglit
