Bug 704509 - fix reftests to work with native fennec. r=dbaron

This commit is contained in:
Joel Maher 2011-12-20 16:33:41 -05:00
parent 46a35a688e
commit 8f0d429677
8 changed files with 229 additions and 50 deletions

View File

@ -52,6 +52,11 @@ ifdef XPI_NAME
NO_JS_MANIFEST = 1
DIST_FILES = install.rdf
ifeq ($(MOZ_BUILD_APP),mobile/android)
DEFINES += -DBOOTSTRAP
DIST_FILES += bootstrap.js
endif
# Used in install.rdf
USE_EXTENSION_MANIFEST=1
else

80
layout/tools/reftest/bootstrap.js vendored Normal file
View File

@ -0,0 +1,80 @@
Components.utils.import("resource://gre/modules/FileUtils.jsm");
function loadIntoWindow(window) {}
function unloadFromWindow(window) {}
function setDefaultPrefs() {
// This code sets the preferences for extension-based reftest; for
// command-line based reftest they are set in function handler_handle in
// reftest-cmdline.js. These two locations should stay in sync.
//
// FIXME: These should be in only one place.
var prefs = Components.classes["@mozilla.org/preferences-service;1"].
getService(Components.interfaces.nsIPrefService);
var branch = prefs.getDefaultBranch("");
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);
}
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);
let wm = Components.classes["@mozilla.org/appshell/window-mediator;1"].getService(Components.interfaces.nsIWindowMediator);
// 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("UIReady", function() {OnRefTestLoad(win);});
break;
}
}, false);
},
onCloseWindow: function(aWindow){ },
onWindowTitleChange: function(){ },
};
function startup(aData, aReason) {
let wm = Components.classes["@mozilla.org/appshell/window-mediator;1"].
getService (Components.interfaces.nsIWindowMediator);
Components.manager.addBootstrappedManifestLocation(aData.installPath);
// Load into any new windows
wm.addListener(windowListener);
}
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;
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);
}
}
function install(aData, aReason) { }
function uninstall(aData, aReason) { }

View File

@ -4,6 +4,10 @@
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:type>2</em:type>
<em:bootstrap>true</em:bootstrap>
#endif
<em:version>1.0</em:version>
<em:targetApplication>
<Description>

View File

@ -1,10 +1,14 @@
reftest.jar:
% content reftest %content/
* content/reftest.js (reftest.js)
content/reftest-content.js (reftest-content.js)
#ifdef BOOTSTRAP
* content/reftest.jsm (reftest.js)
#else
* content/reftest.js (reftest.js)
content/reftest.xul (reftest.xul)
#ifdef XPI_NAME
% component {32530271-8c1b-4b7d-a812-218e42c6bb23} components/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
#endif
#endif

View File

@ -100,6 +100,12 @@ RefTestCmdLineHandler.prototype =
* 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.
*
* If you change these, please adjust them in the bootstrap.js function
* setDefaultPrefs(). These are duplicated there so we can have a
* restartless addon for reftest on native Android.
*
* FIXME: These should be in only one place.
*/
var prefs = Components.classes["@mozilla.org/preferences-service;1"].
getService(Components.interfaces.nsIPrefService);

View File

