[Piglit] [PATCH 12/13] framework: update json version to v4 to fix test changes

Dylan Baker baker.dylan.c at gmail.com
Thu Feb 12 10:38:48 PST 2015


Update the json version to 4 to account for the changed names.

This patch will need to be squashed into the one before it to create a
history that can be bisected across successfully, but for review
purposes I think it makes sense to split it.

v2: - Replace use of json with inline data.

Signed-off-by: Dylan Baker <dylanx.c.baker at intel.com>
---
 framework/backends/json.py          |   2 +-
 framework/results.py                |  33 +++++++++
 framework/tests/results_v2_tests.py |  11 ---
 framework/tests/results_v3_tests.py | 133 ++++++++++++++++++++++++++++++++++++
 framework/tests/utils.py            |  48 +++++++++++++
 5 files changed, 215 insertions(+), 12 deletions(-)
 create mode 100644 framework/tests/results_v3_tests.py

diff --git a/framework/backends/json.py b/framework/backends/json.py
index 23a5b28..d14eeb2 100644
--- a/framework/backends/json.py
+++ b/framework/backends/json.py
@@ -40,7 +40,7 @@ __all__ = [
 
 
 # The current version of the JSON results
-CURRENT_JSON_VERSION = 3
+CURRENT_JSON_VERSION = 4
 
 
 def piglit_encoder(obj):
diff --git a/framework/results.py b/framework/results.py
index 68befd5..cdbf671 100644
--- a/framework/results.py
+++ b/framework/results.py
@@ -242,6 +242,7 @@ def update_results(results, filepath):
             0: _update_zero_to_one,
             1: _update_one_to_two,
             2: _update_two_to_three,
+            3: _update_three_to_four,
         }
 
         while results.results_version < CURRENT_JSON_VERSION:
@@ -419,3 +420,35 @@ def _update_two_to_three(results):
     results.results_version = 3
 
     return results
+
+
+def _update_three_to_four(results):
+    """Update results v3 to v4.
+
+    This update requires renaming a few tests. The complete lists can be found
+    in framework/data/results_v3_to_v4.json, a json file containing a list of
+    lists (They would be tuples if json has tuples), the first element being
+    the original name, and the second being a new name to update to
+
+    """
+    mapped_updates = [
+        ("spec/arb_texture_rg/fs-shadow2d-red-01",
+         "spec/arb_texture_rg/execution/fs-shadow2d-red-01"),
+        ("spec/arb_texture_rg/fs-shadow2d-red-02",
+         "spec/arb_texture_rg/execution/fs-shadow2d-red-02"),
+        ("spec/arb_texture_rg/fs-shadow2d-red-03",
+         "spec/arb_texture_rg/execution/fs-shadow2d-red-03"),
+        ("spec/arb_draw_instanced/draw-non-instanced",
+         "spec/arb_draw_instanced/execution/draw-non-instanced"),
+        ("spec/arb_draw_instanced/instance-array-dereference",
+         "spec/arb_draw_instanced/execution/instance-array-dereference"),
+    ]
+
+    for original, new in mapped_updates:
+        if original in results.tests:
+            results.tests[new] = results.tests[original]
+            del results.tests[original]
+
+    results.results_version = 4
+
+    return results
diff --git a/framework/tests/results_v2_tests.py b/framework/tests/results_v2_tests.py
index e533a2a..3367ffb 100644
--- a/framework/tests/results_v2_tests.py
+++ b/framework/tests/results_v2_tests.py
@@ -90,14 +90,3 @@ def test_unchanged():
 def test_lower():
     """Version 2: results with aps are lowered."""
     nt.ok_('test/is/some/other1/test' in RESULT.tests)
