[Piglit] [PATCH 4/4] framework: Repair result file if test run is interrupted

Ian Romanick idr at freedesktop.org
Sat Jul 23 01:30:35 PDT 2011


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

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?

> 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()

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/

iEYEARECAAYFAk4qhqsACgkQX1gOwKyEAw+1owCfexNoQZUFksS19CXxEkJ2TQBz
j08AoI0qzcl7ltByOLsQEm/KGp0S68Vy
=FQLs
-----END PGP SIGNATURE-----


More information about the Piglit mailing list