Bug 930025 - b2g unittests need to check for crashes in more places, r=jgriffin

This commit is contained in:
Andrew Halberstadt 2013-10-23 14:45:48 -04:00
parent b32a2a0bea
commit 45febf0fde
6 changed files with 49 additions and 27 deletions

View File

@ -15,11 +15,12 @@ import mozcrash
class B2GInstance(B2GBuild):
def __init__(self, devicemanager=None, **kwargs):
def __init__(self, devicemanager=None, symbols_path=None, **kwargs):
B2GBuild.__init__(self, **kwargs)
self._dm = devicemanager
self._remote_profiles = None
self.symbols_path = symbols_path
@property
def dm(self):
@ -52,14 +53,14 @@ class B2GInstance(B2GBuild):
self._remote_profiles = remote_profiles
return remote_profiles
def check_for_crashes(self, symbols_path):
def check_for_crashes(self):
remote_dump_dirs = [posixpath.join(p, 'minidumps') for p in self.remote_profiles]
crashed = False
for remote_dump_dir in remote_dump_dirs:
local_dump_dir = tempfile.mkdtemp()
self.dm.getDirectory(remote_dump_dir, local_dump_dir)
try:
if mozcrash.check_for_crashes(local_dump_dir, symbols_path):
if mozcrash.check_for_crashes(local_dump_dir, self.symbols_path):
crashed = True
except:
traceback.print_exc()

View File

@ -48,7 +48,7 @@ class Emulator(object):
def __init__(self, homedir=None, noWindow=False, logcat_dir=None,
arch="x86", emulatorBinary=None, res=None, sdcard=None,
userdata=None):
symbols_path=None, userdata=None):
self.port = None
self.dm = None
self._emulator_launched = False
@ -69,6 +69,7 @@ class Emulator(object):
self.screen = EmulatorScreen(self)
self.homedir = homedir
self.sdcard = sdcard
self.symbols_path = symbols_path
self.noWindow = noWindow
if self.homedir is not None:
self.homedir = os.path.expanduser(homedir)
@ -76,7 +77,8 @@ class Emulator(object):
self.copy_userdata = self.dataImg is None
def _check_for_b2g(self):
self.b2g = B2GInstance(homedir=self.homedir, emulator=True)
self.b2g = B2GInstance(homedir=self.homedir, emulator=True,
symbols_path=self.symbols_path)
self.adb = self.b2g.adb_path
self.homedir = self.b2g.homedir
@ -159,13 +161,11 @@ class Emulator(object):
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
return self._emulator_launched and self.proc is not None \
and self.proc.poll() is not None
def check_for_minidumps(self, symbols_path):
return self.b2g.check_for_crashes(symbols_path)
def check_for_minidumps(self):
return self.b2g.check_for_crashes()
def create_sdcard(self, sdcard):
self._tmp_sdcard = tempfile.mktemp(prefix='sdcard')
@ -274,6 +274,9 @@ waitFor(
# older emulators. 45s *should* be enough of a delay
# to allow telephony API's to work.
pass
except InvalidResponseException:
self.check_for_minidumps()
raise
print 'done'
marionette.set_context(marionette.CONTEXT_CONTENT)
marionette.delete_session()

View File

@ -442,7 +442,6 @@ class Marionette(object):
self.noWindow = noWindow
self.logcat_dir = logcat_dir
self._test_name = None
self.symbols_path = symbols_path
self.timeout = timeout
self.device_serial = device_serial
@ -471,6 +470,7 @@ class Marionette(object):
logcat_dir=self.logcat_dir,
arch=emulator,
sdcard=sdcard,
symbols_path=symbols_path,
emulatorBinary=emulatorBinary,
userdata=emulatorImg,
res=emulator_res)
@ -648,7 +648,7 @@ class Marionette(object):
name = 'emulator'
crashed = True
if self.symbols_path and self.emulator.check_for_minidumps(self.symbols_path):
if self.emulator.check_for_minidumps():
crashed = True
elif self.instance:
# In the future, a check for crashed Firefox processes

View File

