Bug 1596567 - Normalize test ids for reftests, crashtests, and jsreftests; r=ahal,jmaher

Use test identifiers that look like posix-compliant relative file paths rather than URLs; identifier "paths" are relative to topsrcdir -- an intuitive, brief mapping from identifier to test file.

This patch adds (expands) a --topsrcdir option to runreftest.py and updates CI configuration to set it appropriately. runreftest.py calculates a manifest ID, a path relative to topsrcdir, for each requested manifest and passes those manifest IDs to manifest.jsm. In manifest.jsm, a new manifest ID is generated when a manifest is included from a new directory. Test identifiers are generated by adding the test file name to the manifest ID.

Examples (url -> identifier):

  - file:///builds/worker/workspace/build/tests/reftest/tests/dom/svg/crashtests/398926-fill.svg -> dom/svg/crashtests/398926-fill.svg
  - file:///Z:/task_1577755655/build/tests/reftest/tests/dom/svg/crashtests/398926-fill.svg -> dom/svg/crashtests/398926-fill.svg
  - http://10.7.205.207:8854/tests/dom/svg/crashtests/398926-fill.svg -> dom/svg/crashtests/398926-fill.svg
  - file:///builds/worker/workspace/build/tests/jsreftest/tests/js/src/tests/jsreftest.html?test=test262/built-ins/Array/prototype/indexOf/15.4.4.14-9-b-i-31.js -> js/src/tests/test262/built-ins/Array/prototype/indexOf/15.4.4.14-9-b-i-31.js
  - chrome://reftest/content/bugs/299837-2.xhtml -> layout/reftests/bugs/299837-2.xhtml
  - http://localhost:36067/1577754972876/1/289480.html#top -> layout/reftests/bugs/289480.html#top
  - about:blank -> about:blank
  - data:text/html,<body> -> data:text/html,<body>

Differential Revision: https://phabricator.services.mozilla.com/D58415

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Geoff Brown 2020-01-09 19:25:58 +00:00
Родитель 4f140d99f3
Коммит fc3f08846e
10 изменённых файлов: 124 добавлений и 44 удалений

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

@ -22,6 +22,6 @@ PKG_STAGE = $(DIST)/test-stage
# stage tests for packaging
stage-package:
$(NSINSTALL) -D $(PKG_STAGE)/jsreftest/tests
(cd $(srcdir) && tar $(TAR_CREATE_FLAGS) - $(TEST_FILES)) | (cd $(PKG_STAGE)/jsreftest/tests && tar -xf -)
$(PYTHON) $(srcdir)/jstests.py --make-manifests $(PKG_STAGE)/jsreftest/tests/
$(NSINSTALL) -D $(PKG_STAGE)/jsreftest/tests/js/src/tests
(cd $(srcdir) && tar $(TAR_CREATE_FLAGS) - $(TEST_FILES)) | (cd $(PKG_STAGE)/jsreftest/tests/js/src/tests && tar -xf -)
$(PYTHON) $(srcdir)/jstests.py --make-manifests $(PKG_STAGE)/jsreftest/tests/js/src/tests

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

