Bug 1531202 - Part 1: Don't prepend reftest entries in test262 'raw' tests. r=jwalden

- Add separate function to import fixture files instead of treating them like
  test files. This simplifies the code structure a bit and avoids unnecessary
  output spew, because the test262 test record parser no longer complains about
  missing yaml frontmatter.
- Write reftest terms into a new test262/jstests.list file for raw tests.
- Allow including nested jstests.list files in _parse_external_manifest.

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
André Bargull 2019-03-07 14:42:25 +00:00
parent a4f6ccbced
commit 2c8853ce51
5 changed files with 108 additions and 35 deletions

View File

@ -58,9 +58,12 @@ Adjusting when and how a test runs
used). Only the following two forms are supported:
<failure-type> include <relative_path>
<failure-type> script <relative_path>
include <relative_path>
The <type> "include" indicates that <failure-type> should apply to all test
cases within a directory. A statement for a nested directory or script
overrides one for an enclosing directory.
overrides one for an enclosing directory. The <type> "include" without a
<failure-type> recursively loads another jstests.list file for further
processing.
Running tests
-------------

View File

@ -22,6 +22,13 @@ skip script non262/fields/quirks.js
skip script non262/reflect-parse/class-fields.js
###########################################################################
# Generated jstests.list for test262 when inline |reftest| isn't possible #
###########################################################################
include test262/jstests.list
#################################################################
# Tests disabled due to intentional alternative implementations #
#################################################################

View File

