[Piglit] [PATCH 4/4] framework: Repair result file if test run is interrupted
Chad Versace
chad at chad-versace.us
Mon Jul 25 10:31:00 PDT 2011
On 07/23/2011 01:30 AM, Ian Romanick wrote:
> On 07/19/2011 12:36 PM, Chad Versace wrote:
>> If the JSON result file was not closed properly, perhaps due a system
>> crash during a test run, then TestrunResult.parseFile will attempt to
>> repair the file before parsing it.
>
> What happens if I run piglit-summary-html.py on a set of results while
> piglit-run.py is generating those results? Will it attempt to "repair"
> the output of the in-progress test results? Will this make everything
> explode?
I did not consider this, since I only run piglit-summary-html.py after the test run has finished. Your fear is accurate. It will attempt to "repair" the in-progress result file and hence destroy it.
I see a simple way to fix this. Currently, TestrunResult.__repairFile 1) copies the result file into a buffer, 2) repairs the buffer's contents, and 3) then overwrites the result file with the buffer. To fix this problem, we can replace step 3 with: return the buffer as the repaired file. This way, __repairFile() never overwrites the result file.
>> Signed-off-by: Chad Versace <chad at chad-versace.us>
>> ---
>> framework/core.py | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++-
>> 1 files changed, 66 insertions(+), 2 deletions(-)
>
>> diff --git a/framework/core.py b/framework/core.py
>> index afc5a28..cbd3ef3 100644
>> --- a/framework/core.py
>> +++ b/framework/core.py
>> @@ -291,6 +291,68 @@ class TestrunResult:
>> raise ResultFileInOldFormatError(file.name)
>> file.seek(saved_position)
>
>> + def __repairFile(self, file):
>> + '''
>> + Reapair JSON file if necessary
>> +
>> + If the JSON file is not closed properly, perhaps due a system
>> + crash during a test run, then the JSON is repaired by
>> + discarding the trailing, incomplete item and appending braces
>> + to the file to close the JSON object.
>> +
>> + Warning: This sets the file's position to 0.
>> + '''
>> +
>> + file.seek(0)
>> + lines = file.readlines()
>> +
>> + if lines[-1] == '}':
>> + # JSON object was closed properly. No repair is
>> + # necessary.
>> + file.seek(0)
>> + return
>> +
>> + # JSON object was not closed properly.
>> + #
>> + # To repair the file, we execute these steps:
>> + # 1. Find the closing brace of the last, properly written
>> + # test result.
>> + # 2. Discard all subsequent lines.
>> + # 3. Remove the trailing comma of that test result.
>> + # 4. Append enough closing braces to close the json object.
>> + # 5. Replace file's contents with repaired JSON.
>> +
>> + # Each non-terminal test result ends with this line:
>> + safe_line = 3 * JSONWriter.INDENT * ' ' + '},\n'
>> +
>> + # Search for the last occurence of safe_line.
>> + safe_line_num = None
>> + for i in range(-1, - len(lines), -1):
>> + if lines[i] == safe_line:
>> + safe_line_num = i
>> + break
>> +
>> + if safe_line_num is None:
>> + raise Exception('failed to repair corrupt result file: ' + file.name)
>> +
>> + # Remove corrupt lines.
>> + lines = lines[0:(safe_line_num + 1)]
>> +
>> + # Remove trailing comma.
>> + lines[-1] = 3 * JSONWriter.INDENT * ' ' + '}\n'
>> +
>> + # Close json object.
>> + lines.append(JSONWriter.INDENT * ' ' + '}\n')
>> + lines.append('}')
>> +
>> + # Replace contents of corrupt file.
>> + file.truncate(0)
>> + file.seek(0)
>> + file.writelines(lines)
>> + file.flush()
>> + os.fsync(file.fileno())
>> + file.seek(0)
>> +
>> def write(self, file):
>> # Serialize only the keys in serialized_keys.
>> keys = set(self.__dict__.keys()).intersection(self.serialized_keys)
>> @@ -299,7 +361,7 @@ class TestrunResult:
>
>> def parseFile(self, file):
>> self.__checkFileIsNotInOldFormat(file)
>> -
>> + self.__repairFile(file)
>> raw_dict = json.load(file)
>
>> # Check that only expected keys were unserialized.
>> @@ -510,7 +572,9 @@ def loadTestResults(path):
>
>> testrun = TestrunResult()
>> try:
>> - with open(filepath, 'r') as file:
>> + # Open the file in r+ mode so that it can be repaired if
>> + # necessary.
>> + with open(filepath, 'r+') as file:
>> testrun.parseFile(file)
>> except OSError:
>> traceback.print_exc()
>
> _______________________________________________
> Piglit mailing list
> Piglit at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/piglit
--
Chad Versace
chad at chad-versace.us
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 900 bytes
Desc: OpenPGP digital signature
URL: <http://lists.freedesktop.org/archives/piglit/attachments/20110725/47ddcee3/attachment.pgp>
More information about the Piglit
mailing list