[Piglit] [PATCH 2/2] framework/backends/json.py: preserve 'tests' order
Tomi Sarvela
tomi.p.sarvela at intel.com
Thu Feb 9 11:07:05 UTC 2017
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
+from collections import OrderedDict
try:
import simplejson as json
@@ -62,6 +64,16 @@ MINIMUM_SUPPORTED_VERSION = 7
INDENT = 4
+def numericlistdir(path):
+ """Returns os.listdir with items sorted by their numerical value (if any)
+
+ Pass possible errors (FileNotFoundError, PermissionError) upwards
+ """
+ return sorted(os.listdir(path), key =
+ lambda x: (-1, x) if not re.match(r'^\d+', x)
+ else (int(re.findall(r'^\d+', x)[0]), x) )
+
+
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))
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
More information about the Piglit
mailing list