2 # -*- coding: utf-8 -*-
5 from subprocess import call, check_call
6 from random import randrange
10 outfilename = "/tmp/cache-bisect." + getpass.getuser() + ".log"
11 outfile = open(outfilename, 'w')
12 print 'BBBISECT_BEGIN'
13 #print >> outfile, 'BBBISECT_BEGIN'
14 #print >> outfile, 'BBBISECT_BEGIN'
15 #print >> outfile, 'BBBISECT_BEGIN'
16 #print >> outfile, 'BBBISECT_BEGIN'
17 #print >> outfile, 'BBBISECT_BEGIN'
18 #print 'BBBISECT_BEGIN'
20 source_dir = '/mnt/big/xp/src/lyx-1.6.x-bisect' # must NOT end in a slash
21 cache_dir = source_dir + '.cache/' # must end in a slash
22 source_dir = '/mnt/big/xp/src/lyx-1.6.x-bisect2' # must NOT end in a slash
24 #make_cmd = 'autoconf && ./configure && cd src && echo __________ `pwd` && sleep 9 && make'
25 make_cmd = 'rm -rf autom4te.cache && autoconf && ./configure && cd src && make'
28 reverse_search = False
29 must_make = True # If we fail to make the file, we could this a "bad" rather than "canot test"
33 # replace .tmp with .partial_copy and .not_yet_made
36 def set_revision(new_v, tmp_d):
37 #check_call(['svn', 'up', '-r' + new_v, '--force'], cwd=tmp_d)
38 os.system ('cd "'+tmp_d+'" && yes tf | svn up -r'+new_v+'--force')
40 def cmp_version(x, y):
41 return cmp(int(x), int(y))
44 def get_cached_versions():
45 vers = [f for f in os.listdir(cache_dir) if not f.count('.')]
46 vers.sort(cmp_version)
50 def version_in_range(v, lo, hi):
51 if cmp_version(v, lo) < 0:
53 elif cmp_version(v, hi) > 0:
58 # Unlike killall, this searchs within command parameters, as well as the
61 #os.system("kPID=`ps a | grep '"+s+"' | grep -v grep | sed 's/^ *//g'| sed 's/ .*$//'`
62 os.system("(kPID=`ps a | grep '"+s+
63 "' | grep -v grep | sed 's/^ *//g'| sed 's/ .*$//'`\n\
64 echo kPID $kPID "+s+"\n\
69 kill -9 $kPID) 2> /dev/null")
74 killall_p("keytest.py")
77 def filter_versions(vers, lo, hi):
78 return [v for v in vers if cmp]
85 def make_ver(new_v, old_v=None, alt_v=None):
86 print 'MAKING', new_v, old_v, alt_v
87 new_d = ver2dir(new_v)
91 old_d = ver2dir(old_v)
92 fail_d = new_d + '.fail'
93 tmp_d = new_d + '.tmp'
94 if os.path.exists(cache_dir + fail_d):
96 if os.path.exists(new_d):
98 if not os.path.exists(tmp_d):
99 if not os.path.exists(old_d):
100 old_d = old_d + '.tmp'
101 call(['rm', '-rf', tmp_d + '.cp'])
102 call(['cp', '-rvu', old_d, tmp_d + '.cp'])
103 check_call(['mv', tmp_d + '.cp', tmp_d])
104 set_revision(new_v, tmp_d)
105 call('pwd && sleep 5 && echo ' + make_cmd, cwd=tmp_d, shell=True)
106 result = call(make_cmd, cwd=tmp_d, shell=True)
108 print 'Make successful'
109 check_call(['mv', tmp_d, new_d])
113 def change_after(cmd, v):
114 result = run_cmd(cmd, v)
115 ca = result_after(result)
116 print >> outfile, 'BISECT_change_after', v, ca
117 print 'BISECT_change_after', v, ca
121 def change_before(cmd, v):
122 result = run_cmd(cmd, v)
123 cb = result_before(result)
124 print >> outfile, 'BISECT_change_before', v, cb
125 print 'BISECT_change_before', v, cb
133 return result_good(i)
136 def result_before(i):
138 return result_good(i)
148 return not result_ugly(i) and not result_good(i)
152 return i == 125 # Like git, we treat 125 as "We cannot test this version"
156 #result = call('pwd ; echo SS ' + cmd, shell=True, cwd=ver2dir(v))
158 print "V2D", ver2dir(v)
160 #result = subprocess.call(cmd, shell=True, cwd=ver2dir(v))
161 result = call(cmd, cwd=ver2dir(v))
167 def do_bisect(cmd, vers, build):
173 print vers[lo], vers[hi], vers[m]
176 print >> outfile, 'VERS', final_vers
179 print 'i', lo, hi, m, cmd
180 print 'v', vers[lo], vers[hi], vers[m], cmd
183 print '#ugly = Nonese'
185 if build or must_make:
187 result = make_ver(vers[m], vers[lo], vers[hi])
188 print 'AMKE RESULT', result
190 if result > 0 and not must_make:
191 ugly = True # Not good, or bad, just ugly.
193 result = run_cmd(cmd, vers[m])
197 ugly = result_ugly(result)
199 print vers[m] + ' is UGLY'
202 m = randrange(0, len(vers))
204 if result_after(result):
205 print vers[m] + ' is AFTER'
208 print vers[m] + ' is BEFORE'
209 del vers[m + 1:hi + 1]
213 print 'VERS REMAINING:', vers
218 def check_bisect(cmd, vers):
227 if change_before(cmd, l):
228 print 'Cannot bisect, change before ' + l\
229 + ' or regression test invalid'
231 if change_after(cmd, h):
232 print 'Cannot bisect, change after ' + h\
233 + ' or regression test invalid'
238 def do_check_bisect(cmd, vers, build):
240 if check_bisect(cmd, vers):
241 return do_bisect(cmd, vers, build)
246 def open_and_readlines(fname):
248 lines = f.readlines()
249 for i in range(0, len(lines)):
250 lines[i] = lines[i].rstrip('\n')
254 def get_versions_between(l, h):
255 vers = [f for f in open_and_readlines('all_versions')
256 if version_in_range(f, l, h)]
257 vers.sort(cmp_version)
261 def get_cached_versions_between(l, h):
262 vers = [f for f in get_cached_versions() if version_in_range(f, l, h)]
263 vers.sort(cmp_version)
264 print 'BTWN', l, h, vers
268 def two_level_bisect(cmd, LO, HI):
273 vers = get_cached_versions_between(LO, HI)
274 print 'CACHED_VERSIONS', vers
275 vers = do_check_bisect(cmd, vers, False)
276 print 'Closest Cached Versions', vers
281 vers = get_versions_between(vers[0], vers[1])
282 print 'BETWEEN VERSIONS', vers
283 vers = do_check_bisect(cmd, vers, True)
286 def multisect(cmd, vers):
289 print >> outfile, 'MULTISECT', vers[i]
290 print 'MULTISECT', vers[i]
291 if not ( make_ver(vers[i], vers[i-1])==0 and change_after(cmd, vers[i]) ) :
294 return two_level_bisect(cmd, vers[i], vers[0])
298 print >> outfile, 'BISECT_BEGIN'
300 #final_vers = multisect('$TEST_COMMAND', ['30614', '27418', '23000'])
304 VERS = os.environ.get('MULTISECT_VERS')
306 VERS = ['30614', '27418', '23000']
310 final_vers = multisect(cmd, VERS)
311 #final_vers = two_level_bisect('true', "21107","23000")
312 #final_vers = do_bisect('true', get_versions_between("21107","23000"),True)
315 print >> outfile, 'BISECT_FINAL', final_vers
316 print 'BISECT_FINAL', final_vers
317 os.system('echo BISECT_BEGIN >> /tmp/adsfadsf.log')
318 os.system('echo BISECT_FINAL >> /tmp/adsfadsf.log')