@ -36,6 +36,11 @@
*
* ***** END LICENSE BLOCK ***** */
#if BOOTSTRAP
var EXPORTED_SYMBOLS = ["OnRefTestLoad"];
#endif
const CC = Components.classes;
const CI = Components.interfaces;
const CR = Components.results;
@ -219,7 +224,7 @@ function IDForEventTarget(event)
}
}
function OnRefTestLoad()
function OnRefTestLoad(win)
{
gCrashDumpDir = CC[NS_DIRECTORY_SERVICE_CONTRACTID]
.getService(CI.nsIProperties)
@ -238,8 +243,11 @@ function OnRefTestLoad()
gBrowserIsRemote = false;
}
if (gContainingWindow == null && window != null) {
gContainingWindow = window;
if (win === undefined || win == null) {
win = window;
}
if (gContainingWindow == null && win != null) {
gContainingWindow = win;
}
gBrowser = gContainingWindow.document.createElementNS(XUL_NS, "xul:browser");
@ -250,7 +258,15 @@ function OnRefTestLoad()
// what size our window is
gBrowser.setAttribute("style", "min-width: 800px; min-height: 1000px; max-width: 800px; max-height: 1000px");
#if BOOTSTRAP
var doc = gContainingWindow.document.getElementById('main-window');
while (doc.hasChildNodes()) {
doc.removeChild(doc.firstChild);
}
doc.appendChild(gBrowser);
#else
document.getElementById("reftest-window").appendChild(gBrowser);
#endif
gBrowserMessageManager = gBrowser.QueryInterface(CI.nsIFrameLoaderOwner)
.frameLoader.messageManager;
@ -285,7 +301,11 @@ function InitAndStartRefTests()
var mfl = FileUtils.openFileOutputStream(f, FileUtils.MODE_WRONLY | FileUtils.MODE_CREATE);
// Set to mirror to stdout as well as the file
gDumpLog = function (msg) {
#if BOOTSTRAP
//NOTE: on android-xul, we have a libc crash if we do a dump with %7s in the string
#else
dump(msg);
#endif
mfl.write(msg, msg.length);
};
}
@ -373,6 +393,38 @@ function StartHTTPServer()
function StartTests()
{
#if BOOTSTRAP
/* These prefs are optional, so we don't need to spit an error to the log */
try {
var prefs = Components.classes["@mozilla.org/preferences-service;1"].
getService(Components.interfaces.nsIPrefBranch2);
} catch(e) {
gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | | EXCEPTION: " + e + "\n");
}
try {
gNoCanvasCache = prefs.getIntPref("reftest.nocache");
} catch(e) {
gNoCanvasCache = false;
}
try {
gRunSlowTests = prefs.getIntPref("reftest.skipslowtests");
} catch(e) {
gRunSlowTests = false;
}
try {
uri = prefs.getCharPref("reftest.uri");
} catch(e) {
uri = "";
}
if (uri == "") {
gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | | Unable to find reftest.uri pref. Please ensure your profile is setup properly\n");
DoneTests();
}
#else
try {
// Need to read the manifest once we have the final HTTP_SERVER_PORT.
var args = window.arguments[0].wrappedJSObject;
@ -383,16 +435,25 @@ function StartTests()
if ("skipslowtests" in args && args.skipslowtests)
gRunSlowTests = false;
ReadTopManifest(args.uri);
uri = args.uri;
} catch (e) {
++gTestResults.Exception;
gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | | EXCEPTION: " + ex + "\n");
DoneTests();
}
#endif
try {
ReadTopManifest(uri);
BuildUseCounts();
if (gTotalChunks > 0 && gThisChunk > 0) {
var testsPerChunk = gURLs.length / gTotalChunks;
var start = Math.round((gThisChunk-1) * testsPerChunk);
var end = Math.round(gThisChunk * testsPerChunk);
gURLs = gURLs.slice(start, end);
gDumpLog("REFTEST INFO | Running chunk " + gThisChunk + " out of " + gTotalChunks + " chunks. ")
gDumpLog("tests " + (start+1) + "-" + end + "/" + gURLs.length + "\n");
var testsPerChunk = gURLs.length / gTotalChunks;
var start = Math.round((gThisChunk-1) * testsPerChunk);
var end = Math.round(gThisChunk * testsPerChunk);
gURLs = gURLs.slice(start, end);
gDumpLog("REFTEST INFO | Running chunk " + gThisChunk + " out of " + gTotalChunks + " chunks. ")
gDumpLog("tests " + (start+1) + "-" + end + "/" + gURLs.length + "\n");
}
gTotalTests = gURLs.length;
@ -417,17 +478,17 @@ function OnRefTestUnload()
// as a string.
function getStreamContent(inputStream)
{
var streamBuf = "";
var sis = CC["@mozilla.org/scriptableinputstream;1"].
createInstance(CI.nsIScriptableInputStream);
sis.init(inputStream);
var streamBuf = "";
var sis = CC["@mozilla.org/scriptableinputstream;1"].
createInstance(CI.nsIScriptableInputStream);
sis.init(inputStream);
var available;
while ((available = sis.available()) != 0) {
streamBuf += sis.read(available);
}
return streamBuf;
var available;
while ((available = sis.available()) != 0) {
streamBuf += sis.read(available);
}
return streamBuf;
}
// Build the sandbox for fails-if(), etc., condition evaluation.
@ -440,16 +501,16 @@ function BuildConditionSandbox(aURL) {
// xr.XPCOMABI throws exception for configurations without full ABI
// support (mobile builds on ARM)
try {
sandbox.xulRuntime.XPCOMABI = xr.XPCOMABI;
sandbox.xulRuntime.XPCOMABI = xr.XPCOMABI;
} catch(e) {
sandbox.xulRuntime.XPCOMABI = "";
sandbox.xulRuntime.XPCOMABI = "";
}
try {
// nsIGfxInfo is currently only implemented on Windows
sandbox.d2d = (NS_GFXINFO_CONTRACTID in CC) && CC[NS_GFXINFO_CONTRACTID].getService(CI.nsIGfxInfo).D2DEnabled;
// nsIGfxInfo is currently only implemented on Windows
sandbox.d2d = (NS_GFXINFO_CONTRACTID in CC) && CC[NS_GFXINFO_CONTRACTID].getService(CI.nsIGfxInfo).D2DEnabled;
} catch(e) {
sandbox.d2d = false;
sandbox.d2d = false;
}
sandbox.layersGPUAccelerated =
@ -515,7 +576,7 @@ function BuildConditionSandbox(aURL) {
sandbox.testPluginIsOOP = function () {
try {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
} catch (ex) {}
var prefservice = Components.classes["@mozilla.org/preferences-service;1"]
@ -566,7 +627,7 @@ function ReadTopManifest(aFileURL)
gURLs = new Array();
var url = gIOService.newURI(aFileURL, null, null);
if (!url)
throw "Expected a file or http URL for the manifest.";
throw "Expected a file or http URL for the manifest.";
ReadManifest(url, EXPECTED_PASS);
}

View File

@ -111,6 +111,10 @@ class RemoteOptions(ReftestOptions):
help = "name of the pidfile to generate")
defaults["pidFile"] = ""
self.add_option("--bootstrap", action="store_true", dest = "bootstrap",
help = "test with a bootstrap addon required for native Fennec")
defaults["bootstrap"] = False
self.add_option("--dm_trans", action="store",
type = "string", dest = "dm_trans",
help = "the transport to use to communicate with device: [adb|sut]; default=sut")
@ -290,13 +294,13 @@ class RemoteReftest(RefTest):
localAutomation.UNIXISH = False
hostos = sys.platform
if (hostos == 'mac' or hostos == 'darwin'):
localAutomation.IS_MAC = True
localAutomation.IS_MAC = True
elif (hostos == 'linux' or hostos == 'linux2'):
localAutomation.IS_LINUX = True
localAutomation.UNIXISH = True
localAutomation.IS_LINUX = True
localAutomation.UNIXISH = True
elif (hostos == 'win32' or hostos == 'win64'):
localAutomation.BIN_SUFFIX = ".exe"
localAutomation.IS_WIN32 = True
localAutomation.BIN_SUFFIX = ".exe"
localAutomation.IS_WIN32 = True
paths = [options.xrePath, localAutomation.DIST_BIN, self.automation._product, os.path.join('..', self.automation._product)]
options.xrePath = self.findPath(paths)
@ -328,8 +332,8 @@ class RemoteReftest(RefTest):
def stopWebServer(self, options):
self.server.stop()
def createReftestProfile(self, options, profileDir):
RefTest.createReftestProfile(self, options, profileDir, server=options.remoteWebServer)
def createReftestProfile(self, options, profileDir, reftestlist):
RefTest.createReftestProfile(self, options, profileDir, reftestlist, server=options.remoteWebServer)
# Turn off the locale picker screen
fhandle = open(os.path.join(profileDir, "user.js"), 'a')
@ -337,11 +341,14 @@ class RemoteReftest(RefTest):
user_pref("browser.firstrun.show.localepicker", false);
user_pref("font.size.inflation.emPerLine", 0);
user_pref("font.size.inflation.minTwips", 0);
""")
user_pref("reftest.remote", true);
user_pref("toolkit.telemetry.prompted", true);
user_pref("reftest.uri", "%s");
""" % reftestlist)
#workaround for jsreftests.
if options.enablePrivilege:
fhandle.write("""
fhandle.write("""
user_pref("capability.principal.codebase.p2.granted", "UniversalPreferencesWrite UniversalXPConnect UniversalBrowserWrite UniversalPreferencesRead UniversalBrowserRead");
user_pref("capability.principal.codebase.p2.id", "http://%s:%s");
""" % (options.remoteWebServer, options.httpPort))
@ -349,7 +356,6 @@ user_pref("capability.principal.codebase.p2.id", "http://%s:%s");
# Close the file
fhandle.close()
if (self._devicemanager.pushDir(profileDir, options.remoteProfile) == None):
raise devicemanager.FileError("Failed to copy profiledir to device")
@ -359,6 +365,9 @@ user_pref("capability.principal.codebase.p2.id", "http://%s:%s");
raise devicemanager.FileError("Failed to copy extra files to device")
def registerExtension(self, browserEnv, options, profileDir, extraArgs = ['-silent'] ):
if options.bootstrap:
return
self.automation.log.info("REFTEST INFO | runreftest.py | Performing extension manager registration: start.\n")
# Because our startProcess code doesn't return until fennec starts we just give it
# a maxTime of 20 secs before timing it out and ensuring it is dead.
@ -449,18 +458,22 @@ def main():
procName = options.app.split('/')[-1]
if (dm.processExist(procName)):
dm.killProcess(procName)
dm.killProcess(procName)
#an example manifest name to use on the cli
# manifest = "http://" + options.remoteWebServer + "/reftests/layout/reftests/reftest-sanity/reftest.list"
try:
reftest.runTests(manifest, options)
cmdlineArgs = ["-reftest", manifest]
if options.bootstrap:
cmdlineArgs = []
reftest.runTests(manifest, options, cmdlineArgs)
except:
print "TEST-UNEXPECTED-FAIL | | exception while running reftests"
reftest.stopWebServer(options)
sys.exit(1)
print "TEST-UNEXPECTED-FAIL | | exception while running reftests"
reftest.stopWebServer(options)
sys.exit(1)
reftest.stopWebServer(options)
if __name__ == "__main__":
main()

View File

@ -1,4 +1,3 @@
#
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
@ -74,8 +73,13 @@ class RefTest(object):
path = defaultManifestPath
return path
def createReftestProfile(self, options, profileDir, server='localhost'):
"Sets up a profile for reftest."
def createReftestProfile(self, options, profileDir, manifest, server='localhost'):
"""
Sets up a profile for reftest.
'manifest' is the path to the reftest.list file we want to test with. This is used in
the remote subclass in remotereftest.py so we can write it to a preference for the
bootstrap extension.
"""
self.automation.setupPermissionsDatabase(profileDir,
{'allowXULXBL': [(server, True), ('<file>', True)]})
@ -141,15 +145,18 @@ class RefTest(object):
if profileDir:
shutil.rmtree(profileDir, True)
def runTests(self, testPath, options):
def runTests(self, testPath, options, cmdlineArgs = None):
debuggerInfo = getDebuggerInfo(self.oldcwd, options.debugger, options.debuggerArgs,
options.debuggerInteractive);
profileDir = None
try:
reftestlist = self.getManifestPath(testPath)
if cmdlineArgs == None:
cmdlineArgs = ['-reftest', reftestlist]
profileDir = mkdtemp()
self.copyExtraFilesToProfile(options, profileDir)
self.createReftestProfile(options, profileDir)
self.createReftestProfile(options, profileDir, reftestlist)
self.installExtensionsToProfile(options, profileDir)
# browser environment
@ -159,9 +166,8 @@ class RefTest(object):
# then again to actually run reftest
self.automation.log.info("REFTEST INFO | runreftest.py | Running tests: start.\n")
reftestlist = self.getManifestPath(testPath)
status = self.automation.runApp(None, browserEnv, options.app, profileDir,
["-reftest", reftestlist],
cmdlineArgs,
utilityPath = options.utilityPath,
xrePath=options.xrePath,
debuggerInfo=debuggerInfo,