Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 83 lines (67 sloc) 2.553 kb
e29f631 @kripken bisection bugfinding tool
authored
1 '''
2 Given two similar files, for example one with an additional optimization pass,
3 and with different results, will bisect between them to find the smallest
4 diff that makes the outputs different.
5 '''
6
7 import os, sys, shutil
8 from subprocess import Popen, PIPE, STDOUT
9
10 __rootpath__ = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
11 def path_from_root(*pathelems):
12 return os.path.join(__rootpath__, *pathelems)
13 exec(open(path_from_root('tools', 'shared.py'), 'r').read())
14
15 file1 = open(sys.argv[1]).read()
16 file2 = open(sys.argv[2]).read()
17
18 leftf = open('left', 'w')
19 leftf.write(file1)
20 leftf.close()
21
22 rightf = open('right', 'w')
23 rightf.write(file2)
24 rightf.close()
25
26 print 'running files'
27 left_result = run_js('left', stderr=PIPE)
28 right_result = run_js('right', stderr=PIPE) # right as in left-right, not as in correct
29 assert left_result != right_result
30
31 # Calculate diff chunks
32 print 'diffing'
33 diff = Popen(['diff', '-U', '5', 'left', 'right'], stdout=PIPE).communicate()[0].split('\n')
34 pre_diff = diff[:2]
35 diff = diff[2:]
36
37 chunks = []
38 curr = []
39 for i in range(len(diff)):
40 if diff[i].startswith('@'):
41 if len(curr) > 0:
42 chunks.append(curr)
43 curr = [diff[i]]
44 else:
45 curr.append(diff[i])
46 if len(curr) > 0:
47 chunks.append(curr)
48
49 # Bisect both sides of the span, until we have a single chunk
50 high = len(chunks)
51
52 print 'beginning bisection, %d chunks' % high
53
e490418 @kripken fix bisection bug
authored
54 for mid in range(high):
55 print ' current: %d' % mid
e29f631 @kripken bisection bugfinding tool
authored
56 # Take chunks from the middle and on. This is important because the eliminator removes variables, so starting from the beginning will add errors
57 curr_diff = '\n'.join(map(lambda parts: '\n'.join(parts), chunks[mid:])) + '\n'
58 difff = open('diff.diff', 'w')
59 difff.write(curr_diff)
60 difff.close()
61 shutil.copy('left', 'middle')
62 Popen(['patch', 'middle', 'diff.diff'], stdout=PIPE, stderr=PIPE).communicate()
63 result = run_js('middle', stderr=PIPE)
64 if result == left_result:
e490418 @kripken fix bisection bug
authored
65 print 'found where it starts to work: %d' % mid
66 found = mid
67 break
e29f631 @kripken bisection bugfinding tool
authored
68
e490418 @kripken fix bisection bug
authored
69 critical = '\n'.join(chunks[found-1]) + '\n'
e29f631 @kripken bisection bugfinding tool
authored
70
71 c = open('critical.diff', 'w')
72 c.write(critical)
73 c.close()
74 print 'sanity check'
75 shutil.copy('middle', 'middle2')
76 Popen(['patch', 'middle2', 'critical.diff'], stdout=PIPE, stderr=PIPE).communicate()
e490418 @kripken fix bisection bug
authored
77 assert run_js('middle', stderr=PIPE) == left_result, 'middle was expected %s' % left_result
78 assert run_js('middle2', stderr=PIPE) != left_result, 'middle2 was expected NOT %s' % left_result
e29f631 @kripken bisection bugfinding tool
authored
79
80 print 'middle is like left, middle2 is like right, critical.diff is the difference that matters,'
81 print critical
82
Something went wrong with that request. Please try again.