@ -130,6 +130,7 @@ class B2GMochitest(MochitestUtilsMixin):
'devicemanager': self._dm,
'marionette': self.marionette,
'remote_test_root': self.remote_test_root,
'symbols_path': options.symbolsPath,
'test_script': self.test_script,
'test_script_args': self.test_script_args }
self.runner = B2GRunner(**runner_args)
@ -144,6 +145,7 @@ class B2GMochitest(MochitestUtilsMixin):
except:
traceback.print_exc()
log.error("Automation Error: Received unexpected exception while running application\n")
self.runner.check_for_crashes()
status = 1
self.stopWebServer(options)

View File

@ -6,11 +6,9 @@ import shutil
import subprocess
import tempfile
import time
import traceback
from runner import Runner
from mozdevice import DMError
import mozcrash
import mozlog
__all__ = ['RemoteRunner', 'B2GRunner', 'remote_runners']
@ -23,13 +21,15 @@ class RemoteRunner(Runner):
process_class=None,
env=None,
remote_test_root=None,
restore=True):
restore=True,
**kwargs):
super(RemoteRunner, self).__init__(profile, clean_profile=clean_profile,
process_class=process_class, env=env)
process_class=process_class, env=env, **kwargs)
self.log = mozlog.getLogger('RemoteRunner')
self.dm = devicemanager
self.last_test = None
self.remote_test_root = remote_test_root or self.dm.getDeviceRoot()
self.remote_profile = posixpath.join(self.remote_test_root, 'profile')
self.restore = restore
@ -44,20 +44,21 @@ class RemoteRunner(Runner):
self.backup_files.add(remote_path)
def check_for_crashes(self, symbols_path, last_test=None):
crashed = False
def check_for_crashes(self, last_test=None):
last_test = last_test or self.last_test
remote_dump_dir = posixpath.join(self.remote_profile, 'minidumps')
crashed = False
self.log.info("checking for crashes in '%s'" % remote_dump_dir)
if self.dm.dirExists(remote_dump_dir):
local_dump_dir = tempfile.mkdtemp()
self.dm.getDirectory(remote_dump_dir, local_dump_dir)
try:
crashed = mozcrash.check_for_crashes(local_dump_dir, symbols_path, test_name=last_test)
except:
traceback.print_exc()
finally:
crashed = super(RemoteRunner, self).check_for_crashes(local_dump_dir, \
test_name=last_test)
shutil.rmtree(local_dump_dir)
self.dm.removeDir(remote_dump_dir)
return crashed
def cleanup(self):
@ -197,6 +198,7 @@ class B2GRunner(RemoteRunner):
msg = "%s with no output" % msg
self.log.testFail(msg % (self.last_test, timeout))
self.check_for_crashes()
def _reboot_device(self):
serial, status = self._get_device_status()

View File

@ -4,8 +4,10 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
import subprocess
import traceback
from mozprocess.processhandler import ProcessHandler
import mozcrash
import mozlog
# we can replace this method with 'abc'
@ -21,7 +23,8 @@ def abstractmethod(method):
class Runner(object):
def __init__(self, profile, clean_profile=True, process_class=None, kp_kwargs=None, env=None):
def __init__(self, profile, clean_profile=True, process_class=None,
kp_kwargs=None, env=None, symbols_path=None):
self.clean_profile = clean_profile
self.env = env or {}
self.kp_kwargs = kp_kwargs or {}
@ -29,6 +32,7 @@ class Runner(object):
self.process_handler = None
self.profile = profile
self.log = mozlog.getLogger('MozRunner')
self.symbols_path = symbols_path
@abstractmethod
def start(self, *args, **kwargs):
@ -103,6 +107,16 @@ class Runner(object):
if getattr(self, 'profile', False):
self.profile.reset()
def check_for_crashes(self, dump_directory, test_name=None):
crashed = False
try:
crashed = mozcrash.check_for_crashes(dump_directory,
self.symbols_path,
test_name=test_name)
except:
traceback.print_exc()
return crashed
def cleanup(self):
"""
Cleanup all runner state