This is a pretty substantial patch, but it would be a lot of work to port this incrementally with a lot of code churn, much of which wouldn't receive thorough testing. And honestly, while it touches every python file in the tree, it doesn't touch them substantially.
Due to a lot of work put in in the last few months/years the code base is pretty modern, and most of what needs to be changed are intentional changes to language form upstream: dicts don't have iter* methods, more functions return iterators so they need to be wrapped in list() if they need to be accessed by index or walked multiple times. __future__ imports are removed, and the largest change is the transition from str -> bytes and unicode -> str. This also changes the shbang lines in the scripts, and a small updated to cmake to search for python3 instead of python2. Signed-off-by: Dylan Baker <[email protected]> --- CMakeLists.txt | 2 +- framework/backends/__init__.py | 9 +-- framework/backends/abstract.py | 5 +- framework/backends/json.py | 4 +- framework/backends/junit.py | 13 ++-- framework/core.py | 8 +-- framework/dmesg.py | 6 +- framework/grouptools.py | 8 +-- framework/log.py | 9 ++- framework/profile.py | 25 ++++--- framework/programs/run.py | 10 +-- framework/programs/summary.py | 2 +- framework/results.py | 16 ++--- framework/status.py | 17 ++--- framework/summary.py | 64 +++++++++-------- framework/test/__init__.py | 2 +- framework/test/base.py | 40 ++++------- framework/test/gleantest.py | 2 +- framework/test/glsl_parser_test.py | 4 +- framework/test/gtest.py | 2 +- framework/test/oclconform.py | 2 +- framework/test/opencv.py | 2 +- framework/test/piglit_test.py | 2 +- framework/tests/backends_tests.py | 4 +- framework/tests/base_tests.py | 2 +- framework/tests/core_tests.py | 16 ++--- framework/tests/dmesg_tests.py | 16 ++--- framework/tests/gleantest_tests.py | 2 +- framework/tests/glsl_parser_test_tests.py | 115 +++++++++++++++--------------- framework/tests/grouptools_tests.py | 6 +- framework/tests/gtest_tests.py | 2 +- framework/tests/integration_tests.py | 8 +-- framework/tests/json_tests.py | 2 +- framework/tests/log_tests.py | 4 +- framework/tests/opencv_tests.py | 2 +- framework/tests/piglit_test_tests.py | 2 +- framework/tests/results_tests.py | 4 +- framework/tests/results_v0_tests.py | 14 ++-- framework/tests/results_v1_tests.py | 6 +- framework/tests/results_v2_tests.py | 2 +- framework/tests/results_v3_tests.py | 2 +- framework/tests/run_parser_tests.py | 6 +- framework/tests/shader_test_tests.py | 18 ++--- framework/tests/status_tests.py | 8 +-- framework/tests/summary_tests.py | 8 +-- framework/tests/test_lists.py | 2 +- framework/tests/utils.py | 4 +- piglit | 2 +- piglit-print-commands.py | 4 +- piglit-resume.py | 2 +- piglit-run.py | 2 +- piglit-summary-html.py | 2 +- piglit-summary.py | 2 +- templates/index.mako | 2 +- templates/testrun_info.mako | 4 +- tests/all.py | 2 +- tests/cl.py | 2 +- tests/deqp_gles3.py | 8 +-- tests/igt.py | 12 ++-- tests/xts.py | 2 +- 60 files changed, 267 insertions(+), 288 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index db922d8..69802b6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -189,7 +189,7 @@ IF(PIGLIT_BUILD_GLX_TESTS) pkg_check_modules(GLPROTO REQUIRED glproto) ENDIF() -find_package(PythonInterp 2.7 REQUIRED) +find_package(PythonInterp 3.3 REQUIRED) find_package(PythonNumpy 1.6.2 REQUIRED) find_package(PythonMako 0.8.0 REQUIRED) find_package(PythonSix 1.4.0 REQUIRED) diff --git a/framework/backends/__init__.py b/framework/backends/__init__.py index 257bba9..d3b08ed 100644 --- a/framework/backends/__init__.py +++ b/framework/backends/__init__.py @@ -25,8 +25,8 @@ from .json import * from .junit import * -# A list of available backends -BACKENDS = ['json', 'junit'] +# A set of available backends +BACKENDS = set(['json', 'junit']) def get_backend(backend): @@ -37,6 +37,7 @@ def get_backend(backend): } # Be sure that we're exporting the same list of backends that we actually - # have available - assert backends.keys() == BACKENDS + # have available. These must both be sets since lists are ordered and we + # don't actually care about ordering, just that they have the same elements + assert set(backends.keys()) == BACKENDS return backends[backend] diff --git a/framework/backends/abstract.py b/framework/backends/abstract.py index 928ba9a..b0c0a2d 100644 --- a/framework/backends/abstract.py +++ b/framework/backends/abstract.py @@ -25,13 +25,13 @@ This module provides mixins and base classes for backend modules. """ -from __future__ import print_function, absolute_import + import os import abc import itertools -class Backend(object): +class Backend(object, metaclass=abc.ABCMeta): """ Abstract base class for summary backends This class provides an abstract ancestor for classes implementing backends, @@ -45,7 +45,6 @@ class Backend(object): be thread safe and not need to be locked during write) """ - __metaclass__ = abc.ABCMeta @abc.abstractmethod def __init__(self, dest, metadata, **options): diff --git a/framework/backends/json.py b/framework/backends/json.py index d14eeb2..0bf2da5 100644 --- a/framework/backends/json.py +++ b/framework/backends/json.py @@ -20,7 +20,7 @@ """ Module providing json backend for piglit """ -from __future__ import print_function, absolute_import + import os import shutil @@ -141,7 +141,7 @@ class JSONBackend(FileBackend): def write_test(self, name, data): """ Write a test into the JSON tests dictionary """ t = os.path.join(self._dest, 'tests', - '{}.json'.format(self._counter.next())) + '{}.json'.format(next(self._counter))) with open(t, 'w') as f: json.dump({name: data}, f, default=piglit_encoder) self._fsync(f) diff --git a/framework/backends/junit.py b/framework/backends/junit.py index 53b6086..796ec7c 100644 --- a/framework/backends/junit.py +++ b/framework/backends/junit.py @@ -20,7 +20,7 @@ """ Module implementing a JUnitBackend for piglit """ -from __future__ import print_function, absolute_import + import os.path import re import shutil @@ -96,13 +96,12 @@ class JUnitBackend(FileBackend): # This must be bytes or unicode piglit.attrib['tests'] = str(len(piglit)) - with open(os.path.join(self._dest, 'results.xml'), 'w') as f: - f.write("<?xml version='1.0' encoding='utf-8'?>\n") + with open(os.path.join(self._dest, 'results.xml'), 'wb') as f: # lxml has a pretty print we want to use if etree.__name__ == 'lxml.etree': - f.write(etree.tostring(root, pretty_print=True)) + f.write(etree.tostring(root, encoding='utf-8', pretty_print=True)) else: - f.write(etree.tostring(root)) + f.write(etree.tostring(root, encoding='utf-8')) shutil.rmtree(os.path.join(self._dest, 'tests')) @@ -198,7 +197,7 @@ class JUnitBackend(FileBackend): calculate_result() t = os.path.join(self._dest, 'tests', - '{}.xml'.format(self._counter.next())) - with open(t, 'w') as f: + '{}.xml'.format(next(self._counter))) + with open(t, 'wb') as f: f.write(etree.tostring(element)) self._fsync(f) diff --git a/framework/core.py b/framework/core.py index dfc8f6a..0514afb 100644 --- a/framework/core.py +++ b/framework/core.py @@ -22,13 +22,13 @@ # Piglit core -from __future__ import print_function, absolute_import + import errno import os import re import subprocess import sys -import ConfigParser +import configparser __all__ = [ 'PIGLIT_CONFIG', @@ -40,7 +40,7 @@ __all__ = [ PLATFORMS = ["glx", "x11_egl", "wayland", "gbm", "mixed_glx_egl"] -PIGLIT_CONFIG = ConfigParser.SafeConfigParser(allow_no_value=True) +PIGLIT_CONFIG = configparser.SafeConfigParser(allow_no_value=True) def get_config(arg=None): if arg: @@ -117,7 +117,7 @@ class Options(object): } def __iter__(self): - for key, values in self.__dict__.iteritems(): + for key, values in self.__dict__.items(): # If the values are regex compiled then yield their pattern # attribute, which is the original plaintext they were compiled # from, otherwise yield them normally. diff --git a/framework/dmesg.py b/framework/dmesg.py index 1a5f629..f1cb976 100644 --- a/framework/dmesg.py +++ b/framework/dmesg.py @@ -35,7 +35,7 @@ dmesg implementation for their OS. """ -from __future__ import print_function, absolute_import + import re import sys import subprocess @@ -136,7 +136,7 @@ class BaseDmesg(object): # Replace the results of any subtests if 'subtest' in result: - for key, value in result['subtest'].iteritems(): + for key, value in result['subtest'].items(): result['subtest'][key] = replace(value) # Add the dmesg values to the result @@ -171,7 +171,7 @@ class LinuxDmesg(BaseDmesg): warnings.warn("Cannot check dmesg for timestamp support. If you " "do not have timestamps enabled in your kernel you " "get incomplete dmesg captures", RuntimeWarning) - elif not re.match(r'\[\s*\d+\.\d+\]', self._last_message): + elif not re.match(b'\[\s*\d+\.\d+\]', self._last_message): # Do an initial check to ensure that dmesg has timestamps, we need # timestamps to work correctly. A proper linux dmesg timestamp # looks like this: [ 0.00000] diff --git a/framework/grouptools.py b/framework/grouptools.py index 3d26bbc..1b942cb 100644 --- a/framework/grouptools.py +++ b/framework/grouptools.py @@ -44,7 +44,7 @@ __all__ = [ def _assert_illegal(group): """Helper that checks for illegal characters in input.""" - assert isinstance(group, (str, unicode)), 'Type must be string or unicode' + assert isinstance(group, str), 'Type must be string' assert '\\' not in group, \ 'Groups are not paths and cannot contain \\. ({})'.format(group) assert not group.startswith('/'), \ @@ -104,8 +104,8 @@ def join(*args): """ for group in args: - assert isinstance(group, (str, unicode)), \ - 'Type must be string or unicode' + assert isinstance(group, str), \ + 'Type must be string' assert '\\' not in group, \ 'Groups are not paths and cannot contain \\. ({})'.format(group) assert not args[0].startswith('/'), \ @@ -152,7 +152,7 @@ def from_path(path): This safely handles both Windows and Unix style paths. """ - assert isinstance(path, (str, unicode)), 'Type must be string or unicode' + assert isinstance(path, str), 'Type must be string' assert not path.startswith('/'), \ 'Groups cannot start with /. ({})' .format(path) diff --git a/framework/log.py b/framework/log.py index 759974a..4072326 100644 --- a/framework/log.py +++ b/framework/log.py @@ -26,7 +26,7 @@ returning BaseLog derived instances to individual tests. """ -from __future__ import print_function, absolute_import + import sys import abc import itertools @@ -36,7 +36,7 @@ import collections __all__ = ['LogManager'] -class BaseLog(object): +class BaseLog(object, metaclass=abc.ABCMeta): """ Abstract base class for Log objects It provides a lock, which should be used to lock whever the shared state is @@ -46,7 +46,6 @@ class BaseLog(object): state -- the state dict from LogManager """ - __metaclass__ = abc.ABCMeta SUMMARY_KEYS = set([ 'pass', 'fail', 'warn', 'crash', 'skip', 'dmesg-warn', 'dmesg-fail', @@ -109,7 +108,7 @@ class QuietLog(BaseLog): else: self._endcode = '\n' - self.__counter = self._test_counter.next() + self.__counter = next(self._test_counter) self._state['running'].append(self.__counter) def start(self, name): @@ -154,7 +153,7 @@ class QuietLog(BaseLog): done=str(self._state['complete']).zfill(self._pad), total=str(self._state['total']).zfill(self._pad), status=', '.join('{0}: {1}'.format(k, v) for k, v in - sorted(self._state['summary'].iteritems())), + sorted(self._state['summary'].items())), running=''.join('|/-\\'[x % 4] for x in self._state['running']) ) diff --git a/framework/profile.py b/framework/profile.py index e8e8ba1..037697f 100644 --- a/framework/profile.py +++ b/framework/profile.py @@ -26,13 +26,12 @@ are represented by a TestProfile or a TestProfile derived object. """ -from __future__ import print_function, absolute_import + import os import sys import multiprocessing import multiprocessing.dummy import importlib -import types import contextlib import itertools @@ -67,11 +66,11 @@ class TestDict(dict): # pylint: disable=too-few-public-methods filesystems. """ - assert isinstance(key, basestring), \ + assert isinstance(key, str), \ "Keys must be strings, but was {}".format(type(key)) # None is required to make empty assignment work: # foo = Tree['a'] - assert isinstance(value, (Test, types.NoneType)), \ + assert isinstance(value, (Test, type(None))), \ "Values must be either a Test, but was {}".format(type(value)) super(TestDict, self).__setitem__(key.lower(), value) @@ -154,7 +153,7 @@ class TestProfile(object): return True # Filter out unwanted tests - self.test_list = dict(item for item in self.test_list.iteritems() + self.test_list = dict(item for item in self.test_list.items() if check_all(item)) if not self.test_list: @@ -231,15 +230,15 @@ class TestProfile(object): multi = multiprocessing.dummy.Pool() if opts.concurrent == "all": - run_threads(multi, self.test_list.iteritems()) + run_threads(multi, iter(self.test_list.items())) elif opts.concurrent == "none": - run_threads(single, self.test_list.iteritems()) + run_threads(single, iter(self.test_list.items())) else: # Filter and return only thread safe tests to the threaded pool - run_threads(multi, (x for x in self.test_list.iteritems() + run_threads(multi, (x for x in self.test_list.items() if x[1].run_concurrent)) # Filter and return the non thread safe tests to the single pool - run_threads(single, (x for x in self.test_list.iteritems() + run_threads(single, (x for x in self.test_list.items() if not x[1].run_concurrent)) log.get().summary() @@ -305,7 +304,7 @@ class TestProfile(object): ... g(['power', 'test'], 'powertest') """ - assert isinstance(group, basestring), type(group) + assert isinstance(group, str), type(group) def adder(args, name=None, **kwargs): """Helper function that actually adds the tests. @@ -325,13 +324,13 @@ class TestProfile(object): if not name: lgroup = grouptools.join(group, ' '.join(args)) else: - assert isinstance(name, basestring) + assert isinstance(name, str) lgroup = grouptools.join(group, name) self.test_list[lgroup] = test_class( args, - **{k:v for k, v in itertools.chain(default_args.iteritems(), - kwargs.iteritems())}) + **{k:v for k, v in itertools.chain(default_args.items(), + kwargs.items())}) yield adder diff --git a/framework/programs/run.py b/framework/programs/run.py index 8be6439..062f0ac 100644 --- a/framework/programs/run.py +++ b/framework/programs/run.py @@ -20,13 +20,13 @@ # DEALINGS IN THE SOFTWARE. -from __future__ import print_function + import argparse import sys import os import os.path as path import time -import ConfigParser +import configparser import ctypes import framework.core as core @@ -65,7 +65,7 @@ def _default_platform(): file=sys.stderr) sys.exit(1) return plat - except (ConfigParser.NoOptionError, ConfigParser.NoSectionError): + except (configparser.NoOptionError, configparser.NoSectionError): return 'mixed_glx_egl' @@ -84,7 +84,7 @@ def _default_backend(): file=sys.stderr) sys.exit(1) return backend - except (ConfigParser.NoOptionError, ConfigParser.NoSectionError): + except (configparser.NoOptionError, configparser.NoSectionError): return 'json' @@ -337,7 +337,7 @@ def resume(input_): file_start_count=len(results.tests) + 1) # Specifically do not initialize again, everything initialize does is done. - for name in results.tests.iterkeys(): + for name in results.tests.keys(): opts.exclude_tests.add(name) profile = framework.profile.merge_test_profiles(results.options['profile']) diff --git a/framework/programs/summary.py b/framework/programs/summary.py index a273918..674bfe0 100644 --- a/framework/programs/summary.py +++ b/framework/programs/summary.py @@ -153,7 +153,7 @@ def csv(input_): testrun = framework.results.load_results(args.testResults) def write_results(output): - for name, result in testrun.tests.iteritems(): + for name, result in testrun.tests.items(): output.write("{},{},{},{}\n".format(name, result['time'], result['returncode'], result['result'])) diff --git a/framework/results.py b/framework/results.py index 961376f..501bf98 100644 --- a/framework/results.py +++ b/framework/results.py @@ -21,7 +21,7 @@ """ Module for results generation """ -from __future__ import print_function, absolute_import + import os import sys @@ -66,7 +66,7 @@ class TestResult(dict): """ def update(d, u, check): - for k, v in u.iteritems(): + for k, v in u.items(): if isinstance(v, dict): d[k] = update(d.get(k, {}), v, True) else: @@ -119,8 +119,8 @@ class TestrunResult(object): def write(self, file_): """ Write only values of the serialized_keys out to file """ with open(file_, 'w') as f: - json.dump(dict((k, v) for k, v in self.__dict__.iteritems() - if k in self.serialized_keys), + json.dump({k: v for k, v in self.__dict__.items() + if k in self.serialized_keys}, f, default=piglit_encoder, indent=JSONBackend.INDENT) @classmethod @@ -130,7 +130,7 @@ class TestrunResult(object): result.results_version = 0 result.__dict__.update(json.load(results_file)) - for key, value in result.tests.iteritems(): + for key, value in result.tests.items(): result.tests[key] = TestResult.load(value) return result @@ -172,7 +172,7 @@ class TestrunResult(object): continue # XXX: There has to be a better way to get a single key: value out # of a dict even when the key name isn't known - for key, value in test.iteritems(): + for key, value in test.items(): testrun.tests[key] = TestResult.load(value) return testrun @@ -291,7 +291,7 @@ def _update_zero_to_one(results): updated_results = {} remove = set() - for name, test in results.tests.iteritems(): + for name, test in results.tests.items(): # fix dmesg errors if any if isinstance(test.get('dmesg'), list): test['dmesg'] = '\n'.join(test['dmesg']) @@ -340,7 +340,7 @@ def _update_zero_to_one(results): # # this must be the last thing done in this loop, or there will be pain if test.get('subtest'): - for sub in test['subtest'].iterkeys(): + for sub in test['subtest'].keys(): # adding the leading / ensures that we get exactly what we # expect, since endswith does a character by chacter match, if # the subtest name is duplicated it wont match, and if there diff --git a/framework/status.py b/framework/status.py index 9af2ce6..e6eb7c5 100644 --- a/framework/status.py +++ b/framework/status.py @@ -55,7 +55,7 @@ The formula for determining fixes is: """ -from __future__ import print_function, absolute_import + __all__ = ['NOTRUN', 'PASS', @@ -160,9 +160,6 @@ class Status(object): def __str__(self): return str(self.name) - def __unicode__(self): - return unicode(self.name) - def __lt__(self, other): return not self.__ge__(other) @@ -174,8 +171,8 @@ class Status(object): # the __int__ magic method if isinstance(other, (int, Status)): return int(self) == int(other) - elif isinstance(other, (str, unicode)): - return unicode(self) == unicode(other) + elif isinstance(other, str): + return str(self) == str(other) raise TypeError("Cannot compare type: {}".format(type(other))) def __ne__(self, other): @@ -203,13 +200,13 @@ class NoChangeStatus(Status): super(NoChangeStatus, self).__init__(name, value, fraction) def __eq__(self, other): - if isinstance(other, (str, unicode, Status)): - return unicode(self) == unicode(other) + if isinstance(other, (str, Status)): + return str(self) == str(other) raise TypeError("Cannot compare type: {}".format(type(other))) def __ne__(self, other): - if isinstance(other, (str, unicode, Status)): - return unicode(self) != unicode(other) + if isinstance(other, (str, Status)): + return str(self) != str(other) raise TypeError("Cannot compare type: {}".format(type(other))) diff --git a/framework/summary.py b/framework/summary.py index 619d4f5..0f47e47 100644 --- a/framework/summary.py +++ b/framework/summary.py @@ -19,7 +19,7 @@ # OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. -from __future__ import print_function, absolute_import + import os import os.path as path import itertools @@ -99,7 +99,7 @@ class HTMLIndex(list): if open == close: return [], [] else: - for i, j in itertools.izip_longest(open, close): + for i, j in itertools.zip_longest(open, close): if i != j: for k in common: open.remove(k) @@ -335,7 +335,7 @@ class Summary: # loop will cause a RuntimeError temp_results = {} - for key, value in results.tests.iteritems(): + for key, value in results.tests.items(): # if the first character of key is a / then our while loop will # become an infinite loop. Beyond that / should never be the # leading character, if it is then there is a bug in one of the @@ -346,7 +346,7 @@ class Summary: # subtests' statuses and fractions down to the test, and then # proceed like normal. if 'subtest' in value: - for (subt, subv) in value['subtest'].iteritems(): + for (subt, subv) in value['subtest'].items(): subt = grouptools.join(key, subt) subv = so.status_lookup(subv) @@ -380,7 +380,7 @@ class Summary: # Update the the results.tests dictionary with the subtests so that # they are entered into the appropriate pages other than all. # Updating it in the loop will raise a RuntimeError - for key, value in temp_results.iteritems(): + for key, value in temp_results.items(): results.tests[key] = value # Create the lists of statuses like problems, regressions, fixes, @@ -403,7 +403,7 @@ class Summary: self.tests['skipped'].add(test) # find fixes, regressions, and changes - for i in xrange(len(status) - 1): + for i in range(len(status) - 1): first = status[i] last = status[i + 1] if first in [so.SKIP, so.NOTRUN] and last not in [so.SKIP, so.NOTRUN]: @@ -428,7 +428,7 @@ class Summary: 'timeout': 0, 'warn': 0, 'dmesg-warn': 0, 'dmesg-fail': 0} - for test in results.tests.itervalues(): + for test in results.tests.values(): self.totals[str(test['result'])] += 1 def generate_html(self, destination, exclude): @@ -473,16 +473,17 @@ class Summary: self.__find_totals(each) with open(path.join(destination, name, "index.html"), 'w') as out: - out.write(testindex.render(name=each.name, - totals=self.totals, - time=time, - options=each.options, - uname=each.uname, - glxinfo=each.glxinfo, - lspci=each.lspci)) + out.write(testindex.render_unicode( + name=each.name, + totals=self.totals, + time=time, + options=each.options, + uname=each.uname, + glxinfo=each.glxinfo, + lspci=each.lspci)) # Then build the individual test results - for key, value in each.tests.iteritems(): + for key, value in each.tests.items(): html_path = path.join(destination, name, escape_filename(key + ".html")) temp_path = path.dirname(html_path) @@ -497,7 +498,7 @@ class Summary: value['time'] = datetime.timedelta(0, value['time']) with open(html_path, 'w') as out: - out.write(testfile.render( + out.write(testfile.render_unicode( testname=key, value=value, css=path.relpath(result_css, temp_path), @@ -519,26 +520,29 @@ class Summary: # alltests, where the other pages all use the same name. ie, # changes.html, self.changes, and page=changes. with open(path.join(destination, "index.html"), 'w') as out: - out.write(index.render(results=HTMLIndex(self, self.tests['all']), - page='all', - pages=pages, - colnum=len(self.results), - exclude=exclude)) + out.write(index.render_unicode( + results=HTMLIndex(self, self.tests['all']), + page='all', + pages=pages, + colnum=len(self.results), + exclude=exclude)) # Generate the rest of the pages for page in pages: with open(path.join(destination, page + '.html'), 'w') as out: # If there is information to display display it if self.tests[page]: - out.write(index.render(results=HTMLIndex(self, - self.tests[page]), - pages=pages, - page=page, - colnum=len(self.results), - exclude=exclude)) + out.write(index.render_unicode( + results=HTMLIndex(self, self.tests[page]), + pages=pages, + page=page, + colnum=len(self.results), + exclude=exclude)) # otherwise provide an empty page else: - out.write(empty_status.render(page=page, pages=pages)) + out.write(empty_status.render_unicode( + page=page, + pages=pages)) def generate_text(self, diff, summary): """ Write summary information to the console """ @@ -571,6 +575,6 @@ class Summary: print(" changes: {changes}\n" " fixes: {fixes}\n" "regressions: {regressions}".format( - **dict((k, len(v)) for k, v in self.tests.iteritems()))) + **{k: len(v) for k, v in self.tests.items()})) - print(" total: {}".format(sum(self.totals.itervalues()))) + print(" total: {}".format(sum(self.totals.values()))) diff --git a/framework/test/__init__.py b/framework/test/__init__.py index a9b5f4e..1de27e6 100644 --- a/framework/test/__init__.py +++ b/framework/test/__init__.py @@ -24,7 +24,7 @@ # create a general use API, but allow it to be controlled by setting the # __all__ in each module -from __future__ import print_function, absolute_import + from .base import * from .piglit_test import * from .gleantest import * diff --git a/framework/test/base.py b/framework/test/base.py index efc20cb..23fd522 100644 --- a/framework/test/base.py +++ b/framework/test/base.py @@ -22,7 +22,7 @@ """ Module provides a base class for Tests """ -from __future__ import print_function, absolute_import + import errno import os import subprocess @@ -96,7 +96,7 @@ class ProcessTimeout(threading.Thread): return self.status -class Test(object): +class Test(object, metaclass=abc.ABCMeta): """ Abstract base class for Test classes This class provides the framework for running tests, with several methods @@ -116,7 +116,6 @@ class Test(object): """ OPTS = Options() - __metaclass__ = abc.ABCMeta __slots__ = ['run_concurrent', 'env', 'result', 'cwd', '_command', '_test_hook_execute_run', '__proc_timeout'] timeout = 0 @@ -196,7 +195,7 @@ class Test(object): self.result['command'] = ' '.join(self.command) self.result['environment'] = " ".join( '{0}="{1}"'.format(k, v) for k, v in itertools.chain( - self.OPTS.env.iteritems(), self.env.iteritems())) + iter(self.OPTS.env.items()), iter(self.env.items()))) if self.is_skip(): self.result['result'] = 'skip' @@ -213,7 +212,7 @@ class Test(object): self.interpret_result() - if self.result['returncode'] < 0: + if self.result['returncode'] is not None and self.result['returncode'] < 0: # check if the process was terminated by the timeout if self.timeout > 0 and self.__proc_timeout.join() > 0: self.result['result'] = 'timeout' @@ -273,9 +272,9 @@ class Test(object): # requirements. # fullenv = dict() - for key, value in itertools.chain(os.environ.iteritems(), - self.OPTS.env.iteritems(), - self.env.iteritems()): + for key, value in itertools.chain(iter(os.environ.items()), + iter(self.OPTS.env.items()), + iter(self.env.items())): fullenv[key] = str(value) # preexec_fn is not supported on Windows platforms @@ -317,22 +316,9 @@ class Test(object): else: raise e - # proc.communicate() returns 8-bit strings, but we need - # unicode strings. In Python 2.x, this is because we - # will eventually be serializing the strings as JSON, - # and the JSON library expects unicode. In Python 3.x, - # this is because all string operations require - # unicode. So translate the strings into unicode, - # assuming they are using UTF-8 encoding. - # - # If the subprocess output wasn't properly UTF-8 - # encoded, we don't want to raise an exception, so - # translate the strings using 'replace' mode, which - # replaces erroneous charcters with the Unicode - # "replacement character" (a white question mark inside - # a black diamond). - self.result['out'] = out.decode('utf-8', 'replace') - self.result['err'] = err.decode('utf-8', 'replace') + # Popen returns bytes, but the rest of the code assumes unicode + self.result['out'] = str(out) + self.result['err'] = str(err) self.result['returncode'] = returncode return error @@ -358,7 +344,7 @@ class WindowResizeMixin(object): Test.run() to return early. """ - for _ in xrange(5): + for _ in range(5): err = super(WindowResizeMixin, self)._run_command() if err: return err @@ -370,7 +356,7 @@ class WindowResizeMixin(object): # add a message about why, and return True so that the test will exit # early self.result['result'] = 'fail' - self.result['err'] = unicode() - self.result['out'] = unicode('Got spurious resize more than 5 times') + self.result['err'] = str() + self.result['out'] = str('Got spurious resize more than 5 times') self.result['returncode'] = None return True diff --git a/framework/test/gleantest.py b/framework/test/gleantest.py index de43857..19776ba 100644 --- a/framework/test/gleantest.py +++ b/framework/test/gleantest.py @@ -22,7 +22,7 @@ """ Glean support """ -from __future__ import print_function, absolute_import + import os from .base import Test from .piglit_test import TEST_BIN_DIR diff --git a/framework/test/glsl_parser_test.py b/framework/test/glsl_parser_test.py index 0ab3b0e..3248003 100644 --- a/framework/test/glsl_parser_test.py +++ b/framework/test/glsl_parser_test.py @@ -21,7 +21,7 @@ """ This module enables the running of GLSL parser tests. """ -from __future__ import print_function, absolute_import + import os import re import sys @@ -76,7 +76,7 @@ class GLSLParserTest(PiglitBaseTest): command = self.__get_command(self.__parser(testfile, filepath), filepath) except GLSLParserInternalError as e: - print(e.message, file=sys.stderr) + print(e.args[0], file=sys.stderr) sys.exit(1) super(GLSLParserTest, self).__init__(command, run_concurrent=True) diff --git a/framework/test/gtest.py b/framework/test/gtest.py index cd80871..9cf2390 100644 --- a/framework/test/gtest.py +++ b/framework/test/gtest.py @@ -22,7 +22,7 @@ # Authors: Tom Stellard <[email protected]> # -from __future__ import print_function, absolute_import + import re from .base import Test diff --git a/framework/test/oclconform.py b/framework/test/oclconform.py index 8186f5f..9b391b8 100644 --- a/framework/test/oclconform.py +++ b/framework/test/oclconform.py @@ -22,7 +22,7 @@ # Authors: Tom Stellard <[email protected]> # -from __future__ import print_function, print_function + import re import subprocess from os.path import join diff --git a/framework/test/opencv.py b/framework/test/opencv.py index 157102e..93fcba9 100644 --- a/framework/test/opencv.py +++ b/framework/test/opencv.py @@ -22,7 +22,7 @@ # Authors: Tom Stellard <[email protected]> # -from __future__ import print_function, absolute_import + import re import subprocess from os import path diff --git a/framework/test/piglit_test.py b/framework/test/piglit_test.py index 5dd2de6..95f791d 100644 --- a/framework/test/piglit_test.py +++ b/framework/test/piglit_test.py @@ -22,7 +22,7 @@ """ Module provides a base class for Tests """ -from __future__ import print_function, absolute_import + import os import sys import glob diff --git a/framework/tests/backends_tests.py b/framework/tests/backends_tests.py index b43302a..82461a3 100644 --- a/framework/tests/backends_tests.py +++ b/framework/tests/backends_tests.py @@ -22,7 +22,7 @@ """ Tests for the backend package """ -from __future__ import print_function, absolute_import + import os try: @@ -75,7 +75,7 @@ def test_get_backend(): check = lambda n, i: nt.assert_is(backends.get_backend(n), i) - for name, inst in backends_.iteritems(): + for name, inst in backends_.items(): check.description = 'get_backend({0}) returns {0} backend'.format(name) yield check, name, inst diff --git a/framework/tests/base_tests.py b/framework/tests/base_tests.py index f4b4ad6..6d99a76 100644 --- a/framework/tests/base_tests.py +++ b/framework/tests/base_tests.py @@ -20,7 +20,7 @@ """ Tests for the exectest module """ -from __future__ import print_function, absolute_import + import nose.tools as nt diff --git a/framework/tests/core_tests.py b/framework/tests/core_tests.py index 56c7ac3..3f085d4 100644 --- a/framework/tests/core_tests.py +++ b/framework/tests/core_tests.py @@ -20,11 +20,11 @@ """ Module providing tests for the core module """ -from __future__ import print_function, absolute_import + import os import collections import shutil -import ConfigParser +import configparser import textwrap import nose.tools as nt @@ -66,7 +66,7 @@ class GetConfigFixture(object): if os.path.exists('piglit.conf'): shutil.move('piglit.conf', 'piglit.conf.restore') self.restore = True - core.PIGLIT_CONFIG = ConfigParser.SafeConfigParser( + core.PIGLIT_CONFIG = configparser.SafeConfigParser( allow_no_value=True) except Exception as e: raise utils.UtilsError(e) @@ -82,7 +82,7 @@ class GetConfigFixture(object): if self.restore: shutil.move('piglit.conf.restore', 'piglit.conf') - core.PIGLIT_CONFIG = ConfigParser.SafeConfigParser( + core.PIGLIT_CONFIG = configparser.SafeConfigParser( allow_no_value=True) except Exception as e: raise utils.UtilsError(e) @@ -90,7 +90,7 @@ class GetConfigFixture(object): def _reset_piglit_config(): """ Set core.PIGLIT_CONFIG back to pristine """ - core.PIGLIT_CONFIG = ConfigParser.SafeConfigParser() + core.PIGLIT_CONFIG = configparser.SafeConfigParser() def check_initialize(target): @@ -126,7 +126,7 @@ def test_parse_listfile_return(): should return a list of files with no whitespace """ - contents = "/tmp/foo\n/tmp/bar\n" + contents = b"/tmp/foo\n/tmp/bar\n" with utils.with_tempfile(contents) as tfile: results = core.parse_listfile(tfile) @@ -141,7 +141,7 @@ def check_whitespace(actual, base, message): def test_parse_listfile_whitespace(): """ Test that parse_listfile remove whitespace """ - contents = "/tmp/foo\n/tmp/foo \n/tmp/foo\t\n" + contents = b"/tmp/foo\n/tmp/foo \n/tmp/foo\t\n" with utils.with_tempfile(contents) as tfile: results = core.parse_listfile(tfile) @@ -171,7 +171,7 @@ def test_parse_listfile_tilde(): *BSD, OSX) and Windows. """ - contents = "~/foo\n" + contents = b"~/foo\n" with utils.with_tempfile(contents) as tfile: results = core.parse_listfile(tfile) diff --git a/framework/tests/dmesg_tests.py b/framework/tests/dmesg_tests.py index 9a7fef9..4425e52 100644 --- a/framework/tests/dmesg_tests.py +++ b/framework/tests/dmesg_tests.py @@ -25,7 +25,7 @@ don't want to run them use '-e sudo' with nosetests """ -from __future__ import print_function, absolute_import + import os import sys import subprocess @@ -192,9 +192,10 @@ def test_dmesg_wrap_partial(): test.DMESG_COMMAND = ['echo', 'b\nc\nd\n'] test.update_dmesg() - nt.assert_items_equal(test._new_messages, ['d'], - msg=("_new_messages should be equal to ['d'], but is" - " {} instead.".format(test._new_messages))) + nt.ok_( + test._new_messages == [b'd'], + msg=("_new_messages should be equal to ['d'], but is {} instead.".format( + test._new_messages))) def test_dmesg_wrap_complete(): @@ -215,10 +216,9 @@ def test_dmesg_wrap_complete(): test.DMESG_COMMAND = ['echo', '1\n2\n3\n'] test.update_dmesg() - nt.assert_items_equal(test._new_messages, ['1', '2', '3'], - msg=("_new_messages should be equal to " - "['1', '2', '3'], but is {} instead".format( - test._new_messages))) + nt.ok_(test._new_messages == [b'1', b'2', b'3'], + msg=("_new_messages should be equal to ['1', '2', '3'], " + "but is {} instead".format(test._new_messages))) @utils.nose_generator diff --git a/framework/tests/gleantest_tests.py b/framework/tests/gleantest_tests.py index 26872b0..3cee914 100644 --- a/framework/tests/gleantest_tests.py +++ b/framework/tests/gleantest_tests.py @@ -20,7 +20,7 @@ """ Tests for the glean class. Requires Nose """ -from __future__ import print_function, absolute_import + from framework.test import GleanTest diff --git a/framework/tests/glsl_parser_test_tests.py b/framework/tests/glsl_parser_test_tests.py index eb0f9bd..bb0946d 100644 --- a/framework/tests/glsl_parser_test_tests.py +++ b/framework/tests/glsl_parser_test_tests.py @@ -20,7 +20,7 @@ """ Provides tests for the shader_test module """ -from __future__ import print_function, absolute_import + import sys import os @@ -42,24 +42,21 @@ def _check_config(content): return glsl.GLSLParserTest(tfile), tfile [email protected](glsl.GLSLParserNoConfigError) def test_no_config_start(): """ GLSLParserTest requires [config] """ - content = ('// expect_result: pass\n' - '// glsl_version: 1.00\n' - '// [end config]\n') + content = (b'// expect_result: pass\n' + b'// glsl_version: 1.00\n' + b'// [end config]\n') with utils.with_tempfile(content) as tfile: - with nt.assert_raises(glsl.GLSLParserNoConfigError) as exc: - glsl.GLSLParserTest(tfile) - nt.assert_equal( - exc.exception, 'No [config] section found!', - msg="No config section found, no exception raised") + glsl.GLSLParserTest(tfile) def test_find_config_start(): """ GLSLParserTest finds [config] """ - content = ('// [config]\n' - '// glsl_version: 1.00\n' - '//\n') + content = (b'// [config]\n' + b'// glsl_version: 1.00\n' + b'//\n') with utils.with_tempfile(content) as tfile: with nt.assert_raises(SystemExit) as exc: glsl.GLSLParserTest(tfile) @@ -70,7 +67,7 @@ def test_find_config_start(): def test_no_config_end(): """ GLSLParserTest requires [end config] """ - with utils.with_tempfile('// [config]\n') as tfile: + with utils.with_tempfile(b'// [config]\n') as tfile: with nt.assert_raises(SystemExit) as exc: glsl.GLSLParserTest(tfile) nt.assert_equal( @@ -80,9 +77,9 @@ def test_no_config_end(): def test_no_expect_result(): """ expect_result section is required """ - content = ('// [config]\n' - '// glsl_version: 1.00\n' - '//\n') + content = (b'// [config]\n' + b'// glsl_version: 1.00\n' + b'//\n') with utils.with_tempfile(content) as tfile: with nt.assert_raises(SystemExit) as exc: glsl.GLSLParserTest(tfile) @@ -94,9 +91,9 @@ def test_no_expect_result(): def test_no_glsl_version(): """ glsl_version section is required """ - content = ('// [config]\n' - '// expect_result: pass\n' - '// [end config]\n') + content = (b'// [config]\n' + b'// expect_result: pass\n' + b'// [end config]\n') with utils.with_tempfile(content) as tfile: with nt.assert_raises(SystemExit) as exc: glsl.GLSLParserTest(tfile) @@ -108,10 +105,10 @@ def test_no_glsl_version(): def test_cpp_comments(): """ Parses C++ style comments """ - content = ('// [config]\n' - '// expect_result: pass\n' - '// glsl_version: 1.00\n' - '// [end config]\n') + content = (b'// [config]\n' + b'// expect_result: pass\n' + b'// glsl_version: 1.00\n' + b'// [end config]\n') test, name = _check_config(content) nt.assert_equal( @@ -121,12 +118,12 @@ def test_cpp_comments(): def test_c_comments(): """ Parses C style comments """ - content = ('/*\n' - ' * [config]\n' - ' * expect_result: pass\n' - ' * glsl_version: 1.00\n' - ' * [end config]\n' - ' */\n') + content = (b'/*\n' + b' * [config]\n' + b' * expect_result: pass\n' + b' * glsl_version: 1.00\n' + b' * [end config]\n' + b' */\n') test, name = _check_config(content) nt.assert_equal(test.command, [os.path.join(TEST_BIN_DIR, 'glslparsertest'), @@ -136,11 +133,11 @@ def test_c_comments(): def test_blank_in_config(): """ C++ style comments can have uncommented newlines """ - content = ('// [config]\n' - '\n' - '// expect_result: pass\n' - '// glsl_version: 1.00\n' - '// [end config]\n') + content = (b'// [config]\n' + b'\n' + b'// expect_result: pass\n' + b'// glsl_version: 1.00\n' + b'// [end config]\n') test, name = _check_config(content) @@ -152,11 +149,11 @@ def test_blank_in_config(): def test_empty_in_config(): """ C++ sytle comments can have blank commented lines """ - content = ('// [config]\n' - '//\n' - '// expect_result: pass\n' - '// glsl_version: 1.00\n' - '// [end config]\n') + content = (b'// [config]\n' + b'//\n' + b'// expect_result: pass\n' + b'// glsl_version: 1.00\n' + b'// [end config]\n') test, name = _check_config(content) @@ -183,19 +180,19 @@ def check_config_to_command(config, result): def test_config_to_command(): """ Generate tests that confirm the config file is correctly parsed """ content = [ - ('// [config]\n// expect_result: pass\n// glsl_version: 1.00\n// [end config]\n', + (b'// [config]\n// expect_result: pass\n// glsl_version: 1.00\n// [end config]\n', [os.path.join(TEST_BIN_DIR, 'glslparsertest'), 'pass', '1.00'], 'all required options'), - ('// [config]\n// expect_result: pass\n// glsl_version: 1.00\n//check_link: true\n// [end config]\n', + (b'// [config]\n// expect_result: pass\n// glsl_version: 1.00\n//check_link: true\n// [end config]\n', [os.path.join(TEST_BIN_DIR, 'glslparsertest'), 'pass', '1.00', '--check-link'], 'check_link true'), - ('// [config]\n// expect_result: pass\n// glsl_version: 1.00\n//check_link: false\n// [end config]\n', + (b'// [config]\n// expect_result: pass\n// glsl_version: 1.00\n//check_link: false\n// [end config]\n', [os.path.join(TEST_BIN_DIR, 'glslparsertest'), 'pass', '1.00'], 'check_link false'), - ('// [config]\n// expect_result: pass\n// glsl_version: 1.00\n//require_extensions: ARB_foo\n// [end config]\n', + (b'// [config]\n// expect_result: pass\n// glsl_version: 1.00\n//require_extensions: ARB_foo\n// [end config]\n', [os.path.join(TEST_BIN_DIR, 'glslparsertest'), 'pass', '1.00', 'ARB_foo'], 'one required_extension'), - ('// [config]\n// expect_result: pass\n// glsl_version: 1.00\n//require_extensions: ARB_foo ARB_bar\n// [end config]\n', + (b'// [config]\n// expect_result: pass\n// glsl_version: 1.00\n//require_extensions: ARB_foo ARB_bar\n// [end config]\n', [os.path.join(TEST_BIN_DIR, 'glslparsertest'), 'pass', '1.00', 'ARB_foo', 'ARB_bar'], 'multiple required_extensions'), ] @@ -208,11 +205,11 @@ def test_config_to_command(): def test_bad_section_name(): """ A section name not in the _CONFIG_KEYS name raises an error """ - content = ('// [config]\n' - '// expect_result: pass\n' - '// glsl_version: 1.00\n' - '// new_awesome_key: foo\n' - '// [end config]\n') + content = (b'// [config]\n' + b'// expect_result: pass\n' + b'// glsl_version: 1.00\n' + b'// new_awesome_key: foo\n' + b'// [end config]\n') with utils.with_tempfile(content) as tfile: with nt.assert_raises(SystemExit) as e: @@ -225,12 +222,12 @@ def test_bad_section_name(): def test_good_section_names(): """ A section name in the _CONFIG_KEYS does not raise an error """ - content = ('// [config]\n' - '// expect_result: pass\n' - '// glsl_version: 1.00\n' - '// require_extensions: EXT_foo\n' - '// check_link: True\n' - '// [end config]\n') + content = (b'// [config]\n' + b'// expect_result: pass\n' + b'// glsl_version: 1.00\n' + b'// require_extensions: EXT_foo\n' + b'// check_link: True\n' + b'// [end config]\n') try: _check_config(content) @@ -261,8 +258,8 @@ def test_duplicate_entries(): for name, value in content: check_no_duplicates.description = \ "duplicate values of {0} raise an exception".format(name) - test = '// [config]\n{0}{1}// [end config]'.format( - ''.join(x[1] for x in content), value) + test = bytes('// [config]\n{0}{1}// [end config]'.format( + ''.join(x[1] for x in content), value), encoding='utf-8') yield check_no_duplicates, test, name @@ -300,7 +297,7 @@ def glslparser_exetensions_seperators(): '// [end config]\n') for name, value in problems: - test = content.format(value) + test = bytes(content.format(value), encoding='utf-8') with utils.with_tempfile(test) as tfile: check_bad_character.description = ( 'require_extensions: {0} should raise an error'.format(name)) @@ -332,7 +329,7 @@ def test_good_extensions(): ] for x in options: - test = content.format(x) + test = bytes(content.format(x), encoding='utf-8') check_good_extension.description = \ 'require_extension {} is valid'.format(x) diff --git a/framework/tests/grouptools_tests.py b/framework/tests/grouptools_tests.py index 94f44af..f55bc08 100644 --- a/framework/tests/grouptools_tests.py +++ b/framework/tests/grouptools_tests.py @@ -20,7 +20,7 @@ """Module with tests for grouptools.""" -from __future__ import print_function + import inspect import nose.tools as nt @@ -104,7 +104,7 @@ class _GroupToolsTest(_SharedFunctionTest): @nt.raises(AssertionError) def test_assertion_slash(self): """Test that a leading / is an error.""" - if isinstance(self.input, (str, unicode)): + if isinstance(self.input, str): self.function('/' + self.input) elif not self.explode: self.function(['/' + i for i in self.input]) @@ -115,7 +115,7 @@ class _GroupToolsTest(_SharedFunctionTest): @nt.raises(AssertionError) def test_assertion_backslash(self): """Test that \\ in a group is an error.""" - if isinstance(self.input, (str, unicode)): + if isinstance(self.input, str): self.function(self.input.replace('/', '\\')) elif not self.explode: self.function(i.replace('/', '\\') for i in self.input) diff --git a/framework/tests/gtest_tests.py b/framework/tests/gtest_tests.py index 2a90cf9..13a5500 100644 --- a/framework/tests/gtest_tests.py +++ b/framework/tests/gtest_tests.py @@ -20,7 +20,7 @@ """ Module providing tests for gtest """ -from __future__ import print_function, absolute_import + from framework.test import GTest diff --git a/framework/tests/integration_tests.py b/framework/tests/integration_tests.py index 0971eb3..50166ad 100644 --- a/framework/tests/integration_tests.py +++ b/framework/tests/integration_tests.py @@ -26,9 +26,9 @@ errors and to ensure that the API hasn't changed without fixing these modules """ -from __future__ import print_function, absolute_import + import importlib -import ConfigParser +import configparser from nose.plugins.skip import SkipTest @@ -36,7 +36,7 @@ import framework.core def setup_module(): - framework.core.PIGLIT_CONFIG = ConfigParser.SafeConfigParser( + framework.core.PIGLIT_CONFIG = configparser.SafeConfigParser( allow_no_value=True) framework.core.get_config() @@ -51,7 +51,7 @@ def _import(name): """ try: return importlib.import_module(name) - except (ConfigParser.NoOptionError, ConfigParser.NoSectionError): + except (configparser.NoOptionError, configparser.NoSectionError): raise SkipTest('No config section for {}'.format(name)) except SystemExit as e: if e.code == 0: diff --git a/framework/tests/json_tests.py b/framework/tests/json_tests.py index 70a501a..ba5b51e 100644 --- a/framework/tests/json_tests.py +++ b/framework/tests/json_tests.py @@ -26,7 +26,7 @@ tests and they will change with each version of the json output. """ -from __future__ import print_function, absolute_import + import os import nose.tools as nt diff --git a/framework/tests/log_tests.py b/framework/tests/log_tests.py index 3532b6e..42f22bf 100644 --- a/framework/tests/log_tests.py +++ b/framework/tests/log_tests.py @@ -20,7 +20,7 @@ """ Module provides tests for log.py module """ -from __future__ import print_function, absolute_import + import sys import collections @@ -137,7 +137,7 @@ def check_no_output(func, args, file_=sys.stdout): file_.truncate() func(*args) - file_.seek(-1) + file_.seek(0, 2) assert file_.tell() == 0, 'file.tell() is at {}'.format(file_.tell()) diff --git a/framework/tests/opencv_tests.py b/framework/tests/opencv_tests.py index 82e0ac5..bb54c5f 100644 --- a/framework/tests/opencv_tests.py +++ b/framework/tests/opencv_tests.py @@ -20,7 +20,7 @@ """ Module for testing opencv """ -from __future__ import print_function, absolute_import + from framework.test import OpenCVTest diff --git a/framework/tests/piglit_test_tests.py b/framework/tests/piglit_test_tests.py index 764a9c6..dc38325 100644 --- a/framework/tests/piglit_test_tests.py +++ b/framework/tests/piglit_test_tests.py @@ -20,7 +20,7 @@ """ Tests for the exectest module """ -from __future__ import print_function, absolute_import + import nose.tools as nt diff --git a/framework/tests/results_tests.py b/framework/tests/results_tests.py index 6d90990..af95e53 100644 --- a/framework/tests/results_tests.py +++ b/framework/tests/results_tests.py @@ -21,7 +21,7 @@ """ Module providing tests for the core module """ -from __future__ import print_function, absolute_import + import os import json @@ -156,7 +156,7 @@ def test_update_results_old(): def test_resume_non_folder(): """ TestrunResult.resume doesn't accept a file """ - with utils.with_tempfile('') as f: + with utils.with_tempfile(b'') as f: with nt.assert_raises(AssertionError): results.TestrunResult.resume(f) diff --git a/framework/tests/results_v0_tests.py b/framework/tests/results_v0_tests.py index ff01339..d225ce5 100644 --- a/framework/tests/results_v0_tests.py +++ b/framework/tests/results_v0_tests.py @@ -20,7 +20,7 @@ """ Module provides tests for converting version zero results to version 1 """ -from __future__ import print_function, absolute_import + import os import json import copy @@ -117,7 +117,7 @@ DATA['tests'].update({ }, }) -with utils.with_tempfile(json.dumps(DATA)) as t: +with utils.with_tempfile(bytes(json.dumps(DATA), encoding='ascii')) as t: with open(t, 'r') as f: RESULT = results._update_zero_to_one(results.TestrunResult.load(f)) @@ -147,7 +147,7 @@ def test_subtests_test_is_testresult(): def test_info_delete(): """ Version 1: Remove the info name from results """ - for value in RESULT.tests.itervalues(): + for value in RESULT.tests.values(): assert 'info' not in value @@ -206,7 +206,7 @@ def test_info_split(): data['tests']['sometest']['info'] = \ 'Returncode: 1\n\nErrors:stderr\n\nOutput: stdout\n\nmore\n\nstuff' - with utils.with_tempfile(json.dumps(data)) as t: + with utils.with_tempfile(bytes(json.dumps(data), encoding='ascii')) as t: with open(t, 'r') as f: results._update_zero_to_one(results.TestrunResult.load(f)) @@ -216,13 +216,13 @@ def test_subtests_with_slash(): expected = 'group2/groupA/test/subtest 1' nt.assert_not_in( - expected, RESULT.tests.iterkeys(), + expected, iter(RESULT.tests.keys()), msg='{0} found in result, when it should not be'.format(expected)) def test_handle_fixed_subtests(): """ Version 1: Correctly handle new single entry subtests correctly """ - assert 'group3/groupA/test' in RESULT.tests.iterkeys() + assert 'group3/groupA/test' in iter(RESULT.tests.keys()) def _load_with_update(data): @@ -232,7 +232,7 @@ def _load_with_update(data): """ try: - with utils.with_tempfile(json.dumps(data)) as t: + with utils.with_tempfile(bytes(json.dumps(data), encoding='ascii')) as t: result = results.load_results(t) except OSError as e: # There is the potential that the file will be renamed. In that event diff --git a/framework/tests/results_v1_tests.py b/framework/tests/results_v1_tests.py index 7ce8b92..49acfbe 100644 --- a/framework/tests/results_v1_tests.py +++ b/framework/tests/results_v1_tests.py @@ -20,7 +20,7 @@ """Tests for version 1 to version 2.""" -from __future__ import print_function, absolute_import + try: import simplejson as json @@ -71,7 +71,7 @@ class TestV2Update(object): } } - with utils.with_tempfile(json.dumps(data)) as t: + with utils.with_tempfile(bytes(json.dumps(data), encoding='ascii')) as t: with open(t, 'r') as f: cls.result = results._update_one_to_two( results.TestrunResult.load(f)) @@ -138,7 +138,7 @@ class TestV2NoUpdate(object): } } - with utils.with_tempfile(json.dumps(data)) as t: + with utils.with_tempfile(bytes(json.dumps(data), encoding='ascii')) as t: with open(t, 'r') as f: cls.result = results._update_one_to_two( results.TestrunResult.load(f)) diff --git a/framework/tests/results_v2_tests.py b/framework/tests/results_v2_tests.py index 3367ffb..b67ea84 100644 --- a/framework/tests/results_v2_tests.py +++ b/framework/tests/results_v2_tests.py @@ -76,7 +76,7 @@ DATA = { } } -with utils.with_tempfile(json.dumps(DATA)) as t: +with utils.with_tempfile(bytes(json.dumps(DATA), encoding='ascii')) as t: with open(t, 'r') as f: # pylint: disable=protected-access RESULT = results._update_two_to_three(results.TestrunResult.load(f)) diff --git a/framework/tests/results_v3_tests.py b/framework/tests/results_v3_tests.py index 21164b8..1795ee3 100644 --- a/framework/tests/results_v3_tests.py +++ b/framework/tests/results_v3_tests.py @@ -78,7 +78,7 @@ DATA = { def make_result(data): """Write data to a file and return a result.TestrunResult object.""" - with utils.with_tempfile(json.dumps(data)) as t: + with utils.with_tempfile(bytes(json.dumps(data), encoding='ascii')) as t: with open(t, 'r') as f: # pylint: disable=protected-access return results._update_three_to_four(results.TestrunResult.load(f)) diff --git a/framework/tests/run_parser_tests.py b/framework/tests/run_parser_tests.py index 77f60bb..73d1a6b 100644 --- a/framework/tests/run_parser_tests.py +++ b/framework/tests/run_parser_tests.py @@ -20,11 +20,11 @@ """ Module of tests for the run commandline parser """ -from __future__ import print_function, absolute_import + import sys import os import shutil -import ConfigParser +import configparser import nose.tools as nt @@ -108,7 +108,7 @@ class _Helpers(TestWithEnvClean): def setup(self): # Set core.PIGLIT_CONFIG back to pristine between tests - core.PIGLIT_CONFIG = ConfigParser.SafeConfigParser() + core.PIGLIT_CONFIG = configparser.SafeConfigParser() class TestBackend(_Helpers): diff --git a/framework/tests/shader_test_tests.py b/framework/tests/shader_test_tests.py index 7b06012..8004fe4 100644 --- a/framework/tests/shader_test_tests.py +++ b/framework/tests/shader_test_tests.py @@ -20,7 +20,7 @@ """ Provides tests for the shader_test module """ -from __future__ import print_function, absolute_import + import os import nose.tools as nt @@ -36,8 +36,8 @@ def test_initialize_shader_test(): def test_parse_gl_test_no_decimal(): """ The GL Parser raises an exception if GL version lacks decimal """ - data = ('[require]\n' - 'GL = 2\n') + data = (b'[require]\n' + b'GL = 2\n') with utils.with_tempfile(data) as temp: with nt.assert_raises(testm.ShaderTestParserException) as exc: testm.ShaderTest(temp) @@ -49,9 +49,9 @@ def test_parse_gl_test_no_decimal(): def test_parse_gles2_test(): """ Tests the parser for GLES2 tests """ - data = ('[require]\n' - 'GL ES >= 2.0\n' - 'GLSL ES >= 1.00\n') + data = (b'[require]\n' + b'GL ES >= 2.0\n' + b'GLSL ES >= 1.00\n') with utils.with_tempfile(data) as temp: test = testm.ShaderTest(temp) @@ -63,9 +63,9 @@ def test_parse_gles2_test(): def test_parse_gles3_test(): """ Tests the parser for GLES3 tests """ - data = ('[require]\n' - 'GL ES >= 3.0\n' - 'GLSL ES >= 3.00\n') + data = (b'[require]\n' + b'GL ES >= 3.0\n' + b'GLSL ES >= 3.00\n') with utils.with_tempfile(data) as temp: test = testm.ShaderTest(temp) diff --git a/framework/tests/status_tests.py b/framework/tests/status_tests.py index 52ad134..531017b 100644 --- a/framework/tests/status_tests.py +++ b/framework/tests/status_tests.py @@ -25,7 +25,7 @@ etc """ -from __future__ import print_function, absolute_import + import itertools import nose.tools as nt @@ -239,7 +239,6 @@ def test_nochangestatus_magic(): # generator equality tests for comp, type_ in [(obj, 'status.NoChangeStatus'), (stat, 'status.Status'), - (u'Test', 'unicode'), ('Test', 'str')]: check_operator_equal.description = ( 'Operator eq works with type: {0} on class ' @@ -262,7 +261,6 @@ def test_status_magic(): for func, name, result in [ (str, 'str', 'foo'), - (unicode, 'unicode', u'foo'), (repr, 'repr', 'foo'), (int, 'int', 0)]: check_operator.description = 'Operator {0} works on class {1}'.format( @@ -300,11 +298,11 @@ def test_status_eq_raises(): @nt.raises(TypeError) def test_nochangestatus_eq_raises(): - """ NoChangeStatus == !(str, unicode, Status) raises TypeError """ + """ NoChangeStatus == !(str, Status) raises TypeError """ status.NOTRUN == dict() @nt.raises(TypeError) def test_nochangestatus_ne_raises(): - """ NoChangeStatus != (str, unicode, Status) raises TypeError """ + """ NoChangeStatus != (str, Status) raises TypeError """ status.NOTRUN != dict() diff --git a/framework/tests/summary_tests.py b/framework/tests/summary_tests.py index 14fa5c2..1618d23 100644 --- a/framework/tests/summary_tests.py +++ b/framework/tests/summary_tests.py @@ -21,7 +21,7 @@ """ Module providing tests for the summary module """ -from __future__ import print_function, absolute_import + import copy try: @@ -73,8 +73,8 @@ def check_sets(old, ostat, new, nstat, set_): old['tests']['sometest']['result'] = ostat new['tests']['sometest']['result'] = nstat - with utils.with_tempfile(json.dumps(old)) as ofile: - with utils.with_tempfile(json.dumps(new)) as nfile: + with utils.with_tempfile(bytes(json.dumps(old), encoding='ascii')) as ofile: + with utils.with_tempfile(bytes(json.dumps(new), encoding='ascii')) as nfile: summ = summary.Summary([ofile, nfile]) print(summ.tests) @@ -95,7 +95,7 @@ def test_subtest_handling(): data['tests']['is_skip'] = {} data['tests']['is_skip']['result'] = 'skip' - with utils.with_tempfile(json.dumps(data)) as sumfile: + with utils.with_tempfile(bytes(json.dumps(data), encoding='ascii')) as sumfile: summ = summary.Summary([sumfile]) check_subtests_are_tests.description = \ diff --git a/framework/tests/test_lists.py b/framework/tests/test_lists.py index c96248b..969e24f 100644 --- a/framework/tests/test_lists.py +++ b/framework/tests/test_lists.py @@ -26,7 +26,7 @@ es3conform, etc) """ -from __future__ import print_function, absolute_import + import importlib import os.path as path diff --git a/framework/tests/utils.py b/framework/tests/utils.py index dc8af64..c0e28d2 100644 --- a/framework/tests/utils.py +++ b/framework/tests/utils.py @@ -25,7 +25,7 @@ in a single place. """ -from __future__ import print_function, absolute_import + import os import sys import shutil @@ -85,7 +85,7 @@ class UtilsError(Exception): def resultfile(): """ Create a stringio with some json in it and pass that as results """ with tempfile.NamedTemporaryFile(delete=False) as output: - json.dump(JSON_DATA, output) + output.write(bytes(json.dumps(JSON_DATA), encoding='utf-8')) yield output diff --git a/piglit b/piglit index 53a4bb4..bbd9522 100755 --- a/piglit +++ b/piglit @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 # Copyright (c) 2014 Intel Corporation diff --git a/piglit-print-commands.py b/piglit-print-commands.py index e32ec70..f54e1dc 100755 --- a/piglit-print-commands.py +++ b/piglit-print-commands.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation @@ -22,7 +22,7 @@ # DEALINGS IN THE SOFTWARE. -from __future__ import print_function + import argparse import sys import os diff --git a/piglit-resume.py b/piglit-resume.py index 6b78529..8af6665 100755 --- a/piglit-resume.py +++ b/piglit-resume.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 # Copyright (c) 2014 Intel Corporation diff --git a/piglit-run.py b/piglit-run.py index 4c0f878..93c0bcc 100755 --- a/piglit-run.py +++ b/piglit-run.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 # Copyright (c) 2014 Intel Corporation diff --git a/piglit-summary-html.py b/piglit-summary-html.py index 4b5278e..b9bb003 100755 --- a/piglit-summary-html.py +++ b/piglit-summary-html.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 # Copyright (c) 2014 Intel Corporation diff --git a/piglit-summary.py b/piglit-summary.py index d1294be..5a97806 100755 --- a/piglit-summary.py +++ b/piglit-summary.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 # Copyright (c) 2014 Intel Corporation diff --git a/templates/index.mako b/templates/index.mako index 1ca46d3..3aca903 100644 --- a/templates/index.mako +++ b/templates/index.mako @@ -31,7 +31,7 @@ ## Status columns ## Create an additional column for each summary - % for _ in xrange(colnum): + % for _ in range(colnum): <col /> % endfor </colgroup> diff --git a/templates/testrun_info.mako b/templates/testrun_info.mako index 9ff5022..30d77dd 100644 --- a/templates/testrun_info.mako +++ b/templates/testrun_info.mako @@ -21,10 +21,10 @@ <td>totals</td> <td> <table> - % for key, value in sorted(totals.iteritems(), key=lambda (k,v): (v,k), reverse=True): + % for key, value in sorted(totals.items(), key=lambda t: (t[1], t[0]), reverse=True): <tr><td>${key}</td><td>${value}</td></tr> % endfor - <tr><td>total</td><td>${sum(totals.itervalues())}</td></tr> + <tr><td>total</td><td>${sum(totals.values())}</td></tr> </table> </td> </tr> diff --git a/tests/all.py b/tests/all.py index dc73c77..0cfcd8e 100644 --- a/tests/all.py +++ b/tests/all.py @@ -1959,7 +1959,7 @@ with profile.group_manager( for stage, type_, comp, sampler in itertools.product( stages, types, comps, samplers): for func in ['textureGather'] if 'Cube' in sampler else ['textureGather', 'textureGatherOffset', 'textureGatherOffsets' ]: - for cs in xrange(len(comp)): + for cs in range(len(comp)): assert cs <= 3 address_mode = 'clamp' if sampler == '2DRect' else 'repeat' cmd = ['textureGather', stage, diff --git a/tests/cl.py b/tests/cl.py index 6e0eb6e..cc0a4a4 100644 --- a/tests/cl.py +++ b/tests/cl.py @@ -7,7 +7,7 @@ # invalid constant names, they're not really fixable, so just hide them. # pylint: disable=invalid-name -from __future__ import division, absolute_import, print_function + import os diff --git a/tests/deqp_gles3.py b/tests/deqp_gles3.py index 9b048f5..659f081 100644 --- a/tests/deqp_gles3.py +++ b/tests/deqp_gles3.py @@ -18,7 +18,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -import ConfigParser +import configparser import os import subprocess import xml.etree.cElementTree as ET @@ -68,9 +68,9 @@ def get_option(env_varname, config_option): try: opt = framework.core.PIGLIT_CONFIG.get(config_option[0], config_option[1]) - except ConfigParser.NoSectionError: + except configparser.NoSectionError: pass - except ConfigParser.NoOptionError: + except configparser.NoOptionError: pass return opt @@ -150,7 +150,7 @@ class DEQPTest(Test): for line in self.result['out'].split('\n'): line = line.lstrip() - for k, v in DEQPTest.__RESULT_MAP.iteritems(): + for k, v in DEQPTest.__RESULT_MAP.items(): if line.startswith(k): self.result['result'] = v return diff --git a/tests/igt.py b/tests/igt.py index bd4c70e..54ed25d 100644 --- a/tests/igt.py +++ b/tests/igt.py @@ -44,10 +44,10 @@ __all__ = ['profile'] def checkEnvironment(): debugfs_path = "/sys/kernel/debug/dri" if os.getuid() != 0: - print "Test Environment check: not root!" + print("Test Environment check: not root!") return False if not os.path.isdir(debugfs_path): - print "Test Environment check: debugfs not mounted properly!" + print("Test Environment check: debugfs not mounted properly!") return False for subdir in os.listdir(debugfs_path): if not os.path.isdir(os.path.join(debugfs_path, subdir)): @@ -55,10 +55,10 @@ def checkEnvironment(): clients = open(os.path.join(debugfs_path, subdir, "clients"), 'r') lines = clients.readlines() if len(lines) > 2: - print "Test Environment check: other drm clients running!" + print("Test Environment check: other drm clients running!") return False - print "Test Environment check: Succeeded." + print("Test Environment check: Succeeded.") return True if 'IGT_TEST_ROOT' in os.environ: @@ -71,7 +71,7 @@ else: # check for the test lists if not (os.path.exists(os.path.join(igtTestRoot, 'single-tests.txt')) and os.path.exists(os.path.join(igtTestRoot, 'multi-tests.txt'))): - print "intel-gpu-tools test lists not found." + print("intel-gpu-tools test lists not found.") sys.exit(0) @@ -138,7 +138,7 @@ def addSubTestCases(test): return if proc.returncode != 0: - print "Error: Could not list subtests for " + test + print("Error: Could not list subtests for " + test) return subtests = out.split("\n") diff --git a/tests/xts.py b/tests/xts.py index 0e277dc..5cd5161 100644 --- a/tests/xts.py +++ b/tests/xts.py @@ -23,7 +23,7 @@ """ Test integreation for the X Test Suite """ -from __future__ import print_function, division, absolute_import + import os import re import sys -- 2.3.1 _______________________________________________ Piglit mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/piglit
