Bug 1245092 - Install reftest and specialpowers extensions at runtime via AddonManager.installTemporaryAddon, r=jgriffin, a=test-only

MozReview-Commit-ID: 5HSa3nFVTeF
This commit is contained in:
Andrew Halberstadt 2016-03-09 14:38:13 -05:00
parent 9579ce7214
commit 84d989f303
21 changed files with 323 additions and 416 deletions

View File

@ -38,13 +38,12 @@ class B2GRemoteAutomation(Automation):
_devicemanager = None
def __init__(self, deviceManager, appName='', remoteLog=None,
marionette=None, context_chrome=True):
marionette=None):
self._devicemanager = deviceManager
self._appName = appName
self._remoteProfile = None
self._remoteLog = remoteLog
self.marionette = marionette
self.context_chrome = context_chrome
self._is_emulator = False
self.test_script = None
self.test_script_args = None
@ -356,36 +355,33 @@ class B2GRemoteAutomation(Automation):
if 'b2g' not in session:
raise Exception("bad session value %s returned by start_session" % session)
self.marionette.set_context(self.marionette.CONTEXT_CHROME)
self.marionette.execute_script("""
let SECURITY_PREF = "security.turn_off_all_security_so_that_viruses_can_take_over_this_computer";
Components.utils.import("resource://gre/modules/Services.jsm");
Services.prefs.setBoolPref(SECURITY_PREF, true);
with self.marionette.using_context(self.marionette.CONTEXT_CHROME):
self.marionette.execute_script("""
let SECURITY_PREF = "security.turn_off_all_security_so_that_viruses_can_take_over_this_computer";
Components.utils.import("resource://gre/modules/Services.jsm");
Services.prefs.setBoolPref(SECURITY_PREF, true);
if (!testUtils.hasOwnProperty("specialPowersObserver")) {
let loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
.getService(Components.interfaces.mozIJSSubScriptLoader);
loader.loadSubScript("chrome://specialpowers/content/SpecialPowersObserver.jsm",
testUtils);
testUtils.specialPowersObserver = new testUtils.SpecialPowersObserver();
testUtils.specialPowersObserver.init();
}
""")
if (!testUtils.hasOwnProperty("specialPowersObserver")) {
let loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
.getService(Components.interfaces.mozIJSSubScriptLoader);
loader.loadSubScript("chrome://specialpowers/content/SpecialPowersObserver.jsm",
testUtils);
testUtils.specialPowersObserver = new testUtils.SpecialPowersObserver();
testUtils.specialPowersObserver.init();
}
""")
if not self.context_chrome:
self.marionette.set_context(self.marionette.CONTEXT_CONTENT)
# run the script that starts the tests
if self.test_script:
if os.path.isfile(self.test_script):
script = open(self.test_script, 'r')
self.marionette.execute_script(script.read(), script_args=self.test_script_args)
script.close()
elif isinstance(self.test_script, basestring):
self.marionette.execute_script(self.test_script, script_args=self.test_script_args)
else:
# assumes the tests are started on startup automatically
pass
# run the script that starts the tests
if self.test_script:
if os.path.isfile(self.test_script):
script = open(self.test_script, 'r')
self.marionette.execute_script(script.read(), script_args=self.test_script_args)
script.close()
elif isinstance(self.test_script, basestring):
self.marionette.execute_script(self.test_script, script_args=self.test_script_args)
else:
# assumes the tests are started on startup automatically
pass
return instance

View File

@ -339,6 +339,7 @@ class RemoteAutomation(Automation):
self.logBuffer += newLogContent
lines = self.logBuffer.split('\n')
lines = [l for l in lines if l]
if lines:
# We only keep the last (unfinished) line in the buffer
@ -350,7 +351,6 @@ class RemoteAutomation(Automation):
for line in lines:
# This passes the line to the logger (to be logged or buffered)
# and returns a list of structured messages (dict)
parsed_messages = self.messageLogger.write(line)
for message in parsed_messages:
if isinstance(message, dict) and message.get('action') == 'test_start':

View File

@ -6,8 +6,10 @@
_DEST_DIR = $(DEPTH)/_tests/reftest
_HARNESS_FILES = \
$(srcdir)/b2g_start_script.js \
$(srcdir)/runreftest.py \
$(srcdir)/reftestcommandline.py \
$(srcdir)/reftest-preferences.js \
$(srcdir)/remotereftest.py \
$(srcdir)/runreftestb2g.py \
$(srcdir)/runreftestmulet.py \
@ -20,12 +22,6 @@ _HARNESS_FILES = \
$(topsrcdir)/build/pgo/server-locations.txt \
$(NULL)
_HARNESS_PP_FILES = \
b2g_start_script.js \
$(NULL)
_HARNESS_PP_FILES_PATH = $(_DEST_DIR)
PP_TARGETS += _HARNESS_PP_FILES
include $(topsrcdir)/config/rules.mk
# We're installing to _tests/reftest

View File

