diff options
author | Matt Atwood <matthew.s.atwood@intel.com> | 2012-01-08 15:11:07 -0800 |
---|---|---|
committer | Dylan Baker <dylanx.c.baker@intel.com> | 2014-08-20 11:46:17 -0700 |
commit | 55f386bcf7ed45a66db6453fa52cb64769d4ddcb (patch) | |
tree | a3e2e076897b16d951395a7ff75cf264185012b1 | |
parent | 011dd2e9a052be4da7a0418d13d50f627100e515 (diff) |
programs/run.py add file sync command line option
Currently while running igt tests a kernel panic causes the results json
file to lose all data. This patch adds a command line option (-s,
--sync) that syncs the file descriptor to disk after every test allowing
data to persist through hard crashes.
v2: Call flush() before fsync(), explicitly pass fileno instead of fd
v3: sync write_dict_key added
v4: git log maintenance
v5: - Fix one unit test for JSONWriter, the constructor signature changed
(Dylan)
Reviewed-by: Dylan Baker <dylanx.c.baker@intel.com>
-rw-r--r-- | framework/core.py | 3 | ||||
-rw-r--r-- | framework/programs/run.py | 14 | ||||
-rw-r--r-- | framework/results.py | 15 | ||||
-rw-r--r-- | framework/tests/results_tests.py | 2 |
4 files changed, 27 insertions, 7 deletions
diff --git a/framework/core.py b/framework/core.py index 2205537f4..bf41391f9 100644 --- a/framework/core.py +++ b/framework/core.py @@ -95,7 +95,7 @@ class Options(object): """ def __init__(self, concurrent=True, execute=True, include_filter=None, exclude_filter=None, valgrind=False, dmesg=False, - verbose=False): + verbose=False, sync=False): self.concurrent = concurrent self.execute = execute self.filter = [re.compile(x) for x in include_filter or []] @@ -104,6 +104,7 @@ class Options(object): self.valgrind = valgrind self.dmesg = dmesg self.verbose = verbose + self.sync = sync # env is used to set some base environment variables that are not going # to change across runs, without sending them to os.environ which is # fickle as easy to break diff --git a/framework/programs/run.py b/framework/programs/run.py index ff75afed0..e37e7ade6 100644 --- a/framework/programs/run.py +++ b/framework/programs/run.py @@ -95,6 +95,9 @@ def run(input_): action="store_true", help="Produce a line of output for each test before " "and after it runs") + parser.add_argument("-s", "--sync", + action="store_true", + help="Sync results to disk after every test") parser.add_argument("test_profile", metavar="<Path to one or more test profile(s)>", nargs='+', @@ -138,7 +141,8 @@ def run(input_): execute=args.execute, valgrind=args.valgrind, dmesg=args.dmesg, - verbose=args.verbose) + verbose=args.verbose, + sync=args.sync) # Set the platform to pass to waffle opts.env['PIGLIT_PLATFORM'] = args.platform @@ -159,7 +163,7 @@ def run(input_): # Begin json. result_filepath = path.join(args.results_path, 'results.json') result_file = open(result_filepath, 'w') - json_writer = framework.results.JSONWriter(result_file) + json_writer = framework.results.JSONWriter(result_file, opts.sync) # Create a dictionary to pass to initialize json, it needs the contents of # the env dictionary and profile and platform information @@ -216,14 +220,16 @@ def resume(input_): execute=results.options['execute'], valgrind=results.options['valgrind'], dmesg=results.options['dmesg'], - verbose=results.options['verbose']) + verbose=results.options['verbose'], + sync=results.options['sync']) core.get_config(args.config_file) opts.env['PIGLIT_PLATFORM'] = results.options['platform'] results_path = path.join(args.results_path, 'results.json') - json_writer = framework.results.JSONWriter(open(results_path, 'w+')) + json_writer = framework.results.JSONWriter(open(results_path, 'w+'), + opts.sync) json_writer.initialize_json(results.options, results.name, core.collect_system_info()) diff --git a/framework/results.py b/framework/results.py index 4b5fb30c2..efc702909 100644 --- a/framework/results.py +++ b/framework/results.py @@ -102,8 +102,9 @@ class JSONWriter(object): INDENT = 4 - def __init__(self, f): + def __init__(self, f, fsync): self.file = f + self.fsync = fsync self.__indent_level = 0 self.__inhibit_next_indent = False self.__encoder = json.JSONEncoder(indent=self.INDENT, @@ -175,6 +176,12 @@ class JSONWriter(object): self.file.close() @synchronized_self + def __file_sync(self): + if self.fsync: + self.file.flush() + os.fsync(self.file.fileno()) + + @synchronized_self def __write_indent(self): if self.__inhibit_next_indent: self.__inhibit_next_indent = False @@ -201,6 +208,7 @@ class JSONWriter(object): self.__indent_level += 1 self.__is_collection_empty.append(True) self._open_containers.append('dict') + self.__file_sync() @synchronized_self def close_dict(self): @@ -212,6 +220,7 @@ class JSONWriter(object): self.file.write('}') assert self._open_containers[-1] == 'dict' self._open_containers.pop() + self.__file_sync() @synchronized_self def write_dict_item(self, key, value): @@ -221,6 +230,8 @@ class JSONWriter(object): # Write value. self.__write(value) + self.__file_sync() + @synchronized_self def write_dict_key(self, key): # Write comma if this is not the initial item in the dict. @@ -235,6 +246,8 @@ class JSONWriter(object): self.__inhibit_next_indent = True + self.__file_sync() + class TestResult(dict): def __init__(self, *args): diff --git a/framework/tests/results_tests.py b/framework/tests/results_tests.py index 4afa8101c..54661cce9 100644 --- a/framework/tests/results_tests.py +++ b/framework/tests/results_tests.py @@ -63,7 +63,7 @@ def test_initialize_jsonwriter(): """ with tempfile.TemporaryFile() as tfile: - func = results.JSONWriter(tfile) + func = results.JSONWriter(tfile, False) assert isinstance(func, results.JSONWriter) |