Bug 803254 - Detect emulator crashes, r=ahal, DONTBUILD, a=NPOTB

This commit is contained in:
Jonathan Griffin 2012-10-22 15:00:54 -07:00
Родитель 241e1e76f6
Коммит c064d66316
4 изменённых файлов: 69 добавлений и 5 удалений

Просмотреть файл

@ -150,6 +150,20 @@ class Emulator(object):
else:
return self.port is not None
def check_for_crash(self):
"""
Checks if the emulator has crashed or not. Always returns False if
we've connected to an already-running emulator, since we can't track
the emulator's pid in that case. Otherwise, returns True iff
self.proc is not None (meaning the emulator hasn't been explicitly
closed), and self.proc.poll() is also not None (meaning the emulator
process has terminated).
"""
if (self._emulator_launched and self.proc is not None
and self.proc.poll() is not None):
return True
return False
def create_sdcard(self, sdcard):
self._tmp_sdcard = tempfile.mktemp(prefix='sdcard')
sdargs = [self.mksdcard, "-l", "mySdCard", sdcard, self._tmp_sdcard]

Просмотреть файл

@ -266,6 +266,22 @@ class Marionette(object):
raise MarionetteException(message=message, status=status, stacktrace=stacktrace)
raise MarionetteException(message=response, status=500)
def check_for_crash(self):
returncode = None
name = None
if self.emulator:
if self.emulator.check_for_crash():
returncode = self.emulator.proc.returncode
name = 'emulator'
elif self.instance:
# In the future, a check for crashed Firefox processes
# should be here.
pass
if returncode is not None:
print ('TEST-UNEXPECTED-FAIL - PROCESS CRASH - %s has terminated with exit code %d' %
(name, returncode))
return returncode is not None
def absolute_url(self, relative_url):
return "%s%s" % (self.baseurl, relative_url)

Просмотреть файл

@ -33,8 +33,10 @@ from marionette_test import MarionetteJSTestCase, MarionetteTestCase
class MarionetteTestResult(unittest._TextTestResult):
def __init__(self, *args):
super(MarionetteTestResult, self).__init__(*args)
def __init__(self, *args, **kwargs):
self.marionette = kwargs['marionette']
del kwargs['marionette']
super(MarionetteTestResult, self).__init__(*args, **kwargs)
self.passed = 0
self.perfdata = None
self.tests_passed = []
@ -88,6 +90,12 @@ class MarionetteTestResult(unittest._TextTestResult):
self.stream.writeln("%s" % line)
self.stream.writeln("TEST-UNEXPECTED-FAIL : %s" % errlines[-1])
def stopTest(self, *args, **kwargs):
unittest._TextTestResult.stopTest(self, *args, **kwargs)
if self.marionette.check_for_crash():
# this tells unittest.TestSuite not to continue running tests
self.shouldStop = True
class MarionetteTextTestRunner(unittest.TextTestRunner):
@ -96,10 +104,15 @@ class MarionetteTextTestRunner(unittest.TextTestRunner):
def __init__(self, **kwargs):
self.perf = kwargs['perf']
del kwargs['perf']
self.marionette = kwargs['marionette']
del kwargs['marionette']
unittest.TextTestRunner.__init__(self, **kwargs)
def _makeResult(self):
return self.resultclass(self.stream, self.descriptions, self.verbosity)
return self.resultclass(self.stream,
self.descriptions,
self.verbosity,
marionette=self.marionette)
def run(self, test):
"Run the given test case or test suite."
@ -372,6 +385,8 @@ class MarionetteTestRunner(object):
(filename.endswith('.py') or filename.endswith('.js'))):
filepath = os.path.join(root, filename)
self.run_test(filepath, testtype)
if self.marionette.check_for_crash():
return
return
mod_name,file_ext = os.path.splitext(os.path.split(filepath)[-1])
@ -422,6 +437,8 @@ class MarionetteTestRunner(object):
for i in manifest_tests:
self.run_test(i["path"], testtype)
if self.marionette.check_for_crash():
return
return
self.logger.info('TEST-START %s' % os.path.basename(test))
@ -432,7 +449,10 @@ class MarionetteTestRunner(object):
break
if suite.countTestCases():
results = MarionetteTextTestRunner(verbosity=3, perf=self.perf).run(suite)
runner = MarionetteTextTestRunner(verbosity=3,
perf=self.perf,
marionette=self.marionette)
results = runner.run(suite)
self.results.append(results)
self.failed += len(results.failures) + len(results.errors)

Просмотреть файл

@ -87,6 +87,20 @@ class Emulator(object):
else:
return self.port is not None
def check_for_crash(self):
"""
Checks if the emulator has crashed or not. Always returns False if
we've connected to an already-running emulator, since we can't track
the emulator's pid in that case. Otherwise, returns True iff
self.proc is not None (meaning the emulator hasn't been explicitly
closed), and self.proc.poll() is also not None (meaning the emulator
process has terminated).
"""
if (self._emulator_launched and self.proc is not None
and self.proc.poll() is not None):
return True
return False
def _default_adb(self):
adb = subprocess.Popen(['which', 'adb'],
stdout=subprocess.PIPE,