mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:30:27 +00:00
9489c945bf
- Bug 1169798 - Refresh the marionette server's window reference when switching between windows to avoid intermittent exception.;r=ato (606c3f22d8) - Bug 1169600 - Avoid misleading exception in message listeners in marionette server. r=ato (ec8d12becf) - Bug 1174941: Update server capabilities that are set on startup; r=ato (9ca7a8be79) - Bug 1174941: Remove all capabilities from desired capabilities if they are in the session capabilitiesand in requiredCapabilities; r=ato (453c905a90) - Bug 1174941: Update conditional to switch statement to allow more processing of capabilities; r=ato (1460802be1) - NO BUG: correct import in marionette about_pages tests r=me DONTBUILD (cad6eecb22) - Bug 1169600 - Remove message listeners intended to coordinate registering a new browser with marionette once the browser has been registered. r=ato (86fed67200) - Bug 1165449: Add the ability to set a proxy via capabilities on Marionette session start; r=jgriffin (b2107767bb) - Bug 1178468 - Update marionette cookie support to use nsICookie2. r=jgriffin (90a140c915) - Bug 1196920: Add specificationLevel capability to Marionette; r=jgriffin (d64f1b7b2e) - Bug 1197131: Use dispatcher for listener getCurrentUrl (b2ca32f3d0) - Bug 1197146: Part 2: Use dispatcher for listener findElementsContent (f324b851a6) - Bug 1197146: Part 1: Prime dispatcher in listener to resolve promises (947dc5bd29) - Bug 1197133: Use dispatcher for listener getTitle (76b884bb21) - Bug 1197141: Use dispatcher for listener getPageSource (7ad171b976) - Bug 1197143: Use dispatcher for listener goBack (c8302aa896) - Bug 1191432 - improving coverage for marionette accessibility checks. r=automatedtester (4ce11c5110) - Bug 1197146: Part 3: Use dispatcher for listener findElementContent (26fe7c4198) - Bug 1197146: Part 4: Use dispatcher for listener isElementSelected (de51ad7e17) - Bug 1197146: Part 5: Use dispatcher for listener getElementLocation (5c0620ad1d) - Bug 1197146: Part 6: Use dispatcher for listener clearElement (811670ed39) - Bug 1155716: Part 1: Remove submitElement from Marionette (52122d817e) - Bug 1197146: Part 7: Use dispatcher for listener isElementDisplayed (e7408e94ce) - Bug 1197146: Part 8: Use dispatcher for listener getElementValueOfCssProperty (591c71ba82) - Bug 1196987: Update UUID returned to be a valid UUID 4; r=jgriffin (e0b19efc78) - Bug 1152682: Correct invalid selector errors in elements.js (5466b28ff7) - Bug 1194224 - adding support for Shadow DOM in marionette. r=automatedtester (0f2b2580b9) - Bug 1200420 - Better handling of startup_timeout, r=AutomatedTester (0ae69578ab) - Bug 1139158 - Actions made availabe via marionette_driver object. r=jgriffin (4713e8fc1e) - goanna -> gecko (fa2a0d674f) - Bug 1143565: Change requirements to not be fixed to a specific marionette transport and driver; r=chmanchester (cbc9e7eab6) - Bug 1150050 - Bump manifestparser to v1.1 and marionette-client to v0.9.3 to pick up tagging feature, r=AutomatedTester (f63a01da3b) - Bug 1157823 - Update dependency to reflect that the marionette client requires a more recent mozhttpd. r=ato (594cde8a5e) - Bug 1155260: Fix base URL override in Marionette runner (a99bd14cac) - Bug 1159816 - Bump marionette_client to 0.12. DONTBUILD. CLOSED TREE. r=chmanchester (779b4c9866) - Bug 1161209 - Bump marionette-driver to 0.7, marionette-client to 0.13, r=AutomatedTester (175cc7adea) - Bug 1163833 - Add integration with browsermob-proxy, r=dburns (bd90184ee1) - Bug 983821 - 'marionette' cli entrypoint doesn't have access to proper packages. r=dburns (17d4abf193) - Bug 1168997 - Bump marionette-client to 0.14, r=dburns (5c10bd3404) - Bug 1169751 - Bump marionette-driver to 0.8, marionette-client to 0.15, r=dburns (95b3c45faa) - Bug 1177513 - Bump marionette-client to 0.16, r=dburns (d1228ed4bb) - Bug 902125 - Add a version config/flag for Python Marionette. r=dburns (f72e7463d7) - Bug 1177780 - remove useless stuff in automation.py. r=jgriffin (d0d0baf473) - partial of Bug 1170332 - Fix |mach robocop SINGLE_TEST|. (0838005e10) - goanna->gecko (ef97631963) - Bug 1162285 - Remove unused environment vars on Android; r=jmaher (bf6b44a3ae) - Bug 1160324 - Handle missing robocopApk files in runtestsremote.py. r=gbrown (3d5c874630) - Bug 1169476 -- Implement |mach robocop --serve|. r=gbrown (11039daa39) - Bug 1160351 - Improve newline handling in getLogcat; r=bc Bug 1160351 - Bustage fix for 57c6c589cfa1 on a CLOSED TREE (d64b410ef4) - Bug 1137289 - Guard against dumpsys failure in DroidADB; r=jmaher (4a39532464) - Bug 1175540 - Reduce timeouts for many adb devicemanager calls; r=mcote (528209a4d6) - bit of Bug 1160662 - Refer to robocop.ini in $OBJDIR/_tests, not $OBJDIR (c288d73c16) - Bug 1162479 - Fix mochitest make target regression with duplicate extraProfilePath, r=chmanchester (53251cff28) - Bug 1151533 - Upgrade manually set tc xre r=me (3bb5f8fecd) - Bug 1161709 - Pull from artifacts for xulrunner instead of s3 directly r=me (6314094083) - Bug 1144528 - Use hg share on testers r=garndt ON CLOSED TREE (46779ab50c) - Bug 1142565 - Update tester images to include same fonts as test slaves r=garndt (cf9e546dfa) - bits of Bug 1144927 - Directly bake in linux64-minidump_stackwak to tester images r=garndt (8b1f3ff968) - Bug 1157308 - part 1 - Reduce the leak threshold for content processes more. r=erahm (177289cf32) - Bug 1157308 - part 2 - Reduce the content process leak limit on OS X. r=erahm (98d14f78cd) - Bug 1173114 - Fallback to chunk-by-dir if runtimes file not found, r=ahal (c7cb797636) - Bug 1026290 - Avoid TypeError during Android mochitest-chrome; r=chmanchester (a8112e6ca1) - Bug 1173971 - Force core Xlib events on GTK3. r=karlt (17fc2475e0) - Bug 1144194 - Only parse test manifests once in mochitest, r=jmaher (37f5c3a764) - Bug 1171971 - Move test_paths argument out of mach and into mochitest; remove --test-path, r=chmanchester (3ab9acf758) - Bug 1178154 - move ShutdownLeaks and LSANLeaks from automationutils to mochitest. r=jgriffin (e8ec293a91) - Bug 1156982 - Add separators to BloatView output. r=froydnj (ac92a67ba9) - Bug 1152872 - Don't attempt to leak-check the tools that we run as part of the setup for the mochitest suite; r=mccr8 (dd78bcc8bc) - Bug 1158227 - part 1 - don't run TSan on test tools or the xpcshell HTTP server in mochitests; r=jmaher (59bbf448e5) - Bug 1158227 - part 2 - set TSAN_OPTIONS environment variable in automationutils.py for TSan; r=jmaher (66e607b25e) - Bug 1091284 - Remove systemMemory, environment from automationutils. r=jgriffin (817860ab08)
271 lines
11 KiB
Python
271 lines
11 KiB
Python
import math
|
|
import mozinfo
|
|
|
|
|
|
class Bisect(object):
|
|
|
|
"Class for creating, bisecting and summarizing for --bisect-chunk option."
|
|
|
|
def __init__(self, harness):
|
|
super(Bisect, self).__init__()
|
|
self.summary = []
|
|
self.contents = {}
|
|
self.repeat = 10
|
|
self.failcount = 0
|
|
self.max_failures = 3
|
|
|
|
def setup(self, tests):
|
|
"This method is used to initialize various variables that are required for test bisection"
|
|
status = 0
|
|
self.contents.clear()
|
|
# We need totalTests key in contents for sanity check
|
|
self.contents['totalTests'] = tests
|
|
self.contents['tests'] = tests
|
|
self.contents['loop'] = 0
|
|
return status
|
|
|
|
def reset(self, expectedError, result):
|
|
"This method is used to initialize self.expectedError and self.result for each loop in runtests."
|
|
self.expectedError = expectedError
|
|
self.result = result
|
|
|
|
def get_tests_for_bisection(self, options, tests):
|
|
"Make a list of tests for bisection from a given list of tests"
|
|
bisectlist = []
|
|
for test in tests:
|
|
bisectlist.append(test)
|
|
if test.endswith(options.bisectChunk):
|
|
break
|
|
|
|
return bisectlist
|
|
|
|
def pre_test(self, options, tests, status):
|
|
"This method is used to call other methods for setting up variables and getting the list of tests for bisection."
|
|
if options.bisectChunk == "default":
|
|
return tests
|
|
# The second condition in 'if' is required to verify that the failing
|
|
# test is the last one.
|
|
elif 'loop' not in self.contents or not self.contents['tests'][-1].endswith(options.bisectChunk):
|
|
tests = self.get_tests_for_bisection(options, tests)
|
|
status = self.setup(tests)
|
|
|
|
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."
|
|
self.reset(expectedError, result)
|
|
status = self.summarize_chunk(options)
|
|
# Check whether sanity check has to be done. Also it is necessary to check whether options.bisectChunk is present
|
|
# in self.expectedError as we do not want to run if it is "default".
|
|
if status == -1 and options.bisectChunk in self.expectedError:
|
|
# In case we have a debug build, we don't want to run a sanity
|
|
# check, will take too much time.
|
|
if mozinfo.info['debug']:
|
|
return status
|
|
|
|
testBleedThrough = self.contents['testsToRun'][0]
|
|
tests = self.contents['totalTests']
|
|
tests.remove(testBleedThrough)
|
|
# To make sure that the failing test is dependent on some other
|
|
# test.
|
|
if options.bisectChunk in testBleedThrough:
|
|
return status
|
|
|
|
status = self.setup(tests)
|
|
self.summary.append("Sanity Check:")
|
|
|
|
return status
|
|
|
|
def next_chunk_reverse(self, options, status):
|
|
"This method is used to bisect the tests in a reverse 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']
|
|
|
|
if 'result' in self.contents:
|
|
if self.contents['result'] == "PASS":
|
|
chunkSize = self.contents['end'] - self.contents['start']
|
|
self.contents['end'] = self.contents['start'] - 1
|
|
self.contents['start'] = self.contents['end'] - chunkSize
|
|
|
|
# self.contents['result'] will be expected error only if it fails.
|
|
elif self.contents['result'] == "FAIL":
|
|
self.contents['tests'] = self.contents['testsToRun']
|
|
status = 1 # for initializing
|
|
|
|
# initialize
|
|
if status:
|
|
totalTests = len(self.contents['tests'])
|
|
chunkSize = int(math.ceil(totalTests / 10.0))
|
|
self.contents['start'] = totalTests - chunkSize - 1
|
|
self.contents['end'] = totalTests - 2
|
|
|
|
start = self.contents['start']
|
|
end = self.contents['end'] + 1
|
|
self.contents['testsToRun'] = self.contents['tests'][start:end]
|
|
self.contents['testsToRun'].append(self.contents['tests'][-1])
|
|
self.contents['loop'] += 1
|
|
|
|
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":
|
|
# if no expectedError that means all the tests have successfully
|
|
# passed.
|
|
if len(self.expectedError) == 0:
|
|
return -1
|
|
options.bisectChunk = self.expectedError.keys()[0]
|
|
self.summary.append(
|
|
"\tFound Error in test: %s" %
|
|
options.bisectChunk)
|
|
return 0
|
|
|
|
# If options.bisectChunk is not in self.result then we need to move to
|
|
# the next run.
|
|
if options.bisectChunk not in self.result:
|
|
return -1
|
|
|
|
self.summary.append("\tPass %d:" % self.contents['loop'])
|
|
if len(self.contents['testsToRun']) > 1:
|
|
self.summary.append(
|
|
"\t\t%d test files(start,end,failing). [%s, %s, %s]" % (len(
|
|
self.contents['testsToRun']),
|
|
self.contents['testsToRun'][0],
|
|
self.contents['testsToRun'][
|
|
-2],
|
|
self.contents['testsToRun'][
|
|
-1]))
|
|
else:
|
|
self.summary.append(
|
|
"\t\t1 test file [%s]" %
|
|
self.contents['testsToRun'][0])
|
|
return self.check_for_intermittent(options)
|
|
|
|
if self.result[options.bisectChunk] == "PASS":
|
|
self.summary.append("\t\tno failures found.")
|
|
if self.contents['loop'] == 1:
|
|
status = -1
|
|
else:
|
|
self.contents['result'] = "PASS"
|
|
status = 0
|
|
|
|
elif self.result[options.bisectChunk] == "FAIL":
|
|
if 'expectedError' not in self.contents:
|
|
self.summary.append("\t\t%s failed." %
|
|
self.contents['testsToRun'][-1])
|
|
self.contents['expectedError'] = self.expectedError[
|
|
options.bisectChunk]
|
|
status = 0
|
|
|
|
elif self.expectedError[options.bisectChunk] == self.contents['expectedError']:
|
|
self.summary.append(
|
|
"\t\t%s failed with expected error." % self.contents['testsToRun'][-1])
|
|
self.contents['result'] = "FAIL"
|
|
status = 0
|
|
|
|
# This code checks for test-bleedthrough. Should work for any
|
|
# algorithm.
|
|
numberOfTests = len(self.contents['testsToRun'])
|
|
if numberOfTests < 3:
|
|
# This means that only 2 tests are run. Since the last test
|
|
# is the failing test itself therefore the bleedthrough
|
|
# test is the first test
|
|
self.summary.append(
|
|
"TEST-UNEXPECTED-FAIL | %s | Bleedthrough detected, this test is the root cause for many of the above failures" %
|
|
self.contents['testsToRun'][0])
|
|
status = -1
|
|
else:
|
|
self.summary.append(
|
|
"\t\t%s failed with different error." % self.contents['testsToRun'][-1])
|
|
status = -1
|
|
|
|
return status
|
|
|
|
def check_for_intermittent(self, options):
|
|
"This method is used to check whether a test is an intermittent."
|
|
if self.result[options.bisectChunk] == "PASS":
|
|
self.summary.append(
|
|
"\t\tThe test %s passed." %
|
|
self.contents['testsToRun'][0])
|
|
if self.repeat > 0:
|
|
# loop is set to 1 to again run the single test.
|
|
self.contents['loop'] = 1
|
|
self.repeat -= 1
|
|
return 0
|
|
else:
|
|
if self.failcount > 0:
|
|
# -1 is being returned as the test is intermittent, so no need to bisect further.
|
|
return -1
|
|
# If the test does not fail even once, then proceed to next chunk for bisection.
|
|
# loop is set to 2 to proceed on bisection.
|
|
self.contents['loop'] = 2
|
|
return 1
|
|
elif self.result[options.bisectChunk] == "FAIL":
|
|
self.summary.append(
|
|
"\t\tThe test %s failed." %
|
|
self.contents['testsToRun'][0])
|
|
self.failcount += 1
|
|
self.contents['loop'] = 1
|
|
self.repeat -= 1
|
|
# self.max_failures is the maximum number of times a test is allowed
|
|
# to fail to be called an intermittent. If a test fails more than
|
|
# limit set, it is a perma-fail.
|
|
if self.failcount < self.max_failures:
|
|
if self.repeat == 0:
|
|
# -1 is being returned as the test is intermittent, so no need to bisect further.
|
|
return -1
|
|
return 0
|
|
else:
|
|
self.summary.append(
|
|
"TEST-UNEXPECTED-FAIL | %s | Bleedthrough detected, this test is the root cause for many of the above failures" %
|
|
self.contents['testsToRun'][0])
|
|
return -1
|
|
|
|
def print_summary(self):
|
|
"This method is used to print the recorded summary."
|
|
print "Bisection summary:"
|
|
for line in self.summary:
|
|
print line
|