@ -331,7 +331,8 @@ def _parse_external_manifest(filename, relpath):
entries = []
with open(filename, 'r') as fp:
manifest_re = re.compile(r'^\s*(.*)\s+(include|script)\s+(\S+)$')
manifest_re = re.compile(r'^\s*(?P<terms>.*)\s+(?P<type>include|script)\s+(?P<path>\S+)$')
include_re = re.compile(r'^\s*include\s+(?P<path>\S+)$')
for line in fp:
line, _, comment = line.partition('#')
line = line.strip()
@ -339,12 +340,21 @@ def _parse_external_manifest(filename, relpath):
continue
matches = manifest_re.match(line)
if not matches:
print('warning: unrecognized line in jstests.list:'
' {0}'.format(line))
matches = include_re.match(line)
if not matches:
print('warning: unrecognized line in jstests.list:'
' {0}'.format(line))
continue
include_file = matches.group('path')
include_filename = os.path.join(os.path.dirname(filename), include_file)
include_relpath = os.path.join(relpath, os.path.dirname(include_file))
include_entries = _parse_external_manifest(include_filename, include_relpath)
entries.extend(include_entries)
continue
path = os.path.normpath(os.path.join(relpath, matches.group(3)))
if matches.group(2) == 'include':
path = os.path.normpath(os.path.join(relpath, matches.group('path')))
if matches.group('type') == 'include':
# The manifest spec wants a reference to another manifest here,
# but we need just the directory. We do need the trailing
# separator so we don't accidentally match other paths of which
@ -352,7 +362,7 @@ def _parse_external_manifest(filename, relpath):
assert(path.endswith('jstests.list'))
path = path[:-len('jstests.list')]
entries.append({'path': path, 'terms': matches.group(1),
entries.append({'path': path, 'terms': matches.group('terms'),
'comment': comment.strip()})
# if one directory name is a prefix of another, we want the shorter one

View File

@ -16,6 +16,7 @@ import sys
from functools import partial
from itertools import chain
from operator import itemgetter
# Skip all tests which use features not supported in SpiderMonkey.
UNSUPPORTED_FEATURES = set([
@ -91,8 +92,8 @@ def tryParseTestFile(test262parser, source, testName):
def createRefTestEntry(skip, skipIf, error, isModule):
"""
Creates the |reftest| entry from the input list. Or the empty string if no
reftest entry is required.
Returns the |reftest| tuple (terms, comments) from the input arguments. Or a
tuple of empty strings if no reftest entry is required.
"""
terms = []
@ -112,11 +113,18 @@ def createRefTestEntry(skip, skipIf, error, isModule):
if isModule:
terms.append("module")
line = " ".join(terms)
if comments:
line += " -- " + ", ".join(comments)
return (" ".join(terms), ", ".join(comments))
return line
def createRefTestLine(terms, comments):
"""
Creates the |reftest| line using the given terms and comments.
"""
refTest = terms
if comments:
refTest += " -- " + comments
return refTest
def createSource(testSource, refTest, prologue, epilogue):
@ -201,7 +209,7 @@ def writeShellAndBrowserFiles(test262OutDir, harnessDir, includesMap, localInclu
# Write the concatenated include sources to shell.js.
with io.open(os.path.join(test262OutDir, relPath, "shell.js"), "wb") as shellFile:
if includeSource:
shellFile.write("// GENERATED, DO NOT EDIT\n")
shellFile.write(b"// GENERATED, DO NOT EDIT\n")
shellFile.write(includeSource)
# The browser.js file is always empty for test262 tests.
@ -214,10 +222,6 @@ def pathStartsWith(path, *args):
return os.path.commonprefix([path, prefix]) == prefix
def fileNameEndsWith(filePath, suffix):
return os.path.splitext(os.path.basename(filePath))[0].endswith(suffix)
def convertTestFile(test262parser, testSource, testName, includeSet, strictTests):
"""
Convert a test262 test to a compatible jstests test file.
@ -273,11 +277,6 @@ def convertTestFile(test262parser, testSource, testName, includeSet, strictTests
if "CanBlockIsTrue" in testRec:
refTestSkipIf.append(("!xulRuntime.shell", "browser cannot block main thread"))
# Skip non-test files.
isSupportFile = fileNameEndsWith(testName, "FIXTURE")
if isSupportFile:
refTestSkip.append("not a test file")
# Skip tests with unsupported features.
if "features" in testRec:
unsupported = [f for f in testRec["features"] if f in UNSUPPORTED_FEATURES]
@ -309,15 +308,21 @@ def convertTestFile(test262parser, testSource, testName, includeSet, strictTests
includeSet.update(testRec["includes"])
# Add reportCompare() after all positive, synchronous tests.
if not isNegative and not async and not isSupportFile:
if not isNegative and not async:
testEpilogue = "reportCompare(0, 0);"
else:
testEpilogue = ""
refTest = createRefTestEntry(refTestSkip, refTestSkipIf, errorType, isModule)
(terms, comments) = createRefTestEntry(refTestSkip, refTestSkipIf, errorType, isModule)
if raw:
refTest = ""
externRefTest = (terms, comments)
else:
refTest = createRefTestLine(terms, comments)
externRefTest = None
# Don't write a strict-mode variant for raw, module or support files.
noStrictVariant = raw or isModule or isSupportFile
# Don't write a strict-mode variant for raw or module files.
noStrictVariant = raw or isModule
assert not (noStrictVariant and (onlyStrict or noStrict)),\
"Unexpected onlyStrict or noStrict attribute: %s" % testName
@ -326,7 +331,7 @@ def convertTestFile(test262parser, testSource, testName, includeSet, strictTests
testPrologue = ""
nonStrictSource = createSource(testSource, refTest, testPrologue, testEpilogue)
testFileName = testName
yield (testFileName, nonStrictSource)
yield (testFileName, nonStrictSource, externRefTest)
# Write strict mode test.
if not noStrictVariant and (onlyStrict or (not noStrict and strictTests)):
@ -335,10 +340,29 @@ def convertTestFile(test262parser, testSource, testName, includeSet, strictTests
testFileName = testName
if not noStrict:
testFileName = addSuffixToFileName(testFileName, "-strict")
yield (testFileName, strictSource)
yield (testFileName, strictSource, externRefTest)
def process_test262(test262Dir, test262OutDir, strictTests):
def convertFixtureFile(fixtureSource, fixtureName):
"""
Convert a test262 fixture file to a compatible jstests test file.
"""
# jsreftest meta data
refTestSkip = ["not a test file"]
refTestSkipIf = []
errorType = None
isModule = False
(terms, comments) = createRefTestEntry(refTestSkip, refTestSkipIf, errorType, isModule)
refTest = createRefTestLine(terms, comments)
source = createSource(fixtureSource, refTest, "", "")
externRefTest = None
yield (fixtureName, source, externRefTest)
def process_test262(test262Dir, test262OutDir, strictTests, externManifests):
"""
Process all test262 files and converts them into jstests compatible tests.
"""
@ -407,14 +431,29 @@ def process_test262(test262Dir, test262OutDir, strictTests):
shutil.copyfile(filePath, os.path.join(test262OutDir, testName))
continue
# Files ending with "_FIXTURE.js" are fixture files:
# https://github.com/tc39/test262/blob/master/INTERPRETING.md#modules
isFixtureFile = fileName.endswith("_FIXTURE.js")
# Read the original test source and preprocess it for the jstests harness.
with io.open(filePath, "rb") as testFile:
testSource = testFile.read()
for (newFileName, newSource) in convertTestFile(test262parser, testSource, testName,
includeSet, strictTests):
if isFixtureFile:
convert = convertFixtureFile(testSource, testName)
else:
convert = convertTestFile(test262parser, testSource, testName,
includeSet, strictTests)
for (newFileName, newSource, externRefTest) in convert:
writeTestFile(test262OutDir, newFileName, newSource)
if externRefTest is not None:
externManifests.append({
"name": newFileName,
"reftest": externRefTest,
})
# Add shell.js and browers.js files for the current directory.
writeShellAndBrowserFiles(test262OutDir, harnessDir,
includesMap, localIncludesMap, relPath)
@ -506,7 +545,7 @@ def fetch_local_changes(inDir, outDir, srcDir, strictTests):
shutil.rmtree(outDir)
os.makedirs(outDir)
process_test262(inDir, outDir, strictTests)
process_test262(inDir, outDir, strictTests, [])
def fetch_pr_files(inDir, outDir, prNumber, strictTests):
@ -560,7 +599,7 @@ def fetch_pr_files(inDir, outDir, prNumber, strictTests):
with io.open(os.path.join(inDir, *filename.split("/")), "wb") as output_file:
output_file.write(fileText.encode('utf8'))
process_test262(inDir, prTestsOutDir, strictTests)
process_test262(inDir, prTestsOutDir, strictTests, [])
def general_update(inDir, outDir, strictTests):
@ -595,7 +634,21 @@ def general_update(inDir, outDir, strictTests):
subprocess.check_call(["git", "-C", inDir, "log", "-1"], stdout=info)
# Copy the test files.
process_test262(inDir, outDir, strictTests)
externManifests = []
process_test262(inDir, outDir, strictTests, externManifests)
# Create the external reftest manifest file.
with io.open(os.path.join(outDir, "jstests.list"), "wb") as manifestFile:
manifestFile.write(b"# GENERATED, DO NOT EDIT\n\n")
for externManifest in sorted(externManifests, key=itemgetter("name")):
(terms, comments) = externManifest["reftest"]
if terms:
entry = "%s script %s%s\n" % (
terms,
externManifest["name"],
(" # %s" % comments) if comments else ""
)
manifestFile.write(entry.encode("utf-8"))
# Move test262/local back.
if restoreLocalTestsDir:

View File