Bug 1036374 - Adding a binary search algorithm for bisection of failing tests. r=jmaher

This commit is contained in:
Vaibhav Agrawal 2014-07-09 13:20:00 +02:00
parent 013dc80b0b
commit 7b9ddbd37c
2 changed files with 46 additions and 14 deletions

View File

@ -86,7 +86,7 @@ class Bisect(object):
tests = self.get_tests_for_bisection(options, tests)
status = self.setup(tests)
return self.next_chunk_reverse(options, status)
return self.next_chunk_binary(options, status)
def post_test(self, options, expectedError, result):
"This method is used to call other methods to summarize results and check whether a sanity check is done or not."
@ -115,13 +115,11 @@ class Bisect(object):
"This method is used to bisect the tests in a reverse search fashion."
# Base Cases.
if self.contents['loop'] == 0:
self.contents['loop'] += 1
if self.contents['loop'] <= 1:
self.contents['testsToRun'] = self.contents['tests']
return self.contents['testsToRun']
if self.contents['loop'] == 1:
self.contents['loop'] += 1
self.contents['testsToRun'] = [self.contents['tests'][-1]]
self.contents['loop'] += 1
return self.contents['testsToRun']
if 'result' in self.contents:
@ -150,6 +148,42 @@ class Bisect(object):
return self.contents['testsToRun']
def next_chunk_binary(self, options, status):
"This method is used to bisect the tests in a binary search fashion."
# Base cases.
if self.contents['loop'] <= 1:
self.contents['testsToRun'] = self.contents['tests']
if self.contents['loop'] == 1:
self.contents['testsToRun'] = [self.contents['tests'][-1]]
self.contents['loop'] += 1
return self.contents['testsToRun']
# Initialize the contents dict.
if status:
totalTests = len(self.contents['tests'])
self.contents['start'] = 0
self.contents['end'] = totalTests - 2
mid = (self.contents['start'] + self.contents['end']) / 2
if 'result' in self.contents:
if self.contents['result'] == "PASS":
self.contents['end'] = mid
elif self.contents['result'] == "FAIL":
self.contents['start'] = mid + 1
mid = (self.contents['start'] + self.contents['end']) / 2
start = mid + 1
end = self.contents['end'] + 1
self.contents['testsToRun'] = self.contents['tests'][start:end]
if not self.contents['testsToRun']:
self.contents['testsToRun'].append(self.contents['tests'][mid])
self.contents['testsToRun'].append(self.contents['tests'][-1])
self.contents['loop'] += 1
return self.contents['testsToRun']
def summarize_chunk(self, options):
"This method is used summarize the results after the list of tests is run."
if options.bisectChunk == "default":

View File

@ -1402,7 +1402,7 @@ class Mochitest(MochitestUtilsMixin):
if options.bisectChunk:
testsToRun = bisect.pre_test(options, testsToRun, status)
self.doTests(options, onLaunch, testsToRun)
result = self.doTests(options, onLaunch, testsToRun)
if options.bisectChunk:
status = bisect.post_test(options, self.expectedError, self.result)
else:
@ -1415,9 +1415,8 @@ class Mochitest(MochitestUtilsMixin):
# Also we need to make sure that we do not print the summary in between running tests via --run-by-dir.
if options.bisectChunk and options.bisectChunk in self.result:
bisect.print_summary()
return -1
return 0
return result
def runTests(self, options, onLaunch=None):
""" Prepare, configure, run tests and cleanup """
@ -1425,8 +1424,7 @@ class Mochitest(MochitestUtilsMixin):
self.setTestRoot(options)
if not options.runByDir:
self.runMochitests(options, onLaunch)
return 0
return self.runMochitests(options, onLaunch)
# code for --run-by-dir
dirs = self.getDirectories(options)
@ -1451,9 +1449,7 @@ class Mochitest(MochitestUtilsMixin):
# If we are using --run-by-dir, we should not use the profile path (if) provided
# by the user, since we need to create a new directory for each run. We would face problems
# if we use the directory provided by the user.
runResult = self.runMochitests(options, onLaunch)
if runResult == -1:
return 0
result = self.runMochitests(options, onLaunch)
# printing total number of tests
if options.browserChrome:
@ -1470,6 +1466,8 @@ class Mochitest(MochitestUtilsMixin):
print "3 INFO Todo: %s" % self.counttodo
print "4 INFO SimpleTest FINISHED"
return result
def doTests(self, options, onLaunch=None, testsToFilter = None):
# A call to initializeLooping method is required in case of --run-by-dir or --bisect-chunk
# since we need to initialize variables for each loop.