-
-
-def test_load_results():
-    """Version 2: load_results properly updates."""
-    with utils.tempdir() as d:
-        tempfile = os.path.join(d, 'results.json')
-        with open(tempfile, 'w') as f:
-            json.dump(DATA, f)
-        with open(tempfile, 'r') as f:
-            result = results.load_results(tempfile)
-            nt.assert_equal(result.results_version, 3)
diff --git a/framework/tests/results_v3_tests.py b/framework/tests/results_v3_tests.py
new file mode 100644
index 0000000..c07ff8d
--- /dev/null
+++ b/framework/tests/results_v3_tests.py
@@ -0,0 +1,133 @@
+# Copyright (c) 2015 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.
+
+"""Tests for version 3 to version 4."""
+
+from __future__ import print_function, absolute_import, division
+
+import os
+import copy
+try:
+    import simplejson as json
+except ImportError:
+    import json
+import nose.tools as nt
+
+import framework.results as results
+import framework.tests.utils as utils
+
+TEST_DATA = {
+    'returncode': 0,
+    'err': None,
+    'environment': None,
+    'command': 'foo',
+    'result': 'skip',
+    'time': 0.123,
+    'out': None,
+}
+
+DATA = {
+    "results_version": 3,
+    "name": "test",
+    "options": {
+        "profile": ['quick'],
+        "dmesg": False,
+        "verbose": False,
+        "platform": "gbm",
+        "sync": False,
+        "valgrind": False,
+        "filter": [],
+        "concurrent": "all",
+        "test_count": 0,
+        "exclude_tests": [],
+        "exclude_filter": [],
+        "env": {
+            "lspci": "stuff",
+            "uname": "more stuff",
+            "glxinfo": "and stuff",
+            "wglinfo": "stuff"
+        }
+    },
+    "tests": {
+        "spec/arb_texture_rg/fs-shadow2d-red-01": TEST_DATA,
+        "spec/arb_texture_rg/fs-shadow2d-red-02": TEST_DATA,
+        "spec/arb_texture_rg/fs-shadow2d-red-03": TEST_DATA,
+        "spec/arb_draw_instanced/draw-non-instanced": TEST_DATA,
+        "spec/arb_draw_instanced/instance-array-dereference": TEST_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 open(t, 'r') as f:
+            # pylint: disable=protected-access
+            return results._update_three_to_four(results.TestrunResult.load(f))
+
+
+class TestV4(object):
+    """Generate tests for each update."""
+    @classmethod
+    def setup_class(cls):
+        """Class setup. Create a TestrunResult with v3 data."""
+        cls.old = DATA['tests'].keys()
+        cls.new = [
+            "spec/arb_texture_rg/execution/fs-shadow2d-red-01",
+            "spec/arb_texture_rg/execution/fs-shadow2d-red-02",
+            "spec/arb_texture_rg/execution/fs-shadow2d-red-03",
+            "spec/arb_draw_instanced/execution/draw-non-instanced",
+            "spec/arb_draw_instanced/execution/instance-array-dereference"
+        ]
+        cls.result = make_result(DATA)
+
+    def test_old_removed(self):
+        """Version 3: All old test names are removed."""
+        for old in self.old:
+            nt.assert_not_in(old, self.result.tests)
+
+    def test_new_added(self):
+        """Version 3: All new test names are added."""
+        for new in self.new:
+            nt.assert_in(new, self.result.tests)
+
+    def test_new_has_data(self):
+        """Version 3: All new tests have expected data."""
+        for new in self.new:
+            nt.assert_dict_equal(self.result.tests[new], TEST_DATA)
+
+
+def test_missing():
+    """Version 3: updates successfully when tests to rename are not present."""
+    data = copy.copy(DATA)
+    del data['tests']['spec/arb_draw_instanced/instance-array-dereference']
+
+    utils.fail_if(make_result, [data], KeyError)
+
+
+def test_load_results():
+    """Version 3: load_results properly updates."""
+    with utils.tempdir() as d:
+        tempfile = os.path.join(d, 'results.json')
+        with open(tempfile, 'w') as f:
+            json.dump(DATA, f)
+        with open(tempfile, 'r') as f:
+            result = results.load_results(tempfile)
+            nt.assert_equal(result.results_version, 4)
diff --git a/framework/tests/utils.py b/framework/tests/utils.py
index 15d7668..c4c37a0 100644
--- a/framework/tests/utils.py
+++ b/framework/tests/utils.py
@@ -72,6 +72,10 @@ JSON_DATA = {
 }
 
 
+class TestFailure(AssertionError):
+    pass
+
+
 class UtilsError(Exception):
     """ An exception to be raised by utils """
     pass
@@ -238,3 +242,47 @@ class Test(framework.test.Test):
     """
     def interpret_result(self):
         pass
+
+
+def fail_if(function, values, exceptions, except_error=False):
+    """function fails if any of the exceptions are raised.
+
+    Arguments:
+    function -- a callable to test. If it raises an exception caught by the
+                values of exceptions it will cause the test to fail.
+    values -- arguments to pass to function as an explodable collection (a
+              list-like object). The will be exploded.
+    exceptions -- any value that can be passed to the except keyword such that
+                  any exception that causes the test to fail will be caught.
+
+    Keyword Arguments:
+    except_error -- If false any other exception will cause the test to raise
+                    an error, if set to true any errors other than those of
+                    exceptions will cause be passed. Default: False
+
+    Tests can be catch a single exception:
+    >>> a = {}
+    >>> fail_if(lambda x: a[x], ['foo'], KeyError)
+    Traceback (most recent call last):
+    TestFailure
+
+    They can also catch multiple exceptions:
+    >>> a = {}
+    >>> fail_if(lambda x: a[x], ['foo'], (KeyError, ValueError))
+    Traceback (most recent call last):
+    TestFailure
+
+    If except_error is True and an error is raised that isn't caught by
+    exceptions the test will pass:
+    >>> a = {}
+    >>> fail_if(lambda x: a[x], ['foo'], AssertionError, except_error=True)
+
+    """
+    try:
+        return function(*values)
+    except exceptions:
+        raise TestFailure
+    except Exception:  # pylint: disable=broad-except
+        if not except_error:
+            raise
+        return None
-- 
2.3.0



More information about the Piglit mailing list