summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Atwood <matthew.s.atwood@intel.com>2012-01-08 15:11:07 -0800
committerDylan Baker <dylanx.c.baker@intel.com>2014-08-20 11:46:17 -0700
commit55f386bcf7ed45a66db6453fa52cb64769d4ddcb (patch)
treea3e2e076897b16d951395a7ff75cf264185012b1
parent011dd2e9a052be4da7a0418d13d50f627100e515 (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.py3
-rw-r--r--framework/programs/run.py14
-rw-r--r--framework/results.py15
-rw-r--r--framework/tests/results_tests.py2
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)