Bug 976120 - shell.js should respect crash reporting environment, r=fabrice

This commit is contained in:
Andrew Halberstadt 2014-02-27 16:36:00 -05:00
Родитель 73232d1943
Коммит 06fdef4132
4 изменённых файлов: 98 добавлений и 25 удалений

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

@ -11,3 +11,4 @@ from errors import *
from runner import *
from wait import Wait
from date_time_value import DateTimeValue
import decorators

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

@ -0,0 +1,65 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# 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 errors import MarionetteException
from functools import wraps
import sys
import traceback
def _find_marionette_in_args(*args, **kwargs):
try:
m = [a for a in args + tuple(kwargs.values()) if hasattr(a, 'session')][0]
except IndexError:
print("Can only apply decorator to function using a marionette object")
raise
return m
def do_crash_check(func, always=False):
"""Decorator which checks for crashes after the function has run.
:param always: If False, only checks for crashes if an exception
was raised. If True, always checks for crashes.
"""
@wraps(func)
def _(*args, **kwargs):
def check():
m = _find_marionette_in_args(*args, **kwargs)
try:
m.check_for_crash()
except:
# don't want to lose the original exception
traceback.print_exc()
try:
return func(*args, **kwargs)
except MarionetteException:
exc, val, tb = sys.exc_info()
if not always:
check()
raise exc, val, tb
finally:
if always:
check()
return _
def uses_marionette(func):
"""Decorator which creates a marionette session and deletes it
afterwards if one doesn't already exist.
"""
@wraps(func)
def _(*args, **kwargs):
m = _find_marionette_in_args(*args, **kwargs)
delete_session = False
if not m.session:
delete_session = True
m.start_session()
m.set_context(m.CONTEXT_CHROME)
ret = func(*args, **kwargs)
if delete_session:
m.delete_session()
return ret
return _

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

@ -4,7 +4,6 @@
from b2ginstance import B2GInstance
import datetime
from errors import *
from mozdevice import devicemanagerADB, DMError
from mozprocess import ProcessHandlerMixin
import os
@ -21,6 +20,15 @@ import traceback
from emulator_battery import EmulatorBattery
from emulator_geo import EmulatorGeo
from emulator_screen import EmulatorScreen
from decorators import uses_marionette
from errors import (
InstallGeckoError,
InvalidResponseException,
MarionetteException,
ScriptTimeoutException,
TimeoutException
)
class LogOutputProc(ProcessHandlerMixin):
@ -51,6 +59,9 @@ class Emulator(object):
prefs = {'app.update.enabled': False,
'app.update.staging.enabled': False,
'app.update.service.enabled': False}
env = {'MOZ_CRASHREPORTER': '1',
'MOZ_CRASHREPORTER_NO_REPORT': '1',
'MOZ_CRASHREPORTER_SHUTDOWN': '1'}
def __init__(self, homedir=None, noWindow=False, logcat_dir=None,
arch="x86", emulatorBinary=None, res=None, sdcard=None,
@ -256,9 +267,8 @@ class Emulator(object):
else:
self._adb_started = False
@uses_marionette
def wait_for_system_message(self, marionette):
marionette.start_session()
marionette.set_context(marionette.CONTEXT_CHROME)
marionette.set_script_timeout(45000)
# Telephony API's won't be available immediately upon emulator
# boot; we have to wait for the syste-message-listener-ready
@ -282,9 +292,7 @@ waitFor(
except InvalidResponseException:
self.check_for_minidumps()
raise
print 'done'
marionette.set_context(marionette.CONTEXT_CONTENT)
marionette.delete_session()
print '...done'
def connect(self):
self.adb = B2GInstance.check_adb(self.homedir, emulator=True)
@ -355,14 +363,10 @@ waitFor(
# setup DNS fix for networking
self._run_adb(['shell', 'setprop', 'net.dns1', '10.0.2.3'])
@uses_marionette
def wait_for_homescreen(self, marionette):
print 'waiting for homescreen...'
created_session = False
if not marionette.session:
marionette.start_session()
created_session = True
marionette.set_context(marionette.CONTEXT_CONTENT)
marionette.execute_async_script("""
log('waiting for mozbrowserloadend');
@ -374,10 +378,9 @@ window.addEventListener('mozbrowserloadend', function loaded(aEvent) {
}
});""", script_timeout=120000)
print '...done'
if created_session:
marionette.delete_session()
def setup(self, marionette, gecko_path=None, busybox=None):
self.set_environment(marionette)
if busybox:
self.install_busybox(busybox)
@ -387,9 +390,17 @@ window.addEventListener('mozbrowserloadend', function loaded(aEvent) {
self.wait_for_system_message(marionette)
self.set_prefs(marionette)
@uses_marionette
def set_environment(self, marionette):
for k, v in self.env.iteritems():
marionette.execute_script("""
let env = Cc["@mozilla.org/process/environment;1"].
getService(Ci.nsIEnvironment);
env.set("%s", "%s");
""" % (k, v))
@uses_marionette
def set_prefs(self, marionette):
marionette.start_session()
marionette.set_context(marionette.CONTEXT_CHROME)
for pref in self.prefs:
marionette.execute_script("""
Components.utils.import("resource://gre/modules/Services.jsm");
@ -405,7 +416,6 @@ window.addEventListener('mozbrowserloadend', function loaded(aEvent) {
Services.prefs.setCharPref(arguments[0], arguments[1]);
}
""", [pref, self.prefs[pref]])
marionette.delete_session()
def restart_b2g(self):
print 'restarting B2G'

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

@ -12,6 +12,7 @@ import traceback
from application_cache import ApplicationCache
from client import MarionetteClient
from decorators import do_crash_check
from emulator import Emulator
from emulator_screen import EmulatorScreen
from errors import *
@ -420,6 +421,7 @@ class MultiActions(object):
'''
return self.marionette._send_message('multiAction', 'ok', value=self.multi_actions, max_length=self.max_length)
class Marionette(object):
"""
Represents a Marionette connection to a browser or device.
@ -584,6 +586,7 @@ class Marionette(object):
time.sleep(1)
return False
@do_crash_check
def _send_message(self, command, response_key="ok", **kwargs):
if not self.session and command != "newSession":
raise MarionetteException("Please start a session")
@ -596,7 +599,7 @@ class Marionette(object):
try:
response = self.client.send(message)
except socket.timeout as e:
except socket.timeout:
self.session = None
self.window = None
self.client.close()
@ -714,14 +717,8 @@ class Marionette(object):
"""
try:
# We are ignoring desired_capabilities, at least for now.
self.session = self._send_message('newSession', 'value')
except:
exc, val, tb = sys.exc_info()
self.check_for_crash()
raise exc, val, tb
# We are ignoring desired_capabilities, at least for now.
self.session = self._send_message('newSession', 'value')
self.b2g = 'b2g' in self.session
return self.session