Last active
August 12, 2016 13:50
-
-
Save cramja/f34f34aad39e179211178375d7299591 to your computer and use it in GitHub Desktop.
usage: ctest -R your_test > test.out && python ctest_diff.py test.out
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
import sys | |
import re | |
import os | |
# regex for useful parts of the diff file | |
re_start_digits = re.compile(ur'^\d+: ', re.MULTILINE) | |
re_test_name = re.compile(ur'TRACE,"executing (.*mdp)",', re.MULTILINE) | |
re_actual = re.compile(ur'TRACE,"Actual:', re.MULTILINE) | |
re_expected = re.compile(ur'TRACE,"Expected:', re.MULTILINE) | |
re_end_of_block = re.compile(ur'^",\s*$', re.MULTILINE) | |
def clean(test_str): | |
# removes digits from beginning of lines | |
return re.sub(re_start_digits, "", test_str) | |
def process_test(test_str): | |
# find DXL diffs | |
result = {} | |
m_actual = re_actual.search(test_str) | |
if not m_actual: | |
result['error'] = "no dxl diff found" | |
return result | |
m_end_actual = re_end_of_block.search(test_str, m_actual.end(0)) | |
if not m_end_actual: | |
result['error'] = "no end of actual block found" | |
return result | |
m_expected = re_expected.search(test_str, m_end_actual.end(0)) | |
if not m_expected: | |
result['error'] = "no beginning of expected block found" | |
return result | |
m_end_expected = re_end_of_block.search(test_str, m_expected.end(0)) | |
if not m_end_expected: | |
result['error'] = "no end of expected block found" | |
return result | |
result['actual'] = test_str[m_actual.end(0):m_end_actual.start(0)].strip() | |
result['expected'] = test_str[m_expected.end(0):m_end_expected.start(0)].strip() | |
# find the test name | |
m_filenames = re_test_name.findall(test_str, 0, m_actual.start(0)) | |
if not m_filenames: | |
result['error'] = "no file names matched" | |
return result | |
fname = m_filenames[-1] | |
result['filename'] = fname.split('/')[-1] | |
result['filename_full'] = fname | |
return result | |
def write_result(result): | |
types = ['expected', 'actual'] | |
output = [] | |
for t in types: | |
file_name = "/tmp/{}-{}.txt".format(result['filename'], t) | |
with open(file_name, 'w') as f: | |
f.write(result[t]) | |
output.append(file_name) | |
print "\tdiff -u {} {}".format(output[0], output[1]) | |
print "\tsubl {}".format(output[1]) | |
def try_sub(args): | |
# substitutes the actual plan inside of the original mdp file | |
result = {} | |
full_file = None | |
possible_locs = [args['filename_full'], | |
os.path.expanduser("~/workspace/gporca/" + args['filename_full'][3:]), | |
os.path.expanduser("~/code/gporca/" + args['filename_full'][3:]) ] | |
for f in possible_locs: | |
if os.path.isfile(f): | |
full_file = f | |
break | |
if not full_file: | |
result['error'] = "could not find source mdp file, searched: {}".format(possible_locs) | |
return result | |
dxl = open(full_file, 'r').read() | |
re_plan_start = re.compile(ur'^(\s*)<dxl:Plan.*>\s*$', re.MULTILINE) | |
re_plan_end = re.compile(ur'^\s*</dxl:Plan>$', re.MULTILINE) | |
m_start = re_plan_start.search(dxl) | |
if not m_start: | |
result['error'] = "failed to find start of plan" | |
return result | |
m_end = re_plan_end.search(dxl) | |
if not m_end: | |
result['error'] = "failed to find end of plan" | |
return result | |
leading_whitespace = m_start.group(1) | |
corrected_dxl = dxl[:m_start.start(0)] | |
for line in args['actual'].split('\n'): | |
corrected_dxl = corrected_dxl + leading_whitespace + line + '\n' | |
corrected_dxl = corrected_dxl[:-1] + dxl[m_end.end(0):] | |
corrected_fname = '/tmp/{}'.format(args['filename']) | |
with open(corrected_fname, 'w') as f: | |
f.write(corrected_dxl) | |
result['filename'] = corrected_fname | |
result['src_filename'] = full_file | |
result['newdxl'] = corrected_dxl | |
return result | |
def main(argv=None): | |
if argv is None: | |
argv = sys.argv | |
if len(argv) == 1: | |
print "usage: ctest -R your_test > test.out && python ctest_diff.py test.out " | |
for tfile in argv[1:]: | |
with open(tfile, 'r') as test_file: | |
cleaned_test = clean(test_file.read()) | |
result = process_test(cleaned_test) | |
if 'error' in result: | |
print "error in {}: {}".format(tfile, result['error']) | |
else: | |
sub_result = try_sub(result) | |
if 'error' in sub_result: | |
print "subsitution error: {}\nactual/expected diff:".format(sub_result) | |
write_result(result) | |
else: | |
print "mdp file diff/replace:" | |
print "\tdiff -u {} {}".format(sub_result['filename'], sub_result['src_filename']) | |
print "\tmv {} {}".format(sub_result['filename'], sub_result['src_filename']) | |
if __name__ == "__main__": | |
sys.exit(main()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment