[Piglit] [PATCH 2/2] framework/backends/json.py: preserve 'tests' order
Dylan Baker
dylan at pnwbakers.com
Thu Feb 9 16:52:24 UTC 2017
Quoting Tomi Sarvela (2017-02-09 03:07:05)
> New helper function numericlistdir() arranges the os.listdir()
> in numerical order and deduplicates the code: reading in is done
> in two places, finalize and _resume.
>
> Use OrderedDict when reading data in.
> ---
> framework/backends/json.py | 42 +++++++++++++++++++++++++++++-------------
> 1 file changed, 29 insertions(+), 13 deletions(-)
>
> diff --git a/framework/backends/json.py b/framework/backends/json.py
> index 174c0ca..6e67462 100644
> --- a/framework/backends/json.py
> +++ b/framework/backends/json.py
> @@ -29,6 +29,8 @@ import os
> import posixpath
> import shutil
> import sys
> +import re
Please insert these alphabetically sorted.
> +from collections import OrderedDict
collections is already imported, please just use 'collections.OrderedDict'
>
> try:
> import simplejson as json
> @@ -62,6 +64,16 @@ MINIMUM_SUPPORTED_VERSION = 7
> INDENT = 4
>
>
> +def numericlistdir(path):
This name isn't very descriptive. how about: numeric_sorted_listdir?
> + """Returns os.listdir with items sorted by their numerical value (if any)
> +
> + Pass possible errors (FileNotFoundError, PermissionError) upwards
> + """
> + return sorted(os.listdir(path), key =
No spaces around operators in function signatures, please.
> + lambda x: (-1, x) if not re.match(r'^\d+', x)
> + else (int(re.findall(r'^\d+', x)[0]), x) )
This seems a little complex for what you're actually trying to do, I think this
does the same thing (but in less code):
lambda p: int(os.path.splitext(p)[0])
If that does work, for the two places it's used it's probably just easier to
call sorted inline.
> +
> +
> def piglit_encoder(obj):
> """ Encoder for piglit that can transform additional classes into json
>
> @@ -125,12 +137,15 @@ class JSONBackend(FileBackend):
> containers that are still open and closes the file
>
> """
> + tests_dir = os.path.join(self._dest, 'tests')
> + file_list = numericlistdir(tests_dir)
> +
> # If jsonstreams is not present then build a complete tree of all of
> # the data and write it with json.dump
> if not _STREAMS:
> # Create a dictionary that is full of data to be written to a
> # single file
> - data = collections.OrderedDict()
> + data = OrderedDict()
>
> # Load the metadata and put it into a dictionary
> with open(os.path.join(self._dest, 'metadata.json'), 'r') as f:
> @@ -141,11 +156,10 @@ class JSONBackend(FileBackend):
> data.update(metadata)
>
> # Add the tests to the dictionary
> - data['tests'] = collections.OrderedDict()
> + data['tests'] = OrderedDict()
>
> - test_dir = os.path.join(self._dest, 'tests')
> - for test in os.listdir(test_dir):
> - test = os.path.join(test_dir, test)
> + for test in file_list:
> + test = os.path.join(tests_dir, test)
> if os.path.isfile(test):
> # Try to open the json snippets. If we fail to open a test
> # then throw the whole thing out. This gives us atomic
> @@ -177,15 +191,14 @@ class JSONBackend(FileBackend):
> s.write('__type__', 'TestrunResult')
> with open(os.path.join(self._dest, 'metadata.json'),
> 'r') as n:
> - s.iterwrite(six.iteritems(json.load(n)))
> + s.iterwrite(six.iteritems(json.load(n), object_pairs_hook=OrderedDict))
you've passed object_pairs_hook to the wrong function, it needs to be passed to
json.load
this specifically causes piglit with jsonstreams to fail. You can test it using
tox:
tox -e 'py{27,36}-streams'
>
> if metadata:
> s.iterwrite(six.iteritems(metadata))
>
> - test_dir = os.path.join(self._dest, 'tests')
> with s.subobject('tests') as t:
> - for test in os.listdir(test_dir):
> - test = os.path.join(test_dir, test)
> + for test in file_list:
> + test = os.path.join(tests_dir, test)
> if os.path.isfile(test):
> try:
> with open(test, 'r') as f:
> @@ -259,7 +272,7 @@ def _load(results_file):
>
> """
> try:
> - result = json.load(results_file)
> + result = json.load(results_file, object_pairs_hook=OrderedDict)
> except ValueError as e:
> raise exceptions.PiglitFatalError(
> 'While loading json results file: "{}",\n'
> @@ -283,11 +296,14 @@ def _resume(results_dir):
> assert meta['results_version'] == CURRENT_JSON_VERSION, \
> "Old results version, resume impossible"
>
> - meta['tests'] = {}
> + meta['tests'] = OrderedDict()
>
> # Load all of the test names and added them to the test list
> - for file_ in os.listdir(os.path.join(results_dir, 'tests')):
> - with open(os.path.join(results_dir, 'tests', file_), 'r') as f:
> + tests_dir = os.path.join(results_dir, 'tests')
> + file_list = numericlistdir(tests_dir)
> +
> + for file_ in file_list:
> + with open(os.path.join(tests_dir, file_), 'r') as f:
> try:
> meta['tests'].update(json.load(f))
> except ValueError:
> --
> 2.9.3
>
> _______________________________________________
> Piglit mailing list
> Piglit at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/piglit
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: signature
URL: <https://lists.freedesktop.org/archives/piglit/attachments/20170209/e0964b45/attachment.sig>
More information about the Piglit
mailing list