From 45b84e4a298d5beea5c9e12093ce4d90c980c7f1 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Thu, 3 Dec 2009 17:53:02 -0500 Subject: Trap errors when invoking spatch, and bubble up as exceptions; introduce hooks for writing unit tests for fixers --- fixes/__init__.py | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/fixes/__init__.py b/fixes/__init__.py index 5435e1b..afc578b 100644 --- a/fixes/__init__.py +++ b/fixes/__init__.py @@ -6,6 +6,16 @@ class Fix(object): def transform(self, string): raise NotImplementedError +class CoccinelleError(RuntimeError): + def __init__(self, p, args, stderr): + self.p = p + self.args = args + self.stderr = stderr + + def __str__(self): + return ('Return code: %s (args: %s)\n --- start of captured stderr ---\n%s--- enf of captured stderr ---\n' + % (self.p.returncode, repr(self.args), self.stderr)) + class CocciFix(Fix): def __init__(self, filename): self.filename = filename @@ -23,11 +33,39 @@ class CocciFix(Fix): #print (dst_hn, dst_path) os.write(src_hn, string) - p = Popen(['spatch', '-sp_file', self.get_script_path(), src_path, '-o', dst_path], stdout=PIPE, stderr=PIPE) - p.wait() + args = ['spatch', '-sp_file', self.get_script_path(), src_path, '-o', dst_path] + p = Popen(args, stdout=PIPE, stderr=PIPE) + (stdout, stderr) = p.communicate() + if p.returncode != 0: + raise CoccinelleError(p, args, stderr) string = open(dst_path, 'r').read() os.close(src_hn) os.close(dst_hn) return string + +import unittest +class NonequalStrings(Exception): + def __init__(self, actual_result, exp_result): + self.actual_result = actual_result + self.exp_result = exp_result + + def __str__(self): + from difflib import unified_diff + result = '\n' + for line in unified_diff(self.exp_result.splitlines(), + self.actual_result.splitlines(), + fromfile = 'Expected result', + tofile = 'Actual result', + lineterm=''): + result += line + '\n' + return result + +class FixTest(unittest.TestCase): + '''Subclass of TestCase for verifying that a Fix is working as expected''' + def assertTransformsTo(self, fixer, src, exp_result): + actual_result = fixer.transform(src) + if actual_result != exp_result: + raise NonequalStrings(actual_result, exp_result) + -- cgit