@ -20,19 +20,19 @@ const RE_PROTOCOL = /^\w+:/;
const RE_PREF_ITEM = /^(|test-|ref-)pref\((.+?),(.*)\)$/;
function ReadTopManifest(aFileURL, aFilter)
function ReadTopManifest(aFileURL, aFilter, aManifestID)
{
var url = g.ioService.newURI(aFileURL);
if (!url)
throw "Expected a file or http URL for the manifest.";
g.manifestsLoaded = {};
ReadManifest(url, aFilter);
ReadManifest(url, aFilter, aManifestID);
}
// Note: If you materially change the reftest manifest parsing,
// please keep the parser in print-manifest-dirs.py in sync.
function ReadManifest(aURL, aFilter)
function ReadManifest(aURL, aFilter, aManifestID)
{
// 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
@ -306,7 +306,39 @@ function ReadManifest(aURL, aFilter)
var incURI = g.ioService.newURI(items[1], null, listURL);
secMan.checkLoadURIWithPrincipal(principal, incURI,
Ci.nsIScriptSecurityManager.DISALLOW_SCRIPT);
ReadManifest(incURI, aFilter);
// Cannot use nsIFile or similar to manipulate the manifest ID; although it appears
// path-like, it does not refer to an actual path in the filesystem.
var newManifestID = aManifestID;
var included = items[1];
// Remove included manifest file name.
// eg. dir1/dir2/reftest.list -> dir1/dir2
var pos = included.lastIndexOf("/");
if (pos <= 0) {
included = "";
} else {
included = included.substring(0, pos);
}
// Simplify references to parent directories.
// eg. dir1/dir2/../dir3 -> dir1/dir3
while (included.startsWith("../")) {
pos = newManifestID.lastIndexOf("/");
if (pos < 0) {
pos = 0;
}
newManifestID = newManifestID.substring(0, pos);
included = included.substring(3);
}
// Use a new manifest ID if the included manifest is in a different directory.
if (included.length > 0) {
if (newManifestID.length > 0) {
newManifestID = newManifestID + "/" + included;
} else {
// parent directory includes may refer to the topsrcdir
newManifestID = included;
}
}
ReadManifest(incURI, aFilter, newManifestID);
}
} else if (items[0] == TYPE_LOAD || items[0] == TYPE_SCRIPT) {
var type = items[0];
@ -334,7 +366,7 @@ function ReadManifest(aURL, aFilter)
url2: null,
chaosMode: chaosMode,
wrCapture: wrCapture,
noAutoFuzz: noAutoFuzz }, aFilter);
noAutoFuzz: noAutoFuzz }, aFilter, aManifestID);
} 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];
@ -383,7 +415,7 @@ function ReadManifest(aURL, aFilter)
url2: items[2],
chaosMode: chaosMode,
wrCapture: wrCapture,
noAutoFuzz: noAutoFuzz }, aFilter);
noAutoFuzz: noAutoFuzz }, aFilter, aManifestID);
} else {
throw "Error in manifest file " + aURL.spec + " line " + lineNo + ": unknown test type " + items[0];
}
@ -701,10 +733,28 @@ function CreateUrls(test) {
return test;
}
function AddTestItem(aTest, aFilter) {
function TestIdentifier(aUrl, aManifestID) {
// Construct a platform-independent and location-independent test identifier for
// a url; normally the identifier looks like a posix-compliant relative file
// path.
// Test urls may be simple file names, chrome: urls with full paths, about:blank, etc.
if (aUrl.startsWith("about:") || aUrl.startsWith("data:")) {
return aUrl;
}
var pos = aUrl.lastIndexOf("/");
var url = (pos < 0) ? aUrl : aUrl.substring(pos + 1);
return (aManifestID + "/" + url);
}
function AddTestItem(aTest, aFilter, aManifestID) {
if (!aFilter)
aFilter = [null, [], false];
var identifier = TestIdentifier(aTest.url1, aManifestID);
if (aTest.url2 !== null) {
identifier = [identifier, aTest.type, TestIdentifier(aTest.url2, aManifestID)];
}
var {url1, url2} = CreateUrls(Object.assign({}, aTest));
var globalFilter = aFilter[0];
@ -721,10 +771,7 @@ function AddTestItem(aTest, aFilter) {
aTest.needsFocus)
return;
if (url2 !== null)
aTest.identifier = [url1.spec, aTest.type, url2.spec];
else
aTest.identifier = url1.spec;
aTest.identifier = identifier;
g.urls.push(aTest);
// Periodically log progress to avoid no-output timeout on slow platforms.
// No-output timeouts during manifest parsing have been a problem for

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

@ -420,8 +420,10 @@ function ReadTests() {
manifestURLs.sort(function(a,b) {return a.length - b.length})
manifestURLs.forEach(function(manifestURL) {
logger.info("Reading manifest " + manifestURL);
var filter = manifests[manifestURL] ? new RegExp(manifests[manifestURL]) : null;
ReadTopManifest(manifestURL, [globalFilter, filter, false]);
var manifestInfo = manifests[manifestURL];
var filter = manifestInfo[0] ? new RegExp(manifestInfo[0]) : null;
var manifestID = manifestInfo[1];
ReadTopManifest(manifestURL, [globalFilter, filter, false], manifestID);
});
if (dumpTests) {

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

@ -268,6 +268,13 @@ class ReftestArgumentsParser(argparse.ArgumentParser):
default=False,
help="Run tests in headless mode.")
self.add_argument("--topsrcdir",
action="store",
type=str,
dest="topsrcdir",
default=None,
help="Path to source directory")
mozlog.commandline.add_logging_group(self)
def get_ip(self):
@ -355,6 +362,12 @@ class ReftestArgumentsParser(argparse.ArgumentParser):
# See bug 1404482.
options.leakThresholds["tab"] = 100
if options.topsrcdir is None:
if self.build_obj:
options.topsrcdir = self.build_obj.topsrcdir
else:
options.topsrcdir = os.getcwd()
class DesktopArgumentsParser(ReftestArgumentsParser):
def __init__(self, **kwargs):

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

@ -230,17 +230,20 @@ class ReftestResolver(object):
manifests = {}
for testPath in tests:
for manifest, filter_str in self.findManifest(suite, testPath):
manifest = self.manifestURL(options, manifest)
if manifest not in manifests:
manifests[manifest] = set()
manifests[manifest].add(filter_str)
manifests_by_url = {}
for key in manifests.iterkeys():
id = os.path.relpath(os.path.abspath(os.path.dirname(key)), options.topsrcdir)
id = id.replace(os.sep, posixpath.sep)
if None in manifests[key]:
manifests[key] = None
manifests[key] = (None, id)
else:
manifests[key] = "|".join(list(manifests[key]))
return manifests
manifests[key] = ("|".join(list(manifests[key])), id)
url = self.manifestURL(options, key)
manifests_by_url[url] = manifests[key]
return manifests_by_url
class RefTest(object):
@ -448,7 +451,7 @@ class RefTest(object):
browserEnv = self.environment(
xrePath=options.xrePath, debugger=options.debugger)
browserEnv["XPCOM_DEBUG_BREAK"] = "stack"
if hasattr(options, "topsrcdir"):
if options.topsrcdir:
browserEnv["MOZ_DEVELOPER_REPO_DIR"] = options.topsrcdir
if hasattr(options, "topobjdir"):
browserEnv["MOZ_DEVELOPER_OBJ_DIR"] = options.topobjdir
@ -604,7 +607,7 @@ class RefTest(object):
manifests = self.resolver.resolveManifests(options, tests)
if options.filter:
manifests[""] = options.filter
manifests[""] = (options.filter, None)
if not getattr(options, 'runTestsInParallel', False):
return self.runSerialTests(manifests, options, cmdargs)

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

@ -23,7 +23,7 @@ def parse(get_reftest, normalize):
def inner(*manifests):
assert len(manifests) > 0
manifests = {m: None for m in map(resolve, manifests)}
manifests = {m: (None, "id") for m in map(resolve, manifests)}
return reftest.getActiveTests(manifests, options)
return inner

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

@ -150,6 +150,7 @@ config = {
"--log-errorsummary=%(error_summary_file)s",
"--log-tbpl-level=%(log_tbpl_level)s",
"--deviceSerial=%(device_serial)s",
"--topsrcdir=tests",
],
"tests": ["tests/layout/reftests/reftest.list",],
},
@ -173,6 +174,7 @@ config = {
"--log-errorsummary=%(error_summary_file)s",
"--log-tbpl-level=%(log_tbpl_level)s",
"--deviceSerial=%(device_serial)s",
"--topsrcdir=tests",
],
"tests": ["tests/testing/crashtest/crashtests.list",],
},
@ -202,15 +204,16 @@ config = {
"--utility-path=%(utility_path)s", "--http-port=%(http_port)s",
"--ssl-port=%(ssl_port)s", "--httpd-path", "%(modules_dir)s",
"--symbols-path=%(symbols_path)s",
"--extra-profile-file=jsreftest/tests/user.js",
"--extra-profile-file=jsreftest/tests/js/src/tests/user.js",
"--suite=jstestbrowser",
"--log-raw=%(raw_log_file)s",
"--log-raw-level=%(log_raw_level)s",
"--log-errorsummary=%(error_summary_file)s",
"--log-tbpl-level=%(log_tbpl_level)s",
"--deviceSerial=%(device_serial)s",
"--topsrcdir=../jsreftest/tests",
],
"tests": ["../jsreftest/tests/jstests.list",],
"tests": ["../jsreftest/tests/js/src/tests/jstests.list",],
},
"xpcshell": {
"run_filename": "remotexpcshelltests.py",

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

@ -169,22 +169,26 @@ config = {
# local reftest suites
"all_reftest_suites": {
"crashtest": {
"options": ["--suite=crashtest"],
"options": ["--suite=crashtest",
"--topsrcdir=tests/reftest/tests"],
"tests": ["tests/reftest/tests/testing/crashtest/crashtests.list"]
},
"jsreftest": {
"options": ["--extra-profile-file=tests/jsreftest/tests/user.js",
"--suite=jstestbrowser"],
"tests": ["tests/jsreftest/tests/jstests.list"]
"options": ["--extra-profile-file=tests/jsreftest/tests/js/src/tests/user.js",
"--suite=jstestbrowser",
"--topsrcdir=tests/jsreftest/tests"],
"tests": ["tests/jsreftest/tests/js/src/tests/jstests.list"]
},
"reftest": {
"options": ["--suite=reftest",
"--setpref=layers.acceleration.force-enabled=true"],
"--setpref=layers.acceleration.force-enabled=true",
"--topsrcdir=tests/reftest/tests"],
"tests": ["tests/reftest/tests/layout/reftests/reftest.list"]
},
"reftest-no-accel": {
"options": ["--suite=reftest",
"--setpref=layers.acceleration.disabled=true"],
"--setpref=layers.acceleration.disabled=true",
"--topsrcdir=tests/reftest/tests"],
"tests": ["tests/reftest/tests/layout/reftests/reftest.list"]
},
},

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

