Bug 1274408: Remove emulator support from Marionette Harness code r=maja_zf

The emulator code in Marionette harness makes it very hard to be able to
support other platforms. Since we no longer support B2G we should remove it.

MozReview-Commit-ID: 21HYtUdtfHy

--HG--
extra : rebase_source : 98b027494dd98b924a5a9f64c073c2f9197f1ad2
This commit is contained in:
David Burns 2016-05-24 21:52:57 +01:00
Родитель dd43f4c2a6
Коммит 17e6a49b39
8 изменённых файлов: 10 добавлений и 815 удалений

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

@ -1,442 +0,0 @@
# 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 cStringIO import StringIO
import imp
import os
import re
import subprocess
import time
import types
import weakref
from marionette_driver.marionette import Marionette
from marionette_driver import transport
from .marionette_test import MarionetteTestCase
from b2ginstance import B2GInstance
from .runtests import MarionetteTestRunner, cli
class B2GUpdateMarionetteClient(transport.TcpTransport):
RETRY_TIMEOUT = 5
CONNECT_TIMEOUT = 30
SEND_TIMEOUT = 60 * 5
MAX_RETRIES = 24
def __init__(self, addr, port, runner):
super(B2GUpdateMarionetteClient, self).__init__(addr, port, self.CONNECT_TIMEOUT)
self.runner = runner
def connect(self):
""" When using ADB port forwarding, the ADB server will actually accept
connections even though there isn't a listening socket open on the
device. Here we add a retry loop since we have to restart the debug
server / b2g process for update tests
"""
for i in range(self.MAX_RETRIES):
try:
transport.TcpTransport.connect(self)
break
except:
if i == self.MAX_RETRIES - 1:
raise
time.sleep(self.RETRY_TIMEOUT)
self.runner.port_forward()
# Upon success, reset the socket timeout to something more reasonable
self.sock.settimeout(self.SEND_TIMEOUT)
class B2GUpdateTestRunner(MarionetteTestRunner):
match_re = re.compile(r'update_(smoke)?test_(.*)\.py$')
def __init__(self, **kwargs):
MarionetteTestRunner.__init__(self, **kwargs)
if self.emulator or self.bin:
raise Exception('Update tests do not support emulator or custom binaries')
if not self.address:
raise Exception('Update tests must be run with '
'--address=localhost:<port>')
self.host, port = self.address.split(':')
self.port = int(port)
self.test_handlers.append(self)
self.b2g = B2GInstance(homedir=kwargs.get('homedir'))
self.update_tools = self.b2g.import_update_tools()
self.adb = self.update_tools.AdbTool(path=self.b2g.adb_path,
device=self.device_serial)
def match(self, filename):
return self.match_re.match(filename) is not None
def add_tests_to_suite(self, mod_name, filepath, suite, testloader,
marionette, testvars):
""" Here the runner itself is a handler so we can forward along the
instance to test cases.
"""
test_mod = imp.load_source(mod_name, filepath)
def add_test(testcase, testname, **kwargs):
suite.addTest(testcase(weakref.ref(marionette),
methodName=testname,
filepath=filepath,
testvars=testvars,
**kwargs))
# The TestCase classes are apparently being loaded multiple times, so
# using "isinstance" doesn't actually work. This function just compares
# type names as a close enough analog.
def has_super(cls, super_names):
if not isinstance(super_names, (tuple, list)):
super_names = (super_names)
base = cls
while base:
if base.__name__ in super_names:
return True
base = base.__base__
return False
for name in dir(test_mod):
testcase = getattr(test_mod, name)
if not isinstance(testcase, (type, types.ClassType)):
continue
# Support both B2GUpdateTestCase and MarionetteTestCase
if has_super(testcase, 'B2GUpdateTestCase'):
for testname in testloader.getTestCaseNames(testcase):
add_test(testcase, testname, runner=self)
elif has_super(testcase, ('MarionetteTestCase', 'TestCase')):
for testname in testloader.getTestCaseNames(testcase):
add_test(testcase, testname)
def start_marionette(self):
MarionetteTestRunner.start_marionette(self)
self.marionette.client = B2GUpdateMarionetteClient(self.host,
self.port,
self)
def reset(self, b2g_pid):
if self.marionette.instance:
self.marionette.instance.close()
self.marionette.instance = None
del self.marionette
self.start_marionette()
self.b2g_pid = b2g_pid
return self.marionette
def find_b2g_pid(self):
pids = self.adb.get_pids('b2g')
if len(pids) == 0:
return None
return pids[0]
def port_forward(self):
try:
self.adb.run('forward', 'tcp:%d' % self.port, 'tcp:2828')
except:
# This command causes non-0 return codes even though it succeeds
pass
OTA, FOTA = "OTA", "FOTA"
class B2GUpdateTestCase(MarionetteTestCase):
""" A high level unit test for an OTA or FOTA update. This test case class
has structural support for automatically waiting on an update to apply,
and provides additional javascript support for separating a test into
'pre-update' and 'post-update' lifecycles.
See test examples in toolkit/mozapps/update/test/marionette/update_test_*.py
"""
MAX_OTA_WAIT = 60 * 2 # 2 minutes
MAX_FOTA_WAIT = 60 * 10 # 10 minutes
def __init__(self, marionette_weakref, **kwargs):
if 'runner' in kwargs:
self.runner = kwargs['runner']
del kwargs['runner']
update_test_js = os.path.join(os.path.dirname(__file__), 'atoms',
'b2g_update_test.js')
with open(update_test_js, 'r') as f:
self.update_test_js = f.read()
self.b2g_pid = self.runner.find_b2g_pid()
if not self.b2g_pid:
raise Exception('B2G PID could not be found for update test')
MarionetteTestCase.__init__(self, marionette_weakref, **kwargs)
self.testvars = self.testvars or {}
self.status_newline = True
self.loglines = []
def print_status(self, status, message=None):
if self.status_newline:
print ''
self.status_newline = False
status_msg = 'UPDATE-TEST-' + status
if message:
status_msg += ': ' + message
print status_msg
def setUp(self):
MarionetteTestCase.setUp(self)
self.marionette.set_context(Marionette.CONTEXT_CHROME)
def tearDown(self):
# This completey overrides MarionetteTestCase.tearDown so we can control
# logs being appended between various marionette runs
self.marionette.set_context(Marionette.CONTEXT_CONTENT)
self.marionette.execute_script("log('TEST-END: %s:%s')" %
(self.filepath.replace('\\', '\\\\'), self.methodName))
self.marionette.test_name = None
self.duration = time.time() - self.start_time
if self.marionette.session is not None:
self.loglines.extend(self.marionette.get_logs())
self.marionette.delete_session()
self.marionette = None
def reset(self, b2g_pid):
self.print_status('RESET-MARIONETTE')
self._marionette_weakref = weakref.ref(self.runner.reset(b2g_pid))
self.marionette = self._marionette_weakref()
if self.marionette.session is None:
self.marionette.start_session()
self.marionette.set_context(Marionette.CONTEXT_CHROME)
def execute_update_test(self, path, apply=None):
self.execute_update_js(path, stage='pre-update',
will_restart=(apply is not None))
if not apply:
return
if self.marionette.session is not None:
self.loglines.extend(self.marionette.get_logs())
# This function will probably force-kill b2g, so we can't capture logs
self.execute_update_js(path, stage='apply-update')
self.wait_for_update(apply)
self.execute_update_js(path, stage='post-update')
def execute_update_js(self, path, stage=None, will_restart=True):
data = self.update_test_js[:]
with open(path, "r") as f:
data += f.read()
status = 'EXEC'
if stage:
status += '-' + stage.upper()
data += '\nrunUpdateTest("%s");' % stage
self.print_status(status, os.path.basename(path))
results = self.marionette.execute_async_script(data,
script_args=[self.testvars])
self.handle_results(path, stage, results)
def handle_results(self, path, stage, results):
passed = results['passed']
failed = results['failed']
fails = StringIO()
stage_msg = ' %s' % stage if stage else ''
fails.write('%d%s tests failed:\n' % (failed, stage_msg))
for failure in results['failures']:
diag = failure.get('diag')
diag_msg = "" if not diag else "| %s " % diag
name = failure.get('name') or 'got false, expected true'
fails.write('TEST-UNEXPECTED-FAIL | %s %s| %s\n' %
(os.path.basename(path), diag_msg, name))
self.assertEqual(0, failed, fails.getvalue())
self.assertTrue(passed + failed > 0, 'no tests run')
def stage_update(self, **kwargs):
mar = kwargs.get('complete_mar') or kwargs.get('partial_mar')
short_mar = os.path.relpath(mar, os.path.dirname(os.path.dirname(mar)))
self.print_status('STAGE', short_mar)
prefs = kwargs.pop('prefs', {})
update_xml = kwargs.get('update_xml')
if not update_xml:
xml_kwargs = kwargs.copy()
if 'update_dir' in xml_kwargs:
del xml_kwargs['update_dir']
if 'only_override' in xml_kwargs:
del xml_kwargs['only_override']
builder = self.runner.update_tools.UpdateXmlBuilder(**xml_kwargs)
update_xml = builder.build_xml()
test_kwargs = {
'adb_path': self.runner.adb.tool,
'update_xml': update_xml,
'only_override': kwargs.get('only_override', False),
}
for key in ('complete_mar', 'partial_mar', 'url_template', 'update_dir'):
test_kwargs[key] = kwargs.get(key)
test_update = self.runner.update_tools.TestUpdate(**test_kwargs)
test_update.test_update(write_url_pref=False, restart=False)
if 'prefs' not in self.testvars:
self.testvars['prefs'] = {}
self.testvars['prefs']['app.update.url.override'] = test_update.update_url
self.testvars['prefs'].update(prefs)
def wait_for_update(self, type):
if type == OTA:
self.wait_for_ota_restart()
elif type == FOTA:
self.wait_for_fota_reboot()
def wait_for_new_b2g_pid(self, max_wait):
for i in range(max_wait):
b2g_pid = self.runner.find_b2g_pid()
if b2g_pid and b2g_pid != self.b2g_pid:
return b2g_pid
time.sleep(1)
return None
def wait_for_ota_restart(self):
self.print_status('WAIT-FOR-OTA-RESTART')
new_b2g_pid = self.wait_for_new_b2g_pid(self.MAX_OTA_WAIT)
if not new_b2g_pid:
self.fail('Timed out waiting for B2G process during OTA update')
return
self.reset(new_b2g_pid)
def wait_for_fota_reboot(self):
self.print_status('WAIT-FOR-FOTA-REBOOT')
# First wait for the device to go offline
for i in range(self.MAX_FOTA_WAIT):
online = self.runner.adb.get_online_devices()
if self.runner.device not in online:
break
time.sleep(1)
if i == self.MAX_FOTA_WAIT - 1:
self.fail('Timed out waiting for device to go offline during FOTA update')
# Now wait for the device to come back online
for j in range(i, self.MAX_FOTA_WAIT):
online = self.runner.adb.get_online_devices()
if self.runner.device in online:
break
time.sleep(1)
if j == self.MAX_FOTA_WAIT - 1:
self.fail('Timed out waiting for device to come back online during FOTA update')
# Finally wait for the B2G process
for k in range(j, self.MAX_FOTA_WAIT):
b2g_pid = self.runner.find_b2g_pid()
if b2g_pid:
self.reset(b2g_pid)
return
time.sleep(1)
self.fail('Timed out waiting for B2G process to start during FOTA update')
def flash(self, flash_script):
flash_build = os.path.basename(os.path.dirname(flash_script))
self.print_status('FLASH-BUILD', flash_build)
subprocess.check_call([flash_script, self.runner.device])
self.runner.adb.run('wait-for-device')
self.runner.port_forward()
self.b2g_pid = None
b2g_pid = self.wait_for_new_b2g_pid(self.MAX_OTA_WAIT)
if not b2g_pid:
self.fail('Timed out waiting for B2G process to start after a flash')
self.reset(b2g_pid)
class B2GUpdateSmokeTestCase(B2GUpdateTestCase):
""" An even higher-level update test that is meant to be run with builds
and updates generated in an automated build environment.
Update smoke tests have two main differences from a plain update test:
- They are meant to be passed various MARs and system images through the
--testvars Marionette argument.
- Before each test, the device can be flashed with a specified set of images
by the test case.
See smoketest examples in
toolkit/mozapps/update/test/marionette/update_smoketest_*.py
"""
"The path of the Javascript file that has assertions to run"
JS_PATH = None
""" Which build to flash and vars to stage before the test is run.
Possible values: 'start', 'finish', or None
"""
START_WITH_BUILD = 'start'
"A map of prefs to set while staging, before the test is run"
STAGE_PREFS = None
"Marionette script timeout"
TIMEOUT = 2 * 60 * 1000
"""What kind of update to apply after the 'pre-update' tests have
finished. Possible values: OTA, FOTA, None. None means "Don't apply"
"""
APPLY = OTA
def setUp(self):
if self.START_WITH_BUILD:
build = self.testvars[self.START_WITH_BUILD]
self.flash(build['flash_script'])
B2GUpdateTestCase.setUp(self)
def stage_update(self, build=None, mar=None, **kwargs):
if build and not mar:
raise Exception('mar required with build')
if mar and not build:
raise Exception('build required with mar')
if not build:
B2GUpdateTestCase.stage_update(self, **kwargs)
return
build_vars = self.testvars[build]
mar_key = mar + '_mar'
mar_path = build_vars[mar_key]
stage_kwargs = {
'build_id': build_vars['app_build_id'],
'app_version': build_vars['app_version'],
'platform_version': build_vars['platform_milestone'],
mar_key: mar_path
}
stage_kwargs.update(kwargs)
if self.STAGE_PREFS:
if 'prefs' not in stage_kwargs:
stage_kwargs['prefs'] = self.STAGE_PREFS
B2GUpdateTestCase.stage_update(self, **stage_kwargs)
def execute_smoketest(self):
self.marionette.set_script_timeout(self.TIMEOUT)
self.execute_update_test(self.JS_PATH, apply=self.APPLY)
if __name__ == '__main__':
cli(B2GUpdateTestRunner)

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

