[Piglit] [Patch v7 11/13] framework: consolidate boilerplate in JSNOWriter class

Dylan Baker baker.dylan.c at gmail.com
Mon Jun 23 16:38:31 PDT 2014


This moves all of the code for writing the name, the options, etc out of
run and resume and into a single method of JSONWriter. This should
reduce errors, code duplication, and help abstract a lot of problems
with future changes to the json away.

v7: - add close_json() to JSONWriter
TODO: add tests for close_json()

Signed-off-by: Dylan Baker <baker.dylan.c at gmail.com>
---
 framework/programs/run.py | 43 +++++++++---------------------------
 framework/results.py      | 56 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 66 insertions(+), 33 deletions(-)

diff --git a/framework/programs/run.py b/framework/programs/run.py
index 15b2f53..4a500bd 100644
--- a/framework/programs/run.py
+++ b/framework/programs/run.py
@@ -161,28 +161,18 @@ def run(input_):
     result_filepath = path.join(args.results_path, 'main')
     result_file = open(result_filepath, 'w')
     json_writer = framework.results.JSONWriter(result_file)
-    json_writer.open_dict()
 
-    # Write out command line options for use in resuming.
-    json_writer.write_dict_key('options')
-    json_writer.open_dict()
-    json_writer.write_dict_item('profile', args.test_profile)
-    for key, value in opts:
-        json_writer.write_dict_item(key, value)
+    # Create a dictionary to pass to initialize json, it needs the contents of
+    # the env dictionary and profile and platform information
+    options = {'profile': args.test_profile}
     if args.platform:
-        json_writer.write_dict_item('platform', args.platform)
-    json_writer.close_dict()
-
-    json_writer.write_dict_item('name', results.name)
-
-    for key, value in core.collect_system_info().iteritems():
-        json_writer.write_dict_item(key, value)
+        options['platform'] = args.platform
+    json_writer.initialize_json(options, results.name,
+                                core.collect_system_info())
 
     profile = framework.profile.merge_test_profiles(args.test_profile)
     profile.results_dir = args.results_path
 
-    json_writer.write_dict_key('tests')
-    json_writer.open_dict()
     time_start = time.time()
     # Set the dmesg type
     if args.dmesg:
@@ -196,8 +186,7 @@ def run(input_):
     json_writer.write_dict_item('time_elapsed', results.time_elapsed)
 
     # End json.
-    json_writer.close_dict()
-    json_writer.file.close()
+    json_writer.close_json()
 
     print('Thank you for running Piglit!\n'
           'Results have been written to ' + result_filepath)
@@ -225,19 +214,9 @@ def resume(input_):
 
     results_path = path.join(args.results_path, "main")
     json_writer = framework.results.JSONWriter(open(results_path, 'w+'))
-    json_writer.open_dict()
-    json_writer.write_dict_key("options")
-    json_writer.open_dict()
-    for key, value in results.options.iteritems():
-        json_writer.write_dict_item(key, value)
-    json_writer.close_dict()
-
-    json_writer.write_dict_item('name', results.name)
-    for key, value in core.collect_system_info().iteritems():
-        json_writer.write_dict_item(key, value)
+    json_writer.initialize_json(results.options, results.name,
+                                core.collect_system_info())
 
-    json_writer.write_dict_key('tests')
-    json_writer.open_dict()
     for key, value in results.tests.iteritems():
         json_writer.write_dict_item(key, value)
         opts.exclude_tests.add(key)
@@ -250,9 +229,7 @@ def resume(input_):
     # This is resumed, don't bother with time since it wont be accurate anyway
     profile.run(opts, json_writer)
 
-    json_writer.close_dict()
-    json_writer.close_dict()
-    json_writer.file.close()
+    json_writer.close_json()
 
     print("Thank you for running Piglit!\n"
           "Results have ben wrriten to {0}".format(results_path))
diff --git a/framework/results.py b/framework/results.py
index 2321a89..5f0316a 100644
--- a/framework/results.py
+++ b/framework/results.py
@@ -118,6 +118,59 @@ class JSONWriter(object):
         #
         self.__is_collection_empty = []
 
+        # self._open_containers
+        #
+        # A FILO stack that stores container information, each time
+        # self.open_dict() 'dict' is added to the stack, (other elements like
+        # 'list' could be added if support was added to JSONWriter for handling
+        # them), each to time self.close_dict() is called an element is
+        # removed. When self.close_json() is called each element of the stack
+        # is popped and written into the json
+        self._open_containers = []
+
+    def initialize_json(self, options, name, env):
+        """ Write boilerplate json code 
+
+        This writes all of the json except the actual tests.
+
+        Arguments:
+        options -- any values to be put in the options dictionary, must be a
+                   dict-like object
+        name -- the name of the test
+        env -- any environment information to be written into the results, must
+               be a dict-like object
+
+        """
+        self.open_dict()
+        self.write_dict_item('name', name)
+
+        self.write_dict_key('options')
+        self.open_dict()
+        for key, value in options.iteritems():
+            # Loading a NoneType will break resume, and are a bug
+            assert value is not None, "Value {} is NoneType".format(key)
+            self.write_dict_item(key, value)
+        self.close_dict()
+
+        for key, value in env.iteritems():
+            self.write_dict_item(key, value)
+
+        self.write_dict_key('tests')
+        self.open_dict()
+
+    def close_json(self):
+        """ End json serialization and cleanup
+
+        This method is called after all of tests are written, it closes any
+        containers that are still open and closes the file
+
+        """
+        for elem in reversed(self._open_containers):
+            if elem == 'dict':
+                self.close_dict()
+
+        self.file.close()
+
     @synchronized_self
     def __write_indent(self):
         if self.__inhibit_next_indent:
@@ -144,6 +197,7 @@ class JSONWriter(object):
 
         self.__indent_level += 1
         self.__is_collection_empty.append(True)
+        self._open_containers.append('dict')
 
     @synchronized_self
     def close_dict(self):
@@ -153,6 +207,8 @@ class JSONWriter(object):
         self.file.write('\n')
         self.__write_indent()
         self.file.write('}')
+        assert self._open_containers[-1] == 'dict'
+        self._open_containers.pop()
 
     @synchronized_self
     def write_dict_item(self, key, value):
-- 
2.0.0



More information about the Piglit mailing list