@ -136,16 +136,19 @@ config = {
# local reftest suites
"all_reftest_suites": {
"crashtest": {
'options': ["--suite=crashtest"],
'options': ["--suite=crashtest",
"--topsrcdir=tests/reftest/tests"],
'tests': ["tests/reftest/tests/testing/crashtest/crashtests.list"]
},
"jsreftest": {
'options':["--extra-profile-file=tests/jsreftest/tests/user.js",
"--suite=jstestbrowser"],
'tests': ["tests/jsreftest/tests/jstests.list"]
'options':["--extra-profile-file=tests/jsreftest/tests/js/src/tests/user.js",
"--suite=jstestbrowser",
"--topsrcdir=tests/jsreftest/tests"],
'tests': ["tests/jsreftest/tests/js/src/tests/jstests.list"]
},
"reftest": {
'options': ["--suite=reftest"],
'options': ["--suite=reftest",
"--topsrcdir=tests/reftest/tests"],
'tests': ["tests/reftest/tests/layout/reftests/reftest.list"]
},
},

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

@ -158,26 +158,31 @@ config = {
# local reftest suites
"all_reftest_suites": {
"crashtest": {
'options': ["--suite=crashtest"],
'options': ["--suite=crashtest",
"--topsrcdir=tests/reftest/tests"],
'tests': ["tests/reftest/tests/testing/crashtest/crashtests.list"]
},
"jsreftest": {
'options':["--extra-profile-file=tests/jsreftest/tests/user.js",
"--suite=jstestbrowser"],
'tests': ["tests/jsreftest/tests/jstests.list"]
'options':["--extra-profile-file=tests/jsreftest/tests/js/src/tests/user.js",
"--suite=jstestbrowser",
"--topsrcdir=tests/jsreftest/tests"],
'tests': ["tests/jsreftest/tests/js/src/tests/jstests.list"]
},
"reftest": {
'options': ["--suite=reftest"],
'options': ["--suite=reftest",
"--topsrcdir=tests/reftest/tests"],
'tests': ["tests/reftest/tests/layout/reftests/reftest.list"]
},
"reftest-gpu": {
'options': ["--suite=reftest",
"--setpref=layers.gpu-process.force-enabled=true"],
"--setpref=layers.gpu-process.force-enabled=true",
"--topsrcdir=tests/reftest/tests"],
'tests': ["tests/reftest/tests/layout/reftests/reftest.list"]
},
"reftest-no-accel": {
"options": ["--suite=reftest",
"--setpref=layers.acceleration.disabled=true"],
"--setpref=layers.acceleration.disabled=true",
"--topsrcdir=tests/reftest/tests"],
"tests": ["tests/reftest/tests/layout/reftests/reftest.list"]
},
},