Wed, 31 Dec 2014 06:55:50 +0100
Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2
michael@0 | 1 | /* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- / |
michael@0 | 2 | /* vim: set shiftwidth=4 tabstop=8 autoindent cindent expandtab: */ |
michael@0 | 3 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 4 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 5 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 6 | |
michael@0 | 7 | #if BOOTSTRAP |
michael@0 | 8 | this.EXPORTED_SYMBOLS = ["OnRefTestLoad"]; |
michael@0 | 9 | #endif |
michael@0 | 10 | |
michael@0 | 11 | |
michael@0 | 12 | const CC = Components.classes; |
michael@0 | 13 | const CI = Components.interfaces; |
michael@0 | 14 | const CR = Components.results; |
michael@0 | 15 | |
michael@0 | 16 | const XHTML_NS = "http://www.w3.org/1999/xhtml"; |
michael@0 | 17 | const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; |
michael@0 | 18 | |
michael@0 | 19 | const NS_LOCAL_FILE_CONTRACTID = "@mozilla.org/file/local;1"; |
michael@0 | 20 | const NS_GFXINFO_CONTRACTID = "@mozilla.org/gfx/info;1"; |
michael@0 | 21 | const IO_SERVICE_CONTRACTID = "@mozilla.org/network/io-service;1"; |
michael@0 | 22 | const DEBUG_CONTRACTID = "@mozilla.org/xpcom/debug;1"; |
michael@0 | 23 | const NS_LOCALFILEINPUTSTREAM_CONTRACTID = |
michael@0 | 24 | "@mozilla.org/network/file-input-stream;1"; |
michael@0 | 25 | const NS_SCRIPTSECURITYMANAGER_CONTRACTID = |
michael@0 | 26 | "@mozilla.org/scriptsecuritymanager;1"; |
michael@0 | 27 | const NS_REFTESTHELPER_CONTRACTID = |
michael@0 | 28 | "@mozilla.org/reftest-helper;1"; |
michael@0 | 29 | const NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX = |
michael@0 | 30 | "@mozilla.org/network/protocol;1?name="; |
michael@0 | 31 | const NS_XREAPPINFO_CONTRACTID = |
michael@0 | 32 | "@mozilla.org/xre/app-info;1"; |
michael@0 | 33 | const NS_DIRECTORY_SERVICE_CONTRACTID = |
michael@0 | 34 | "@mozilla.org/file/directory_service;1"; |
michael@0 | 35 | const NS_OBSERVER_SERVICE_CONTRACTID = |
michael@0 | 36 | "@mozilla.org/observer-service;1"; |
michael@0 | 37 | |
michael@0 | 38 | Components.utils.import("resource://gre/modules/FileUtils.jsm"); |
michael@0 | 39 | |
michael@0 | 40 | var gLoadTimeout = 0; |
michael@0 | 41 | var gTimeoutHook = null; |
michael@0 | 42 | var gRemote = false; |
michael@0 | 43 | var gIgnoreWindowSize = false; |
michael@0 | 44 | var gShuffle = false; |
michael@0 | 45 | var gTotalChunks = 0; |
michael@0 | 46 | var gThisChunk = 0; |
michael@0 | 47 | var gContainingWindow = null; |
michael@0 | 48 | var gURLFilterRegex = null; |
michael@0 | 49 | const FOCUS_FILTER_ALL_TESTS = "all"; |
michael@0 | 50 | const FOCUS_FILTER_NEEDS_FOCUS_TESTS = "needs-focus"; |
michael@0 | 51 | const FOCUS_FILTER_NON_NEEDS_FOCUS_TESTS = "non-needs-focus"; |
michael@0 | 52 | var gFocusFilterMode = FOCUS_FILTER_ALL_TESTS; |
michael@0 | 53 | |
michael@0 | 54 | // "<!--CLEAR-->" |
michael@0 | 55 | const BLANK_URL_FOR_CLEARING = "data:text/html;charset=UTF-8,%3C%21%2D%2DCLEAR%2D%2D%3E"; |
michael@0 | 56 | |
michael@0 | 57 | var gBrowser; |
michael@0 | 58 | // Are we testing web content loaded in a separate process? |
michael@0 | 59 | var gBrowserIsRemote; // bool |
michael@0 | 60 | // Are we using <iframe mozbrowser>? |
michael@0 | 61 | var gBrowserIsIframe; // bool |
michael@0 | 62 | var gBrowserMessageManager; |
michael@0 | 63 | var gCanvas1, gCanvas2; |
michael@0 | 64 | // gCurrentCanvas is non-null between InitCurrentCanvasWithSnapshot and the next |
michael@0 | 65 | // RecordResult. |
michael@0 | 66 | var gCurrentCanvas = null; |
michael@0 | 67 | var gURLs; |
michael@0 | 68 | // Map from URI spec to the number of times it remains to be used |
michael@0 | 69 | var gURIUseCounts; |
michael@0 | 70 | // Map from URI spec to the canvas rendered for that URI |
michael@0 | 71 | var gURICanvases; |
michael@0 | 72 | var gTestResults = { |
michael@0 | 73 | // Successful... |
michael@0 | 74 | Pass: 0, |
michael@0 | 75 | LoadOnly: 0, |
michael@0 | 76 | // Unexpected... |
michael@0 | 77 | Exception: 0, |
michael@0 | 78 | FailedLoad: 0, |
michael@0 | 79 | UnexpectedFail: 0, |
michael@0 | 80 | UnexpectedPass: 0, |
michael@0 | 81 | AssertionUnexpected: 0, |
michael@0 | 82 | AssertionUnexpectedFixed: 0, |
michael@0 | 83 | // Known problems... |
michael@0 | 84 | KnownFail : 0, |
michael@0 | 85 | AssertionKnown: 0, |
michael@0 | 86 | Random : 0, |
michael@0 | 87 | Skip: 0, |
michael@0 | 88 | Slow: 0, |
michael@0 | 89 | }; |
michael@0 | 90 | var gTotalTests = 0; |
michael@0 | 91 | var gState; |
michael@0 | 92 | var gCurrentURL; |
michael@0 | 93 | var gTestLog = []; |
michael@0 | 94 | var gServer; |
michael@0 | 95 | var gCount = 0; |
michael@0 | 96 | var gAssertionCount = 0; |
michael@0 | 97 | |
michael@0 | 98 | var gIOService; |
michael@0 | 99 | var gDebug; |
michael@0 | 100 | var gWindowUtils; |
michael@0 | 101 | |
michael@0 | 102 | var gSlowestTestTime = 0; |
michael@0 | 103 | var gSlowestTestURL; |
michael@0 | 104 | |
michael@0 | 105 | var gDrawWindowFlags; |
michael@0 | 106 | |
michael@0 | 107 | var gExpectingProcessCrash = false; |
michael@0 | 108 | var gExpectedCrashDumpFiles = []; |
michael@0 | 109 | var gUnexpectedCrashDumpFiles = { }; |
michael@0 | 110 | var gCrashDumpDir; |
michael@0 | 111 | var gFailedNoPaint = false; |
michael@0 | 112 | |
michael@0 | 113 | // The enabled-state of the test-plugins, stored so they can be reset later |
michael@0 | 114 | var gTestPluginEnabledStates = null; |
michael@0 | 115 | |
michael@0 | 116 | const TYPE_REFTEST_EQUAL = '=='; |
michael@0 | 117 | const TYPE_REFTEST_NOTEQUAL = '!='; |
michael@0 | 118 | const TYPE_LOAD = 'load'; // test without a reference (just test that it does |
michael@0 | 119 | // not assert, crash, hang, or leak) |
michael@0 | 120 | const TYPE_SCRIPT = 'script'; // test contains individual test results |
michael@0 | 121 | |
michael@0 | 122 | // The order of these constants matters, since when we have a status |
michael@0 | 123 | // listed for a *manifest*, we combine the status with the status for |
michael@0 | 124 | // the test by using the *larger*. |
michael@0 | 125 | // FIXME: In the future, we may also want to use this rule for combining |
michael@0 | 126 | // statuses that are on the same line (rather than making the last one |
michael@0 | 127 | // win). |
michael@0 | 128 | const EXPECTED_PASS = 0; |
michael@0 | 129 | const EXPECTED_FAIL = 1; |
michael@0 | 130 | const EXPECTED_RANDOM = 2; |
michael@0 | 131 | const EXPECTED_DEATH = 3; // test must be skipped to avoid e.g. crash/hang |
michael@0 | 132 | const EXPECTED_FUZZY = 4; |
michael@0 | 133 | |
michael@0 | 134 | // types of preference value we might want to set for a specific test |
michael@0 | 135 | const PREF_BOOLEAN = 0; |
michael@0 | 136 | const PREF_STRING = 1; |
michael@0 | 137 | const PREF_INTEGER = 2; |
michael@0 | 138 | |
michael@0 | 139 | var gPrefsToRestore = []; |
michael@0 | 140 | |
michael@0 | 141 | const gProtocolRE = /^\w+:/; |
michael@0 | 142 | const gPrefItemRE = /^(|test-|ref-)pref\((.+?),(.*)\)$/; |
michael@0 | 143 | |
michael@0 | 144 | var gHttpServerPort = -1; |
michael@0 | 145 | |
michael@0 | 146 | // whether to run slow tests or not |
michael@0 | 147 | var gRunSlowTests = true; |
michael@0 | 148 | |
michael@0 | 149 | // whether we should skip caching canvases |
michael@0 | 150 | var gNoCanvasCache = false; |
michael@0 | 151 | |
michael@0 | 152 | var gRecycledCanvases = new Array(); |
michael@0 | 153 | |
michael@0 | 154 | // By default we just log to stdout |
michael@0 | 155 | var gDumpLog = dump; |
michael@0 | 156 | var gVerbose = false; |
michael@0 | 157 | |
michael@0 | 158 | // Only dump the sandbox once, because it doesn't depend on the |
michael@0 | 159 | // manifest URL (yet!). |
michael@0 | 160 | var gDumpedConditionSandbox = false; |
michael@0 | 161 | |
michael@0 | 162 | function LogWarning(str) |
michael@0 | 163 | { |
michael@0 | 164 | gDumpLog("REFTEST INFO | " + str + "\n"); |
michael@0 | 165 | gTestLog.push(str); |
michael@0 | 166 | } |
michael@0 | 167 | |
michael@0 | 168 | function LogInfo(str) |
michael@0 | 169 | { |
michael@0 | 170 | if (gVerbose) |
michael@0 | 171 | gDumpLog("REFTEST INFO | " + str + "\n"); |
michael@0 | 172 | gTestLog.push(str); |
michael@0 | 173 | } |
michael@0 | 174 | |
michael@0 | 175 | function FlushTestLog() |
michael@0 | 176 | { |
michael@0 | 177 | if (!gVerbose) { |
michael@0 | 178 | // In verbose mode, we've dumped all these messages already. |
michael@0 | 179 | for (var i = 0; i < gTestLog.length; ++i) { |
michael@0 | 180 | gDumpLog("REFTEST INFO | Saved log: " + gTestLog[i] + "\n"); |
michael@0 | 181 | } |
michael@0 | 182 | } |
michael@0 | 183 | gTestLog = []; |
michael@0 | 184 | } |
michael@0 | 185 | |
michael@0 | 186 | function AllocateCanvas() |
michael@0 | 187 | { |
michael@0 | 188 | if (gRecycledCanvases.length > 0) |
michael@0 | 189 | return gRecycledCanvases.shift(); |
michael@0 | 190 | |
michael@0 | 191 | var canvas = gContainingWindow.document.createElementNS(XHTML_NS, "canvas"); |
michael@0 | 192 | var r = gBrowser.getBoundingClientRect(); |
michael@0 | 193 | canvas.setAttribute("width", Math.ceil(r.width)); |
michael@0 | 194 | canvas.setAttribute("height", Math.ceil(r.height)); |
michael@0 | 195 | |
michael@0 | 196 | return canvas; |
michael@0 | 197 | } |
michael@0 | 198 | |
michael@0 | 199 | function ReleaseCanvas(canvas) |
michael@0 | 200 | { |
michael@0 | 201 | // store a maximum of 2 canvases, if we're not caching |
michael@0 | 202 | if (!gNoCanvasCache || gRecycledCanvases.length < 2) |
michael@0 | 203 | gRecycledCanvases.push(canvas); |
michael@0 | 204 | } |
michael@0 | 205 | |
michael@0 | 206 | function IDForEventTarget(event) |
michael@0 | 207 | { |
michael@0 | 208 | try { |
michael@0 | 209 | return "'" + event.target.getAttribute('id') + "'"; |
michael@0 | 210 | } catch (ex) { |
michael@0 | 211 | return "<unknown>"; |
michael@0 | 212 | } |
michael@0 | 213 | } |
michael@0 | 214 | |
michael@0 | 215 | function getTestPlugin(aName) { |
michael@0 | 216 | var ph = CC["@mozilla.org/plugin/host;1"].getService(CI.nsIPluginHost); |
michael@0 | 217 | var tags = ph.getPluginTags(); |
michael@0 | 218 | |
michael@0 | 219 | // Find the test plugin |
michael@0 | 220 | for (var i = 0; i < tags.length; i++) { |
michael@0 | 221 | if (tags[i].name == aName) |
michael@0 | 222 | return tags[i]; |
michael@0 | 223 | } |
michael@0 | 224 | |
michael@0 | 225 | LogWarning("Failed to find the test-plugin."); |
michael@0 | 226 | return null; |
michael@0 | 227 | } |
michael@0 | 228 | |
michael@0 | 229 | this.OnRefTestLoad = function OnRefTestLoad(win) |
michael@0 | 230 | { |
michael@0 | 231 | gCrashDumpDir = CC[NS_DIRECTORY_SERVICE_CONTRACTID] |
michael@0 | 232 | .getService(CI.nsIProperties) |
michael@0 | 233 | .get("ProfD", CI.nsIFile); |
michael@0 | 234 | gCrashDumpDir.append("minidumps"); |
michael@0 | 235 | |
michael@0 | 236 | var env = CC["@mozilla.org/process/environment;1"]. |
michael@0 | 237 | getService(CI.nsIEnvironment); |
michael@0 | 238 | gVerbose = !!env.get("MOZ_REFTEST_VERBOSE"); |
michael@0 | 239 | |
michael@0 | 240 | var prefs = Components.classes["@mozilla.org/preferences-service;1"]. |
michael@0 | 241 | getService(Components.interfaces.nsIPrefBranch); |
michael@0 | 242 | try { |
michael@0 | 243 | gBrowserIsRemote = prefs.getBoolPref("browser.tabs.remote.autostart"); |
michael@0 | 244 | } catch (e) { |
michael@0 | 245 | gBrowserIsRemote = false; |
michael@0 | 246 | } |
michael@0 | 247 | |
michael@0 | 248 | try { |
michael@0 | 249 | gBrowserIsIframe = prefs.getBoolPref("reftest.browser.iframe.enabled"); |
michael@0 | 250 | } catch (e) { |
michael@0 | 251 | gBrowserIsIframe = false; |
michael@0 | 252 | } |
michael@0 | 253 | |
michael@0 | 254 | if (win === undefined || win == null) { |
michael@0 | 255 | win = window; |
michael@0 | 256 | } |
michael@0 | 257 | if (gContainingWindow == null && win != null) { |
michael@0 | 258 | gContainingWindow = win; |
michael@0 | 259 | } |
michael@0 | 260 | |
michael@0 | 261 | if (gBrowserIsIframe) { |
michael@0 | 262 | gBrowser = gContainingWindow.document.createElementNS(XHTML_NS, "iframe"); |
michael@0 | 263 | gBrowser.setAttribute("mozbrowser", ""); |
michael@0 | 264 | gBrowser.setAttribute("mozapp", prefs.getCharPref("browser.manifestURL")); |
michael@0 | 265 | } else { |
michael@0 | 266 | gBrowser = gContainingWindow.document.createElementNS(XUL_NS, "xul:browser"); |
michael@0 | 267 | } |
michael@0 | 268 | gBrowser.setAttribute("id", "browser"); |
michael@0 | 269 | gBrowser.setAttribute("type", "content-primary"); |
michael@0 | 270 | gBrowser.setAttribute("remote", gBrowserIsRemote ? "true" : "false"); |
michael@0 | 271 | gBrowser.setAttribute("mozasyncpanzoom", "true"); |
michael@0 | 272 | // Make sure the browser element is exactly 800x1000, no matter |
michael@0 | 273 | // what size our window is |
michael@0 | 274 | gBrowser.setAttribute("style", "min-width: 800px; min-height: 1000px; max-width: 800px; max-height: 1000px"); |
michael@0 | 275 | |
michael@0 | 276 | #ifdef BOOTSTRAP |
michael@0 | 277 | #ifdef REFTEST_B2G |
michael@0 | 278 | var doc = gContainingWindow.document.getElementsByTagName("html")[0]; |
michael@0 | 279 | #else |
michael@0 | 280 | var doc = gContainingWindow.document.getElementById('main-window'); |
michael@0 | 281 | #endif |
michael@0 | 282 | while (doc.hasChildNodes()) { |
michael@0 | 283 | doc.removeChild(doc.firstChild); |
michael@0 | 284 | } |
michael@0 | 285 | doc.appendChild(gBrowser); |
michael@0 | 286 | #else |
michael@0 | 287 | document.getElementById("reftest-window").appendChild(gBrowser); |
michael@0 | 288 | #endif |
michael@0 | 289 | |
michael@0 | 290 | // reftests should have the test plugins enabled, not click-to-play |
michael@0 | 291 | let plugin1 = getTestPlugin("Test Plug-in"); |
michael@0 | 292 | let plugin2 = getTestPlugin("Second Test Plug-in"); |
michael@0 | 293 | if (plugin1 && plugin2) { |
michael@0 | 294 | gTestPluginEnabledStates = [plugin1.enabledState, plugin2.enabledState]; |
michael@0 | 295 | plugin1.enabledState = CI.nsIPluginTag.STATE_ENABLED; |
michael@0 | 296 | plugin2.enabledState = CI.nsIPluginTag.STATE_ENABLED; |
michael@0 | 297 | } else { |
michael@0 | 298 | LogWarning("Could not get test plugin tags."); |
michael@0 | 299 | } |
michael@0 | 300 | |
michael@0 | 301 | gBrowserMessageManager = gBrowser.QueryInterface(CI.nsIFrameLoaderOwner) |
michael@0 | 302 | .frameLoader.messageManager; |
michael@0 | 303 | // The content script waits for the initial onload, then notifies |
michael@0 | 304 | // us. |
michael@0 | 305 | RegisterMessageListenersAndLoadContentScript(); |
michael@0 | 306 | } |
michael@0 | 307 | |
michael@0 | 308 | function InitAndStartRefTests() |
michael@0 | 309 | { |
michael@0 | 310 | /* These prefs are optional, so we don't need to spit an error to the log */ |
michael@0 | 311 | try { |
michael@0 | 312 | var prefs = Components.classes["@mozilla.org/preferences-service;1"]. |
michael@0 | 313 | getService(Components.interfaces.nsIPrefBranch); |
michael@0 | 314 | } catch(e) { |
michael@0 | 315 | gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | | EXCEPTION: " + e + "\n"); |
michael@0 | 316 | } |
michael@0 | 317 | |
michael@0 | 318 | try { |
michael@0 | 319 | prefs.setBoolPref("android.widget_paints_background", false); |
michael@0 | 320 | } catch (e) {} |
michael@0 | 321 | |
michael@0 | 322 | /* set the gLoadTimeout */ |
michael@0 | 323 | try { |
michael@0 | 324 | gLoadTimeout = prefs.getIntPref("reftest.timeout"); |
michael@0 | 325 | } catch(e) { |
michael@0 | 326 | gLoadTimeout = 5 * 60 * 1000; //5 minutes as per bug 479518 |
michael@0 | 327 | } |
michael@0 | 328 | |
michael@0 | 329 | /* Get the logfile for android tests */ |
michael@0 | 330 | try { |
michael@0 | 331 | var logFile = prefs.getCharPref("reftest.logFile"); |
michael@0 | 332 | if (logFile) { |
michael@0 | 333 | try { |
michael@0 | 334 | var f = FileUtils.File(logFile); |
michael@0 | 335 | var mfl = FileUtils.openFileOutputStream(f, FileUtils.MODE_WRONLY | FileUtils.MODE_CREATE); |
michael@0 | 336 | // Set to mirror to stdout as well as the file |
michael@0 | 337 | gDumpLog = function (msg) { |
michael@0 | 338 | #ifdef BOOTSTRAP |
michael@0 | 339 | #ifdef REFTEST_B2G |
michael@0 | 340 | dump(msg); |
michael@0 | 341 | #else |
michael@0 | 342 | //NOTE: on android-xul, we have a libc crash if we do a dump with %7s in the string |
michael@0 | 343 | #endif |
michael@0 | 344 | #else |
michael@0 | 345 | dump(msg); |
michael@0 | 346 | #endif |
michael@0 | 347 | mfl.write(msg, msg.length); |
michael@0 | 348 | }; |
michael@0 | 349 | } |
michael@0 | 350 | catch(e) { |
michael@0 | 351 | // If there is a problem, just use stdout |
michael@0 | 352 | gDumpLog = dump; |
michael@0 | 353 | } |
michael@0 | 354 | } |
michael@0 | 355 | } catch(e) {} |
michael@0 | 356 | |
michael@0 | 357 | try { |
michael@0 | 358 | gRemote = prefs.getBoolPref("reftest.remote"); |
michael@0 | 359 | } catch(e) { |
michael@0 | 360 | gRemote = false; |
michael@0 | 361 | } |
michael@0 | 362 | |
michael@0 | 363 | try { |
michael@0 | 364 | gIgnoreWindowSize = prefs.getBoolPref("reftest.ignoreWindowSize"); |
michael@0 | 365 | } catch(e) { |
michael@0 | 366 | gIgnoreWindowSize = false; |
michael@0 | 367 | } |
michael@0 | 368 | |
michael@0 | 369 | /* Support for running a chunk (subset) of tests. In separate try as this is optional */ |
michael@0 | 370 | try { |
michael@0 | 371 | gTotalChunks = prefs.getIntPref("reftest.totalChunks"); |
michael@0 | 372 | gThisChunk = prefs.getIntPref("reftest.thisChunk"); |
michael@0 | 373 | } |
michael@0 | 374 | catch(e) { |
michael@0 | 375 | gTotalChunks = 0; |
michael@0 | 376 | gThisChunk = 0; |
michael@0 | 377 | } |
michael@0 | 378 | |
michael@0 | 379 | try { |
michael@0 | 380 | gURLFilterRegex = new RegExp(prefs.getCharPref("reftest.filter")); |
michael@0 | 381 | } catch(e) {} |
michael@0 | 382 | |
michael@0 | 383 | try { |
michael@0 | 384 | gFocusFilterMode = prefs.getCharPref("reftest.focusFilterMode"); |
michael@0 | 385 | } catch(e) {} |
michael@0 | 386 | |
michael@0 | 387 | gWindowUtils = gContainingWindow.QueryInterface(CI.nsIInterfaceRequestor).getInterface(CI.nsIDOMWindowUtils); |
michael@0 | 388 | if (!gWindowUtils || !gWindowUtils.compareCanvases) |
michael@0 | 389 | throw "nsIDOMWindowUtils inteface missing"; |
michael@0 | 390 | |
michael@0 | 391 | gIOService = CC[IO_SERVICE_CONTRACTID].getService(CI.nsIIOService); |
michael@0 | 392 | gDebug = CC[DEBUG_CONTRACTID].getService(CI.nsIDebug2); |
michael@0 | 393 | |
michael@0 | 394 | RegisterProcessCrashObservers(); |
michael@0 | 395 | |
michael@0 | 396 | if (gRemote) { |
michael@0 | 397 | gServer = null; |
michael@0 | 398 | } else { |
michael@0 | 399 | // not all gecko applications autoregister xpcom components |
michael@0 | 400 | if (CC["@mozilla.org/server/jshttp;1"] === undefined) { |
michael@0 | 401 | var file = CC["@mozilla.org/file/directory_service;1"]. |
michael@0 | 402 | getService(CI.nsIProperties).get("ProfD", CI.nsIFile); |
michael@0 | 403 | file.appendRelativePath("extensions/reftest@mozilla.org/chrome.manifest"); |
michael@0 | 404 | |
michael@0 | 405 | registrar = Components.manager.QueryInterface(CI.nsIComponentRegistrar); |
michael@0 | 406 | registrar.autoRegister(file); |
michael@0 | 407 | } |
michael@0 | 408 | gServer = CC["@mozilla.org/server/jshttp;1"]. |
michael@0 | 409 | createInstance(CI.nsIHttpServer); |
michael@0 | 410 | } |
michael@0 | 411 | try { |
michael@0 | 412 | if (gServer) |
michael@0 | 413 | StartHTTPServer(); |
michael@0 | 414 | } catch (ex) { |
michael@0 | 415 | //gBrowser.loadURI('data:text/plain,' + ex); |
michael@0 | 416 | ++gTestResults.Exception; |
michael@0 | 417 | gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | | EXCEPTION: " + ex + "\n"); |
michael@0 | 418 | DoneTests(); |
michael@0 | 419 | } |
michael@0 | 420 | |
michael@0 | 421 | // Focus the content browser. |
michael@0 | 422 | if (gFocusFilterMode != FOCUS_FILTER_NON_NEEDS_FOCUS_TESTS) { |
michael@0 | 423 | gBrowser.focus(); |
michael@0 | 424 | } |
michael@0 | 425 | |
michael@0 | 426 | StartTests(); |
michael@0 | 427 | } |
michael@0 | 428 | |
michael@0 | 429 | function StartHTTPServer() |
michael@0 | 430 | { |
michael@0 | 431 | gServer.registerContentType("sjs", "sjs"); |
michael@0 | 432 | gServer.start(-1); |
michael@0 | 433 | gHttpServerPort = gServer.identity.primaryPort; |
michael@0 | 434 | } |
michael@0 | 435 | |
michael@0 | 436 | // Perform a Fisher-Yates shuffle of the array. |
michael@0 | 437 | function Shuffle(array) |
michael@0 | 438 | { |
michael@0 | 439 | for (var i = array.length - 1; i > 0; i--) { |
michael@0 | 440 | var j = Math.floor(Math.random() * (i + 1)); |
michael@0 | 441 | var temp = array[i]; |
michael@0 | 442 | array[i] = array[j]; |
michael@0 | 443 | array[j] = temp; |
michael@0 | 444 | } |
michael@0 | 445 | } |
michael@0 | 446 | |
michael@0 | 447 | function StartTests() |
michael@0 | 448 | { |
michael@0 | 449 | var uri; |
michael@0 | 450 | #if BOOTSTRAP |
michael@0 | 451 | /* These prefs are optional, so we don't need to spit an error to the log */ |
michael@0 | 452 | try { |
michael@0 | 453 | var prefs = Components.classes["@mozilla.org/preferences-service;1"]. |
michael@0 | 454 | getService(Components.interfaces.nsIPrefBranch); |
michael@0 | 455 | } catch(e) { |
michael@0 | 456 | gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | | EXCEPTION: " + e + "\n"); |
michael@0 | 457 | } |
michael@0 | 458 | |
michael@0 | 459 | try { |
michael@0 | 460 | gNoCanvasCache = prefs.getIntPref("reftest.nocache"); |
michael@0 | 461 | } catch(e) { |
michael@0 | 462 | gNoCanvasCache = false; |
michael@0 | 463 | } |
michael@0 | 464 | |
michael@0 | 465 | try { |
michael@0 | 466 | gShuffle = prefs.getBoolPref("reftest.shuffle"); |
michael@0 | 467 | } catch (e) { |
michael@0 | 468 | gShuffle = false; |
michael@0 | 469 | } |
michael@0 | 470 | |
michael@0 | 471 | try { |
michael@0 | 472 | gRunSlowTests = prefs.getIntPref("reftest.skipslowtests"); |
michael@0 | 473 | } catch(e) { |
michael@0 | 474 | gRunSlowTests = false; |
michael@0 | 475 | } |
michael@0 | 476 | |
michael@0 | 477 | try { |
michael@0 | 478 | uri = prefs.getCharPref("reftest.uri"); |
michael@0 | 479 | } catch(e) { |
michael@0 | 480 | uri = ""; |
michael@0 | 481 | } |
michael@0 | 482 | |
michael@0 | 483 | if (uri == "") { |
michael@0 | 484 | gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | | Unable to find reftest.uri pref. Please ensure your profile is setup properly\n"); |
michael@0 | 485 | DoneTests(); |
michael@0 | 486 | } |
michael@0 | 487 | #else |
michael@0 | 488 | try { |
michael@0 | 489 | // Need to read the manifest once we have gHttpServerPort.. |
michael@0 | 490 | var args = window.arguments[0].wrappedJSObject; |
michael@0 | 491 | |
michael@0 | 492 | if ("nocache" in args && args["nocache"]) |
michael@0 | 493 | gNoCanvasCache = true; |
michael@0 | 494 | |
michael@0 | 495 | if ("skipslowtests" in args && args.skipslowtests) |
michael@0 | 496 | gRunSlowTests = false; |
michael@0 | 497 | |
michael@0 | 498 | uri = args.uri; |
michael@0 | 499 | } catch (e) { |
michael@0 | 500 | ++gTestResults.Exception; |
michael@0 | 501 | gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | | EXCEPTION: " + ex + "\n"); |
michael@0 | 502 | DoneTests(); |
michael@0 | 503 | } |
michael@0 | 504 | #endif |
michael@0 | 505 | |
michael@0 | 506 | if (gShuffle) { |
michael@0 | 507 | gNoCanvasCache = true; |
michael@0 | 508 | } |
michael@0 | 509 | |
michael@0 | 510 | try { |
michael@0 | 511 | ReadTopManifest(uri); |
michael@0 | 512 | BuildUseCounts(); |
michael@0 | 513 | |
michael@0 | 514 | // Filter tests which will be skipped to get a more even distribution when chunking |
michael@0 | 515 | // tURLs is a temporary array containing all active tests |
michael@0 | 516 | var tURLs = new Array(); |
michael@0 | 517 | for (var i = 0; i < gURLs.length; ++i) { |
michael@0 | 518 | if (gURLs[i].expected == EXPECTED_DEATH) |
michael@0 | 519 | continue; |
michael@0 | 520 | |
michael@0 | 521 | if (gURLs[i].needsFocus && !Focus()) |
michael@0 | 522 | continue; |
michael@0 | 523 | |
michael@0 | 524 | if (gURLs[i].slow && !gRunSlowTests) |
michael@0 | 525 | continue; |
michael@0 | 526 | |
michael@0 | 527 | tURLs.push(gURLs[i]); |
michael@0 | 528 | } |
michael@0 | 529 | |
michael@0 | 530 | gDumpLog("REFTEST INFO | Discovered " + gURLs.length + " tests, after filtering SKIP tests, we have " + tURLs.length + "\n"); |
michael@0 | 531 | |
michael@0 | 532 | if (gTotalChunks > 0 && gThisChunk > 0) { |
michael@0 | 533 | // Calculate start and end indices of this chunk if tURLs array were |
michael@0 | 534 | // divided evenly |
michael@0 | 535 | var testsPerChunk = tURLs.length / gTotalChunks; |
michael@0 | 536 | var start = Math.round((gThisChunk-1) * testsPerChunk); |
michael@0 | 537 | var end = Math.round(gThisChunk * testsPerChunk); |
michael@0 | 538 | |
michael@0 | 539 | // Map these indices onto the gURLs array. This avoids modifying the |
michael@0 | 540 | // gURLs array which prevents skipped tests from showing up in the log |
michael@0 | 541 | start = gThisChunk == 1 ? 0 : gURLs.indexOf(tURLs[start]); |
michael@0 | 542 | end = gThisChunk == gTotalChunks ? gURLs.length : gURLs.indexOf(tURLs[end + 1]) - 1; |
michael@0 | 543 | gURLs = gURLs.slice(start, end); |
michael@0 | 544 | |
michael@0 | 545 | gDumpLog("REFTEST INFO | Running chunk " + gThisChunk + " out of " + gTotalChunks + " chunks. "); |
michael@0 | 546 | gDumpLog("tests " + (start+1) + "-" + end + "/" + gURLs.length + "\n"); |
michael@0 | 547 | } |
michael@0 | 548 | |
michael@0 | 549 | if (gShuffle) { |
michael@0 | 550 | Shuffle(gURLs); |
michael@0 | 551 | } |
michael@0 | 552 | |
michael@0 | 553 | gTotalTests = gURLs.length; |
michael@0 | 554 | |
michael@0 | 555 | if (!gTotalTests) |
michael@0 | 556 | throw "No tests to run"; |
michael@0 | 557 | |
michael@0 | 558 | gURICanvases = {}; |
michael@0 | 559 | StartCurrentTest(); |
michael@0 | 560 | } catch (ex) { |
michael@0 | 561 | //gBrowser.loadURI('data:text/plain,' + ex); |
michael@0 | 562 | ++gTestResults.Exception; |
michael@0 | 563 | gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | | EXCEPTION: " + ex + "\n"); |
michael@0 | 564 | DoneTests(); |
michael@0 | 565 | } |
michael@0 | 566 | } |
michael@0 | 567 | |
michael@0 | 568 | function OnRefTestUnload() |
michael@0 | 569 | { |
michael@0 | 570 | let plugin1 = getTestPlugin("Test Plug-in"); |
michael@0 | 571 | let plugin2 = getTestPlugin("Second Test Plug-in"); |
michael@0 | 572 | if (plugin1 && plugin2) { |
michael@0 | 573 | plugin1.enabledState = gTestPluginEnabledStates[0]; |
michael@0 | 574 | plugin2.enabledState = gTestPluginEnabledStates[1]; |
michael@0 | 575 | } else { |
michael@0 | 576 | LogWarning("Failed to get test plugin tags."); |
michael@0 | 577 | } |
michael@0 | 578 | } |
michael@0 | 579 | |
michael@0 | 580 | // Read all available data from an input stream and return it |
michael@0 | 581 | // as a string. |
michael@0 | 582 | function getStreamContent(inputStream) |
michael@0 | 583 | { |
michael@0 | 584 | var streamBuf = ""; |
michael@0 | 585 | var sis = CC["@mozilla.org/scriptableinputstream;1"]. |
michael@0 | 586 | createInstance(CI.nsIScriptableInputStream); |
michael@0 | 587 | sis.init(inputStream); |
michael@0 | 588 | |
michael@0 | 589 | var available; |
michael@0 | 590 | while ((available = sis.available()) != 0) { |
michael@0 | 591 | streamBuf += sis.read(available); |
michael@0 | 592 | } |
michael@0 | 593 | |
michael@0 | 594 | return streamBuf; |
michael@0 | 595 | } |
michael@0 | 596 | |
michael@0 | 597 | // Build the sandbox for fails-if(), etc., condition evaluation. |
michael@0 | 598 | function BuildConditionSandbox(aURL) { |
michael@0 | 599 | var sandbox = new Components.utils.Sandbox(aURL.spec); |
michael@0 | 600 | var xr = CC[NS_XREAPPINFO_CONTRACTID].getService(CI.nsIXULRuntime); |
michael@0 | 601 | var appInfo = CC[NS_XREAPPINFO_CONTRACTID].getService(CI.nsIXULAppInfo); |
michael@0 | 602 | sandbox.isDebugBuild = gDebug.isDebugBuild; |
michael@0 | 603 | sandbox.xulRuntime = {widgetToolkit: xr.widgetToolkit, OS: xr.OS, __exposedProps__: { widgetToolkit: "r", OS: "r", XPCOMABI: "r", shell: "r" } }; |
michael@0 | 604 | |
michael@0 | 605 | // xr.XPCOMABI throws exception for configurations without full ABI |
michael@0 | 606 | // support (mobile builds on ARM) |
michael@0 | 607 | try { |
michael@0 | 608 | sandbox.xulRuntime.XPCOMABI = xr.XPCOMABI; |
michael@0 | 609 | } catch(e) { |
michael@0 | 610 | sandbox.xulRuntime.XPCOMABI = ""; |
michael@0 | 611 | } |
michael@0 | 612 | |
michael@0 | 613 | var testRect = gBrowser.getBoundingClientRect(); |
michael@0 | 614 | sandbox.smallScreen = false; |
michael@0 | 615 | if (gContainingWindow.innerWidth < 800 || gContainingWindow.innerHeight < 1000) { |
michael@0 | 616 | sandbox.smallScreen = true; |
michael@0 | 617 | } |
michael@0 | 618 | |
michael@0 | 619 | var gfxInfo = (NS_GFXINFO_CONTRACTID in CC) && CC[NS_GFXINFO_CONTRACTID].getService(CI.nsIGfxInfo); |
michael@0 | 620 | try { |
michael@0 | 621 | sandbox.d2d = gfxInfo.D2DEnabled; |
michael@0 | 622 | } catch (e) { |
michael@0 | 623 | sandbox.d2d = false; |
michael@0 | 624 | } |
michael@0 | 625 | var info = gfxInfo.getInfo(); |
michael@0 | 626 | sandbox.azureQuartz = info.AzureCanvasBackend == "quartz"; |
michael@0 | 627 | sandbox.azureSkia = info.AzureCanvasBackend == "skia"; |
michael@0 | 628 | sandbox.azureSkiaGL = info.AzureSkiaAccelerated; // FIXME: assumes GL right now |
michael@0 | 629 | // true if we are using the same Azure backend for rendering canvas and content |
michael@0 | 630 | sandbox.contentSameGfxBackendAsCanvas = info.AzureContentBackend == info.AzureCanvasBackend |
michael@0 | 631 | || (info.AzureContentBackend == "none" && info.AzureCanvasBackend == "cairo"); |
michael@0 | 632 | |
michael@0 | 633 | sandbox.layersGPUAccelerated = |
michael@0 | 634 | gWindowUtils.layerManagerType != "Basic"; |
michael@0 | 635 | sandbox.layersOpenGL = |
michael@0 | 636 | gWindowUtils.layerManagerType == "OpenGL"; |
michael@0 | 637 | sandbox.layersOMTC = |
michael@0 | 638 | gWindowUtils.layerManagerRemote == true; |
michael@0 | 639 | |
michael@0 | 640 | // Shortcuts for widget toolkits. |
michael@0 | 641 | sandbox.B2G = xr.widgetToolkit == "gonk"; |
michael@0 | 642 | sandbox.B2GDT = appInfo.name.toLowerCase() == "b2g" && !sandbox.B2G; |
michael@0 | 643 | sandbox.Android = xr.OS == "Android" && !sandbox.B2G; |
michael@0 | 644 | sandbox.cocoaWidget = xr.widgetToolkit == "cocoa"; |
michael@0 | 645 | sandbox.gtk2Widget = xr.widgetToolkit == "gtk2"; |
michael@0 | 646 | sandbox.qtWidget = xr.widgetToolkit == "qt"; |
michael@0 | 647 | sandbox.winWidget = xr.widgetToolkit == "windows"; |
michael@0 | 648 | |
michael@0 | 649 | if (sandbox.Android) { |
michael@0 | 650 | var sysInfo = CC["@mozilla.org/system-info;1"].getService(CI.nsIPropertyBag2); |
michael@0 | 651 | |
michael@0 | 652 | // This is currently used to distinguish Android 4.0.3 (SDK version 15) |
michael@0 | 653 | // and later from Android 2.x |
michael@0 | 654 | sandbox.AndroidVersion = sysInfo.getPropertyAsInt32("version"); |
michael@0 | 655 | } |
michael@0 | 656 | |
michael@0 | 657 | #if MOZ_ASAN |
michael@0 | 658 | sandbox.AddressSanitizer = true; |
michael@0 | 659 | #else |
michael@0 | 660 | sandbox.AddressSanitizer = false; |
michael@0 | 661 | #endif |
michael@0 | 662 | |
michael@0 | 663 | #if MOZ_WEBRTC |
michael@0 | 664 | sandbox.webrtc = true; |
michael@0 | 665 | #else |
michael@0 | 666 | sandbox.webrtc = false; |
michael@0 | 667 | #endif |
michael@0 | 668 | |
michael@0 | 669 | var hh = CC[NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX + "http"]. |
michael@0 | 670 | getService(CI.nsIHttpProtocolHandler); |
michael@0 | 671 | sandbox.http = { __exposedProps__: {} }; |
michael@0 | 672 | for each (var prop in [ "userAgent", "appName", "appVersion", |
michael@0 | 673 | "vendor", "vendorSub", |
michael@0 | 674 | "product", "productSub", |
michael@0 | 675 | "platform", "oscpu", "language", "misc" ]) { |
michael@0 | 676 | sandbox.http[prop] = hh[prop]; |
michael@0 | 677 | sandbox.http.__exposedProps__[prop] = "r"; |
michael@0 | 678 | } |
michael@0 | 679 | |
michael@0 | 680 | // Set OSX to the Mac OS X version for Mac, and 0 otherwise. |
michael@0 | 681 | var osxmatch = /Mac OS X (\d+.\d+)$/.exec(hh.oscpu); |
michael@0 | 682 | sandbox.OSX = osxmatch ? parseFloat(osxmatch[1]) : 0; |
michael@0 | 683 | |
michael@0 | 684 | // see if we have the test plugin available, |
michael@0 | 685 | // and set a sandox prop accordingly |
michael@0 | 686 | var navigator = gContainingWindow.navigator; |
michael@0 | 687 | var testPlugin = navigator.plugins["Test Plug-in"]; |
michael@0 | 688 | sandbox.haveTestPlugin = !!testPlugin; |
michael@0 | 689 | |
michael@0 | 690 | // Set a flag on sandbox if the windows default theme is active |
michael@0 | 691 | var box = gContainingWindow.document.createElement("box"); |
michael@0 | 692 | box.setAttribute("id", "_box_windowsDefaultTheme"); |
michael@0 | 693 | gContainingWindow.document.documentElement.appendChild(box); |
michael@0 | 694 | sandbox.windowsDefaultTheme = (gContainingWindow.getComputedStyle(box, null).display == "none"); |
michael@0 | 695 | gContainingWindow.document.documentElement.removeChild(box); |
michael@0 | 696 | |
michael@0 | 697 | var prefs = CC["@mozilla.org/preferences-service;1"]. |
michael@0 | 698 | getService(CI.nsIPrefBranch); |
michael@0 | 699 | try { |
michael@0 | 700 | sandbox.nativeThemePref = !prefs.getBoolPref("mozilla.widget.disable-native-theme"); |
michael@0 | 701 | } catch (e) { |
michael@0 | 702 | sandbox.nativeThemePref = true; |
michael@0 | 703 | } |
michael@0 | 704 | |
michael@0 | 705 | sandbox.prefs = { |
michael@0 | 706 | __exposedProps__: { |
michael@0 | 707 | getBoolPref: 'r', |
michael@0 | 708 | getIntPref: 'r', |
michael@0 | 709 | }, |
michael@0 | 710 | _prefs: prefs, |
michael@0 | 711 | getBoolPref: function(p) { return this._prefs.getBoolPref(p); }, |
michael@0 | 712 | getIntPref: function(p) { return this._prefs.getIntPref(p); } |
michael@0 | 713 | } |
michael@0 | 714 | |
michael@0 | 715 | sandbox.testPluginIsOOP = function () { |
michael@0 | 716 | try { |
michael@0 | 717 | netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); |
michael@0 | 718 | } catch (ex) {} |
michael@0 | 719 | |
michael@0 | 720 | var prefservice = Components.classes["@mozilla.org/preferences-service;1"] |
michael@0 | 721 | .getService(CI.nsIPrefBranch); |
michael@0 | 722 | |
michael@0 | 723 | var testPluginIsOOP = false; |
michael@0 | 724 | if (navigator.platform.indexOf("Mac") == 0) { |
michael@0 | 725 | var xulRuntime = Components.classes["@mozilla.org/xre/app-info;1"] |
michael@0 | 726 | .getService(CI.nsIXULAppInfo) |
michael@0 | 727 | .QueryInterface(CI.nsIXULRuntime); |
michael@0 | 728 | if (xulRuntime.XPCOMABI.match(/x86-/)) { |
michael@0 | 729 | try { |
michael@0 | 730 | testPluginIsOOP = prefservice.getBoolPref("dom.ipc.plugins.enabled.i386.test.plugin"); |
michael@0 | 731 | } catch (e) { |
michael@0 | 732 | testPluginIsOOP = prefservice.getBoolPref("dom.ipc.plugins.enabled.i386"); |
michael@0 | 733 | } |
michael@0 | 734 | } |
michael@0 | 735 | else if (xulRuntime.XPCOMABI.match(/x86_64-/)) { |
michael@0 | 736 | try { |
michael@0 | 737 | testPluginIsOOP = prefservice.getBoolPref("dom.ipc.plugins.enabled.x86_64.test.plugin"); |
michael@0 | 738 | } catch (e) { |
michael@0 | 739 | testPluginIsOOP = prefservice.getBoolPref("dom.ipc.plugins.enabled.x86_64"); |
michael@0 | 740 | } |
michael@0 | 741 | } |
michael@0 | 742 | } |
michael@0 | 743 | else { |
michael@0 | 744 | testPluginIsOOP = prefservice.getBoolPref("dom.ipc.plugins.enabled"); |
michael@0 | 745 | } |
michael@0 | 746 | |
michael@0 | 747 | return testPluginIsOOP; |
michael@0 | 748 | }; |
michael@0 | 749 | |
michael@0 | 750 | // Tests shouldn't care about this except for when they need to |
michael@0 | 751 | // crash the content process |
michael@0 | 752 | sandbox.browserIsRemote = gBrowserIsRemote; |
michael@0 | 753 | |
michael@0 | 754 | // Distinguish the Fennecs: |
michael@0 | 755 | sandbox.xulFennec = sandbox.Android && sandbox.browserIsRemote; |
michael@0 | 756 | sandbox.nativeFennec = sandbox.Android && !sandbox.browserIsRemote; |
michael@0 | 757 | |
michael@0 | 758 | if (!gDumpedConditionSandbox) { |
michael@0 | 759 | dump("REFTEST INFO | Dumping JSON representation of sandbox \n"); |
michael@0 | 760 | dump("REFTEST INFO | " + JSON.stringify(sandbox) + " \n"); |
michael@0 | 761 | gDumpedConditionSandbox = true; |
michael@0 | 762 | } |
michael@0 | 763 | return sandbox; |
michael@0 | 764 | } |
michael@0 | 765 | |
michael@0 | 766 | function AddPrefSettings(aWhere, aPrefName, aPrefValExpression, aSandbox, aTestPrefSettings, aRefPrefSettings) |
michael@0 | 767 | { |
michael@0 | 768 | var prefVal = Components.utils.evalInSandbox("(" + aPrefValExpression + ")", aSandbox); |
michael@0 | 769 | var prefType; |
michael@0 | 770 | var valType = typeof(prefVal); |
michael@0 | 771 | if (valType == "boolean") { |
michael@0 | 772 | prefType = PREF_BOOLEAN; |
michael@0 | 773 | } else if (valType == "string") { |
michael@0 | 774 | prefType = PREF_STRING; |
michael@0 | 775 | } else if (valType == "number" && (parseInt(prefVal) == prefVal)) { |
michael@0 | 776 | prefType = PREF_INTEGER; |
michael@0 | 777 | } else { |
michael@0 | 778 | return false; |
michael@0 | 779 | } |
michael@0 | 780 | var setting = { name: aPrefName, |
michael@0 | 781 | type: prefType, |
michael@0 | 782 | value: prefVal }; |
michael@0 | 783 | if (aWhere != "ref-") { |
michael@0 | 784 | aTestPrefSettings.push(setting); |
michael@0 | 785 | } |
michael@0 | 786 | if (aWhere != "test-") { |
michael@0 | 787 | aRefPrefSettings.push(setting); |
michael@0 | 788 | } |
michael@0 | 789 | return true; |
michael@0 | 790 | } |
michael@0 | 791 | |
michael@0 | 792 | function ReadTopManifest(aFileURL) |
michael@0 | 793 | { |
michael@0 | 794 | gURLs = new Array(); |
michael@0 | 795 | var url = gIOService.newURI(aFileURL, null, null); |
michael@0 | 796 | if (!url) |
michael@0 | 797 | throw "Expected a file or http URL for the manifest."; |
michael@0 | 798 | ReadManifest(url, EXPECTED_PASS); |
michael@0 | 799 | } |
michael@0 | 800 | |
michael@0 | 801 | function AddTestItem(aTest) |
michael@0 | 802 | { |
michael@0 | 803 | if (gURLFilterRegex && !gURLFilterRegex.test(aTest.url1.spec)) |
michael@0 | 804 | return; |
michael@0 | 805 | if (gFocusFilterMode == FOCUS_FILTER_NEEDS_FOCUS_TESTS && |
michael@0 | 806 | !aTest.needsFocus) |
michael@0 | 807 | return; |
michael@0 | 808 | if (gFocusFilterMode == FOCUS_FILTER_NON_NEEDS_FOCUS_TESTS && |
michael@0 | 809 | aTest.needsFocus) |
michael@0 | 810 | return; |
michael@0 | 811 | gURLs.push(aTest); |
michael@0 | 812 | } |
michael@0 | 813 | |
michael@0 | 814 | // Note: If you materially change the reftest manifest parsing, |
michael@0 | 815 | // please keep the parser in print-manifest-dirs.py in sync. |
michael@0 | 816 | function ReadManifest(aURL, inherited_status) |
michael@0 | 817 | { |
michael@0 | 818 | var secMan = CC[NS_SCRIPTSECURITYMANAGER_CONTRACTID] |
michael@0 | 819 | .getService(CI.nsIScriptSecurityManager); |
michael@0 | 820 | |
michael@0 | 821 | var listURL = aURL; |
michael@0 | 822 | var channel = gIOService.newChannelFromURI(aURL); |
michael@0 | 823 | var inputStream = channel.open(); |
michael@0 | 824 | if (channel instanceof Components.interfaces.nsIHttpChannel |
michael@0 | 825 | && channel.responseStatus != 200) { |
michael@0 | 826 | gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | | HTTP ERROR : " + |
michael@0 | 827 | channel.responseStatus + "\n"); |
michael@0 | 828 | } |
michael@0 | 829 | var streamBuf = getStreamContent(inputStream); |
michael@0 | 830 | inputStream.close(); |
michael@0 | 831 | var lines = streamBuf.split(/\n|\r|\r\n/); |
michael@0 | 832 | |
michael@0 | 833 | // Build the sandbox for fails-if(), etc., condition evaluation. |
michael@0 | 834 | var sandbox = BuildConditionSandbox(aURL); |
michael@0 | 835 | var lineNo = 0; |
michael@0 | 836 | var urlprefix = ""; |
michael@0 | 837 | var defaultTestPrefSettings = [], defaultRefPrefSettings = []; |
michael@0 | 838 | for each (var str in lines) { |
michael@0 | 839 | ++lineNo; |
michael@0 | 840 | if (str.charAt(0) == "#") |
michael@0 | 841 | continue; // entire line was a comment |
michael@0 | 842 | var i = str.search(/\s+#/); |
michael@0 | 843 | if (i >= 0) |
michael@0 | 844 | str = str.substring(0, i); |
michael@0 | 845 | // strip leading and trailing whitespace |
michael@0 | 846 | str = str.replace(/^\s*/, '').replace(/\s*$/, ''); |
michael@0 | 847 | if (!str || str == "") |
michael@0 | 848 | continue; |
michael@0 | 849 | var items = str.split(/\s+/); // split on whitespace |
michael@0 | 850 | |
michael@0 | 851 | if (items[0] == "url-prefix") { |
michael@0 | 852 | if (items.length != 2) |
michael@0 | 853 | throw "url-prefix requires one url in manifest file " + aURL.spec + " line " + lineNo; |
michael@0 | 854 | urlprefix = items[1]; |
michael@0 | 855 | continue; |
michael@0 | 856 | } |
michael@0 | 857 | |
michael@0 | 858 | if (items[0] == "default-preferences") { |
michael@0 | 859 | var m; |
michael@0 | 860 | var item; |
michael@0 | 861 | defaultTestPrefSettings = []; |
michael@0 | 862 | defaultRefPrefSettings = []; |
michael@0 | 863 | items.shift(); |
michael@0 | 864 | while ((item = items.shift())) { |
michael@0 | 865 | if (!(m = item.match(gPrefItemRE))) { |
michael@0 | 866 | throw "Unexpected item in default-preferences list in manifest file " + aURL.spec + " line " + lineNo; |
michael@0 | 867 | } |
michael@0 | 868 | if (!AddPrefSettings(m[1], m[2], m[3], sandbox, defaultTestPrefSettings, defaultRefPrefSettings)) { |
michael@0 | 869 | throw "Error in pref value in manifest file " + aURL.spec + " line " + lineNo; |
michael@0 | 870 | } |
michael@0 | 871 | } |
michael@0 | 872 | continue; |
michael@0 | 873 | } |
michael@0 | 874 | |
michael@0 | 875 | var expected_status = EXPECTED_PASS; |
michael@0 | 876 | var allow_silent_fail = false; |
michael@0 | 877 | var minAsserts = 0; |
michael@0 | 878 | var maxAsserts = 0; |
michael@0 | 879 | var needs_focus = false; |
michael@0 | 880 | var slow = false; |
michael@0 | 881 | var testPrefSettings = defaultTestPrefSettings.concat(); |
michael@0 | 882 | var refPrefSettings = defaultRefPrefSettings.concat(); |
michael@0 | 883 | var fuzzy_max_delta = 2; |
michael@0 | 884 | var fuzzy_max_pixels = 1; |
michael@0 | 885 | |
michael@0 | 886 | while (items[0].match(/^(fails|needs-focus|random|skip|asserts|slow|require-or|silentfail|pref|test-pref|ref-pref|fuzzy)/)) { |
michael@0 | 887 | var item = items.shift(); |
michael@0 | 888 | var stat; |
michael@0 | 889 | var cond; |
michael@0 | 890 | var m = item.match(/^(fails|random|skip|silentfail)-if(\(.*\))$/); |
michael@0 | 891 | if (m) { |
michael@0 | 892 | stat = m[1]; |
michael@0 | 893 | // Note: m[2] contains the parentheses, and we want them. |
michael@0 | 894 | cond = Components.utils.evalInSandbox(m[2], sandbox); |
michael@0 | 895 | } else if (item.match(/^(fails|random|skip)$/)) { |
michael@0 | 896 | stat = item; |
michael@0 | 897 | cond = true; |
michael@0 | 898 | } else if (item == "needs-focus") { |
michael@0 | 899 | needs_focus = true; |
michael@0 | 900 | cond = false; |
michael@0 | 901 | } else if ((m = item.match(/^asserts\((\d+)(-\d+)?\)$/))) { |
michael@0 | 902 | cond = false; |
michael@0 | 903 | minAsserts = Number(m[1]); |
michael@0 | 904 | maxAsserts = (m[2] == undefined) ? minAsserts |
michael@0 | 905 | : Number(m[2].substring(1)); |
michael@0 | 906 | } else if ((m = item.match(/^asserts-if\((.*?),(\d+)(-\d+)?\)$/))) { |
michael@0 | 907 | cond = false; |
michael@0 | 908 | if (Components.utils.evalInSandbox("(" + m[1] + ")", sandbox)) { |
michael@0 | 909 | minAsserts = Number(m[2]); |
michael@0 | 910 | maxAsserts = |
michael@0 | 911 | (m[3] == undefined) ? minAsserts |
michael@0 | 912 | : Number(m[3].substring(1)); |
michael@0 | 913 | } |
michael@0 | 914 | } else if (item == "slow") { |
michael@0 | 915 | cond = false; |
michael@0 | 916 | slow = true; |
michael@0 | 917 | } else if ((m = item.match(/^require-or\((.*?)\)$/))) { |
michael@0 | 918 | var args = m[1].split(/,/); |
michael@0 | 919 | if (args.length != 2) { |
michael@0 | 920 | throw "Error 7 in manifest file " + aURL.spec + " line " + lineNo + ": wrong number of args to require-or"; |
michael@0 | 921 | } |
michael@0 | 922 | var [precondition_str, fallback_action] = args; |
michael@0 | 923 | var preconditions = precondition_str.split(/&&/); |
michael@0 | 924 | cond = false; |
michael@0 | 925 | for each (var precondition in preconditions) { |
michael@0 | 926 | if (precondition === "debugMode") { |
michael@0 | 927 | // Currently unimplemented. Requires asynchronous |
michael@0 | 928 | // JSD call + getting an event while no JS is running |
michael@0 | 929 | stat = fallback_action; |
michael@0 | 930 | cond = true; |
michael@0 | 931 | break; |
michael@0 | 932 | } else if (precondition === "true") { |
michael@0 | 933 | // For testing |
michael@0 | 934 | } else { |
michael@0 | 935 | // Unknown precondition. Assume it is unimplemented. |
michael@0 | 936 | stat = fallback_action; |
michael@0 | 937 | cond = true; |
michael@0 | 938 | break; |
michael@0 | 939 | } |
michael@0 | 940 | } |
michael@0 | 941 | } else if ((m = item.match(/^slow-if\((.*?)\)$/))) { |
michael@0 | 942 | cond = false; |
michael@0 | 943 | if (Components.utils.evalInSandbox("(" + m[1] + ")", sandbox)) |
michael@0 | 944 | slow = true; |
michael@0 | 945 | } else if (item == "silentfail") { |
michael@0 | 946 | cond = false; |
michael@0 | 947 | allow_silent_fail = true; |
michael@0 | 948 | } else if ((m = item.match(gPrefItemRE))) { |
michael@0 | 949 | cond = false; |
michael@0 | 950 | if (!AddPrefSettings(m[1], m[2], m[3], sandbox, testPrefSettings, refPrefSettings)) { |
michael@0 | 951 | throw "Error in pref value in manifest file " + aURL.spec + " line " + lineNo; |
michael@0 | 952 | } |
michael@0 | 953 | } else if ((m = item.match(/^fuzzy\((\d+),(\d+)\)$/))) { |
michael@0 | 954 | cond = false; |
michael@0 | 955 | expected_status = EXPECTED_FUZZY; |
michael@0 | 956 | fuzzy_max_delta = Number(m[1]); |
michael@0 | 957 | fuzzy_max_pixels = Number(m[2]); |
michael@0 | 958 | } else if ((m = item.match(/^fuzzy-if\((.*?),(\d+),(\d+)\)$/))) { |
michael@0 | 959 | cond = false; |
michael@0 | 960 | if (Components.utils.evalInSandbox("(" + m[1] + ")", sandbox)) { |
michael@0 | 961 | expected_status = EXPECTED_FUZZY; |
michael@0 | 962 | fuzzy_max_delta = Number(m[2]); |
michael@0 | 963 | fuzzy_max_pixels = Number(m[3]); |
michael@0 | 964 | } |
michael@0 | 965 | } else { |
michael@0 | 966 | throw "Error 1 in manifest file " + aURL.spec + " line " + lineNo; |
michael@0 | 967 | } |
michael@0 | 968 | |
michael@0 | 969 | if (cond) { |
michael@0 | 970 | if (stat == "fails") { |
michael@0 | 971 | expected_status = EXPECTED_FAIL; |
michael@0 | 972 | } else if (stat == "random") { |
michael@0 | 973 | expected_status = EXPECTED_RANDOM; |
michael@0 | 974 | } else if (stat == "skip") { |
michael@0 | 975 | expected_status = EXPECTED_DEATH; |
michael@0 | 976 | } else if (stat == "silentfail") { |
michael@0 | 977 | allow_silent_fail = true; |
michael@0 | 978 | } |
michael@0 | 979 | } |
michael@0 | 980 | } |
michael@0 | 981 | |
michael@0 | 982 | expected_status = Math.max(expected_status, inherited_status); |
michael@0 | 983 | |
michael@0 | 984 | if (minAsserts > maxAsserts) { |
michael@0 | 985 | throw "Bad range in manifest file " + aURL.spec + " line " + lineNo; |
michael@0 | 986 | } |
michael@0 | 987 | |
michael@0 | 988 | var runHttp = false; |
michael@0 | 989 | var httpDepth; |
michael@0 | 990 | if (items[0] == "HTTP") { |
michael@0 | 991 | runHttp = (aURL.scheme == "file"); // We can't yet run the local HTTP server |
michael@0 | 992 | // for non-local reftests. |
michael@0 | 993 | httpDepth = 0; |
michael@0 | 994 | items.shift(); |
michael@0 | 995 | } else if (items[0].match(/HTTP\(\.\.(\/\.\.)*\)/)) { |
michael@0 | 996 | // Accept HTTP(..), HTTP(../..), HTTP(../../..), etc. |
michael@0 | 997 | runHttp = (aURL.scheme == "file"); // We can't yet run the local HTTP server |
michael@0 | 998 | // for non-local reftests. |
michael@0 | 999 | httpDepth = (items[0].length - 5) / 3; |
michael@0 | 1000 | items.shift(); |
michael@0 | 1001 | } |
michael@0 | 1002 | |
michael@0 | 1003 | // do not prefix the url for include commands or urls specifying |
michael@0 | 1004 | // a protocol |
michael@0 | 1005 | if (urlprefix && items[0] != "include") { |
michael@0 | 1006 | if (items.length > 1 && !items[1].match(gProtocolRE)) { |
michael@0 | 1007 | items[1] = urlprefix + items[1]; |
michael@0 | 1008 | } |
michael@0 | 1009 | if (items.length > 2 && !items[2].match(gProtocolRE)) { |
michael@0 | 1010 | items[2] = urlprefix + items[2]; |
michael@0 | 1011 | } |
michael@0 | 1012 | } |
michael@0 | 1013 | |
michael@0 | 1014 | var principal = secMan.getSimpleCodebasePrincipal(aURL); |
michael@0 | 1015 | |
michael@0 | 1016 | if (items[0] == "include") { |
michael@0 | 1017 | if (items.length != 2 || runHttp) |
michael@0 | 1018 | throw "Error 2 in manifest file " + aURL.spec + " line " + lineNo; |
michael@0 | 1019 | var incURI = gIOService.newURI(items[1], null, listURL); |
michael@0 | 1020 | secMan.checkLoadURIWithPrincipal(principal, incURI, |
michael@0 | 1021 | CI.nsIScriptSecurityManager.DISALLOW_SCRIPT); |
michael@0 | 1022 | ReadManifest(incURI, expected_status); |
michael@0 | 1023 | } else if (items[0] == TYPE_LOAD) { |
michael@0 | 1024 | if (items.length != 2 || |
michael@0 | 1025 | (expected_status != EXPECTED_PASS && |
michael@0 | 1026 | expected_status != EXPECTED_DEATH)) |
michael@0 | 1027 | throw "Error 3 in manifest file " + aURL.spec + " line " + lineNo; |
michael@0 | 1028 | var [testURI] = runHttp |
michael@0 | 1029 | ? ServeFiles(principal, httpDepth, |
michael@0 | 1030 | listURL, [items[1]]) |
michael@0 | 1031 | : [gIOService.newURI(items[1], null, listURL)]; |
michael@0 | 1032 | var prettyPath = runHttp |
michael@0 | 1033 | ? gIOService.newURI(items[1], null, listURL).spec |
michael@0 | 1034 | : testURI.spec; |
michael@0 | 1035 | secMan.checkLoadURIWithPrincipal(principal, testURI, |
michael@0 | 1036 | CI.nsIScriptSecurityManager.DISALLOW_SCRIPT); |
michael@0 | 1037 | AddTestItem({ type: TYPE_LOAD, |
michael@0 | 1038 | expected: expected_status, |
michael@0 | 1039 | allowSilentFail: allow_silent_fail, |
michael@0 | 1040 | prettyPath: prettyPath, |
michael@0 | 1041 | minAsserts: minAsserts, |
michael@0 | 1042 | maxAsserts: maxAsserts, |
michael@0 | 1043 | needsFocus: needs_focus, |
michael@0 | 1044 | slow: slow, |
michael@0 | 1045 | prefSettings1: testPrefSettings, |
michael@0 | 1046 | prefSettings2: refPrefSettings, |
michael@0 | 1047 | fuzzyMaxDelta: fuzzy_max_delta, |
michael@0 | 1048 | fuzzyMaxPixels: fuzzy_max_pixels, |
michael@0 | 1049 | url1: testURI, |
michael@0 | 1050 | url2: null }); |
michael@0 | 1051 | } else if (items[0] == TYPE_SCRIPT) { |
michael@0 | 1052 | if (items.length != 2) |
michael@0 | 1053 | throw "Error 4 in manifest file " + aURL.spec + " line " + lineNo; |
michael@0 | 1054 | var [testURI] = runHttp |
michael@0 | 1055 | ? ServeFiles(principal, httpDepth, |
michael@0 | 1056 | listURL, [items[1]]) |
michael@0 | 1057 | : [gIOService.newURI(items[1], null, listURL)]; |
michael@0 | 1058 | var prettyPath = runHttp |
michael@0 | 1059 | ? gIOService.newURI(items[1], null, listURL).spec |
michael@0 | 1060 | : testURI.spec; |
michael@0 | 1061 | secMan.checkLoadURIWithPrincipal(principal, testURI, |
michael@0 | 1062 | CI.nsIScriptSecurityManager.DISALLOW_SCRIPT); |
michael@0 | 1063 | AddTestItem({ type: TYPE_SCRIPT, |
michael@0 | 1064 | expected: expected_status, |
michael@0 | 1065 | allowSilentFail: allow_silent_fail, |
michael@0 | 1066 | prettyPath: prettyPath, |
michael@0 | 1067 | minAsserts: minAsserts, |
michael@0 | 1068 | maxAsserts: maxAsserts, |
michael@0 | 1069 | needsFocus: needs_focus, |
michael@0 | 1070 | slow: slow, |
michael@0 | 1071 | prefSettings1: testPrefSettings, |
michael@0 | 1072 | prefSettings2: refPrefSettings, |
michael@0 | 1073 | fuzzyMaxDelta: fuzzy_max_delta, |
michael@0 | 1074 | fuzzyMaxPixels: fuzzy_max_pixels, |
michael@0 | 1075 | url1: testURI, |
michael@0 | 1076 | url2: null }); |
michael@0 | 1077 | } else if (items[0] == TYPE_REFTEST_EQUAL || items[0] == TYPE_REFTEST_NOTEQUAL) { |
michael@0 | 1078 | if (items.length != 3) |
michael@0 | 1079 | throw "Error 5 in manifest file " + aURL.spec + " line " + lineNo; |
michael@0 | 1080 | var [testURI, refURI] = runHttp |
michael@0 | 1081 | ? ServeFiles(principal, httpDepth, |
michael@0 | 1082 | listURL, [items[1], items[2]]) |
michael@0 | 1083 | : [gIOService.newURI(items[1], null, listURL), |
michael@0 | 1084 | gIOService.newURI(items[2], null, listURL)]; |
michael@0 | 1085 | var prettyPath = runHttp |
michael@0 | 1086 | ? gIOService.newURI(items[1], null, listURL).spec |
michael@0 | 1087 | : testURI.spec; |
michael@0 | 1088 | secMan.checkLoadURIWithPrincipal(principal, testURI, |
michael@0 | 1089 | CI.nsIScriptSecurityManager.DISALLOW_SCRIPT); |
michael@0 | 1090 | secMan.checkLoadURIWithPrincipal(principal, refURI, |
michael@0 | 1091 | CI.nsIScriptSecurityManager.DISALLOW_SCRIPT); |
michael@0 | 1092 | AddTestItem({ type: items[0], |
michael@0 | 1093 | expected: expected_status, |
michael@0 | 1094 | allowSilentFail: allow_silent_fail, |
michael@0 | 1095 | prettyPath: prettyPath, |
michael@0 | 1096 | minAsserts: minAsserts, |
michael@0 | 1097 | maxAsserts: maxAsserts, |
michael@0 | 1098 | needsFocus: needs_focus, |
michael@0 | 1099 | slow: slow, |
michael@0 | 1100 | prefSettings1: testPrefSettings, |
michael@0 | 1101 | prefSettings2: refPrefSettings, |
michael@0 | 1102 | fuzzyMaxDelta: fuzzy_max_delta, |
michael@0 | 1103 | fuzzyMaxPixels: fuzzy_max_pixels, |
michael@0 | 1104 | url1: testURI, |
michael@0 | 1105 | url2: refURI }); |
michael@0 | 1106 | } else { |
michael@0 | 1107 | throw "Error 6 in manifest file " + aURL.spec + " line " + lineNo; |
michael@0 | 1108 | } |
michael@0 | 1109 | } |
michael@0 | 1110 | } |
michael@0 | 1111 | |
michael@0 | 1112 | function AddURIUseCount(uri) |
michael@0 | 1113 | { |
michael@0 | 1114 | if (uri == null) |
michael@0 | 1115 | return; |
michael@0 | 1116 | |
michael@0 | 1117 | var spec = uri.spec; |
michael@0 | 1118 | if (spec in gURIUseCounts) { |
michael@0 | 1119 | gURIUseCounts[spec]++; |
michael@0 | 1120 | } else { |
michael@0 | 1121 | gURIUseCounts[spec] = 1; |
michael@0 | 1122 | } |
michael@0 | 1123 | } |
michael@0 | 1124 | |
michael@0 | 1125 | function BuildUseCounts() |
michael@0 | 1126 | { |
michael@0 | 1127 | gURIUseCounts = {}; |
michael@0 | 1128 | for (var i = 0; i < gURLs.length; ++i) { |
michael@0 | 1129 | var url = gURLs[i]; |
michael@0 | 1130 | if (url.expected != EXPECTED_DEATH && |
michael@0 | 1131 | (url.type == TYPE_REFTEST_EQUAL || |
michael@0 | 1132 | url.type == TYPE_REFTEST_NOTEQUAL)) { |
michael@0 | 1133 | if (url.prefSettings1.length == 0) { |
michael@0 | 1134 | AddURIUseCount(gURLs[i].url1); |
michael@0 | 1135 | } |
michael@0 | 1136 | if (url.prefSettings2.length == 0) { |
michael@0 | 1137 | AddURIUseCount(gURLs[i].url2); |
michael@0 | 1138 | } |
michael@0 | 1139 | } |
michael@0 | 1140 | } |
michael@0 | 1141 | } |
michael@0 | 1142 | |
michael@0 | 1143 | function ServeFiles(manifestPrincipal, depth, aURL, files) |
michael@0 | 1144 | { |
michael@0 | 1145 | var listURL = aURL.QueryInterface(CI.nsIFileURL); |
michael@0 | 1146 | var directory = listURL.file.parent; |
michael@0 | 1147 | |
michael@0 | 1148 | // Allow serving a tree that's an ancestor of the directory containing |
michael@0 | 1149 | // the files so that they can use resources in ../ (etc.). |
michael@0 | 1150 | var dirPath = "/"; |
michael@0 | 1151 | while (depth > 0) { |
michael@0 | 1152 | dirPath = "/" + directory.leafName + dirPath; |
michael@0 | 1153 | directory = directory.parent; |
michael@0 | 1154 | --depth; |
michael@0 | 1155 | } |
michael@0 | 1156 | |
michael@0 | 1157 | gCount++; |
michael@0 | 1158 | var path = "/" + Date.now() + "/" + gCount; |
michael@0 | 1159 | gServer.registerDirectory(path + "/", directory); |
michael@0 | 1160 | |
michael@0 | 1161 | var secMan = CC[NS_SCRIPTSECURITYMANAGER_CONTRACTID] |
michael@0 | 1162 | .getService(CI.nsIScriptSecurityManager); |
michael@0 | 1163 | |
michael@0 | 1164 | var testbase = gIOService.newURI("http://localhost:" + gHttpServerPort + |
michael@0 | 1165 | path + dirPath, null, null); |
michael@0 | 1166 | |
michael@0 | 1167 | function FileToURI(file) |
michael@0 | 1168 | { |
michael@0 | 1169 | // Only serve relative URIs via the HTTP server, not absolute |
michael@0 | 1170 | // ones like about:blank. |
michael@0 | 1171 | var testURI = gIOService.newURI(file, null, testbase); |
michael@0 | 1172 | |
michael@0 | 1173 | // XXX necessary? manifestURL guaranteed to be file, others always HTTP |
michael@0 | 1174 | secMan.checkLoadURIWithPrincipal(manifestPrincipal, testURI, |
michael@0 | 1175 | CI.nsIScriptSecurityManager.DISALLOW_SCRIPT); |
michael@0 | 1176 | |
michael@0 | 1177 | return testURI; |
michael@0 | 1178 | } |
michael@0 | 1179 | |
michael@0 | 1180 | return files.map(FileToURI); |
michael@0 | 1181 | } |
michael@0 | 1182 | |
michael@0 | 1183 | // Return true iff this window is focused when this function returns. |
michael@0 | 1184 | function Focus() |
michael@0 | 1185 | { |
michael@0 | 1186 | var fm = CC["@mozilla.org/focus-manager;1"].getService(CI.nsIFocusManager); |
michael@0 | 1187 | fm.focusedWindow = gContainingWindow; |
michael@0 | 1188 | #ifdef XP_MACOSX |
michael@0 | 1189 | try { |
michael@0 | 1190 | var dock = CC["@mozilla.org/widget/macdocksupport;1"].getService(CI.nsIMacDockSupport); |
michael@0 | 1191 | dock.activateApplication(true); |
michael@0 | 1192 | } catch(ex) { |
michael@0 | 1193 | } |
michael@0 | 1194 | #endif // XP_MACOSX |
michael@0 | 1195 | return true; |
michael@0 | 1196 | } |
michael@0 | 1197 | |
michael@0 | 1198 | function Blur() |
michael@0 | 1199 | { |
michael@0 | 1200 | // On non-remote reftests, this will transfer focus to the dummy window |
michael@0 | 1201 | // we created to hold focus for non-needs-focus tests. Buggy tests |
michael@0 | 1202 | // (ones which require focus but don't request needs-focus) will then |
michael@0 | 1203 | // fail. |
michael@0 | 1204 | gContainingWindow.blur(); |
michael@0 | 1205 | } |
michael@0 | 1206 | |
michael@0 | 1207 | function StartCurrentTest() |
michael@0 | 1208 | { |
michael@0 | 1209 | gTestLog = []; |
michael@0 | 1210 | |
michael@0 | 1211 | // make sure we don't run tests that are expected to kill the browser |
michael@0 | 1212 | while (gURLs.length > 0) { |
michael@0 | 1213 | var test = gURLs[0]; |
michael@0 | 1214 | if (test.expected == EXPECTED_DEATH) { |
michael@0 | 1215 | ++gTestResults.Skip; |
michael@0 | 1216 | gDumpLog("REFTEST TEST-KNOWN-FAIL | " + test.url1.spec + " | (SKIP)\n"); |
michael@0 | 1217 | gURLs.shift(); |
michael@0 | 1218 | } else if (test.needsFocus && !Focus()) { |
michael@0 | 1219 | // FIXME: Marking this as a known fail is dangerous! What |
michael@0 | 1220 | // if it starts failing all the time? |
michael@0 | 1221 | ++gTestResults.Skip; |
michael@0 | 1222 | gDumpLog("REFTEST TEST-KNOWN-FAIL | " + test.url1.spec + " | (SKIPPED; COULDN'T GET FOCUS)\n"); |
michael@0 | 1223 | gURLs.shift(); |
michael@0 | 1224 | } else if (test.slow && !gRunSlowTests) { |
michael@0 | 1225 | ++gTestResults.Slow; |
michael@0 | 1226 | gDumpLog("REFTEST TEST-KNOWN-SLOW | " + test.url1.spec + " | (SLOW)\n"); |
michael@0 | 1227 | gURLs.shift(); |
michael@0 | 1228 | } else { |
michael@0 | 1229 | break; |
michael@0 | 1230 | } |
michael@0 | 1231 | } |
michael@0 | 1232 | |
michael@0 | 1233 | if (gURLs.length == 0) { |
michael@0 | 1234 | RestoreChangedPreferences(); |
michael@0 | 1235 | DoneTests(); |
michael@0 | 1236 | } |
michael@0 | 1237 | else { |
michael@0 | 1238 | gDumpLog("REFTEST TEST-START | " + gURLs[0].prettyPath + "\n"); |
michael@0 | 1239 | if (!gURLs[0].needsFocus) { |
michael@0 | 1240 | Blur(); |
michael@0 | 1241 | } |
michael@0 | 1242 | var currentTest = gTotalTests - gURLs.length; |
michael@0 | 1243 | gContainingWindow.document.title = "reftest: " + currentTest + " / " + gTotalTests + |
michael@0 | 1244 | " (" + Math.floor(100 * (currentTest / gTotalTests)) + "%)"; |
michael@0 | 1245 | StartCurrentURI(1); |
michael@0 | 1246 | } |
michael@0 | 1247 | } |
michael@0 | 1248 | |
michael@0 | 1249 | function StartCurrentURI(aState) |
michael@0 | 1250 | { |
michael@0 | 1251 | gState = aState; |
michael@0 | 1252 | gCurrentURL = gURLs[0]["url" + aState].spec; |
michael@0 | 1253 | |
michael@0 | 1254 | RestoreChangedPreferences(); |
michael@0 | 1255 | |
michael@0 | 1256 | var prefSettings = gURLs[0]["prefSettings" + aState]; |
michael@0 | 1257 | if (prefSettings.length > 0) { |
michael@0 | 1258 | var prefs = Components.classes["@mozilla.org/preferences-service;1"]. |
michael@0 | 1259 | getService(Components.interfaces.nsIPrefBranch); |
michael@0 | 1260 | var badPref = undefined; |
michael@0 | 1261 | try { |
michael@0 | 1262 | prefSettings.forEach(function(ps) { |
michael@0 | 1263 | var oldVal; |
michael@0 | 1264 | if (ps.type == PREF_BOOLEAN) { |
michael@0 | 1265 | try { |
michael@0 | 1266 | oldVal = prefs.getBoolPref(ps.name); |
michael@0 | 1267 | } catch (e) { |
michael@0 | 1268 | badPref = "boolean preference '" + ps.name + "'"; |
michael@0 | 1269 | throw "bad pref"; |
michael@0 | 1270 | } |
michael@0 | 1271 | } else if (ps.type == PREF_STRING) { |
michael@0 | 1272 | try { |
michael@0 | 1273 | oldVal = prefs.getCharPref(ps.name); |
michael@0 | 1274 | } catch (e) { |
michael@0 | 1275 | badPref = "string preference '" + ps.name + "'"; |
michael@0 | 1276 | throw "bad pref"; |
michael@0 | 1277 | } |
michael@0 | 1278 | } else if (ps.type == PREF_INTEGER) { |
michael@0 | 1279 | try { |
michael@0 | 1280 | oldVal = prefs.getIntPref(ps.name); |
michael@0 | 1281 | } catch (e) { |
michael@0 | 1282 | badPref = "integer preference '" + ps.name + "'"; |
michael@0 | 1283 | throw "bad pref"; |
michael@0 | 1284 | } |
michael@0 | 1285 | } else { |
michael@0 | 1286 | throw "internal error - unknown preference type"; |
michael@0 | 1287 | } |
michael@0 | 1288 | if (oldVal != ps.value) { |
michael@0 | 1289 | gPrefsToRestore.push( { name: ps.name, |
michael@0 | 1290 | type: ps.type, |
michael@0 | 1291 | value: oldVal } ); |
michael@0 | 1292 | var value = ps.value; |
michael@0 | 1293 | if (ps.type == PREF_BOOLEAN) { |
michael@0 | 1294 | prefs.setBoolPref(ps.name, value); |
michael@0 | 1295 | } else if (ps.type == PREF_STRING) { |
michael@0 | 1296 | prefs.setCharPref(ps.name, value); |
michael@0 | 1297 | value = '"' + value + '"'; |
michael@0 | 1298 | } else if (ps.type == PREF_INTEGER) { |
michael@0 | 1299 | prefs.setIntPref(ps.name, value); |
michael@0 | 1300 | } |
michael@0 | 1301 | gDumpLog("SET PREFERENCE pref(" + ps.name + "," + value + ")\n"); |
michael@0 | 1302 | } |
michael@0 | 1303 | }); |
michael@0 | 1304 | } catch (e) { |
michael@0 | 1305 | if (e == "bad pref") { |
michael@0 | 1306 | var test = gURLs[0]; |
michael@0 | 1307 | if (test.expected == EXPECTED_FAIL) { |
michael@0 | 1308 | gDumpLog("REFTEST TEST-KNOWN-FAIL | " + test.url1.spec + |
michael@0 | 1309 | " | (SKIPPED; " + badPref + " not known or wrong type)\n"); |
michael@0 | 1310 | ++gTestResults.Skip; |
michael@0 | 1311 | } else { |
michael@0 | 1312 | gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | " + test.url1.spec + |
michael@0 | 1313 | " | " + badPref + " not known or wrong type\n"); |
michael@0 | 1314 | ++gTestResults.UnexpectedFail; |
michael@0 | 1315 | } |
michael@0 | 1316 | } else { |
michael@0 | 1317 | throw e; |
michael@0 | 1318 | } |
michael@0 | 1319 | } |
michael@0 | 1320 | if (badPref != undefined) { |
michael@0 | 1321 | // skip the test that had a bad preference |
michael@0 | 1322 | gURLs.shift(); |
michael@0 | 1323 | |
michael@0 | 1324 | StartCurrentTest(); |
michael@0 | 1325 | return; |
michael@0 | 1326 | } |
michael@0 | 1327 | } |
michael@0 | 1328 | |
michael@0 | 1329 | if (prefSettings.length == 0 && |
michael@0 | 1330 | gURICanvases[gCurrentURL] && |
michael@0 | 1331 | (gURLs[0].type == TYPE_REFTEST_EQUAL || |
michael@0 | 1332 | gURLs[0].type == TYPE_REFTEST_NOTEQUAL) && |
michael@0 | 1333 | gURLs[0].maxAsserts == 0) { |
michael@0 | 1334 | // Pretend the document loaded --- RecordResult will notice |
michael@0 | 1335 | // there's already a canvas for this URL |
michael@0 | 1336 | gContainingWindow.setTimeout(RecordResult, 0); |
michael@0 | 1337 | } else { |
michael@0 | 1338 | var currentTest = gTotalTests - gURLs.length; |
michael@0 | 1339 | gDumpLog("REFTEST TEST-LOAD | " + gCurrentURL + " | " + currentTest + " / " + gTotalTests + |
michael@0 | 1340 | " (" + Math.floor(100 * (currentTest / gTotalTests)) + "%)\n"); |
michael@0 | 1341 | LogInfo("START " + gCurrentURL); |
michael@0 | 1342 | var type = gURLs[0].type |
michael@0 | 1343 | if (TYPE_SCRIPT == type) { |
michael@0 | 1344 | SendLoadScriptTest(gCurrentURL, gLoadTimeout); |
michael@0 | 1345 | } else { |
michael@0 | 1346 | SendLoadTest(type, gCurrentURL, gLoadTimeout); |
michael@0 | 1347 | } |
michael@0 | 1348 | } |
michael@0 | 1349 | } |
michael@0 | 1350 | |
michael@0 | 1351 | function DoneTests() |
michael@0 | 1352 | { |
michael@0 | 1353 | gDumpLog("REFTEST FINISHED: Slowest test took " + gSlowestTestTime + |
michael@0 | 1354 | "ms (" + gSlowestTestURL + ")\n"); |
michael@0 | 1355 | |
michael@0 | 1356 | gDumpLog("REFTEST INFO | Result summary:\n"); |
michael@0 | 1357 | var count = gTestResults.Pass + gTestResults.LoadOnly; |
michael@0 | 1358 | gDumpLog("REFTEST INFO | Successful: " + count + " (" + |
michael@0 | 1359 | gTestResults.Pass + " pass, " + |
michael@0 | 1360 | gTestResults.LoadOnly + " load only)\n"); |
michael@0 | 1361 | count = gTestResults.Exception + gTestResults.FailedLoad + |
michael@0 | 1362 | gTestResults.UnexpectedFail + gTestResults.UnexpectedPass + |
michael@0 | 1363 | gTestResults.AssertionUnexpected + |
michael@0 | 1364 | gTestResults.AssertionUnexpectedFixed; |
michael@0 | 1365 | gDumpLog("REFTEST INFO | Unexpected: " + count + " (" + |
michael@0 | 1366 | gTestResults.UnexpectedFail + " unexpected fail, " + |
michael@0 | 1367 | gTestResults.UnexpectedPass + " unexpected pass, " + |
michael@0 | 1368 | gTestResults.AssertionUnexpected + " unexpected asserts, " + |
michael@0 | 1369 | gTestResults.AssertionUnexpectedFixed + " unexpected fixed asserts, " + |
michael@0 | 1370 | gTestResults.FailedLoad + " failed load, " + |
michael@0 | 1371 | gTestResults.Exception + " exception)\n"); |
michael@0 | 1372 | count = gTestResults.KnownFail + gTestResults.AssertionKnown + |
michael@0 | 1373 | gTestResults.Random + gTestResults.Skip + gTestResults.Slow; |
michael@0 | 1374 | gDumpLog("REFTEST INFO | Known problems: " + count + " (" + |
michael@0 | 1375 | gTestResults.KnownFail + " known fail, " + |
michael@0 | 1376 | gTestResults.AssertionKnown + " known asserts, " + |
michael@0 | 1377 | gTestResults.Random + " random, " + |
michael@0 | 1378 | gTestResults.Skip + " skipped, " + |
michael@0 | 1379 | gTestResults.Slow + " slow)\n"); |
michael@0 | 1380 | |
michael@0 | 1381 | gDumpLog("REFTEST INFO | Total canvas count = " + gRecycledCanvases.length + "\n"); |
michael@0 | 1382 | |
michael@0 | 1383 | gDumpLog("REFTEST TEST-START | Shutdown\n"); |
michael@0 | 1384 | function onStopped() { |
michael@0 | 1385 | let appStartup = CC["@mozilla.org/toolkit/app-startup;1"].getService(CI.nsIAppStartup); |
michael@0 | 1386 | appStartup.quit(CI.nsIAppStartup.eForceQuit); |
michael@0 | 1387 | } |
michael@0 | 1388 | if (gServer) { |
michael@0 | 1389 | gServer.stop(onStopped); |
michael@0 | 1390 | } |
michael@0 | 1391 | else { |
michael@0 | 1392 | onStopped(); |
michael@0 | 1393 | } |
michael@0 | 1394 | } |
michael@0 | 1395 | |
michael@0 | 1396 | function UpdateCanvasCache(url, canvas) |
michael@0 | 1397 | { |
michael@0 | 1398 | var spec = url.spec; |
michael@0 | 1399 | |
michael@0 | 1400 | --gURIUseCounts[spec]; |
michael@0 | 1401 | |
michael@0 | 1402 | if (gNoCanvasCache || gURIUseCounts[spec] == 0) { |
michael@0 | 1403 | ReleaseCanvas(canvas); |
michael@0 | 1404 | delete gURICanvases[spec]; |
michael@0 | 1405 | } else if (gURIUseCounts[spec] > 0) { |
michael@0 | 1406 | gURICanvases[spec] = canvas; |
michael@0 | 1407 | } else { |
michael@0 | 1408 | throw "Use counts were computed incorrectly"; |
michael@0 | 1409 | } |
michael@0 | 1410 | } |
michael@0 | 1411 | |
michael@0 | 1412 | // Recompute drawWindow flags for every drawWindow operation. |
michael@0 | 1413 | // We have to do this every time since our window can be |
michael@0 | 1414 | // asynchronously resized (e.g. by the window manager, to make |
michael@0 | 1415 | // it fit on screen) at unpredictable times. |
michael@0 | 1416 | // Fortunately this is pretty cheap. |
michael@0 | 1417 | function DoDrawWindow(ctx, x, y, w, h) |
michael@0 | 1418 | { |
michael@0 | 1419 | var flags = ctx.DRAWWINDOW_DRAW_CARET | ctx.DRAWWINDOW_DRAW_VIEW; |
michael@0 | 1420 | var testRect = gBrowser.getBoundingClientRect(); |
michael@0 | 1421 | if (gIgnoreWindowSize || |
michael@0 | 1422 | (0 <= testRect.left && |
michael@0 | 1423 | 0 <= testRect.top && |
michael@0 | 1424 | gContainingWindow.innerWidth >= testRect.right && |
michael@0 | 1425 | gContainingWindow.innerHeight >= testRect.bottom)) { |
michael@0 | 1426 | // We can use the window's retained layer manager |
michael@0 | 1427 | // because the window is big enough to display the entire |
michael@0 | 1428 | // browser element |
michael@0 | 1429 | flags |= ctx.DRAWWINDOW_USE_WIDGET_LAYERS; |
michael@0 | 1430 | } else if (gBrowserIsRemote) { |
michael@0 | 1431 | gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | " + gCurrentURL + " | can't drawWindow remote content\n"); |
michael@0 | 1432 | ++gTestResults.Exception; |
michael@0 | 1433 | } |
michael@0 | 1434 | |
michael@0 | 1435 | if (gDrawWindowFlags != flags) { |
michael@0 | 1436 | // Every time the flags change, dump the new state. |
michael@0 | 1437 | gDrawWindowFlags = flags; |
michael@0 | 1438 | var flagsStr = "DRAWWINDOW_DRAW_CARET | DRAWWINDOW_DRAW_VIEW"; |
michael@0 | 1439 | if (flags & ctx.DRAWWINDOW_USE_WIDGET_LAYERS) { |
michael@0 | 1440 | flagsStr += " | DRAWWINDOW_USE_WIDGET_LAYERS"; |
michael@0 | 1441 | } else { |
michael@0 | 1442 | // Output a special warning because we need to be able to detect |
michael@0 | 1443 | // this whenever it happens. |
michael@0 | 1444 | gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | WARNING: USE_WIDGET_LAYERS disabled\n"); |
michael@0 | 1445 | } |
michael@0 | 1446 | gDumpLog("REFTEST INFO | drawWindow flags = " + flagsStr + |
michael@0 | 1447 | "; window size = " + gContainingWindow.innerWidth + "," + gContainingWindow.innerHeight + |
michael@0 | 1448 | "; test browser size = " + testRect.width + "," + testRect.height + |
michael@0 | 1449 | "\n"); |
michael@0 | 1450 | } |
michael@0 | 1451 | |
michael@0 | 1452 | LogInfo("DoDrawWindow " + x + "," + y + "," + w + "," + h); |
michael@0 | 1453 | ctx.drawWindow(gContainingWindow, x, y, w, h, "rgb(255,255,255)", |
michael@0 | 1454 | gDrawWindowFlags); |
michael@0 | 1455 | } |
michael@0 | 1456 | |
michael@0 | 1457 | function InitCurrentCanvasWithSnapshot() |
michael@0 | 1458 | { |
michael@0 | 1459 | LogInfo("Initializing canvas snapshot"); |
michael@0 | 1460 | |
michael@0 | 1461 | if (gURLs[0].type == TYPE_LOAD || gURLs[0].type == TYPE_SCRIPT) { |
michael@0 | 1462 | // We don't want to snapshot this kind of test |
michael@0 | 1463 | return false; |
michael@0 | 1464 | } |
michael@0 | 1465 | |
michael@0 | 1466 | if (!gCurrentCanvas) { |
michael@0 | 1467 | gCurrentCanvas = AllocateCanvas(); |
michael@0 | 1468 | } |
michael@0 | 1469 | |
michael@0 | 1470 | var ctx = gCurrentCanvas.getContext("2d"); |
michael@0 | 1471 | DoDrawWindow(ctx, 0, 0, gCurrentCanvas.width, gCurrentCanvas.height); |
michael@0 | 1472 | return true; |
michael@0 | 1473 | } |
michael@0 | 1474 | |
michael@0 | 1475 | function UpdateCurrentCanvasForInvalidation(rects) |
michael@0 | 1476 | { |
michael@0 | 1477 | LogInfo("Updating canvas for invalidation"); |
michael@0 | 1478 | |
michael@0 | 1479 | if (!gCurrentCanvas) { |
michael@0 | 1480 | return; |
michael@0 | 1481 | } |
michael@0 | 1482 | |
michael@0 | 1483 | var ctx = gCurrentCanvas.getContext("2d"); |
michael@0 | 1484 | for (var i = 0; i < rects.length; ++i) { |
michael@0 | 1485 | var r = rects[i]; |
michael@0 | 1486 | // Set left/top/right/bottom to pixel boundaries |
michael@0 | 1487 | var left = Math.floor(r.left); |
michael@0 | 1488 | var top = Math.floor(r.top); |
michael@0 | 1489 | var right = Math.ceil(r.right); |
michael@0 | 1490 | var bottom = Math.ceil(r.bottom); |
michael@0 | 1491 | |
michael@0 | 1492 | ctx.save(); |
michael@0 | 1493 | ctx.translate(left, top); |
michael@0 | 1494 | DoDrawWindow(ctx, left, top, right - left, bottom - top); |
michael@0 | 1495 | ctx.restore(); |
michael@0 | 1496 | } |
michael@0 | 1497 | } |
michael@0 | 1498 | |
michael@0 | 1499 | function UpdateWholeCurrentCanvasForInvalidation() |
michael@0 | 1500 | { |
michael@0 | 1501 | LogInfo("Updating entire canvas for invalidation"); |
michael@0 | 1502 | |
michael@0 | 1503 | if (!gCurrentCanvas) { |
michael@0 | 1504 | return; |
michael@0 | 1505 | } |
michael@0 | 1506 | |
michael@0 | 1507 | var ctx = gCurrentCanvas.getContext("2d"); |
michael@0 | 1508 | DoDrawWindow(ctx, 0, 0, gCurrentCanvas.width, gCurrentCanvas.height); |
michael@0 | 1509 | } |
michael@0 | 1510 | |
michael@0 | 1511 | function RecordResult(testRunTime, errorMsg, scriptResults) |
michael@0 | 1512 | { |
michael@0 | 1513 | LogInfo("RecordResult fired"); |
michael@0 | 1514 | |
michael@0 | 1515 | // Keep track of which test was slowest, and how long it took. |
michael@0 | 1516 | if (testRunTime > gSlowestTestTime) { |
michael@0 | 1517 | gSlowestTestTime = testRunTime; |
michael@0 | 1518 | gSlowestTestURL = gCurrentURL; |
michael@0 | 1519 | } |
michael@0 | 1520 | |
michael@0 | 1521 | // Not 'const ...' because of 'EXPECTED_*' value dependency. |
michael@0 | 1522 | var outputs = {}; |
michael@0 | 1523 | const randomMsg = "(EXPECTED RANDOM)"; |
michael@0 | 1524 | outputs[EXPECTED_PASS] = { |
michael@0 | 1525 | true: {s: "TEST-PASS" , n: "Pass"}, |
michael@0 | 1526 | false: {s: "TEST-UNEXPECTED-FAIL" , n: "UnexpectedFail"} |
michael@0 | 1527 | }; |
michael@0 | 1528 | outputs[EXPECTED_FAIL] = { |
michael@0 | 1529 | true: {s: "TEST-UNEXPECTED-PASS" , n: "UnexpectedPass"}, |
michael@0 | 1530 | false: {s: "TEST-KNOWN-FAIL" , n: "KnownFail"} |
michael@0 | 1531 | }; |
michael@0 | 1532 | outputs[EXPECTED_RANDOM] = { |
michael@0 | 1533 | true: {s: "TEST-PASS" + randomMsg , n: "Random"}, |
michael@0 | 1534 | false: {s: "TEST-KNOWN-FAIL" + randomMsg, n: "Random"} |
michael@0 | 1535 | }; |
michael@0 | 1536 | outputs[EXPECTED_FUZZY] = outputs[EXPECTED_PASS]; |
michael@0 | 1537 | |
michael@0 | 1538 | var output; |
michael@0 | 1539 | |
michael@0 | 1540 | if (gURLs[0].type == TYPE_LOAD) { |
michael@0 | 1541 | ++gTestResults.LoadOnly; |
michael@0 | 1542 | gDumpLog("REFTEST TEST-PASS | " + gURLs[0].prettyPath + " | (LOAD ONLY)\n"); |
michael@0 | 1543 | gCurrentCanvas = null; |
michael@0 | 1544 | FinishTestItem(); |
michael@0 | 1545 | return; |
michael@0 | 1546 | } |
michael@0 | 1547 | if (gURLs[0].type == TYPE_SCRIPT) { |
michael@0 | 1548 | var expected = gURLs[0].expected; |
michael@0 | 1549 | |
michael@0 | 1550 | if (errorMsg) { |
michael@0 | 1551 | // Force an unexpected failure to alert the test author to fix the test. |
michael@0 | 1552 | expected = EXPECTED_PASS; |
michael@0 | 1553 | } else if (scriptResults.length == 0) { |
michael@0 | 1554 | // This failure may be due to a JavaScript Engine bug causing |
michael@0 | 1555 | // early termination of the test. If we do not allow silent |
michael@0 | 1556 | // failure, report an error. |
michael@0 | 1557 | if (!gURLs[0].allowSilentFail) |
michael@0 | 1558 | errorMsg = "No test results reported. (SCRIPT)\n"; |
michael@0 | 1559 | else |
michael@0 | 1560 | gDumpLog("REFTEST INFO | An expected silent failure occurred \n"); |
michael@0 | 1561 | } |
michael@0 | 1562 | |
michael@0 | 1563 | if (errorMsg) { |
michael@0 | 1564 | output = outputs[expected][false]; |
michael@0 | 1565 | ++gTestResults[output.n]; |
michael@0 | 1566 | var result = "REFTEST " + output.s + " | " + |
michael@0 | 1567 | gURLs[0].prettyPath + " | " + // the URL being tested |
michael@0 | 1568 | errorMsg; |
michael@0 | 1569 | |
michael@0 | 1570 | gDumpLog(result); |
michael@0 | 1571 | FinishTestItem(); |
michael@0 | 1572 | return; |
michael@0 | 1573 | } |
michael@0 | 1574 | |
michael@0 | 1575 | var anyFailed = scriptResults.some(function(result) { return !result.passed; }); |
michael@0 | 1576 | var outputPair; |
michael@0 | 1577 | if (anyFailed && expected == EXPECTED_FAIL) { |
michael@0 | 1578 | // If we're marked as expected to fail, and some (but not all) tests |
michael@0 | 1579 | // passed, treat those tests as though they were marked random |
michael@0 | 1580 | // (since we can't tell whether they were really intended to be |
michael@0 | 1581 | // marked failing or not). |
michael@0 | 1582 | outputPair = { true: outputs[EXPECTED_RANDOM][true], |
michael@0 | 1583 | false: outputs[expected][false] }; |
michael@0 | 1584 | } else { |
michael@0 | 1585 | outputPair = outputs[expected]; |
michael@0 | 1586 | } |
michael@0 | 1587 | var index = 0; |
michael@0 | 1588 | scriptResults.forEach(function(result) { |
michael@0 | 1589 | var output = outputPair[result.passed]; |
michael@0 | 1590 | |
michael@0 | 1591 | ++gTestResults[output.n]; |
michael@0 | 1592 | result = "REFTEST " + output.s + " | " + |
michael@0 | 1593 | gURLs[0].prettyPath + " | " + // the URL being tested |
michael@0 | 1594 | result.description + " item " + (++index) + "\n"; |
michael@0 | 1595 | gDumpLog(result); |
michael@0 | 1596 | }); |
michael@0 | 1597 | |
michael@0 | 1598 | if (anyFailed && expected == EXPECTED_PASS) { |
michael@0 | 1599 | FlushTestLog(); |
michael@0 | 1600 | } |
michael@0 | 1601 | |
michael@0 | 1602 | FinishTestItem(); |
michael@0 | 1603 | return; |
michael@0 | 1604 | } |
michael@0 | 1605 | |
michael@0 | 1606 | if (gURLs[0]["prefSettings" + gState].length == 0 && |
michael@0 | 1607 | gURICanvases[gCurrentURL]) { |
michael@0 | 1608 | gCurrentCanvas = gURICanvases[gCurrentURL]; |
michael@0 | 1609 | } |
michael@0 | 1610 | if (gCurrentCanvas == null) { |
michael@0 | 1611 | gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | " + gCurrentURL + " | program error managing snapshots\n"); |
michael@0 | 1612 | ++gTestResults.Exception; |
michael@0 | 1613 | } |
michael@0 | 1614 | if (gState == 1) { |
michael@0 | 1615 | gCanvas1 = gCurrentCanvas; |
michael@0 | 1616 | } else { |
michael@0 | 1617 | gCanvas2 = gCurrentCanvas; |
michael@0 | 1618 | } |
michael@0 | 1619 | gCurrentCanvas = null; |
michael@0 | 1620 | |
michael@0 | 1621 | ResetRenderingState(); |
michael@0 | 1622 | |
michael@0 | 1623 | switch (gState) { |
michael@0 | 1624 | case 1: |
michael@0 | 1625 | // First document has been loaded. |
michael@0 | 1626 | // Proceed to load the second document. |
michael@0 | 1627 | |
michael@0 | 1628 | CleanUpCrashDumpFiles(); |
michael@0 | 1629 | StartCurrentURI(2); |
michael@0 | 1630 | break; |
michael@0 | 1631 | case 2: |
michael@0 | 1632 | // Both documents have been loaded. Compare the renderings and see |
michael@0 | 1633 | // if the comparison result matches the expected result specified |
michael@0 | 1634 | // in the manifest. |
michael@0 | 1635 | |
michael@0 | 1636 | // number of different pixels |
michael@0 | 1637 | var differences; |
michael@0 | 1638 | // whether the two renderings match: |
michael@0 | 1639 | var equal; |
michael@0 | 1640 | var maxDifference = {}; |
michael@0 | 1641 | |
michael@0 | 1642 | differences = gWindowUtils.compareCanvases(gCanvas1, gCanvas2, maxDifference); |
michael@0 | 1643 | equal = (differences == 0); |
michael@0 | 1644 | |
michael@0 | 1645 | // what is expected on this platform (PASS, FAIL, or RANDOM) |
michael@0 | 1646 | var expected = gURLs[0].expected; |
michael@0 | 1647 | |
michael@0 | 1648 | if (maxDifference.value > 0 && maxDifference.value <= gURLs[0].fuzzyMaxDelta && |
michael@0 | 1649 | differences <= gURLs[0].fuzzyMaxPixels) { |
michael@0 | 1650 | if (equal) { |
michael@0 | 1651 | throw "Inconsistent result from compareCanvases."; |
michael@0 | 1652 | } |
michael@0 | 1653 | equal = expected == EXPECTED_FUZZY; |
michael@0 | 1654 | gDumpLog("REFTEST fuzzy match\n"); |
michael@0 | 1655 | } |
michael@0 | 1656 | |
michael@0 | 1657 | // whether the comparison result matches what is in the manifest |
michael@0 | 1658 | var test_passed = (equal == (gURLs[0].type == TYPE_REFTEST_EQUAL)) && !gFailedNoPaint; |
michael@0 | 1659 | |
michael@0 | 1660 | output = outputs[expected][test_passed]; |
michael@0 | 1661 | |
michael@0 | 1662 | ++gTestResults[output.n]; |
michael@0 | 1663 | |
michael@0 | 1664 | // It's possible that we failed both reftest-no-paint and the normal comparison, but we don't |
michael@0 | 1665 | // have a way to annotate these separately, so just print an error for the no-paint failure. |
michael@0 | 1666 | if (gFailedNoPaint) { |
michael@0 | 1667 | if (expected == EXPECTED_FAIL) { |
michael@0 | 1668 | gDumpLog("REFTEST TEST-KNOWN-FAIL | " + gURLs[0].prettyPath + " | failed reftest-no-paint\n"); |
michael@0 | 1669 | } else { |
michael@0 | 1670 | gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | " + gURLs[0].prettyPath + " | failed reftest-no-paint\n"); |
michael@0 | 1671 | } |
michael@0 | 1672 | } else { |
michael@0 | 1673 | var result = "REFTEST " + output.s + " | " + |
michael@0 | 1674 | gURLs[0].prettyPath + " | "; // the URL being tested |
michael@0 | 1675 | switch (gURLs[0].type) { |
michael@0 | 1676 | case TYPE_REFTEST_NOTEQUAL: |
michael@0 | 1677 | result += "image comparison (!=)"; |
michael@0 | 1678 | break; |
michael@0 | 1679 | case TYPE_REFTEST_EQUAL: |
michael@0 | 1680 | result += "image comparison (==)"; |
michael@0 | 1681 | break; |
michael@0 | 1682 | } |
michael@0 | 1683 | |
michael@0 | 1684 | if (!test_passed && expected == EXPECTED_PASS || |
michael@0 | 1685 | !test_passed && expected == EXPECTED_FUZZY || |
michael@0 | 1686 | test_passed && expected == EXPECTED_FAIL) { |
michael@0 | 1687 | if (!equal) { |
michael@0 | 1688 | result += ", max difference: " + maxDifference.value + ", number of differing pixels: " + differences + "\n"; |
michael@0 | 1689 | result += "REFTEST IMAGE 1 (TEST): " + gCanvas1.toDataURL() + "\n"; |
michael@0 | 1690 | result += "REFTEST IMAGE 2 (REFERENCE): " + gCanvas2.toDataURL() + "\n"; |
michael@0 | 1691 | } else { |
michael@0 | 1692 | result += "\n"; |
michael@0 | 1693 | result += "REFTEST IMAGE: " + gCanvas1.toDataURL() + "\n"; |
michael@0 | 1694 | } |
michael@0 | 1695 | } else { |
michael@0 | 1696 | result += "\n"; |
michael@0 | 1697 | } |
michael@0 | 1698 | |
michael@0 | 1699 | gDumpLog(result); |
michael@0 | 1700 | } |
michael@0 | 1701 | |
michael@0 | 1702 | if (!test_passed && expected == EXPECTED_PASS) { |
michael@0 | 1703 | FlushTestLog(); |
michael@0 | 1704 | } |
michael@0 | 1705 | |
michael@0 | 1706 | if (gURLs[0].prefSettings1.length == 0) { |
michael@0 | 1707 | UpdateCanvasCache(gURLs[0].url1, gCanvas1); |
michael@0 | 1708 | } |
michael@0 | 1709 | if (gURLs[0].prefSettings2.length == 0) { |
michael@0 | 1710 | UpdateCanvasCache(gURLs[0].url2, gCanvas2); |
michael@0 | 1711 | } |
michael@0 | 1712 | |
michael@0 | 1713 | CleanUpCrashDumpFiles(); |
michael@0 | 1714 | FinishTestItem(); |
michael@0 | 1715 | break; |
michael@0 | 1716 | default: |
michael@0 | 1717 | throw "Unexpected state."; |
michael@0 | 1718 | } |
michael@0 | 1719 | } |
michael@0 | 1720 | |
michael@0 | 1721 | function LoadFailed(why) |
michael@0 | 1722 | { |
michael@0 | 1723 | ++gTestResults.FailedLoad; |
michael@0 | 1724 | // Once bug 896840 is fixed, this can go away, but for now it will give log |
michael@0 | 1725 | // output that is TBPL starable for bug 789751 and bug 720452. |
michael@0 | 1726 | if (!why) { |
michael@0 | 1727 | gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | load failed with unknown reason\n"); |
michael@0 | 1728 | } |
michael@0 | 1729 | gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | " + |
michael@0 | 1730 | gURLs[0]["url" + gState].spec + " | load failed: " + why + "\n"); |
michael@0 | 1731 | FlushTestLog(); |
michael@0 | 1732 | FinishTestItem(); |
michael@0 | 1733 | } |
michael@0 | 1734 | |
michael@0 | 1735 | function RemoveExpectedCrashDumpFiles() |
michael@0 | 1736 | { |
michael@0 | 1737 | if (gExpectingProcessCrash) { |
michael@0 | 1738 | for each (let crashFilename in gExpectedCrashDumpFiles) { |
michael@0 | 1739 | let file = gCrashDumpDir.clone(); |
michael@0 | 1740 | file.append(crashFilename); |
michael@0 | 1741 | if (file.exists()) { |
michael@0 | 1742 | file.remove(false); |
michael@0 | 1743 | } |
michael@0 | 1744 | } |
michael@0 | 1745 | } |
michael@0 | 1746 | gExpectedCrashDumpFiles.length = 0; |
michael@0 | 1747 | } |
michael@0 | 1748 | |
michael@0 | 1749 | function FindUnexpectedCrashDumpFiles() |
michael@0 | 1750 | { |
michael@0 | 1751 | if (!gCrashDumpDir.exists()) { |
michael@0 | 1752 | return; |
michael@0 | 1753 | } |
michael@0 | 1754 | |
michael@0 | 1755 | let entries = gCrashDumpDir.directoryEntries; |
michael@0 | 1756 | if (!entries) { |
michael@0 | 1757 | return; |
michael@0 | 1758 | } |
michael@0 | 1759 | |
michael@0 | 1760 | let foundCrashDumpFile = false; |
michael@0 | 1761 | while (entries.hasMoreElements()) { |
michael@0 | 1762 | let file = entries.getNext().QueryInterface(CI.nsIFile); |
michael@0 | 1763 | let path = String(file.path); |
michael@0 | 1764 | if (path.match(/\.(dmp|extra)$/) && !gUnexpectedCrashDumpFiles[path]) { |
michael@0 | 1765 | if (!foundCrashDumpFile) { |
michael@0 | 1766 | ++gTestResults.UnexpectedFail; |
michael@0 | 1767 | foundCrashDumpFile = true; |
michael@0 | 1768 | gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | " + gCurrentURL + |
michael@0 | 1769 | " | This test left crash dumps behind, but we weren't expecting it to!\n"); |
michael@0 | 1770 | } |
michael@0 | 1771 | gDumpLog("REFTEST INFO | Found unexpected crash dump file " + path + |
michael@0 | 1772 | ".\n"); |
michael@0 | 1773 | gUnexpectedCrashDumpFiles[path] = true; |
michael@0 | 1774 | } |
michael@0 | 1775 | } |
michael@0 | 1776 | } |
michael@0 | 1777 | |
michael@0 | 1778 | function CleanUpCrashDumpFiles() |
michael@0 | 1779 | { |
michael@0 | 1780 | RemoveExpectedCrashDumpFiles(); |
michael@0 | 1781 | FindUnexpectedCrashDumpFiles(); |
michael@0 | 1782 | gExpectingProcessCrash = false; |
michael@0 | 1783 | } |
michael@0 | 1784 | |
michael@0 | 1785 | function FinishTestItem() |
michael@0 | 1786 | { |
michael@0 | 1787 | // Replace document with BLANK_URL_FOR_CLEARING in case there are |
michael@0 | 1788 | // assertions when unloading. |
michael@0 | 1789 | gDumpLog("REFTEST INFO | Loading a blank page\n"); |
michael@0 | 1790 | // After clearing, content will notify us of the assertion count |
michael@0 | 1791 | // and tests will continue. |
michael@0 | 1792 | SetAsyncScroll(false); |
michael@0 | 1793 | SendClear(); |
michael@0 | 1794 | gFailedNoPaint = false; |
michael@0 | 1795 | } |
michael@0 | 1796 | |
michael@0 | 1797 | function DoAssertionCheck(numAsserts) |
michael@0 | 1798 | { |
michael@0 | 1799 | if (gDebug.isDebugBuild) { |
michael@0 | 1800 | if (gBrowserIsRemote) { |
michael@0 | 1801 | // Count chrome-process asserts too when content is out of |
michael@0 | 1802 | // process. |
michael@0 | 1803 | var newAssertionCount = gDebug.assertionCount; |
michael@0 | 1804 | var numLocalAsserts = newAssertionCount - gAssertionCount; |
michael@0 | 1805 | gAssertionCount = newAssertionCount; |
michael@0 | 1806 | |
michael@0 | 1807 | numAsserts += numLocalAsserts; |
michael@0 | 1808 | } |
michael@0 | 1809 | |
michael@0 | 1810 | var minAsserts = gURLs[0].minAsserts; |
michael@0 | 1811 | var maxAsserts = gURLs[0].maxAsserts; |
michael@0 | 1812 | |
michael@0 | 1813 | var expectedAssertions = "expected " + minAsserts; |
michael@0 | 1814 | if (minAsserts != maxAsserts) { |
michael@0 | 1815 | expectedAssertions += " to " + maxAsserts; |
michael@0 | 1816 | } |
michael@0 | 1817 | expectedAssertions += " assertions"; |
michael@0 | 1818 | |
michael@0 | 1819 | if (numAsserts < minAsserts) { |
michael@0 | 1820 | ++gTestResults.AssertionUnexpectedFixed; |
michael@0 | 1821 | gDumpLog("REFTEST TEST-UNEXPECTED-PASS | " + gURLs[0].prettyPath + |
michael@0 | 1822 | " | assertion count " + numAsserts + " is less than " + |
michael@0 | 1823 | expectedAssertions + "\n"); |
michael@0 | 1824 | } else if (numAsserts > maxAsserts) { |
michael@0 | 1825 | ++gTestResults.AssertionUnexpected; |
michael@0 | 1826 | gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | " + gURLs[0].prettyPath + |
michael@0 | 1827 | " | assertion count " + numAsserts + " is more than " + |
michael@0 | 1828 | expectedAssertions + "\n"); |
michael@0 | 1829 | } else if (numAsserts != 0) { |
michael@0 | 1830 | ++gTestResults.AssertionKnown; |
michael@0 | 1831 | gDumpLog("REFTEST TEST-KNOWN-FAIL | " + gURLs[0].prettyPath + |
michael@0 | 1832 | " | assertion count " + numAsserts + " matches " + |
michael@0 | 1833 | expectedAssertions + "\n"); |
michael@0 | 1834 | } |
michael@0 | 1835 | } |
michael@0 | 1836 | |
michael@0 | 1837 | gDumpLog("REFTEST TEST-END | " + gURLs[0].prettyPath + "\n"); |
michael@0 | 1838 | |
michael@0 | 1839 | // And start the next test. |
michael@0 | 1840 | gURLs.shift(); |
michael@0 | 1841 | StartCurrentTest(); |
michael@0 | 1842 | } |
michael@0 | 1843 | |
michael@0 | 1844 | function ResetRenderingState() |
michael@0 | 1845 | { |
michael@0 | 1846 | SendResetRenderingState(); |
michael@0 | 1847 | // We would want to clear any viewconfig here, if we add support for it |
michael@0 | 1848 | } |
michael@0 | 1849 | |
michael@0 | 1850 | function RestoreChangedPreferences() |
michael@0 | 1851 | { |
michael@0 | 1852 | if (gPrefsToRestore.length > 0) { |
michael@0 | 1853 | var prefs = Components.classes["@mozilla.org/preferences-service;1"]. |
michael@0 | 1854 | getService(Components.interfaces.nsIPrefBranch); |
michael@0 | 1855 | gPrefsToRestore.reverse(); |
michael@0 | 1856 | gPrefsToRestore.forEach(function(ps) { |
michael@0 | 1857 | var value = ps.value; |
michael@0 | 1858 | if (ps.type == PREF_BOOLEAN) { |
michael@0 | 1859 | prefs.setBoolPref(ps.name, value); |
michael@0 | 1860 | } else if (ps.type == PREF_STRING) { |
michael@0 | 1861 | prefs.setCharPref(ps.name, value); |
michael@0 | 1862 | value = '"' + value + '"'; |
michael@0 | 1863 | } else if (ps.type == PREF_INTEGER) { |
michael@0 | 1864 | prefs.setIntPref(ps.name, value); |
michael@0 | 1865 | } |
michael@0 | 1866 | gDumpLog("RESTORE PREFERENCE pref(" + ps.name + "," + value + ")\n"); |
michael@0 | 1867 | }); |
michael@0 | 1868 | gPrefsToRestore = []; |
michael@0 | 1869 | } |
michael@0 | 1870 | } |
michael@0 | 1871 | |
michael@0 | 1872 | function RegisterMessageListenersAndLoadContentScript() |
michael@0 | 1873 | { |
michael@0 | 1874 | gBrowserMessageManager.addMessageListener( |
michael@0 | 1875 | "reftest:AssertionCount", |
michael@0 | 1876 | function (m) { RecvAssertionCount(m.json.count); } |
michael@0 | 1877 | ); |
michael@0 | 1878 | gBrowserMessageManager.addMessageListener( |
michael@0 | 1879 | "reftest:ContentReady", |
michael@0 | 1880 | function (m) { return RecvContentReady() } |
michael@0 | 1881 | ); |
michael@0 | 1882 | gBrowserMessageManager.addMessageListener( |
michael@0 | 1883 | "reftest:Exception", |
michael@0 | 1884 | function (m) { RecvException(m.json.what) } |
michael@0 | 1885 | ); |
michael@0 | 1886 | gBrowserMessageManager.addMessageListener( |
michael@0 | 1887 | "reftest:FailedLoad", |
michael@0 | 1888 | function (m) { RecvFailedLoad(m.json.why); } |
michael@0 | 1889 | ); |
michael@0 | 1890 | gBrowserMessageManager.addMessageListener( |
michael@0 | 1891 | "reftest:FailedNoPaint", |
michael@0 | 1892 | function (m) { RecvFailedNoPaint(); } |
michael@0 | 1893 | ); |
michael@0 | 1894 | gBrowserMessageManager.addMessageListener( |
michael@0 | 1895 | "reftest:InitCanvasWithSnapshot", |
michael@0 | 1896 | function (m) { return RecvInitCanvasWithSnapshot(); } |
michael@0 | 1897 | ); |
michael@0 | 1898 | gBrowserMessageManager.addMessageListener( |
michael@0 | 1899 | "reftest:Log", |
michael@0 | 1900 | function (m) { RecvLog(m.json.type, m.json.msg); } |
michael@0 | 1901 | ); |
michael@0 | 1902 | gBrowserMessageManager.addMessageListener( |
michael@0 | 1903 | "reftest:ScriptResults", |
michael@0 | 1904 | function (m) { RecvScriptResults(m.json.runtimeMs, m.json.error, m.json.results); } |
michael@0 | 1905 | ); |
michael@0 | 1906 | gBrowserMessageManager.addMessageListener( |
michael@0 | 1907 | "reftest:TestDone", |
michael@0 | 1908 | function (m) { RecvTestDone(m.json.runtimeMs); } |
michael@0 | 1909 | ); |
michael@0 | 1910 | gBrowserMessageManager.addMessageListener( |
michael@0 | 1911 | "reftest:UpdateCanvasForInvalidation", |
michael@0 | 1912 | function (m) { RecvUpdateCanvasForInvalidation(m.json.rects); } |
michael@0 | 1913 | ); |
michael@0 | 1914 | gBrowserMessageManager.addMessageListener( |
michael@0 | 1915 | "reftest:UpdateWholeCanvasForInvalidation", |
michael@0 | 1916 | function (m) { RecvUpdateWholeCanvasForInvalidation(); } |
michael@0 | 1917 | ); |
michael@0 | 1918 | gBrowserMessageManager.addMessageListener( |
michael@0 | 1919 | "reftest:ExpectProcessCrash", |
michael@0 | 1920 | function (m) { RecvExpectProcessCrash(); } |
michael@0 | 1921 | ); |
michael@0 | 1922 | gBrowserMessageManager.addMessageListener( |
michael@0 | 1923 | "reftest:EnableAsyncScroll", |
michael@0 | 1924 | function (m) { SetAsyncScroll(true); } |
michael@0 | 1925 | ); |
michael@0 | 1926 | |
michael@0 | 1927 | gBrowserMessageManager.loadFrameScript("chrome://reftest/content/reftest-content.js", true, true); |
michael@0 | 1928 | } |
michael@0 | 1929 | |
michael@0 | 1930 | function SetAsyncScroll(enabled) |
michael@0 | 1931 | { |
michael@0 | 1932 | gBrowser.QueryInterface(CI.nsIFrameLoaderOwner).frameLoader.renderMode = |
michael@0 | 1933 | enabled ? CI.nsIFrameLoader.RENDER_MODE_ASYNC_SCROLL : |
michael@0 | 1934 | CI.nsIFrameLoader.RENDER_MODE_DEFAULT; |
michael@0 | 1935 | } |
michael@0 | 1936 | |
michael@0 | 1937 | function RecvAssertionCount(count) |
michael@0 | 1938 | { |
michael@0 | 1939 | DoAssertionCheck(count); |
michael@0 | 1940 | } |
michael@0 | 1941 | |
michael@0 | 1942 | function RecvContentReady() |
michael@0 | 1943 | { |
michael@0 | 1944 | InitAndStartRefTests(); |
michael@0 | 1945 | return { remote: gBrowserIsRemote }; |
michael@0 | 1946 | } |
michael@0 | 1947 | |
michael@0 | 1948 | function RecvException(what) |
michael@0 | 1949 | { |
michael@0 | 1950 | gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | " + gCurrentURL + " | " + what + "\n"); |
michael@0 | 1951 | ++gTestResults.Exception; |
michael@0 | 1952 | } |
michael@0 | 1953 | |
michael@0 | 1954 | function RecvFailedLoad(why) |
michael@0 | 1955 | { |
michael@0 | 1956 | LoadFailed(why); |
michael@0 | 1957 | } |
michael@0 | 1958 | |
michael@0 | 1959 | function RecvFailedNoPaint() |
michael@0 | 1960 | { |
michael@0 | 1961 | gFailedNoPaint = true; |
michael@0 | 1962 | } |
michael@0 | 1963 | |
michael@0 | 1964 | function RecvInitCanvasWithSnapshot() |
michael@0 | 1965 | { |
michael@0 | 1966 | var painted = InitCurrentCanvasWithSnapshot(); |
michael@0 | 1967 | return { painted: painted }; |
michael@0 | 1968 | } |
michael@0 | 1969 | |
michael@0 | 1970 | function RecvLog(type, msg) |
michael@0 | 1971 | { |
michael@0 | 1972 | msg = "[CONTENT] "+ msg; |
michael@0 | 1973 | if (type == "info") { |
michael@0 | 1974 | LogInfo(msg); |
michael@0 | 1975 | } else if (type == "warning") { |
michael@0 | 1976 | LogWarning(msg); |
michael@0 | 1977 | } else { |
michael@0 | 1978 | gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | " + gCurrentURL + " | unknown log type " + type + "\n"); |
michael@0 | 1979 | ++gTestResults.Exception; |
michael@0 | 1980 | } |
michael@0 | 1981 | } |
michael@0 | 1982 | |
michael@0 | 1983 | function RecvScriptResults(runtimeMs, error, results) |
michael@0 | 1984 | { |
michael@0 | 1985 | RecordResult(runtimeMs, error, results); |
michael@0 | 1986 | } |
michael@0 | 1987 | |
michael@0 | 1988 | function RecvTestDone(runtimeMs) |
michael@0 | 1989 | { |
michael@0 | 1990 | RecordResult(runtimeMs, '', [ ]); |
michael@0 | 1991 | } |
michael@0 | 1992 | |
michael@0 | 1993 | function RecvUpdateCanvasForInvalidation(rects) |
michael@0 | 1994 | { |
michael@0 | 1995 | UpdateCurrentCanvasForInvalidation(rects); |
michael@0 | 1996 | } |
michael@0 | 1997 | |
michael@0 | 1998 | function RecvUpdateWholeCanvasForInvalidation() |
michael@0 | 1999 | { |
michael@0 | 2000 | UpdateWholeCurrentCanvasForInvalidation(); |
michael@0 | 2001 | } |
michael@0 | 2002 | |
michael@0 | 2003 | function OnProcessCrashed(subject, topic, data) |
michael@0 | 2004 | { |
michael@0 | 2005 | var id; |
michael@0 | 2006 | subject = subject.QueryInterface(CI.nsIPropertyBag2); |
michael@0 | 2007 | if (topic == "plugin-crashed") { |
michael@0 | 2008 | id = subject.getPropertyAsAString("pluginDumpID"); |
michael@0 | 2009 | } else if (topic == "ipc:content-shutdown") { |
michael@0 | 2010 | id = subject.getPropertyAsAString("dumpID"); |
michael@0 | 2011 | } |
michael@0 | 2012 | if (id) { |
michael@0 | 2013 | gExpectedCrashDumpFiles.push(id + ".dmp"); |
michael@0 | 2014 | gExpectedCrashDumpFiles.push(id + ".extra"); |
michael@0 | 2015 | } |
michael@0 | 2016 | } |
michael@0 | 2017 | |
michael@0 | 2018 | function RegisterProcessCrashObservers() |
michael@0 | 2019 | { |
michael@0 | 2020 | var os = CC[NS_OBSERVER_SERVICE_CONTRACTID] |
michael@0 | 2021 | .getService(CI.nsIObserverService); |
michael@0 | 2022 | os.addObserver(OnProcessCrashed, "plugin-crashed", false); |
michael@0 | 2023 | os.addObserver(OnProcessCrashed, "ipc:content-shutdown", false); |
michael@0 | 2024 | } |
michael@0 | 2025 | |
michael@0 | 2026 | function RecvExpectProcessCrash() |
michael@0 | 2027 | { |
michael@0 | 2028 | gExpectingProcessCrash = true; |
michael@0 | 2029 | } |
michael@0 | 2030 | |
michael@0 | 2031 | function SendClear() |
michael@0 | 2032 | { |
michael@0 | 2033 | gBrowserMessageManager.sendAsyncMessage("reftest:Clear"); |
michael@0 | 2034 | } |
michael@0 | 2035 | |
michael@0 | 2036 | function SendLoadScriptTest(uri, timeout) |
michael@0 | 2037 | { |
michael@0 | 2038 | gBrowserMessageManager.sendAsyncMessage("reftest:LoadScriptTest", |
michael@0 | 2039 | { uri: uri, timeout: timeout }); |
michael@0 | 2040 | } |
michael@0 | 2041 | |
michael@0 | 2042 | function SendLoadTest(type, uri, timeout) |
michael@0 | 2043 | { |
michael@0 | 2044 | gBrowserMessageManager.sendAsyncMessage("reftest:LoadTest", |
michael@0 | 2045 | { type: type, uri: uri, timeout: timeout } |
michael@0 | 2046 | ); |
michael@0 | 2047 | } |
michael@0 | 2048 | |
michael@0 | 2049 | function SendResetRenderingState() |
michael@0 | 2050 | { |
michael@0 | 2051 | gBrowserMessageManager.sendAsyncMessage("reftest:ResetRenderingState"); |
michael@0 | 2052 | } |