@ -2,14 +2,7 @@
* 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/. */
function setDefaultPrefs() {
// This code sets the preferences for extension-based reftest.
var prefs = Cc["@mozilla.org/preferences-service;1"].
getService(Ci.nsIPrefService);
var branch = prefs.getDefaultBranch("");
#include reftest-preferences.js
}
const { utils: Cu, classes: Cc, interfaces: Ci } = Components;
function setPermissions() {
if (__marionetteParams.length < 2) {
@ -27,7 +20,7 @@ function setPermissions() {
}
var cm = Cc["@mozilla.org/categorymanager;1"]
.getService(Components.interfaces.nsICategoryManager);
.getService(Ci.nsICategoryManager);
// Disable update timers that cause b2g failures.
if (cm) {
@ -40,8 +33,6 @@ var wm = Cc["@mozilla.org/appshell/window-mediator;1"]
.getService(Ci.nsIWindowMediator);
var win = wm.getMostRecentWindow('');
// Set preferences and permissions
setDefaultPrefs();
setPermissions();
// Loading this into the global namespace causes intermittent failures.

View File

@ -1,73 +1,78 @@
Components.utils.import("resource://gre/modules/FileUtils.jsm");
/* 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/. */
function loadIntoWindow(window) {}
function unloadFromWindow(window) {}
const { utils: Cu, interfaces: Ci, classes: Cc, manager: Cm } = Components;
function setDefaultPrefs() {
// This code sets the preferences for extension-based reftest.
var prefs = Components.classes["@mozilla.org/preferences-service;1"].
getService(Components.interfaces.nsIPrefService);
var branch = prefs.getDefaultBranch("");
Cu.import("resource://gre/modules/FileUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
#include reftest-preferences.js
}
var WindowListener = {
onOpenWindow: function(win) {
Services.wm.removeListener(WindowListener);
var windowListener = {
onOpenWindow: function(aWindow) {
let domWindow = aWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIDOMWindowInternal || Components.interfaces.nsIDOMWindow);
domWindow.addEventListener("load", function() {
domWindow.removeEventListener("load", arguments.callee, false);
win = win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindow);
win.addEventListener("load", function listener() {
win.removeEventListener("load", listener, false);
let wm = Components.classes["@mozilla.org/appshell/window-mediator;1"].getService(Components.interfaces.nsIWindowMediator);
// Load into any existing windows.
let windows = Services.wm.getEnumerator("navigator:browser");
while (windows.hasMoreElements()) {
win = windows.getNext().QueryInterface(Ci.nsIDOMWindow);
break;
}
// Load into any existing windows
let enumerator = wm.getEnumerator("navigator:browser");
while (enumerator.hasMoreElements()) {
let win = enumerator.getNext().QueryInterface(Components.interfaces.nsIDOMWindow);
setDefaultPrefs();
Components.utils.import("chrome://reftest/content/reftest.jsm");
win.addEventListener("pageshow", function() {
win.removeEventListener("pageshow", arguments.callee);
// We add a setTimeout here because windows.innerWidth/Height are not set yet;
win.setTimeout(function () {OnRefTestLoad(win);}, 0);
});
break;
}
}, false);
},
onCloseWindow: function(aWindow){ },
onWindowTitleChange: function(){ },
Cu.import("chrome://reftest/content/reftest.jsm");
win.addEventListener("pageshow", function listener() {
win.removeEventListener("pageshow", listener);
// Add setTimeout here because windows.innerWidth/Height are not set yet.
win.setTimeout(function() {OnRefTestLoad(win);}, 0);
});
}, false);
}
};
function startup(aData, aReason) {
let wm = Components.classes["@mozilla.org/appshell/window-mediator;1"].
getService (Components.interfaces.nsIWindowMediator);
function startup(data, reason) {
// b2g is bootstrapped by b2g_start_script.js
if (Services.appinfo.widgetToolkit == "gonk") {
return;
}
Components.manager.addBootstrappedManifestLocation(aData.installPath);
if (Services.appinfo.OS == "Android") {
Cm.addBootstrappedManifestLocation(data.installPath);
Services.wm.addListener(WindowListener);
return;
}
// Load into any new windows
wm.addListener(windowListener);
let ios = Cc["@mozilla.org/network/io-service;1"]
.getService(Ci.nsIIOService2);
ios.manageOfflineStatus = false;
ios.offline = false;
let wwatch = Cc["@mozilla.org/embedcomp/window-watcher;1"]
.getService(Ci.nsIWindowWatcher);
let dummy = wwatch.openWindow(null, "about:blank", "dummy",
"chrome,dialog=no,left=800,height=200,width=200,all",null);
dummy.onload = function() {
dummy.focus();
wwatch.openWindow(null, "chrome://reftest/content/reftest.xul", "_blank",
"chrome,dialog=no,all", {});
};
}
function shutdown(aData, aReason) {
// When the application is shutting down we normally don't have to clean up any UI changes
if (aReason == APP_SHUTDOWN)
return;
function shutdown(data, reason) {
if (Services.appinfo.widgetToolkit == "gonk") {
return;
}
let wm = Components.classes["@mozilla.org/appshell/window-mediator;1"].
getService(Components.interfaces.nsIWindowMediator);
// Stop watching for new windows
wm.removeListener(windowListener);
// Unload from any existing windows
let enumerator = wm.getEnumerator("navigator:browser");
while (enumerator.hasMoreElements()) {
let win = enumerator.getNext().QueryInterface(Components.interfaces.nsIDOMWindow);
unloadFromWindow(win);
}
if (Services.appinfo.OS == "Android") {
Services.wm.removeListener(WindowListener);
Cm.removedBootstrappedManifestLocation(data.installPath);
OnRefTestUnload();
Cu.unload("chrome://reftest/content/reftest.jsm");
}
}
function install(aData, aReason) { }
function uninstall(aData, aReason) { }
function install(data, reason) {}
function uninstall(data, reason) {}

View File

@ -4,11 +4,9 @@
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>reftest@mozilla.org</em:id>
#ifdef BOOTSTRAP
<em:version>1.0</em:version>
<em:type>2</em:type>
<em:bootstrap>true</em:bootstrap>
#endif
<em:version>1.0</em:version>
<em:targetApplication>
<Description>
<em:id>toolkit@mozilla.org</em:id>

View File

@ -3,9 +3,5 @@ reftest.jar:
* content/reftest-content.js (reftest-content.js)
content/httpd.jsm (../../../netwerk/test/httpserver/httpd.js)
content/StructuredLog.jsm (../../../testing/modules/StructuredLog.jsm)
#ifdef BOOTSTRAP
* content/reftest.jsm (reftest.js)
#else
* content/reftest.js (reftest.js)
* content/reftest.jsm (reftest.jsm)
content/reftest.xul (reftest.xul)
#endif

View File

@ -7,25 +7,8 @@
with Files('**'):
BUG_COMPONENT = ('Testing', 'Reftest')
if CONFIG['MOZ_BUILD_APP'] in ('b2g', 'b2g/dev', 'mobile/android'):
DEFINES['BOOTSTRAP'] = True
if CONFIG['MOZ_BUILD_APP'] in ('b2g', 'b2g/dev'):
DEFINES['REFTEST_B2G'] = True
else:
EXTRA_PP_COMPONENTS += [
'reftest-cmdline.js',
]
EXTRA_COMPONENTS += [
'reftest-cmdline.manifest',
]
JAR_MANIFESTS += ['jar.mn']
USE_EXTENSION_MANIFEST = True
XPI_NAME = 'reftest'
USE_EXTENSION_MANIFEST = True
JAR_MANIFESTS += ['jar.mn']
FINAL_TARGET_PP_FILES += ['install.rdf']
if CONFIG['MOZ_BUILD_APP'] == 'mobile/android':
FINAL_TARGET_PP_FILES += ['bootstrap.js']
FINAL_TARGET_FILES += ['bootstrap.js']

View File

@ -1,80 +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/. */
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
const nsISupports = Components.interfaces.nsISupports;
const nsICommandLine = Components.interfaces.nsICommandLine;
const nsICommandLineHandler = Components.interfaces.nsICommandLineHandler;
const nsISupportsString = Components.interfaces.nsISupportsString;
const nsIWindowWatcher = Components.interfaces.nsIWindowWatcher;
function RefTestCmdLineHandler() {}
RefTestCmdLineHandler.prototype =
{
classID: Components.ID('{32530271-8c1b-4b7d-a812-218e42c6bb23}'),
/* nsISupports */
QueryInterface: XPCOMUtils.generateQI([nsICommandLineHandler]),
/* nsICommandLineHandler */
handle : function handler_handle(cmdLine) {
/* Ignore the platform's online/offline status while running reftests. */
var ios = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService2);
ios.manageOfflineStatus = false;
ios.offline = false;
/**
* Manipulate preferences by adding to the *default* branch. Adding
* to the default branch means the changes we make won't get written
* back to user preferences.
*
* We want to do this here rather than in reftest.js because it's
* important to force sRGB as an output profile for color management
* before we load a window.
*/
var prefs = Components.classes["@mozilla.org/preferences-service;1"].
getService(Components.interfaces.nsIPrefService);
var branch = prefs.getDefaultBranch("");
#include reftest-preferences.js
var wwatch = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
.getService(nsIWindowWatcher);
function loadReftests() {
wwatch.openWindow(null, "chrome://reftest/content/reftest.xul", "_blank",
"chrome,dialog=no,all", {});
}
var remote = false;
try {
remote = prefs.getBoolPref("reftest.remote");
} catch (ex) {
}
// If we are running on a remote machine, assume that we can't open another
// window for transferring focus to when tests don't require focus.
if (remote) {
loadReftests();
}
else {
// This dummy window exists solely for enforcing proper focus discipline.
var dummy = wwatch.openWindow(null, "about:blank", "dummy",
"chrome,dialog=no,left=800,height=200,width=200,all", null);
dummy.onload = function dummyOnload() {
dummy.focus();
loadReftests();
}
}
cmdLine.preventDefault = true;
},
helpInfo : " --reftest <file> Run layout acceptance tests on given manifest.\n"
};
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([RefTestCmdLineHandler]);

View File

@ -1,3 +0,0 @@
component {32530271-8c1b-4b7d-a812-218e42c6bb23} reftest-cmdline.js
contract @mozilla.org/commandlinehandler/general-startup;1?type=reftest {32530271-8c1b-4b7d-a812-218e42c6bb23}
category command-line-handler m-reftest @mozilla.org/commandlinehandler/general-startup;1?type=reftest

View File

@ -1,70 +1,112 @@
// For mochitests, we're more interested in testing the behavior of in-
// content XBL bindings, so we set this pref to true. In reftests, we're
// more interested in testing the behavior of XBL as it works in chrome,
// so we want this pref to be false.
branch.setBoolPref("dom.use_xbl_scopes_for_remote_xul", false);
branch.setIntPref("gfx.color_management.mode", 2);
branch.setBoolPref("gfx.color_management.force_srgb", true);
branch.setBoolPref("browser.dom.window.dump.enabled", true);
branch.setIntPref("ui.caretBlinkTime", -1);
branch.setBoolPref("dom.send_after_paint_to_content", true);
// no slow script dialogs
branch.setIntPref("dom.max_script_run_time", 0);
branch.setIntPref("dom.max_chrome_script_run_time", 0);
branch.setIntPref("hangmonitor.timeout", 0);
// Ensure autoplay is enabled for all platforms.
branch.setBoolPref("media.autoplay.enabled", true);
// Disable updates
branch.setBoolPref("app.update.enabled", false);
// Disable addon updates and prefetching so we don't leak them
branch.setBoolPref("extensions.update.enabled", false);
branch.setBoolPref("extensions.getAddons.cache.enabled", false);
// Disable blocklist updates so we don't have them reported as leaks
branch.setBoolPref("extensions.blocklist.enabled", false);
// Make url-classifier updates so rare that they won't affect tests
branch.setIntPref("urlclassifier.updateinterval", 172800);
// Disable downscale-during-decode, since it makes reftests more difficult.
branch.setBoolPref("image.downscale-during-decode.enabled", false);
// Disable the single-color optimization, since it can cause intermittent
// oranges and it causes many of our tests to test a different code path
// than the one that normal images on the web use.
branch.setBoolPref("image.single-color-optimization.enabled", false);
// Checking whether two files are the same is slow on Windows.
// Setting this pref makes tests run much faster there.
branch.setBoolPref("security.fileuri.strict_origin_policy", false);
// Disable the thumbnailing service
branch.setBoolPref("browser.pagethumbnails.capturing_disabled", true);
// Since our tests are 800px wide, set the assume-designed-for width of all
// pages to be 800px (instead of the default of 980px). This ensures that
// in our 800px window we don't zoom out by default to try to fit the
// assumed 980px content.
branch.setIntPref("browser.viewport.desktopWidth", 800);
// Disable the fade out (over time) of overlay scrollbars, since we
// can't guarantee taking both reftest snapshots at the same point
// during the fade.
branch.setBoolPref("layout.testing.overlay-scrollbars.always-visible", true);
// Disable interruptible reflow since (1) it's normally not going to
// happen, but (2) it might happen if we somehow end up with both
// pending user events and clock skew. So to avoid having to change
// MakeProgress to deal with waiting for interruptible reflows to
// complete for a rare edge case, we just disable interruptible
// reflow so that that rare edge case doesn't lead to reftest
// failures.
branch.setBoolPref("layout.interruptible-reflow.enabled", false);
// For mochitests, we're more interested in testing the behavior of in-
// content XBL bindings, so we set this pref to true. In reftests, we're
// more interested in testing the behavior of XBL as it works in chrome,
// so we want this pref to be false.
user_pref("dom.use_xbl_scopes_for_remote_xul", false);
user_pref("gfx.color_management.mode", 2);
user_pref("gfx.color_management.force_srgb", true);
user_pref("browser.dom.window.dump.enabled", true);
user_pref("ui.caretBlinkTime", -1);
user_pref("dom.send_after_paint_to_content", true);
// no slow script dialogs
user_pref("dom.max_script_run_time", 0);
user_pref("dom.max_chrome_script_run_time", 0);
user_pref("hangmonitor.timeout", 0);
// Ensure autoplay is enabled for all platforms.
user_pref("media.autoplay.enabled", true);
// Disable updates
user_pref("app.update.enabled", false);
user_pref("app.update.staging.enabled", false);
user_pref("app.update.url.android", "");
// Disable addon updates and prefetching so we don't leak them
user_pref("extensions.update.enabled", false);
user_pref("extensions.systemAddon.update.url", "http://localhost/dummy-system-addons.xml");
user_pref("extensions.getAddons.cache.enabled", false);
// Disable blocklist updates so we don't have them reported as leaks
user_pref("extensions.blocklist.enabled", false);
// Make url-classifier updates so rare that they won't affect tests
user_pref("urlclassifier.updateinterval", 172800);
// Disable downscale-during-decode, since it makes reftests more difficult.
user_pref("image.downscale-during-decode.enabled", false);
// Disable the single-color optimization, since it can cause intermittent
// oranges and it causes many of our tests to test a different code path
// than the one that normal images on the web use.
user_pref("image.single-color-optimization.enabled", false);
// Checking whether two files are the same is slow on Windows.
// Setting this pref makes tests run much faster there.
user_pref("security.fileuri.strict_origin_policy", false);
// Disable the thumbnailing service
user_pref("browser.pagethumbnails.capturing_disabled", true);
// Since our tests are 800px wide, set the assume-designed-for width of all
// pages to be 800px (instead of the default of 980px). This ensures that
// in our 800px window we don't zoom out by default to try to fit the
// assumed 980px content.
user_pref("browser.viewport.desktopWidth", 800);
// Disable the fade out (over time) of overlay scrollbars, since we
// can't guarantee taking both reftest snapshots at the same point
// during the fade.
user_pref("layout.testing.overlay-scrollbars.always-visible", true);
// Disable interruptible reflow since (1) it's normally not going to
// happen, but (2) it might happen if we somehow end up with both
// pending user events and clock skew. So to avoid having to change
// MakeProgress to deal with waiting for interruptible reflows to
// complete for a rare edge case, we just disable interruptible
// reflow so that that rare edge case doesn't lead to reftest
// failures.
user_pref("layout.interruptible-reflow.enabled", false);
// Tell the search service we are running in the US. This also has the
// desired side-effect of preventing our geoip lookup.
branch.setBoolPref("browser.search.isUS", true);
branch.setCharPref("browser.search.countryCode", "US");
// Prevent the geoSpecificDefaults XHR by emptying the URL.
branch.setCharPref("browser.search.geoSpecificDefaults.url", "");
// Tell the search service we are running in the US. This also has the
// desired side-effect of preventing our geoip lookup.
user_pref("browser.search.isUS", true);
user_pref("browser.search.countryCode", "US");
user_pref("browser.search.geoSpecificDefaults", false);
// Make sure SelfSupport doesn't hit the network.
branch.setCharPref("browser.selfsupport.url", "https://%(server)s/selfsupport-dummy/");
// Make sure SelfSupport doesn't hit the network.
user_pref("browser.selfsupport.url", "https://localhost/selfsupport-dummy/");
// Allow XUL and XBL files to be opened from file:// URIs
branch.setBoolPref("dom.allow_XUL_XBL_for_file", true);
// use about:blank, not browser.startup.homepage
user_pref("browser.startup.page", 0);
// Allow view-source URIs to be opened from URIs that share
// their protocol with the inner URI of the view-source URI
branch.setBoolPref("security.view-source.reachable-from-inner-protocol", true);
// Allow XUL and XBL files to be opened from file:// URIs
user_pref("dom.allow_XUL_XBL_for_file", true);
// Allow view-source URIs to be opened from URIs that share
// their protocol with the inner URI of the view-source URI
user_pref("security.view-source.reachable-from-inner-protocol", true);
// Ensure that telemetry is disabled, so we don't connect to the telemetry
// server in the middle of the tests.
user_pref("toolkit.telemetry.enabled", false);
user_pref("toolkit.telemetry.unified", false);
// Likewise for safebrowsing.
user_pref("browser.safebrowsing.enabled", false);
user_pref("browser.safebrowsing.malware.enabled", false);
// Likewise for tracking protection.
user_pref("privacy.trackingprotection.enabled", false);
user_pref("privacy.trackingprotection.pbmode.enabled", false);
// And for snippets.
user_pref("browser.snippets.enabled", false);
user_pref("browser.snippets.syncPromo.enabled", false);
user_pref("browser.snippets.firstrunHomepage.enabled", false);
// And for useragent updates.
user_pref("general.useragent.updates.enabled", false);
// And for webapp updates. Yes, it is supposed to be an integer.
user_pref("browser.webapps.checkForUpdates", 0);
// And for about:newtab content fetch and pings.
user_pref("browser.newtabpage.directory.source", "data:application/json,{\"reftest\":1}");
user_pref("browser.newtabpage.directory.ping", "");
// Only allow add-ons from the profile and app and allow foreign
// injection
user_pref("extensions.enabledScopes", 5);
user_pref("extensions.autoDisableScopes", 0);
// Allow unsigned add-ons
user_pref("xpinstall.signatures.required", false);
// Don't use auto-enabled e10s
user_pref("browser.tabs.remote.autostart.1", false);
user_pref("browser.tabs.remote.autostart.2", false);
user_pref("startup.homepage_welcome_url", "");
user_pref("startup.homepage_override_url", "");
user_pref("media.gmp-manager.url.override", "http://localhost/dummy-gmp-manager.xml");

View File

@ -4,10 +4,7 @@
* 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/. */
#if BOOTSTRAP
this.EXPORTED_SYMBOLS = ["OnRefTestLoad"];
#endif
this.EXPORTED_SYMBOLS = ["OnRefTestLoad", "OnRefTestUnload"];
var CC = Components.classes;
const CI = Components.interfaces;
@ -180,29 +177,33 @@ function HasUnexpectedResult()
}
// By default we just log to stdout
var gDumpFn = dump;
var gLogFile = null;
var gDumpRawLog = function(record) {
// Dump JSON representation of data on a single line
var line = JSON.stringify(record);
gDumpFn("\n" + line + "\n");
var line = "\n" + JSON.stringify(record) + "\n";
dump(line);
if (gLogFile) {
gLogFile.write(line, line.length);
}
}
var logger = new StructuredLogger('reftest', gDumpRawLog);
function TestBuffer(str)
{
logger.debug(str);
gTestLog.push(str);
logger.debug(str);
gTestLog.push(str);
}
function FlushTestBuffer()
{
// In debug mode, we've dumped all these messages already.
if (gLogLevel !== 'debug') {
for (var i = 0; i < gTestLog.length; ++i) {
logger.info("Saved log: " + gTestLog[i]);
}
// In debug mode, we've dumped all these messages already.
if (gLogLevel !== 'debug') {
for (var i = 0; i < gTestLog.length; ++i) {
logger.info("Saved log: " + gTestLog[i]);
}
gTestLog = [];
}
gTestLog = [];
}
function AllocateCanvas()
@ -305,19 +306,20 @@ this.OnRefTestLoad = function OnRefTestLoad(win)
// what size our window is
gBrowser.setAttribute("style", "padding: 0px; margin: 0px; border:none; min-width: 800px; min-height: 1000px; max-width: 800px; max-height: 1000px");
#ifdef BOOTSTRAP
#ifdef REFTEST_B2G
var doc = gContainingWindow.document.getElementsByTagName("html")[0];
#else
var doc = gContainingWindow.document.getElementById('main-window');
#endif
while (doc.hasChildNodes()) {
doc.removeChild(doc.firstChild);
if (Services.appinfo.OS == "Android") {
let doc;
if (Services.appinfo.widgetToolkit == "gonk") {
doc = gContainingWindow.document.getElementsByTagName("html")[0];
} else {
doc = gContainingWindow.document.getElementById('main-window');
}
while (doc.hasChildNodes()) {
doc.removeChild(doc.firstChild);
}
doc.appendChild(gBrowser);
} else {
document.getElementById("reftest-window").appendChild(gBrowser);
}
doc.appendChild(gBrowser);
#else
document.getElementById("reftest-window").appendChild(gBrowser);
#endif
// reftests should have the test plugins enabled, not click-to-play
let plugin1 = getTestPlugin("Test Plug-in");
@ -362,27 +364,8 @@ function InitAndStartRefTests()
try {
var logFile = prefs.getCharPref("reftest.logFile");
if (logFile) {
try {
var f = FileUtils.File(logFile);
var mfl = FileUtils.openFileOutputStream(f, FileUtils.MODE_WRONLY | FileUtils.MODE_CREATE);
// Set to mirror to stdout as well as the file
gDumpFn = function (msg) {
#ifdef BOOTSTRAP
#ifdef REFTEST_B2G
dump(msg);
#else
//NOTE: on android-xul, we have a libc crash if we do a dump with %7s in the string
#endif
#else
dump(msg);
#endif
mfl.write(msg, msg.length);
};
}
catch(e) {
// If there is a problem, just use stdout
gDumpFn = dump;
}
var f = FileUtils.File(logFile);
gLogFile = FileUtils.openFileOutputStream(f, FileUtils.MODE_WRONLY | FileUtils.MODE_CREATE);
}
} catch(e) {}
@ -1382,8 +1365,8 @@ function StartCurrentURI(aState)
var currentTest = gTotalTests - gURLs.length;
// Log this to preserve the same overall log format,
// should be removed if the format is updated
gDumpFn("REFTEST TEST-LOAD | " + gCurrentURL + " | " + currentTest + " / " + gTotalTests +
" (" + Math.floor(100 * (currentTest / gTotalTests)) + "%)\n");
dump("REFTEST TEST-LOAD | " + gCurrentURL + " | " + currentTest + " / " + gTotalTests +
" (" + Math.floor(100 * (currentTest / gTotalTests)) + "%)\n");
TestBuffer("START " + gCurrentURL);
var type = gURLs[0].type
if (TYPE_SCRIPT == type) {
@ -1835,19 +1818,19 @@ function DoAssertionCheck(numAsserts)
if (numAsserts < minAsserts) {
++gTestResults.AssertionUnexpectedFixed;
gDumpFn("REFTEST TEST-UNEXPECTED-PASS | " + gURLs[0].prettyPath +
" | assertion count" + numAsserts + " is less than " +
dump("REFTEST TEST-UNEXPECTED-PASS | " + gURLs[0].prettyPath +
" | assertion count" + numAsserts + " is less than " +
expectedAssertions + "\n");
} else if (numAsserts > maxAsserts) {
++gTestResults.AssertionUnexpected;
gDumpFn("REFTEST TEST-UNEXPECTED-FAIL | " + gURLs[0].prettyPath +
" | assertion count " + numAsserts + " is more than " +
dump("REFTEST TEST-UNEXPECTED-FAIL | " + gURLs[0].prettyPath +
" | assertion count " + numAsserts + " is more than " +
expectedAssertions + "\n");
} else if (numAsserts != 0) {
++gTestResults.AssertionKnown;
gDumpFn("REFTEST TEST-KNOWN-FAIL | " + gURLs[0].prettyPath +
"assertion count " + numAsserts + " matches " +
expectedAssertions + "\n");
dump("REFTEST TEST-KNOWN-FAIL | " + gURLs[0].prettyPath +
"assertion count " + numAsserts + " matches " +
expectedAssertions + "\n");
}
}

View File

@ -9,6 +9,6 @@
onunload="OnRefTestUnload();"
style="background:white; overflow:hidden"
>
<script type="application/ecmascript" src="reftest.js" />
<script type="application/ecmascript" src="reftest.jsm" />
<!-- The reftest browser element is dynamically created, here -->
</window>

View File

@ -130,6 +130,10 @@ class ReftestArgumentsParser(argparse.ArgumentParser):
"the extension's id as indicated in its install.rdf. "
"An optional path can be specified too.")
self.add_argument("--marionette",
default=None,
help="host:port to use when connecting to Marionette")
self.add_argument("--setenv",
action="append",
type=str,
@ -388,12 +392,6 @@ class B2GArgumentParser(ReftestArgumentsParser):
dest="b2gPath",
help="path to B2G repo or qemu dir")
self.add_argument("--marionette",
action="store",
type=str,
dest="marionette",
help="host:port to use when connecting to Marionette")
self.add_argument("--emulator",
action="store",
type=str,
@ -656,12 +654,6 @@ class RemoteArgumentsParser(ReftestArgumentsParser):
default="",
help="name of the pidfile to generate")
self.add_argument("--bootstrap",
action="store_true",
dest="bootstrap",
default=False,
help="test with a bootstrap addon required for native Fennec")
self.add_argument("--dm_trans",
action="store",
type=str,

View File

@ -126,6 +126,7 @@ class ReftestServer:
self._process.kill()
class RemoteReftest(RefTest):
use_marionette = False
remoteApp = ''
resolver_cls = RemoteReftestResolver

View File

@ -33,6 +33,12 @@ import mozrunner
from mozrunner.utils import get_stack_fixer_function, test_environment
from mozscreenshot import printstatus, dump_screen
try:
from marionette import Marionette
from marionette_driver.addons import Addons
except ImportError:
Marionette=None
from output import OutputHandler, ReftestFormatter
import reftestcommandline
@ -65,9 +71,9 @@ printLock = threading.Lock()
class ReftestThread(threading.Thread):
def __init__(self, cmdlineArgs):
def __init__(self, cmdargs):
threading.Thread.__init__(self)
self.cmdlineArgs = cmdlineArgs
self.cmdargs = cmdargs
self.summaryMatches = {}
self.retcode = -1
for text, _ in summaryLines:
@ -75,9 +81,9 @@ class ReftestThread(threading.Thread):
def run(self):
with printLock:
print "Starting thread with", self.cmdlineArgs
print "Starting thread with", self.cmdargs
sys.stdout.flush()
process = subprocess.Popen(self.cmdlineArgs, stdout=subprocess.PIPE)
process = subprocess.Popen(self.cmdargs, stdout=subprocess.PIPE)
for chunk in self.chunkForMergedOutput(process.stdout):
with printLock:
print chunk,
@ -191,7 +197,9 @@ class ReftestResolver(object):
manifests[key] = "|".join(list(manifests[key]))
return manifests
class RefTest(object):
use_marionette = True
oldcwd = os.getcwd()
resolver_cls = ReftestResolver
@ -241,7 +249,8 @@ class RefTest(object):
:param manifests: Dictionary of the form {manifest_path: [filters]}
:param server: Server name to use for http tests
:param profile_to_clone: Path to a profile to use as the basis for the
test profile"""
test profile
"""
locations = mozprofile.permissions.ServerLocations()
locations.add_host(server, scheme='http', port=port)
@ -249,7 +258,7 @@ class RefTest(object):
# Set preferences for communication between our command line arguments
# and the reftest harness. Preferences that are required for reftest
# to work should instead be set in reftest-cmdline.js .
# to work should instead be set in reftest-preferences.js .
prefs = {}
prefs['reftest.timeout'] = options.timeout * 1000
if options.totalChunks:
@ -270,58 +279,38 @@ class RefTest(object):
prefs['reftest.logLevel'] = options.log_tbpl_level or 'info'
prefs['reftest.manifests'] = json.dumps(manifests)
# Ensure that telemetry is disabled, so we don't connect to the telemetry
# server in the middle of the tests.
prefs['toolkit.telemetry.enabled'] = False
prefs['toolkit.telemetry.unified'] = False
# Likewise for safebrowsing.
prefs['browser.safebrowsing.enabled'] = False
prefs['browser.safebrowsing.malware.enabled'] = False
# Likewise for tracking protection.
prefs['privacy.trackingprotection.enabled'] = False
prefs['privacy.trackingprotection.pbmode.enabled'] = False
# And for snippets.
prefs['browser.snippets.enabled'] = False
prefs['browser.snippets.syncPromo.enabled'] = False
prefs['browser.snippets.firstrunHomepage.enabled'] = False
# And for useragent updates.
prefs['general.useragent.updates.enabled'] = False
# And for webapp updates. Yes, it is supposed to be an integer.
prefs['browser.webapps.checkForUpdates'] = 0
# And for about:newtab content fetch and pings.
prefs['browser.newtabpage.directory.source'] = 'data:application/json,{"reftest":1}'
prefs['browser.newtabpage.directory.ping'] = ''
# Only allow add-ons from the profile and app and allow foreign
# injection
prefs["extensions.enabledScopes"] = 5
prefs["extensions.autoDisableScopes"] = 0
# Allow unsigned add-ons
prefs['xpinstall.signatures.required'] = False
# Don't use auto-enabled e10s
prefs['browser.tabs.remote.autostart.1'] = False
prefs['browser.tabs.remote.autostart.2'] = False
if options.e10s:
prefs['browser.tabs.remote.autostart'] = True
prefs['extensions.e10sBlocksEnabling'] = False
if options.marionette:
port = options.marionette.split(':')[1]
prefs['marionette.defaultPrefs.port'] = int(port)
preference_file = os.path.join(here, 'reftest-preferences.js')
prefs.update(mozprofile.Preferences.read_prefs(preference_file))
for v in options.extraPrefs:
thispref = v.split('=')
if len(thispref) < 2:
print "Error: syntax error in --setpref=" + v
sys.exit(1)
prefs[thispref[0]] = mozprofile.Preferences.cast(
thispref[1].strip())
prefs[thispref[0]] = thispref[1].strip()
# install the reftest extension bits into the profile
addons = [options.reftestExtensionPath]
addons = []
if not self.use_marionette:
addons.append(options.reftestExtensionPath)
if options.specialPowersExtensionPath is not None:
addons.append(options.specialPowersExtensionPath)
if not self.use_marionette:
addons.append(options.specialPowersExtensionPath)
# SpecialPowers requires insecure automation-only features that we
# put behind a pref.
prefs['security.turn_off_all_security_so_that_viruses_can_take_over_this_computer'] = True
for pref in prefs:
prefs[pref] = mozprofile.Preferences.cast(prefs[pref])
# Install distributed extensions, if application has any.
distExtDir = os.path.join(options.app[:options.app.rfind(os.sep)],
"distribution", "extensions")
@ -405,7 +394,8 @@ class RefTest(object):
if profileDir:
shutil.rmtree(profileDir, True)
def runTests(self, tests, options, cmdlineArgs=None):
def runTests(self, tests, options, cmdargs=None):
cmdargs = cmdargs or []
self._populate_logger(options)
# Despite our efforts to clean up servers started by this script, in practice
@ -420,8 +410,8 @@ class RefTest(object):
if options.filter:
manifests[""] = options.filter
if not hasattr(options, "runTestsInParallel") or not options.runTestsInParallel:
return self.runSerialTests(manifests, options, cmdlineArgs)
if not getattr(options, 'runTestsInParallel', False):
return self.runSerialTests(manifests, options, cmdargs)
cpuCount = multiprocessing.cpu_count()
@ -439,13 +429,20 @@ class RefTest(object):
totalJobs = jobsWithoutFocus + 1
perProcessArgs = [sys.argv[:] for i in range(0, totalJobs)]
host = 'localhost'
port = 2828
if options.marionette:
host, port = options.marionette.split(':')
# First job is only needs-focus tests. Remaining jobs are
# non-needs-focus and chunked.
perProcessArgs[0].insert(-1, "--focus-filter-mode=needs-focus")
for (chunkNumber, jobArgs) in enumerate(perProcessArgs[1:], start=1):
jobArgs[-1:-1] = ["--focus-filter-mode=non-needs-focus",
"--total-chunks=%d" % jobsWithoutFocus,
"--this-chunk=%d" % chunkNumber]
"--this-chunk=%d" % chunkNumber,
"--marionette=%s:%d" % (host, port)]
port += 1
for jobArgs in perProcessArgs:
try:
@ -598,6 +595,24 @@ class RefTest(object):
outputTimeout=timeout)
proc = runner.process_handler
if self.use_marionette:
marionette_args = { 'symbols_path': options.symbolsPath }
if options.marionette:
host, port = options.marionette.split(':')
marionette_args['host'] = host
marionette_args['port'] = int(port)
marionette = Marionette(**marionette_args)
marionette.start_session()
addons = Addons(marionette)
if options.specialPowersExtensionPath:
addons.install(options.specialPowersExtensionPath, temp=True)
addons.install(options.reftestExtensionPath, temp=True)
marionette.delete_session()
status = runner.wait()
runner.process_handler = None
@ -617,7 +632,7 @@ class RefTest(object):
status = 1
return status
def runSerialTests(self, manifests, options, cmdlineArgs=None):
def runSerialTests(self, manifests, options, cmdargs=None):
debuggerInfo = None
if options.debugger:
debuggerInfo = mozdebug.get_debugger_info(options.debugger, options.debuggerArgs,
@ -625,8 +640,12 @@ class RefTest(object):
profileDir = None
try:
if cmdlineArgs is None:
cmdlineArgs = []
if cmdargs is None:
cmdargs = []
if self.use_marionette:
cmdargs.append('-marionette')
profile = self.createReftestProfile(options, manifests)
profileDir = profile.profile # name makes more sense
@ -635,7 +654,7 @@ class RefTest(object):
status = self.runApp(profile,
binary=options.app,
cmdargs=cmdlineArgs,
cmdargs=cmdargs,
# give the JS harness 30 seconds to deal with
# its own timeouts
env=browserEnv,

View File

@ -52,6 +52,7 @@ class ProfileConfigParser(ConfigParser.RawConfigParser):
class B2GRemoteReftest(RefTest):
_devicemanager = None
use_marionette = False
localProfile = None
remoteApp = ''
profile = None
@ -325,7 +326,7 @@ class B2GRemoteReftest(RefTest):
def run_remote_reftests(parser, options):
auto = B2GRemoteAutomation(None, "fennec", context_chrome=True)
auto = B2GRemoteAutomation(None, "fennec")
# create our Marionette instance
kwargs = {}

View File

@ -93,7 +93,6 @@ config = {
"--utility-path=../hostutils/bin",
"--app=%(app_name)s",
"--ignore-window-size",
"--bootstrap",
"--http-port=%(http_port)s",
"--ssl-port=%(ssl_port)s",
"--symbols-path=%(symbols_path)s",
@ -127,7 +126,6 @@ config = {
"--utility-path=../hostutils/bin",
"--app=%(app_name)s",
"--ignore-window-size",
"--bootstrap",
"--extra-profile-file=jsreftest/tests/user.js",
"--http-port=%(http_port)s",
"--ssl-port=%(ssl_port)s",
@ -165,7 +163,6 @@ config = {
"--utility-path=../hostutils/bin",
"--app=%(app_name)s",
"--ignore-window-size",
"--bootstrap",
"--http-port=%(http_port)s",
"--ssl-port=%(ssl_port)s",
"--symbols-path=%(symbols_path)s",

View File

@ -129,7 +129,6 @@ config = {
"options": [
"--app=%(app)s",
"--ignore-window-size",
"--bootstrap",
"--remote-webserver=%(remote_webserver)s",
"--xre-path=%(xre_path)s",
"--utility-path=%(utility_path)s",
@ -154,7 +153,6 @@ config = {
"options": [
"--app=%(app)s",
"--ignore-window-size",
"--bootstrap",
"--remote-webserver=%(remote_webserver)s",
"--xre-path=%(xre_path)s",
"--utility-path=%(utility_path)s",
@ -176,7 +174,6 @@ config = {
"options": [
"--app=%(app)s",
"--ignore-window-size",
"--bootstrap",
"--remote-webserver=%(remote_webserver)s",
"--xre-path=%(xre_path)s",
"--utility-path=%(utility_path)s",

View File

@ -130,7 +130,6 @@ config = {
"--app=%(app)s",
"--ignore-window-size",
"--dm_trans=adb",
"--bootstrap",
"--remote-webserver=%(remote_webserver)s",
"--xre-path=%(xre_path)s",
"--utility-path=%(utility_path)s",
@ -153,7 +152,6 @@ config = {
"--app=%(app)s",
"--ignore-window-size",
"--dm_trans=adb",
"--bootstrap",
"--remote-webserver=%(remote_webserver)s",
"--xre-path=%(xre_path)s",
"--utility-path=%(utility_path)s",
@ -173,7 +171,6 @@ config = {
"--app=%(app)s",
"--ignore-window-size",
"--dm_trans=adb",
"--bootstrap",
"--remote-webserver=%(remote_webserver)s",
"--xre-path=%(xre_path)s",
"--utility-path=%(utility_path)s",
@ -194,7 +191,6 @@ config = {
"--app=%(app)s",
"--ignore-window-size",
"--dm_trans=adb",
"--bootstrap",
"--remote-webserver=%(remote_webserver)s",
"--xre-path=%(xre_path)s",
"--utility-path=%(utility_path)s",
@ -214,7 +210,6 @@ config = {
"--app=%(app)s",
"--ignore-window-size",
"--dm_trans=adb",
"--bootstrap",
"--remote-webserver=%(remote_webserver)s", "--xre-path=%(xre_path)s",
"--utility-path=%(utility_path)s", "--http-port=%(http_port)s",
"--ssl-port=%(ssl_port)s", "--httpd-path", "%(modules_dir)s",
@ -232,7 +227,6 @@ config = {
"--app=%(app)s",
"--ignore-window-size",
"--dm_trans=adb",
"--bootstrap",
"--remote-webserver=%(remote_webserver)s", "--xre-path=%(xre_path)s",
"--utility-path=%(utility_path)s", "--http-port=%(http_port)s",
"--ssl-port=%(ssl_port)s", "--httpd-path", "%(modules_dir)s",

View File

@ -92,7 +92,6 @@ config = {
"run_filename": "remotereftest.py",
"options": ["--app=%(app)s",
"--ignore-window-size",
"--bootstrap",
"--remote-webserver=%(remote_webserver)s",
"--xre-path=%(xre_path)s",
"--utility-path=%(utility_path)s",