@ -428,25 +428,6 @@ class CommonTestCase(unittest.TestCase):
# consistency.
return self.test_name
def set_up_test_page(self, emulator, url="test.html", permissions=None):
emulator.set_context("content")
url = emulator.absolute_url(url)
emulator.navigate(url)
if not permissions:
return
emulator.set_context("chrome")
emulator.execute_script("""
Components.utils.import("resource://gre/modules/Services.jsm");
let [url, permissions] = arguments;
let uri = Services.io.newURI(url, null, null);
permissions.forEach(function (perm) {
Services.perms.add(uri, "sms", Components.interfaces.nsIPermissionManager.ALLOW_ACTION);
});
""", [url, permissions])
emulator.set_context("content")
def setUp(self):
# Convert the marionette weakref to an object, just for the
# duration of the test; this is deleted in tearDown() to prevent
@ -463,13 +444,6 @@ permissions.forEach(function (perm) {
else:
self.marionette.timeouts(self.marionette.TIMEOUT_PAGE, 30000)
if hasattr(self, 'test_container') and self.test_container:
self.switch_into_test_container()
elif hasattr(self, 'test_container') and self.test_container is False:
if self.marionette.session_capabilities.has_key('b2g') \
and self.marionette.session_capabilities['b2g'] == True:
self.close_test_container()
def tearDown(self):
pass
@ -496,58 +470,6 @@ permissions.forEach(function (perm) {
pass
self.marionette = None
def switch_into_test_container(self):
self.marionette.set_context(self.marionette.CONTEXT_CONTENT)
frame = Wait(self.marionette, timeout=10, interval=0.2).until(element_present(
'css selector',
'iframe[src*="app://test-container.gaiamobile.org/index.html"]'
))
self.marionette.switch_to_frame(frame)
def close_test_container(self):
self.marionette.set_context(self.marionette.CONTEXT_CONTENT)
result = self.marionette.execute_async_script("""
if((navigator.mozSettings == undefined) || (navigator.mozSettings == null) || (navigator.mozApps == undefined) || (navigator.mozApps == null)) {
marionetteScriptFinished(false);
return;
}
let setReq = navigator.mozSettings.createLock().set({'lockscreen.enabled': false});
setReq.onsuccess = function() {
let appsReq = navigator.mozApps.mgmt.getAll();
appsReq.onsuccess = function() {
let apps = appsReq.result;
for (let i = 0; i < apps.length; i++) {
let app = apps[i];
if (app.manifest.name === 'Test Container') {
window.wrappedJSObject.Service.request('AppWindowManager:kill', app.origin).then(function() {
marionetteScriptFinished(true);
}).catch(function() {
marionetteScriptFinished(false);
});
return;
}
}
marionetteScriptFinished(false);
}
appsReq.onerror = function() {
marionetteScriptFinished(false);
}
}
setReq.onerror = function() {
marionetteScriptFinished(false);
}""", script_timeout=60000)
if not result:
raise Exception('Failed to close Test Container app')
Wait(self.marionette, timeout=10, interval=0.2).until(element_not_present(
'css selector',
'iframe[src*="app://test-container.gaiamobile.org/index.html"]'
))
def setup_SpecialPowers_observer(self):
self.marionette.set_context("chrome")
self.marionette.execute_script("""
@ -693,7 +615,6 @@ class MarionetteTestCase(CommonTestCase):
filepath='', **kwargs):
self._marionette_weakref = marionette_weakref
self.marionette = None
self.extra_emulator_index = -1
self.methodName = methodName
self.filepath = filepath
self.testvars = kwargs.pop('testvars', None)
@ -753,21 +674,6 @@ class MarionetteTestCase(CommonTestCase):
CommonTestCase.tearDown(self)
def get_new_emulator(self):
self.extra_emulator_index += 1
if len(self.marionette.extra_emulators) == self.extra_emulator_index:
qemu = Marionette(emulator=self.marionette.emulator.arch,
emulatorBinary=self.marionette.emulator.binary,
homedir=self.marionette.homedir,
baseurl=self.marionette.baseurl,
noWindow=self.marionette.noWindow,
gecko_path=self.marionette.gecko_path)
qemu.start_session()
self.marionette.extra_emulators.append(qemu)
else:
qemu = self.marionette.extra_emulators[self.extra_emulator_index]
return qemu
def wait_for_condition(self, method, timeout=30):
timeout = float(timeout) + time.time()
while time.time() < timeout:

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

@ -68,13 +68,12 @@ class MarionetteTestResult(StructuredTestResult, TestResultCollection):
self.testsRun = 0
self.result_modifiers = [] # used by mixins to modify the result
pid = kwargs.pop('b2g_pid')
logcat_stdout = kwargs.pop('logcat_stdout')
if pid:
if B2GTestResultMixin not in self.__class__.__bases__:
bases = [b for b in self.__class__.__bases__]
bases.append(B2GTestResultMixin)
self.__class__.__bases__ = tuple(bases)
B2GTestResultMixin.__init__(self, b2g_pid=pid, logcat_stdout=logcat_stdout)
B2GTestResultMixin.__init__(self, b2g_pid=pid)
StructuredTestResult.__init__(self, *args, **kwargs)
@property
@ -230,7 +229,6 @@ class MarionetteTextTestRunner(StructuredTestRunner):
self.capabilities = kwargs.pop('capabilities')
self.pre_run_functions = []
self.b2g_pid = None
self.logcat_stdout = kwargs.pop('logcat_stdout')
if self.capabilities["device"] != "desktop" and self.capabilities["browserName"] == "B2G":
def b2g_pre_run():
@ -249,7 +247,6 @@ class MarionetteTextTestRunner(StructuredTestRunner):
marionette=self.marionette,
b2g_pid=self.b2g_pid,
logger=self.logger,
logcat_stdout=self.logcat_stdout,
result_callbacks=self.result_callbacks)
def run(self, test):
@ -283,44 +280,11 @@ class BaseMarionetteArguments(ArgumentParser):
action='count',
help='Increase verbosity to include debug messages with -v, '
'and trace messages with -vv.')
self.add_argument('--emulator',
choices=['x86', 'arm'],
help='if no --address is given, then the harness will launch a B2G emulator on which to run '
'emulator tests. if --address is given, then the harness assumes you are running an '
'emulator already, and will run the emulator tests using that emulator. you need to '
'specify which architecture to emulate for both cases')
self.add_argument('--emulator-binary',
help='launch a specific emulator binary rather than launching from the B2G built emulator')
self.add_argument('--emulator-img',
help='use a specific image file instead of a fresh one')
self.add_argument('--emulator-res',
help='set a custom resolution for the emulator'
'Example: "480x800"')
self.add_argument('--sdcard',
help='size of sdcard to create for the emulator')
self.add_argument('--no-window',
action='store_true',
default=False,
help='when Marionette launches an emulator, start it with the -no-window argument')
self.add_argument('--logcat-dir',
dest='logdir',
help='directory to store logcat dump files',
type=dir_path)
self.add_argument('--logcat-stdout',
action='store_true',
default=False,
help='dump adb logcat to stdout')
self.add_argument('--address',
help='host:port of running Gecko instance to connect to')
self.add_argument('--device',
dest='device_serial',
help='serial ID of a device to use for adb / fastboot')
self.add_argument('--adb-host',
help='host to use for adb connection')
self.add_argument('--adb-port',
help='port to use for adb connection')
self.add_argument('--homedir',
help='home directory of emulator files')
self.add_argument('--app',
help='application to use')
self.add_argument('--app-arg',
@ -474,26 +438,10 @@ class BaseMarionetteArguments(ArgumentParser):
print '{0} does not exist'.format(path)
sys.exit(1)
if not args.emulator and not args.address and not args.binary:
print 'must specify --binary, --emulator or --address'
if not args.address and not args.binary:
print 'must specify --binary, or --address'
sys.exit(1)
if args.emulator and args.binary:
print 'can\'t specify both --emulator and --binary'
sys.exit(1)
# check for valid resolution string, strip whitespaces
try:
if args.emulator_res:
dims = args.emulator_res.split('x')
assert len(dims) == 2
width = str(int(dims[0]))
height = str(int(dims[1]))
args.emulator_res = 'x'.join([width, height])
except:
raise ValueError('Invalid emulator resolution format. '
'Should be like "480x800".')
if args.total_chunks is not None and args.this_chunk is None:
self.error('You must specify which chunk to run.')
@ -530,40 +478,31 @@ class BaseMarionetteTestRunner(object):
textrunnerclass = MarionetteTextTestRunner
driverclass = Marionette
def __init__(self, address=None, emulator=None, emulator_binary=None,
emulator_img=None, emulator_res='480x800', homedir=None,
def __init__(self, address=None,
app=None, app_args=None, binary=None, profile=None,
logger=None, no_window=False, logdir=None, logcat_stdout=False,
logger=None, logdir=None,
repeat=0, testvars=None, tree=None,
device_serial=None, symbols_path=None, timeout=None,
symbols_path=None, timeout=None,
shuffle=False, shuffle_seed=random.randint(0, sys.maxint),
sdcard=None, this_chunk=1, total_chunks=1, sources=None,
server_root=None, gecko_log=None, result_callbacks=None,
adb_host=None, adb_port=None, prefs=None, test_tags=None,
prefs=None, test_tags=None,
socket_timeout=BaseMarionetteArguments.socket_timeout_default,
startup_timeout=None, addons=None, workspace=None,
verbose=0, e10s=True, **kwargs):
self.address = address
self.emulator = emulator
self.emulator_binary = emulator_binary
self.emulator_img = emulator_img
self.emulator_res = emulator_res
self.homedir = homedir
self.app = app
self.app_args = app_args or []
self.bin = binary
self.profile = profile
self.addons = addons
self.logger = logger
self.no_window = no_window
self.httpd = None
self.marionette = None
self.logdir = logdir
self.logcat_stdout = logcat_stdout
self.repeat = repeat
self.test_kwargs = kwargs
self.tree = tree
self.device_serial = device_serial
self.symbols_path = symbols_path
self.timeout = timeout
self.socket_timeout = socket_timeout
@ -582,13 +521,11 @@ class BaseMarionetteTestRunner(object):
self.manifest_skipped_tests = []
self.tests = []
self.result_callbacks = result_callbacks or []
self._adb_host = adb_host
self._adb_port = adb_port
self.prefs = prefs or {}
self.test_tags = test_tags
self.startup_timeout = startup_timeout
self.workspace = workspace
# If no workspace is set, default location for logcat and gecko.log is .
# If no workspace is set, default location for gecko.log is .
# and default location for profile is TMP
self.workspace_path = workspace or os.getcwd()
self.verbose = verbose
@ -623,9 +560,6 @@ class BaseMarionetteTestRunner(object):
self.logger.info('Using workspace for temporary data: '
'"{}"'.format(self.workspace_path))
if self.emulator and not self.logdir:
self.logdir = os.path.join(self.workspace_path or '', 'logcat')
if not gecko_log:
self.gecko_log = os.path.join(self.workspace_path or '', 'gecko.log')
else:
@ -747,12 +681,8 @@ class BaseMarionetteTestRunner(object):
os.mkdir(self.logdir)
kwargs = {
'device_serial': self.device_serial,
'symbols_path': self.symbols_path,
'timeout': self.timeout,
'socket_timeout': self.socket_timeout,
'adb_host': self._adb_host,
'adb_port': self._adb_port,
'prefs': self.prefs,
'startup_timeout': self.startup_timeout,
'verbose': self.verbose,
@ -769,20 +699,12 @@ class BaseMarionetteTestRunner(object):
'gecko_log': self.gecko_log,
})
if self.emulator:
kwargs.update({
'homedir': self.homedir,
'logdir': self.logdir,
})
if self.address:
host, port = self.address.split(':')
kwargs.update({
'host': host,
'port': int(port),
})
if self.emulator:
kwargs['connectToRunningEmulator'] = True
if not self.bin:
try:
@ -792,15 +714,6 @@ class BaseMarionetteTestRunner(object):
connection.close()
except Exception, e:
raise Exception("Connection attempt to %s:%s failed with error: %s" %(host,port,e))
elif self.emulator:
kwargs.update({
'emulator': self.emulator,
'emulator_binary': self.emulator_binary,
'emulator_img': self.emulator_img,
'emulator_res': self.emulator_res,
'no_window': self.no_window,
'sdcard': self.sdcard,
})
if self.workspace:
kwargs['workspace'] = self.workspace_path
return kwargs
@ -917,10 +830,7 @@ setReq.onerror = function() {
self.logger.info("running with e10s: {}".format(self.e10s))
version_info = mozversion.get_version(binary=self.bin,
sources=self.sources,
dm_type=os.environ.get('DM_TRANS', 'adb'),
device_serial=self.device_serial,
adb_host=self.marionette.adb_host,
adb_port=self.marionette.adb_port)
dm_type=os.environ.get('DM_TRANS', 'adb') )
self.logger.suite_start(self.tests,
version_info=version_info,
@ -1091,7 +1001,6 @@ setReq.onerror = function() {
runner = self.textrunnerclass(logger=self.logger,
marionette=self.marionette,
capabilities=self.capabilities,
logcat_stdout=self.logcat_stdout,
result_callbacks=self.result_callbacks)
if test_container:

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

@ -67,8 +67,6 @@ def mach_parsed_kwargs(logger):
call to mach marionette-test
"""
return {
'adb_host': None,
'adb_port': None,
'addon': None,
'address': None,
'app': None,
@ -76,10 +74,6 @@ def mach_parsed_kwargs(logger):
'binary': u'/path/to/firefox',
'device_serial': None,
'e10s': False,
'emulator': None,
'emulator_binary': None,
'emulator_img': None,
'emulator_res': None,
'gecko_log': None,
'homedir': None,
'jsdebugger': False,
@ -96,7 +90,6 @@ def mach_parsed_kwargs(logger):
'log_tbpl_level': None,
'log_unittest': None,
'log_xunit': None,
'logcat_stdout': False,
'logdir': None,
'logger_name': 'Marionette-based Tests',
'no_window': False,
@ -250,7 +243,7 @@ def test_crash_is_recorded_as_error(empty_marionette_test,
# collect results from the empty test
result = MarionetteTestResult(
marionette=empty_marionette_test._marionette_weakref(),
b2g_pid=0, logcat_stdout=False, logger=logger, verbosity=None,
b2g_pid=0, logger=logger, verbosity=None,
stream=None, descriptions=None,
)
result.startTest(empty_marionette_test)

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

@ -1,152 +0,0 @@
# 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 unittest import skip
from marionette.marionette_test import MarionetteTestCase, skip_if_desktop, skip_unless_protocol
from marionette_driver.errors import MarionetteException, JavascriptException
class TestEmulatorContent(MarionetteTestCase):
@skip_if_desktop
def test_emulator_cmd(self):
self.marionette.set_script_timeout(10000)
expected = ["<build>", "OK"]
res = self.marionette.execute_async_script(
"runEmulatorCmd('avd name', marionetteScriptFinished)");
self.assertEqual(res, expected)
@skip_if_desktop
def test_emulator_shell(self):
self.marionette.set_script_timeout(10000)
expected = ["Hello World!"]
res = self.marionette.execute_async_script(
"runEmulatorShell(['echo', 'Hello World!'], marionetteScriptFinished)")
self.assertEqual(res, expected)
@skip_if_desktop
def test_emulator_order(self):
self.marionette.set_script_timeout(10000)
with self.assertRaises(MarionetteException):
self.marionette.execute_async_script("""
runEmulatorCmd("gsm status", function(res) {});
marionetteScriptFinished(true);
""")
class TestEmulatorChrome(TestEmulatorContent):
def setUp(self):
super(TestEmulatorChrome, self).setUp()
self.marionette.set_context("chrome")
class TestEmulatorScreen(MarionetteTestCase):
@skip_if_desktop
def test_emulator_orientation(self):
self.screen = self.marionette.emulator.screen
self.screen.initialize()
self.assertEqual(self.screen.orientation, self.screen.SO_PORTRAIT_PRIMARY,
'Orientation has been correctly initialized.')
self.screen.orientation = self.screen.SO_PORTRAIT_SECONDARY
self.assertEqual(self.screen.orientation, self.screen.SO_PORTRAIT_SECONDARY,
'Orientation has been set to portrait-secondary')
self.screen.orientation = self.screen.SO_LANDSCAPE_PRIMARY
self.assertEqual(self.screen.orientation, self.screen.SO_LANDSCAPE_PRIMARY,
'Orientation has been set to landscape-primary')
self.screen.orientation = self.screen.SO_LANDSCAPE_SECONDARY
self.assertEqual(self.screen.orientation, self.screen.SO_LANDSCAPE_SECONDARY,
'Orientation has been set to landscape-secondary')
self.screen.orientation = self.screen.SO_PORTRAIT_PRIMARY
self.assertEqual(self.screen.orientation, self.screen.SO_PORTRAIT_PRIMARY,
'Orientation has been set to portrait-primary')
class TestEmulatorCallbacks(MarionetteTestCase):
def setUp(self):
MarionetteTestCase.setUp(self)
self.original_emulator_cmd = self.marionette._emulator_cmd
self.original_emulator_shell = self.marionette._emulator_shell
self.marionette._emulator_cmd = self.mock_emulator_cmd
self.marionette._emulator_shell = self.mock_emulator_shell
def tearDown(self):
self.marionette._emulator_cmd = self.original_emulator_cmd
self.marionette._emulator_shell = self.original_emulator_shell
def mock_emulator_cmd(self, *args):
return self.marionette._send_emulator_result("cmd response")
def mock_emulator_shell(self, *args):
return self.marionette._send_emulator_result("shell response")
def _execute_emulator(self, action, args):
script = "%s(%s, function(res) { marionetteScriptFinished(res); })" % (action, args)
return self.marionette.execute_async_script(script)
def emulator_cmd(self, cmd):
return self._execute_emulator("runEmulatorCmd", escape(cmd))
def emulator_shell(self, *args):
js_args = ", ".join(map(escape, args))
js_args = "[%s]" % js_args
return self._execute_emulator("runEmulatorShell", js_args)
def test_emulator_cmd_content(self):
with self.marionette.using_context("content"):
res = self.emulator_cmd("yo")
self.assertEqual("cmd response", res)
def test_emulator_shell_content(self):
with self.marionette.using_context("content"):
res = self.emulator_shell("first", "second")
self.assertEqual("shell response", res)
@skip_unless_protocol(lambda level: level >= 3)
def test_emulator_result_error_content(self):
with self.marionette.using_context("content"):
with self.assertRaisesRegexp(JavascriptException, "TypeError"):
self.marionette.execute_async_script("runEmulatorCmd()")
def test_emulator_cmd_chrome(self):
with self.marionette.using_context("chrome"):
res = self.emulator_cmd("yo")
self.assertEqual("cmd response", res)
def test_emulator_shell_chrome(self):
with self.marionette.using_context("chrome"):
res = self.emulator_shell("first", "second")
self.assertEqual("shell response", res)
@skip_unless_protocol(lambda level: level >= 3)
def test_emulator_result_error_chrome(self):
with self.marionette.using_context("chrome"):
with self.assertRaisesRegexp(JavascriptException, "TypeError"):
self.marionette.execute_async_script("runEmulatorCmd()")
def test_multiple_callbacks(self):
res = self.marionette.execute_async_script("""
runEmulatorCmd("what");
runEmulatorCmd("ho");
marionetteScriptFinished("Frobisher");
""")
self.assertEqual("Frobisher", res)
# This should work, but requires work on emulator callbacks:
"""
def test_multiple_nested_callbacks(self):
res = self.marionette.execute_async_script('''
runEmulatorCmd("what", function(res) {
runEmulatorCmd("ho", marionetteScriptFinished);
});''')
self.assertEqual("cmd response", res)
"""
def escape(word):
return "'%s'" % word

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

@ -90,9 +90,3 @@ class TestGetActiveFrameOOP(MarionetteTestCase):
self.marionette.switch_to_frame()
self.marionette.switch_to_frame(active_frame2)
self.assertTrue("test_oop_2.html" in self.marionette.execute_script("return document.wrappedJSObject.location.href"))
# NOTE: For some reason the emulator, the contents of the OOP iframes are not
# actually rendered, even though the page_source is correct. When this test runs
# on a b2g device, the contents do appear
# print self.marionette.get_url()
# print self.marionette.page_source

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

@ -139,18 +139,6 @@ class TestProto2Command(MessageTestCase):
self.assertEqual("name", cmd.name)
self.assertEqual("params", cmd.params)
def test_from_data_emulator_cmd(self):
data = {"emulator_cmd": "emulator_cmd"}
cmd = Proto2Command.from_data(data)
self.assertEqual("runEmulatorCmd", cmd.name)
self.assertEqual(data, cmd.params)
def test_from_data_emulator_shell(self):
data = {"emulator_shell": "emulator_shell"}
cmd = Proto2Command.from_data(data)
self.assertEqual("runEmulatorShell", cmd.name)
self.assertEqual(data, cmd.params)
def test_from_data_unknown(self):
with self.assertRaises(ValueError):
cmd = Proto2Command.from_data({})

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

@ -32,7 +32,6 @@ skip-if = true # "Bug 896046"
[test_typing.py]
[test_log.py]
[test_emulator.py]
[test_about_pages.py]
skip-if = buildapp == 'b2g'