[Piglit] [PATCH 6/9] backend.py: split initialize() out of constructor

Dylan Baker baker.dylan.c at gmail.com
Tue Sep 23 17:55:53 PDT 2014


This allows the initialize method to take different arguments than the
constructor. The decision to merge the initializer into the constructor
was a bad one, and this should have been kept out.
---
 framework/backends/abstract.py    | 21 +++++++++++++++------
 framework/backends/json_.py       |  7 ++-----
 framework/backends/junit.py       |  5 +++--
 framework/programs/run.py         |  8 ++++----
 framework/tests/backends_tests.py | 13 +++++++++----
 5 files changed, 33 insertions(+), 21 deletions(-)

diff --git a/framework/backends/abstract.py b/framework/backends/abstract.py
index 3815304..7665cb7 100644
--- a/framework/backends/abstract.py
+++ b/framework/backends/abstract.py
@@ -72,12 +72,9 @@ class Backend(object):
     def __init__(self, dest, metadata, **options):
         """ Generic constructor
 
-        The backend storage container should be created and made ready to write
-        into in the constructor, along with any other setup.
-
-        This method also write any initial metadata as appropriate. No backend
-        is required to write all metadata, but each should write as much as
-        possible.
+        This method should setup the container and open any files or conections
+        as necissary. It should not however, write anything into the backend
+        store, that job is for the iniitalize method.
 
         In addition it takes keyword arguments that define options for the
         backends. options should be prefixed to identify which backends they
@@ -88,6 +85,18 @@ class Backend(object):
         dest -- the place to write the results to. This should be correctly
                 handled based on the backend, the example is calls open() on a
                 file, but other backends might want different options
+
+        """
+
+    @abc.abstractmethod
+    def initialize(self, metadata):
+        """ Write initial metadata and setup
+
+        This method is used to write metadata into the backend store and do any
+        other initial backend writing that is required. This method and the
+        finalize() method are bookends, one starts, the other finishes.
+
+        Arguments:
         metadata -- a dict or dict-like object that contains metadata to be
                     written into the backend
 
diff --git a/framework/backends/json_.py b/framework/backends/json_.py
index 9273e4f..a61051d 100644
--- a/framework/backends/json_.py
+++ b/framework/backends/json_.py
@@ -99,7 +99,7 @@ class JSONBackend(FSyncMixin, Backend):
     INDENT = 4
     _LOCK = threading.RLock()
 
-    def __init__(self, f, metadata, **options):
+    def __init__(self, f, **options):
         self._file = open(os.path.join(f, 'results.json'), 'w')
         FSyncMixin.__init__(self, **options)
         self.__indent_level = 0
@@ -130,10 +130,7 @@ class JSONBackend(FSyncMixin, Backend):
         # is popped and written into the json
         self._open_containers = []
 
-        # Write initial metadata into the backend store
-        self._initialize(metadata)
-
-    def _initialize(self, metadata):
+    def initialize(self, metadata):
         """ Write boilerplate json code
 
         This writes all of the json except the actual tests.
diff --git a/framework/backends/junit.py b/framework/backends/junit.py
index 51f55a6..10f65b3 100644
--- a/framework/backends/junit.py
+++ b/framework/backends/junit.py
@@ -43,17 +43,18 @@ class JUnitBackend(FSyncMixin, Backend):
     """
     _REPLACE = re.compile(r'[/\\]')
 
-    def __init__(self, dest, metadata, **options):
+    def __init__(self, dest, junit_test_suffix='', **options):
         self._file = open(os.path.join(dest, 'results.xml'), 'w')
         FSyncMixin.__init__(self, **options)
+        self._test_suffix = junit_test_suffix
 
+    def initialize(self, metadata):
         # Write initial headers and other data that etree cannot write for us
         self._file.write('<?xml version="1.0" encoding="UTF-8" ?>\n')
         self._file.write('<testsuites>\n')
         self._file.write(
             '<testsuite name="piglit" tests="{}">\n'.format(
                 metadata['test_count']))
-        self._test_suffix = metadata["test_suffix"]
         self._fsync(self._file)
 
     def finalize(self, metadata=None):
diff --git a/framework/programs/run.py b/framework/programs/run.py
index a784080..f0d703d 100644
--- a/framework/programs/run.py
+++ b/framework/programs/run.py
@@ -254,13 +254,13 @@ def run(input_):
     # refactored to make that possible because of the flattening pass that is
     # part of profile.run
     options['test_count'] = 0
-    options['test_suffix'] = args.junit_suffix
 
     # Begin json.
     backend = backends.get_backend(args.backend)(
         args.results_path,
-        options,
-        file_fsync=opts.sync)
+        file_fsync=opts.sync,
+        junit_suffix=args.junit_suffix)
+    backend.initialize(options)
 
     profile = framework.profile.merge_test_profiles(args.test_profile)
     profile.results_dir = args.results_path
@@ -311,8 +311,8 @@ def resume(input_):
     # Resume only works with the JSON backend
     backend = backends.get_backend('json')(
         args.results_path,
-        results.options,
         file_fsync=opts.sync)
+    backend.initialize(results.options)
 
     for key, value in results.tests.iteritems():
         backend.write_test(key, value)
diff --git a/framework/tests/backends_tests.py b/framework/tests/backends_tests.py
index 482cd6d..816f672 100644
--- a/framework/tests/backends_tests.py
+++ b/framework/tests/backends_tests.py
@@ -18,6 +18,8 @@
 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 # SOFTWARE.
 
+# pylint: disable=missing-docstring
+
 """ Tests for the backend package """
 
 import os
@@ -49,7 +51,7 @@ def test_initialize_jsonbackend():
 
     """
     with utils.tempdir() as tdir:
-        func = results.JSONBackend(tdir, BACKEND_INITIAL_META)
+        func = results.JSONBackend(tdir)
         assert isinstance(func, results.JSONBackend)
 
 
@@ -74,7 +76,8 @@ class TestJunitNoTests(utils.StaticDirectory):
     @classmethod
     def setup_class(cls):
         super(TestJunitNoTests, cls).setup_class()
-        test = backends.JUnitBackend(cls.tdir, BACKEND_INITIAL_META)
+        test = backends.JUnitBackend(cls.tdir)
+        test.initialize(BACKEND_INITIAL_META)
         test.finalize()
         cls.test_file = os.path.join(cls.tdir, 'results.xml')
 
@@ -96,7 +99,8 @@ class TestJUnitSingleTest(TestJunitNoTests):
     def setup_class(cls):
         super(TestJUnitSingleTest, cls).setup_class()
         cls.test_file = os.path.join(cls.tdir, 'results.xml')
-        test = backends.JUnitBackend(cls.tdir, BACKEND_INITIAL_META)
+        test = backends.JUnitBackend(cls.tdir)
+        test.initialize(BACKEND_INITIAL_META)
         test.write_test(
             'a/test/group/test1',
             results.TestResult({
@@ -124,7 +128,8 @@ class TestJUnitMultiTest(TestJUnitSingleTest):
     def setup_class(cls):
         super(TestJUnitMultiTest, cls).setup_class()
         cls.test_file = os.path.join(cls.tdir, 'results.xml')
-        test = backends.JUnitBackend(cls.tdir, BACKEND_INITIAL_META)
+        test = backends.JUnitBackend(cls.tdir)
+        test.initialize(BACKEND_INITIAL_META)
         test.write_test(
             'a/test/group/test1',
             results.TestResult({
-- 
2.1.1



More information about the Piglit mailing list