2017-10-02 19:03:43 +03:00
/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- /
/* vim: set shiftwidth=4 tabstop=8 autoindent cindent expandtab: */
/ * T h i s S o u r c e C o d e F o r m i s s u b j e c t t o t h e t e r m s o f t h e M o z i l l a P u b l i c
* License , v . 2.0 . If a copy of the MPL was not distributed with this
* file , You can obtain one at http : //mozilla.org/MPL/2.0/. */
"use strict" ;
2018-02-23 22:50:01 +03:00
var EXPORTED _SYMBOLS = [ "ReadTopManifest" , "CreateUrls" ] ;
2017-10-02 19:03:43 +03:00
2018-02-28 20:51:34 +03:00
Cu . import ( "chrome://reftest/content/globals.jsm" , this ) ;
Cu . import ( "chrome://reftest/content/reftest.jsm" , this ) ;
Cu . import ( "resource://gre/modules/Services.jsm" ) ;
Cu . import ( "resource://gre/modules/NetUtil.jsm" ) ;
2017-10-02 19:03:43 +03:00
const NS _SCRIPTSECURITYMANAGER _CONTRACTID = "@mozilla.org/scriptsecuritymanager;1" ;
const NS _NETWORK _PROTOCOL _CONTRACTID _PREFIX = "@mozilla.org/network/protocol;1?name=" ;
const NS _XREAPPINFO _CONTRACTID = "@mozilla.org/xre/app-info;1" ;
const RE _PROTOCOL = /^\w+:/ ;
const RE _PREF _ITEM = /^(|test-|ref-)pref\((.+?),(.*)\)$/ ;
function ReadTopManifest ( aFileURL , aFilter )
{
var url = g . ioService . newURI ( aFileURL ) ;
if ( ! url )
throw "Expected a file or http URL for the manifest." ;
g . manifestsLoaded = { } ;
2018-01-11 17:53:10 +03:00
ReadManifest ( url , aFilter ) ;
2017-10-02 19:03:43 +03:00
}
// Note: If you materially change the reftest manifest parsing,
// please keep the parser in print-manifest-dirs.py in sync.
2018-01-11 17:53:10 +03:00
function ReadManifest ( aURL , aFilter )
2017-10-02 19:03:43 +03:00
{
2018-01-11 17:53:10 +03:00
// Ensure each manifest is only read once. This assumes that manifests that
// are included with filters will be read via their include before they are
// read directly in the case of a duplicate
2017-10-02 19:03:43 +03:00
if ( g . manifestsLoaded . hasOwnProperty ( aURL . spec ) ) {
if ( g . manifestsLoaded [ aURL . spec ] === null )
return ;
else
aFilter = [ aFilter [ 0 ] , aFilter [ 1 ] , true ] ;
}
g . manifestsLoaded [ aURL . spec ] = aFilter [ 1 ] ;
2018-02-28 20:51:34 +03:00
var secMan = Cc [ NS _SCRIPTSECURITYMANAGER _CONTRACTID ]
. getService ( Ci . nsIScriptSecurityManager ) ;
2017-10-02 19:03:43 +03:00
var listURL = aURL ;
var channel = NetUtil . newChannel ( { uri : aURL , loadUsingSystemPrincipal : true } ) ;
var inputStream = channel . open2 ( ) ;
2018-02-28 20:51:33 +03:00
if ( channel instanceof Ci . nsIHttpChannel
2017-10-02 19:03:43 +03:00
&& channel . responseStatus != 200 ) {
g . logger . error ( "HTTP ERROR : " + channel . responseStatus ) ;
}
var streamBuf = getStreamContent ( inputStream ) ;
inputStream . close ( ) ;
var lines = streamBuf . split ( /\n|\r|\r\n/ ) ;
// Build the sandbox for fails-if(), etc., condition evaluation.
var sandbox = BuildConditionSandbox ( aURL ) ;
var lineNo = 0 ;
var urlprefix = "" ;
var defaultTestPrefSettings = [ ] , defaultRefPrefSettings = [ ] ;
2017-10-31 12:44:17 +03:00
if ( g . compareRetainedDisplayLists ) {
AddRetainedDisplayListTestPrefs ( sandbox , defaultTestPrefSettings ,
defaultRefPrefSettings ) ;
}
2017-10-02 19:03:43 +03:00
for ( var str of lines ) {
++ lineNo ;
if ( str . charAt ( 0 ) == "#" )
continue ; // entire line was a comment
var i = str . search ( /\s+#/ ) ;
if ( i >= 0 )
str = str . substring ( 0 , i ) ;
// strip leading and trailing whitespace
str = str . replace ( /^\s*/ , '' ) . replace ( /\s*$/ , '' ) ;
if ( ! str || str == "" )
continue ;
var items = str . split ( /\s+/ ) ; // split on whitespace
if ( items [ 0 ] == "url-prefix" ) {
if ( items . length != 2 )
throw "url-prefix requires one url in manifest file " + aURL . spec + " line " + lineNo ;
urlprefix = items [ 1 ] ;
continue ;
}
if ( items [ 0 ] == "default-preferences" ) {
var m ;
var item ;
defaultTestPrefSettings = [ ] ;
defaultRefPrefSettings = [ ] ;
items . shift ( ) ;
while ( ( item = items . shift ( ) ) ) {
if ( ! ( m = item . match ( RE _PREF _ITEM ) ) ) {
throw "Unexpected item in default-preferences list in manifest file " + aURL . spec + " line " + lineNo ;
}
if ( ! AddPrefSettings ( m [ 1 ] , m [ 2 ] , m [ 3 ] , sandbox , defaultTestPrefSettings , defaultRefPrefSettings ) ) {
throw "Error in pref value in manifest file " + aURL . spec + " line " + lineNo ;
}
}
2017-10-31 12:44:17 +03:00
if ( g . compareRetainedDisplayLists ) {
AddRetainedDisplayListTestPrefs ( sandbox , defaultTestPrefSettings ,
defaultRefPrefSettings ) ;
}
2017-10-02 19:03:43 +03:00
continue ;
}
var expected _status = EXPECTED _PASS ;
var allow _silent _fail = false ;
var minAsserts = 0 ;
var maxAsserts = 0 ;
var needs _focus = false ;
var slow = false ;
var testPrefSettings = defaultTestPrefSettings . concat ( ) ;
var refPrefSettings = defaultRefPrefSettings . concat ( ) ;
var fuzzy _delta = { min : 0 , max : 2 } ;
var fuzzy _pixels = { min : 0 , max : 1 } ;
var chaosMode = false ;
2018-01-11 17:53:10 +03:00
var nonSkipUsed = false ;
2017-10-02 19:03:43 +03:00
while ( items [ 0 ] . match ( /^(fails|needs-focus|random|skip|asserts|slow|require-or|silentfail|pref|test-pref|ref-pref|fuzzy|chaos-mode)/ ) ) {
var item = items . shift ( ) ;
var stat ;
var cond ;
var m = item . match ( /^(fails|random|skip|silentfail)-if(\(.*\))$/ ) ;
if ( m ) {
stat = m [ 1 ] ;
// Note: m[2] contains the parentheses, and we want them.
2018-02-28 20:51:33 +03:00
cond = Cu . evalInSandbox ( m [ 2 ] , sandbox ) ;
2017-10-02 19:03:43 +03:00
} else if ( item . match ( /^(fails|random|skip)$/ ) ) {
stat = item ;
cond = true ;
} else if ( item == "needs-focus" ) {
needs _focus = true ;
cond = false ;
} else if ( ( m = item . match ( /^asserts\((\d+)(-\d+)?\)$/ ) ) ) {
cond = false ;
minAsserts = Number ( m [ 1 ] ) ;
maxAsserts = ( m [ 2 ] == undefined ) ? minAsserts
: Number ( m [ 2 ] . substring ( 1 ) ) ;
} else if ( ( m = item . match ( /^asserts-if\((.*?),(\d+)(-\d+)?\)$/ ) ) ) {
cond = false ;
2018-02-28 20:51:33 +03:00
if ( Cu . evalInSandbox ( "(" + m [ 1 ] + ")" , sandbox ) ) {
2017-10-02 19:03:43 +03:00
minAsserts = Number ( m [ 2 ] ) ;
maxAsserts =
( m [ 3 ] == undefined ) ? minAsserts
: Number ( m [ 3 ] . substring ( 1 ) ) ;
}
} else if ( item == "slow" ) {
cond = false ;
slow = true ;
} else if ( ( m = item . match ( /^require-or\((.*?)\)$/ ) ) ) {
var args = m [ 1 ] . split ( /,/ ) ;
if ( args . length != 2 ) {
throw "Error in manifest file " + aURL . spec + " line " + lineNo + ": wrong number of args to require-or" ;
}
var [ precondition _str , fallback _action ] = args ;
var preconditions = precondition _str . split ( /&&/ ) ;
cond = false ;
for ( var precondition of preconditions ) {
if ( precondition === "debugMode" ) {
// Currently unimplemented. Requires asynchronous
// JSD call + getting an event while no JS is running
stat = fallback _action ;
cond = true ;
break ;
} else if ( precondition === "true" ) {
// For testing
} else {
// Unknown precondition. Assume it is unimplemented.
stat = fallback _action ;
cond = true ;
break ;
}
}
} else if ( ( m = item . match ( /^slow-if\((.*?)\)$/ ) ) ) {
cond = false ;
2018-02-28 20:51:33 +03:00
if ( Cu . evalInSandbox ( "(" + m [ 1 ] + ")" , sandbox ) )
2017-10-02 19:03:43 +03:00
slow = true ;
} else if ( item == "silentfail" ) {
cond = false ;
allow _silent _fail = true ;
} else if ( ( m = item . match ( RE _PREF _ITEM ) ) ) {
cond = false ;
if ( ! AddPrefSettings ( m [ 1 ] , m [ 2 ] , m [ 3 ] , sandbox , testPrefSettings , refPrefSettings ) ) {
throw "Error in pref value in manifest file " + aURL . spec + " line " + lineNo ;
}
} else if ( ( m = item . match ( /^fuzzy\((\d+)(-\d+)?,(\d+)(-\d+)?\)$/ ) ) ) {
cond = false ;
expected _status = EXPECTED _FUZZY ;
fuzzy _delta = ExtractRange ( m , 1 ) ;
fuzzy _pixels = ExtractRange ( m , 3 ) ;
} else if ( ( m = item . match ( /^fuzzy-if\((.*?),(\d+)(-\d+)?,(\d+)(-\d+)?\)$/ ) ) ) {
cond = false ;
2018-02-28 20:51:33 +03:00
if ( Cu . evalInSandbox ( "(" + m [ 1 ] + ")" , sandbox ) ) {
2017-10-02 19:03:43 +03:00
expected _status = EXPECTED _FUZZY ;
fuzzy _delta = ExtractRange ( m , 2 ) ;
fuzzy _pixels = ExtractRange ( m , 4 ) ;
}
} else if ( item == "chaos-mode" ) {
cond = false ;
chaosMode = true ;
} else {
throw "Error in manifest file " + aURL . spec + " line " + lineNo + ": unexpected item " + item ;
}
2018-01-11 17:53:10 +03:00
if ( stat != "skip" ) {
nonSkipUsed = true ;
}
2017-10-02 19:03:43 +03:00
if ( cond ) {
if ( stat == "fails" ) {
expected _status = EXPECTED _FAIL ;
} else if ( stat == "random" ) {
expected _status = EXPECTED _RANDOM ;
} else if ( stat == "skip" ) {
expected _status = EXPECTED _DEATH ;
} else if ( stat == "silentfail" ) {
allow _silent _fail = true ;
}
}
}
if ( minAsserts > maxAsserts ) {
throw "Bad range in manifest file " + aURL . spec + " line " + lineNo ;
}
var runHttp = false ;
var httpDepth ;
if ( items [ 0 ] == "HTTP" ) {
runHttp = ( aURL . scheme == "file" ) ; // We can't yet run the local HTTP server
// for non-local reftests.
httpDepth = 0 ;
items . shift ( ) ;
} else if ( items [ 0 ] . match ( /HTTP\(\.\.(\/\.\.)*\)/ ) ) {
// Accept HTTP(..), HTTP(../..), HTTP(../../..), etc.
runHttp = ( aURL . scheme == "file" ) ; // We can't yet run the local HTTP server
// for non-local reftests.
httpDepth = ( items [ 0 ] . length - 5 ) / 3 ;
items . shift ( ) ;
}
// do not prefix the url for include commands or urls specifying
// a protocol
if ( urlprefix && items [ 0 ] != "include" ) {
if ( items . length > 1 && ! items [ 1 ] . match ( RE _PROTOCOL ) ) {
items [ 1 ] = urlprefix + items [ 1 ] ;
}
if ( items . length > 2 && ! items [ 2 ] . match ( RE _PROTOCOL ) ) {
items [ 2 ] = urlprefix + items [ 2 ] ;
}
}
var principal = secMan . createCodebasePrincipal ( aURL , { } ) ;
if ( items [ 0 ] == "include" ) {
if ( items . length != 2 )
throw "Error in manifest file " + aURL . spec + " line " + lineNo + ": incorrect number of arguments to include" ;
if ( runHttp )
throw "Error in manifest file " + aURL . spec + " line " + lineNo + ": use of include with http" ;
2018-01-11 17:53:10 +03:00
// If the expected_status is EXPECTED_PASS (the default) then allow
// the include. If it is EXPECTED_DEATH, that means there was a skip
// or skip-if annotation (with a true condition) on this include
// statement, so we should skip the include. Any other expected_status
// is disallowed since it's nonintuitive as to what the intended
// effect is.
if ( nonSkipUsed ) {
throw "Error in manifest file " + aURL . spec + " line " + lineNo + ": include statement with annotation other than 'skip' or 'skip-if'" ;
} else if ( expected _status == EXPECTED _DEATH ) {
g . logger . info ( "Skipping included manifest at " + aURL . spec + " line " + lineNo + " due to matching skip condition" ) ;
} else {
// poor man's assertion
if ( expected _status != EXPECTED _PASS ) {
throw "Error in manifest file parsing code: we should never get expected_status=" + expected _status + " when nonSkipUsed=false (from " + aURL . spec + " line " + lineNo + ")" ;
}
var incURI = g . ioService . newURI ( items [ 1 ] , null , listURL ) ;
secMan . checkLoadURIWithPrincipal ( principal , incURI ,
2018-02-28 20:51:34 +03:00
Ci . nsIScriptSecurityManager . DISALLOW _SCRIPT ) ;
2018-01-11 17:53:10 +03:00
ReadManifest ( incURI , aFilter ) ;
2018-01-11 17:53:10 +03:00
}
2018-02-02 00:22:55 +03:00
} else if ( items [ 0 ] == TYPE _LOAD || items [ 0 ] == TYPE _SCRIPT ) {
2017-10-02 19:03:43 +03:00
if ( items . length != 2 )
2018-02-02 00:22:55 +03:00
throw "Error in manifest file " + aURL . spec + " line " + lineNo + ": incorrect number of arguments to " + items [ 0 ] ;
if ( items [ 0 ] == TYPE _LOAD && expected _status != EXPECTED _PASS && expected _status != EXPECTED _DEATH )
2017-10-02 19:03:43 +03:00
throw "Error in manifest file " + aURL . spec + " line " + lineNo + ": incorrect known failure type for load test" ;
AddTestItem ( { type : TYPE _LOAD ,
expected : expected _status ,
2018-02-02 00:22:55 +03:00
manifest : aURL . spec ,
2017-10-02 19:03:43 +03:00
allowSilentFail : allow _silent _fail ,
minAsserts : minAsserts ,
maxAsserts : maxAsserts ,
needsFocus : needs _focus ,
slow : slow ,
prefSettings1 : testPrefSettings ,
prefSettings2 : refPrefSettings ,
fuzzyMinDelta : fuzzy _delta . min ,
fuzzyMaxDelta : fuzzy _delta . max ,
fuzzyMinPixels : fuzzy _pixels . min ,
fuzzyMaxPixels : fuzzy _pixels . max ,
2018-02-02 00:22:55 +03:00
runHttp : runHttp ,
httpDepth : httpDepth ,
url1 : items [ 1 ] ,
2017-10-02 19:03:43 +03:00
url2 : null ,
chaosMode : chaosMode } , aFilter ) ;
} else if ( items [ 0 ] == TYPE _REFTEST _EQUAL || items [ 0 ] == TYPE _REFTEST _NOTEQUAL || items [ 0 ] == TYPE _PRINT ) {
if ( items . length != 3 )
throw "Error in manifest file " + aURL . spec + " line " + lineNo + ": incorrect number of arguments to " + items [ 0 ] ;
if ( items [ 0 ] == TYPE _REFTEST _NOTEQUAL &&
expected _status == EXPECTED _FUZZY &&
( fuzzy _delta . min > 0 || fuzzy _pixels . min > 0 ) ) {
throw "Error in manifest file " + aURL . spec + " line " + lineNo + ": minimum fuzz must be zero for tests of type " + items [ 0 ] ;
}
var type = items [ 0 ] ;
2018-03-19 16:22:24 +03:00
if ( g . compareRetainedDisplayLists ) {
2017-10-02 19:03:43 +03:00
type = TYPE _REFTEST _EQUAL ;
2018-05-29 18:17:28 +03:00
// We expect twice as many assertion failures when comparing
// tests because we run each test twice.
2017-10-02 19:03:43 +03:00
minAsserts *= 2 ;
maxAsserts *= 2 ;
2018-05-29 18:17:28 +03:00
// Skip the test if it is expected to fail in both modes.
// It would unexpectedly "pass" in comparison mode mode when
// comparing the two failures, which is not a useful result.
2017-10-02 19:03:43 +03:00
if ( expected _status === EXPECTED _FAIL ||
expected _status === EXPECTED _RANDOM ) {
expected _status = EXPECTED _DEATH ;
}
}
AddTestItem ( { type : type ,
expected : expected _status ,
2018-02-02 00:22:55 +03:00
manifest : aURL . spec ,
2017-10-02 19:03:43 +03:00
allowSilentFail : allow _silent _fail ,
minAsserts : minAsserts ,
maxAsserts : maxAsserts ,
needsFocus : needs _focus ,
slow : slow ,
prefSettings1 : testPrefSettings ,
prefSettings2 : refPrefSettings ,
fuzzyMinDelta : fuzzy _delta . min ,
fuzzyMaxDelta : fuzzy _delta . max ,
fuzzyMinPixels : fuzzy _pixels . min ,
fuzzyMaxPixels : fuzzy _pixels . max ,
2018-02-02 00:22:55 +03:00
runHttp : runHttp ,
httpDepth : httpDepth ,
url1 : items [ 1 ] ,
url2 : items [ 2 ] ,
2017-10-02 19:03:43 +03:00
chaosMode : chaosMode } , aFilter ) ;
} else {
throw "Error in manifest file " + aURL . spec + " line " + lineNo + ": unknown test type " + items [ 0 ] ;
}
}
}
// Read all available data from an input stream and return it
// as a string.
function getStreamContent ( inputStream )
{
var streamBuf = "" ;
2018-02-28 20:51:34 +03:00
var sis = Cc [ "@mozilla.org/scriptableinputstream;1" ] .
createInstance ( Ci . nsIScriptableInputStream ) ;
2017-10-02 19:03:43 +03:00
sis . init ( inputStream ) ;
var available ;
while ( ( available = sis . available ( ) ) != 0 ) {
streamBuf += sis . read ( available ) ;
}
return streamBuf ;
}
// Build the sandbox for fails-if(), etc., condition evaluation.
function BuildConditionSandbox ( aURL ) {
2018-02-28 20:51:33 +03:00
var sandbox = new Cu . Sandbox ( aURL . spec ) ;
2018-02-28 20:51:34 +03:00
var xr = Cc [ NS _XREAPPINFO _CONTRACTID ] . getService ( Ci . nsIXULRuntime ) ;
var appInfo = Cc [ NS _XREAPPINFO _CONTRACTID ] . getService ( Ci . nsIXULAppInfo ) ;
2017-10-02 19:03:43 +03:00
sandbox . isDebugBuild = g . debug . isDebugBuild ;
2018-02-28 20:51:34 +03:00
var prefs = Cc [ "@mozilla.org/preferences-service;1" ] .
getService ( Ci . nsIPrefBranch ) ;
var env = Cc [ "@mozilla.org/process/environment;1" ] .
getService ( Ci . nsIEnvironment ) ;
2017-10-02 19:03:43 +03:00
2018-02-28 20:51:34 +03:00
sandbox . xulRuntime = Cu . cloneInto ( { widgetToolkit : xr . widgetToolkit , OS : xr . OS , XPCOMABI : xr . XPCOMABI } , sandbox ) ;
2017-10-02 19:03:43 +03:00
var testRect = g . browser . getBoundingClientRect ( ) ;
sandbox . smallScreen = false ;
if ( g . containingWindow . innerWidth < 800 || g . containingWindow . innerHeight < 1000 ) {
sandbox . smallScreen = true ;
}
2018-02-28 20:51:34 +03:00
var gfxInfo = ( NS _GFXINFO _CONTRACTID in Cc ) && Cc [ NS _GFXINFO _CONTRACTID ] . getService ( Ci . nsIGfxInfo ) ;
2017-10-02 19:03:43 +03:00
let readGfxInfo = function ( obj , key ) {
if ( g . contentGfxInfo && ( key in g . contentGfxInfo ) ) {
return g . contentGfxInfo [ key ] ;
}
return obj [ key ] ;
}
try {
sandbox . d2d = readGfxInfo ( gfxInfo , "D2DEnabled" ) ;
sandbox . dwrite = readGfxInfo ( gfxInfo , "DWriteEnabled" ) ;
} catch ( e ) {
sandbox . d2d = false ;
sandbox . dwrite = false ;
}
var info = gfxInfo . getInfo ( ) ;
var canvasBackend = readGfxInfo ( info , "AzureCanvasBackend" ) ;
var contentBackend = readGfxInfo ( info , "AzureContentBackend" ) ;
var canvasAccelerated = readGfxInfo ( info , "AzureCanvasAccelerated" ) ;
sandbox . gpuProcess = gfxInfo . usingGPUProcess ;
sandbox . azureCairo = canvasBackend == "cairo" ;
sandbox . azureSkia = canvasBackend == "skia" ;
sandbox . skiaContent = contentBackend == "skia" ;
sandbox . azureSkiaGL = canvasAccelerated ; // FIXME: assumes GL right now
// true if we are using the same Azure backend for rendering canvas and content
sandbox . contentSameGfxBackendAsCanvas = contentBackend == canvasBackend
|| ( contentBackend == "none" && canvasBackend == "cairo" ) ;
sandbox . layersGPUAccelerated =
g . windowUtils . layerManagerType != "Basic" ;
sandbox . d3d11 =
g . windowUtils . layerManagerType == "Direct3D 11" ;
sandbox . d3d9 =
g . windowUtils . layerManagerType == "Direct3D 9" ;
sandbox . layersOpenGL =
g . windowUtils . layerManagerType == "OpenGL" ;
sandbox . webrender =
g . windowUtils . layerManagerType == "WebRender" ;
sandbox . layersOMTC =
g . windowUtils . layerManagerRemote == true ;
sandbox . advancedLayers =
g . windowUtils . usingAdvancedLayers == true ;
sandbox . layerChecksEnabled = ! sandbox . webrender ;
2017-09-27 07:17:11 +03:00
sandbox . retainedDisplayList =
prefs . getBoolPref ( "layout.display-list.retain" ) ;
2017-10-02 19:03:43 +03:00
// Shortcuts for widget toolkits.
sandbox . Android = xr . OS == "Android" ;
sandbox . cocoaWidget = xr . widgetToolkit == "cocoa" ;
2018-01-10 10:55:38 +03:00
sandbox . gtkWidget = xr . widgetToolkit == "gtk3" ;
2017-10-02 19:03:43 +03:00
sandbox . qtWidget = xr . widgetToolkit == "qt" ;
sandbox . winWidget = xr . widgetToolkit == "windows" ;
// Scrollbars that are semi-transparent. See bug 1169666.
sandbox . transparentScrollbars = xr . widgetToolkit == "gtk3" ;
if ( sandbox . Android ) {
2018-02-28 20:51:34 +03:00
var sysInfo = Cc [ "@mozilla.org/system-info;1" ] . getService ( Ci . nsIPropertyBag2 ) ;
2017-10-02 19:03:43 +03:00
// This is currently used to distinguish Android 4.0.3 (SDK version 15)
// and later from Android 2.x
sandbox . AndroidVersion = sysInfo . getPropertyAsInt32 ( "version" ) ;
}
# if MOZ _ASAN
sandbox . AddressSanitizer = true ;
# else
sandbox . AddressSanitizer = false ;
# endif
# if MOZ _WEBRTC
sandbox . webrtc = true ;
# else
sandbox . webrtc = false ;
# endif
2017-10-31 12:44:17 +03:00
let retainedDisplayListsEnabled = prefs . getBoolPref ( "layout.display-list.retain" , false ) ;
sandbox . retainedDisplayLists = retainedDisplayListsEnabled && ! g . compareRetainedDisplayLists ;
sandbox . compareRetainedDisplayLists = g . compareRetainedDisplayLists ;
2017-10-02 19:03:43 +03:00
sandbox . skiaPdf = false ;
# ifdef RELEASE _OR _BETA
sandbox . release _or _beta = true ;
# else
sandbox . release _or _beta = false ;
# endif
2018-02-28 20:51:34 +03:00
var hh = Cc [ NS _NETWORK _PROTOCOL _CONTRACTID _PREFIX + "http" ] .
getService ( Ci . nsIHttpProtocolHandler ) ;
2017-10-02 19:03:43 +03:00
var httpProps = [ "userAgent" , "appName" , "appVersion" , "vendor" ,
"vendorSub" , "product" , "productSub" , "platform" ,
"oscpu" , "language" , "misc" ] ;
sandbox . http = new sandbox . Object ( ) ;
httpProps . forEach ( ( x ) => sandbox . http [ x ] = hh [ x ] ) ;
// Set OSX to be the Mac OS X version, as an integer, or undefined
// for other platforms. The integer is formed by 100 times the
// major version plus the minor version, so 1006 for 10.6, 1010 for
// 10.10, etc.
var osxmatch = /Mac OS X (\d+).(\d+)$/ . exec ( hh . oscpu ) ;
sandbox . OSX = osxmatch ? parseInt ( osxmatch [ 1 ] ) * 100 + parseInt ( osxmatch [ 2 ] ) : undefined ;
// see if we have the test plugin available,
// and set a sandox prop accordingly
sandbox . haveTestPlugin = ! sandbox . Android && ! ! getTestPlugin ( "Test Plug-in" ) ;
// Set a flag on sandbox if the windows default theme is active
sandbox . windowsDefaultTheme = g . containingWindow . matchMedia ( "(-moz-windows-default-theme)" ) . matches ;
try {
sandbox . nativeThemePref = ! prefs . getBoolPref ( "mozilla.widget.disable-native-theme" ) ;
} catch ( e ) {
sandbox . nativeThemePref = true ;
}
sandbox . gpuProcessForceEnabled = prefs . getBoolPref ( "layers.gpu-process.force-enabled" , false ) ;
2018-02-28 20:51:34 +03:00
sandbox . prefs = Cu . cloneInto ( {
2017-10-02 19:03:43 +03:00
getBoolPref : function ( p ) { return prefs . getBoolPref ( p ) ; } ,
getIntPref : function ( p ) { return prefs . getIntPref ( p ) ; }
} , sandbox , { cloneFunctions : true } ) ;
// Tests shouldn't care about this except for when they need to
// crash the content process
sandbox . browserIsRemote = g . browserIsRemote ;
try {
2018-05-22 02:58:23 +03:00
sandbox . asyncPan = g . containingWindow . docShell . asyncPanZoomEnabled ;
2017-10-02 19:03:43 +03:00
} catch ( e ) {
sandbox . asyncPan = false ;
}
// Graphics features
sandbox . usesRepeatResampling = sandbox . d2d ;
2018-03-06 00:39:53 +03:00
// Running in a test-verify session?
sandbox . verify = prefs . getBoolPref ( "reftest.verify" , false ) ;
2017-10-02 19:03:43 +03:00
if ( ! g . dumpedConditionSandbox ) {
g . logger . info ( "Dumping JSON representation of sandbox" ) ;
2018-02-28 20:51:34 +03:00
g . logger . info ( JSON . stringify ( Cu . waiveXrays ( sandbox ) ) ) ;
2017-10-02 19:03:43 +03:00
g . dumpedConditionSandbox = true ;
}
return sandbox ;
}
2017-10-31 12:44:17 +03:00
function AddRetainedDisplayListTestPrefs ( aSandbox , aTestPrefSettings ,
aRefPrefSettings ) {
AddPrefSettings ( "test-" , "layout.display-list.retain" , "true" , aSandbox ,
aTestPrefSettings , aRefPrefSettings ) ;
AddPrefSettings ( "ref-" , "layout.display-list.retain" , "false" , aSandbox ,
aTestPrefSettings , aRefPrefSettings ) ;
}
2017-10-02 19:03:43 +03:00
function AddPrefSettings ( aWhere , aPrefName , aPrefValExpression , aSandbox , aTestPrefSettings , aRefPrefSettings ) {
2018-02-28 20:51:33 +03:00
var prefVal = Cu . evalInSandbox ( "(" + aPrefValExpression + ")" , aSandbox ) ;
2017-10-02 19:03:43 +03:00
var prefType ;
var valType = typeof ( prefVal ) ;
if ( valType == "boolean" ) {
prefType = PREF _BOOLEAN ;
} else if ( valType == "string" ) {
prefType = PREF _STRING ;
} else if ( valType == "number" && ( parseInt ( prefVal ) == prefVal ) ) {
prefType = PREF _INTEGER ;
} else {
return false ;
}
var setting = { name : aPrefName ,
type : prefType ,
value : prefVal } ;
2018-03-19 16:22:24 +03:00
if ( g . compareRetainedDisplayLists && aPrefName != "layout.display-list.retain" ) {
2017-10-02 19:03:43 +03:00
// ref-pref() is ignored, test-pref() and pref() are added to both
if ( aWhere != "ref-" ) {
aTestPrefSettings . push ( setting ) ;
aRefPrefSettings . push ( setting ) ;
}
} else {
if ( aWhere != "ref-" ) {
aTestPrefSettings . push ( setting ) ;
}
if ( aWhere != "test-" ) {
aRefPrefSettings . push ( setting ) ;
}
}
return true ;
}
function ExtractRange ( matches , startIndex , defaultMin = 0 ) {
if ( matches [ startIndex + 1 ] === undefined ) {
return {
min : defaultMin ,
max : Number ( matches [ startIndex ] )
} ;
}
return {
min : Number ( matches [ startIndex ] ) ,
max : Number ( matches [ startIndex + 1 ] . substring ( 1 ) )
} ;
}
2018-02-02 00:22:55 +03:00
function ServeTestBase ( aURL , depth ) {
2018-02-28 20:51:34 +03:00
var listURL = aURL . QueryInterface ( Ci . nsIFileURL ) ;
2017-10-02 19:03:43 +03:00
var directory = listURL . file . parent ;
// Allow serving a tree that's an ancestor of the directory containing
// the files so that they can use resources in ../ (etc.).
var dirPath = "/" ;
while ( depth > 0 ) {
dirPath = "/" + directory . leafName + dirPath ;
directory = directory . parent ;
-- depth ;
}
g . count ++ ;
var path = "/" + Date . now ( ) + "/" + g . count ;
g . server . registerDirectory ( path + "/" , directory ) ;
2018-02-28 20:51:34 +03:00
var secMan = Cc [ NS _SCRIPTSECURITYMANAGER _CONTRACTID ]
. getService ( Ci . nsIScriptSecurityManager ) ;
2017-10-02 19:03:43 +03:00
var testbase = g . ioService . newURI ( "http://localhost:" + g . httpServerPort +
path + dirPath ) ;
// Give the testbase URI access to XUL and XBL
Services . perms . add ( testbase , "allowXULXBL" , Services . perms . ALLOW _ACTION ) ;
2018-02-02 00:22:55 +03:00
return testbase ;
}
function CreateUrls ( test ) {
2018-02-28 20:51:34 +03:00
let secMan = Cc [ NS _SCRIPTSECURITYMANAGER _CONTRACTID ]
. getService ( Ci . nsIScriptSecurityManager ) ;
2018-02-02 00:22:55 +03:00
let manifestURL = g . ioService . newURI ( test . manifest ) ;
let principal = secMan . createCodebasePrincipal ( manifestURL , { } ) ;
let testbase = manifestURL ;
if ( test . runHttp )
testbase = ServeTestBase ( manifestURL , test . httpDepth )
2017-10-02 19:03:43 +03:00
function FileToURI ( file )
{
2018-02-02 00:22:55 +03:00
if ( file === null )
return file ;
2018-02-07 03:20:38 +03:00
2018-02-02 00:22:55 +03:00
var testURI = g . ioService . newURI ( file , null , testbase ) ;
secMan . checkLoadURIWithPrincipal ( principal , testURI ,
2018-02-28 20:51:34 +03:00
Ci . nsIScriptSecurityManager . DISALLOW _SCRIPT ) ;
2017-10-02 19:03:43 +03:00
return testURI ;
}
2018-02-02 00:22:55 +03:00
let files = [ test . url1 , test . url2 ] ;
[ test . url1 , test . url2 ] = files . map ( FileToURI ) ;
return test ;
2017-10-02 19:03:43 +03:00
}
function AddTestItem ( aTest , aFilter ) {
if ( ! aFilter )
aFilter = [ null , [ ] , false ] ;
2018-02-01 22:18:00 +03:00
var { url1 , url2 } = CreateUrls ( Object . assign ( { } , aTest ) ) ;
2018-02-02 00:22:55 +03:00
2017-10-02 19:03:43 +03:00
var globalFilter = aFilter [ 0 ] ;
var manifestFilter = aFilter [ 1 ] ;
var invertManifest = aFilter [ 2 ] ;
2018-06-18 16:46:27 +03:00
if ( globalFilter && ! globalFilter . test ( url1 . spec ) )
return ;
if ( manifestFilter && ! ( invertManifest ^ manifestFilter . test ( url1 . spec ) ) )
2017-10-02 19:03:43 +03:00
return ;
if ( g . focusFilterMode == FOCUS _FILTER _NEEDS _FOCUS _TESTS &&
! aTest . needsFocus )
return ;
if ( g . focusFilterMode == FOCUS _FILTER _NON _NEEDS _FOCUS _TESTS &&
aTest . needsFocus )
return ;
2018-02-01 22:18:00 +03:00
if ( url2 !== null )
aTest . identifier = [ url1 . spec , aTest . type , url2 . spec ] ;
2017-10-02 19:03:43 +03:00
else
2018-02-01 22:18:00 +03:00
aTest . identifier = url1 . spec ;
2017-10-02 19:03:43 +03:00
g . urls . push ( aTest ) ;
2018-06-18 15:47:29 +03:00
// Periodically log progress to avoid no-output timeout on slow platforms.
// No-output timeouts during manifest parsing have been a problem for
// jsreftests on Android/debug. Any logging resets the no-output timer,
// even debug logging which is normally not displayed.
if ( ( g . urls . length % 5000 ) == 0 )
g . logger . debug ( g . urls . length + " tests found..." ) ;
2017-10-02 19:03:43 +03:00
}