Bug 843296 - check for crashes in b2g emulator unittests during failures in marionette start up, r=jgriffin

This commit is contained in:
Andrew Halberstadt 2013-03-26 09:50:00 -04:00
parent 29e85efb07
commit f7f283237c
7 changed files with 82 additions and 5 deletions

View File

@ -10,6 +10,7 @@ import re
import shutil
import tempfile
import time
import traceback
from automation import Automation
from devicemanager import NetworkTools
@ -106,11 +107,14 @@ class B2GRemoteAutomation(Automation):
def checkForCrashes(self, directory, symbolsPath):
crashed = False
remote_dump_dir = self._remoteProfile + '/minidumps'
print "checking for crashes in '%s'" % remote_dump_dir
if self._devicemanager.dirExists(remote_dump_dir):
local_dump_dir = tempfile.mkdtemp()
self._devicemanager.getDirectory(remote_dump_dir, local_dump_dir)
try:
crashed = mozcrash.check_for_crashes(local_dump_dir, symbolsPath, test_name=self.lastTestSeen)
except:
traceback.print_exc()
finally:
shutil.rmtree(local_dump_dir)
self._devicemanager.removeDir(remote_dump_dir)

View File

@ -480,6 +480,8 @@ def main(args=sys.argv[1:]):
kwargs['logcat_dir'] = options.logcat_dir
if options.busybox:
kwargs['busybox'] = options.busybox
if options.symbolsPath:
kwargs['symbols_path'] = options.symbolsPath
if options.emulator_res:
kwargs['emulator_res'] = options.emulator_res
if options.b2gPath:

View File

@ -2,10 +2,18 @@
# 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/.
from ConfigParser import ConfigParser
import os
import platform
import posixpath
import shutil
import subprocess
import sys
import tempfile
import traceback
from mozdevice import DeviceManagerADB
import mozcrash
class B2GInstance(object):
@classmethod
@ -68,7 +76,7 @@ class B2GInstance(object):
return option
raise Exception('%s not found!' % binary)
def __init__(self, homedir=None):
def __init__(self, homedir=None, devicemanager=None):
if not homedir:
homedir = self.find_b2g_dir()
else:
@ -81,6 +89,13 @@ class B2GInstance(object):
self.adb_path = self.check_adb(self.homedir)
self.fastboot_path = self.check_fastboot(self.homedir)
self.update_tools = os.path.join(self.homedir, 'tools', 'update-tools')
self._dm = devicemanager
@property
def dm(self):
if not self._dm:
self._dm = DeviceManagerADB(adbPath=self.adb_path)
return self._dm
def check_file(self, filePath):
if not os.access(filePath, os.F_OK):
@ -88,6 +103,43 @@ class B2GInstance(object):
'directory as the homedir parameter, or set '
'B2G_HOME correctly?') % filePath)
def check_remote_profiles(self, remote_profiles_ini='/data/b2g/mozilla/profiles.ini'):
if not self.dm.fileExists(remote_profiles_ini):
raise Exception("Remote file '%s' not found" % remote_profiles_ini)
local_profiles_ini = tempfile.NamedTemporaryFile()
self.dm.getFile(remote_profiles_ini, local_profiles_ini.name)
cfg = ConfigParser()
cfg.readfp(local_profiles_ini)
remote_profiles = []
for section in cfg.sections():
if cfg.has_option(section, 'Path'):
is_relative = 0
if cfg.has_option(section, 'IsRelative'):
is_relative = cfg.getint(section, 'IsRelative')
remote_profiles.append(posixpath.join(remote_profiles_ini, cfg.get(section, 'Path'))
if is_relative else cfg.get(section, 'Path'))
return remote_profiles
def check_for_crashes(self, symbols_path):
remote_dump_dirs = [posixpath.join(p, 'minidumps') for p in self.check_remote_profiles()]
crashed = False
for remote_dump_dir in remote_dump_dirs:
print "checking for crashes in '%s'" % remote_dump_dir
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):
crashed = True
except:
traceback.print_exc()
finally:
shutil.rmtree(local_dump_dir)
self.dm.removeDir(remote_dump_dir)
return crashed
def import_update_tools(self):
"""Import the update_tools package from B2G"""
sys.path.append(self.update_tools)

View File

@ -162,6 +162,9 @@ class Emulator(object):
return True
return False
def check_for_minidumps(self, symbols_path):
return self.b2g.check_for_crashes(symbols_path)
def create_sdcard(self, sdcard):
self._tmp_sdcard = tempfile.mktemp(prefix='sdcard')
sdargs = [self.mksdcard, "-l", "mySdCard", sdcard, self._tmp_sdcard]

View File

@ -168,7 +168,7 @@ class Marionette(object):
emulator=None, sdcard=None, emulatorBinary=None,
emulatorImg=None, emulator_res=None, gecko_path=None,
connectToRunningEmulator=False, homedir=None, baseurl=None,
noWindow=False, logcat_dir=None, busybox=None):
noWindow=False, logcat_dir=None, busybox=None, symbols_path=None):
self.host = host
self.port = self.local_port = port
self.bin = bin
@ -183,6 +183,7 @@ class Marionette(object):
self.noWindow = noWindow
self.logcat_dir = logcat_dir
self._test_name = None
self.symbols_path = symbols_path
if bin:
port = int(self.port)
@ -366,10 +367,15 @@ class Marionette(object):
def check_for_crash(self):
returncode = None
name = None
crashed = False
if self.emulator:
if self.emulator.check_for_crash():
returncode = self.emulator.proc.returncode
name = 'emulator'
crashed = True
if self.symbols_path and self.emulator.check_for_minidumps(self.symbols_path):
crashed = True
elif self.instance:
# In the future, a check for crashed Firefox processes
# should be here.
@ -377,7 +383,7 @@ class Marionette(object):
if returncode is not None:
print ('PROCESS-CRASH | %s | abnormal termination with exit code %d' %
(name, returncode))
return returncode is not None
return crashed
def absolute_url(self, relative_url):
return "%s%s" % (self.baseurl, relative_url)
@ -386,8 +392,14 @@ class Marionette(object):
return self._send_message('getStatus', 'value')
def start_session(self, desired_capabilities=None):
# We are ignoring desired_capabilities, at least for now.
self.session = self._send_message('newSession', 'value')
try:
# We are ignoring desired_capabilities, at least for now.
self.session = self._send_message('newSession', 'value')
except:
traceback.print_exc()
self.check_for_crash()
sys.exit()
self.b2g = 'b2g' in self.session
return self.session

View File

@ -566,6 +566,8 @@ def run_remote_mochitests(automation, parser, options):
kwargs['logcat_dir'] = options.logcat_dir
if options.busybox:
kwargs['busybox'] = options.busybox
if options.symbolsPath:
kwargs['symbols_path'] = options.symbolsPath
# needless to say sdcard is only valid if using an emulator
if options.sdcard:
kwargs['sdcard'] = options.sdcard

View File

@ -167,6 +167,8 @@ def main():
kwargs['logcat_dir'] = options.logcat_dir
if options.busybox:
kwargs['busybox'] = options.busybox
if options.symbolsPath:
kwargs['symbols_path'] = options.symbolsPath
if options.b2g_path:
kwargs['homedir'] = options.emu_path or options.b2g_path
if options.address: