path = None for dir in dirs:
_path = posixpath.join(dir, "config", "autoconf.mk") if os.path.isfile(_path):
path = _path break
if path isNone:
print( "Can't find config/autoconf.mk on a directory containing" " the JS shell (searched from {})".format(jsdir)
)
sys.exit(1)
# Read the values.
val_re = re.compile(r"(TARGET_XPCOM_ABI|OS_TARGET|MOZ_DEBUG)\s*=\s*(.*)")
kw = {"isdebug": False} for line in io.open(path, encoding="utf-8"):
m = val_re.match(line) if m:
key, val = m.groups()
val = val.rstrip() if key == "TARGET_XPCOM_ABI":
kw["abi"] = val if key == "OS_TARGET":
kw["os"] = val if key == "MOZ_DEBUG":
kw["isdebug"] = val == "1" return cls(**kw)
class XULInfoTester: def __init__(self, xulinfo, options, js_args):
self.js_prologue = xulinfo.as_js()
self.js_bin = options.js_shell
self.js_args = js_args # options here are the command line options
self.options = options # Maps JS expr to evaluation result.
self.cache = {}
cmd = (
[self.js_bin]
+ self.js_args
+ options
+ [ # run in safe configuration, since it is hard to debug # crashes when running code here. In particular, msan will # error out if the jit is active. "--no-baseline", "--no-blinterp", "-e",
self.js_prologue, "-e", "print(!!({}))".format(cond),
]
)
cmd = ADBDevice._escape_command_line(cmd) try: # Allow ADBError or ADBTimeoutError to terminate the test run, # but handle ADBProcessError in order to support the use of # non-zero exit codes in the JavaScript shell tests.
out = self.device.shell_output(
cmd, env=env, cwd=self.options.remote_test_root, timeout=None
)
err = "" except ADBProcessError as e:
out = ""
err = str(e.adb_process.stdout)
if out == "true":
ans = True elif out == "false":
ans = False else: raise Exception( "Failed to test XUL condition {!r};" " output was {!r}, stderr was {!r}".format(cond, out, err)
)
self.cache[cond] = ans return ans
def _test_local(self, cond, options=[]): """Test a XUL predicate condition against this local info."""
ans = self.cache.get(cond, None) if ans isNone:
cmd = (
[self.js_bin]
+ self.js_args
+ options
+ [ # run in safe configuration, since it is hard to debug # crashes when running code here. In particular, msan will # error out if the jit is active. "--no-baseline", "--no-blinterp", "-e",
self.js_prologue, "-e", "print(!!({}))".format(cond),
]
)
p = Popen(
cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE, universal_newlines=True
)
out, err = p.communicate() if out in ("true\n", "true\r\n"):
ans = True elif out in ("false\n", "false\r\n"):
ans = False else: raise Exception( "Failed to test XUL condition {!r};" " output was {!r}, stderr was {!r}".format(cond, out, err)
)
self.cache[cond] = ans return ans
class NullXULInfoTester: """Can be used to parse manifests without a JS shell."""
def test(self, cond, options=[]): returnFalse
def _parse_one(testcase, terms, xul_tester):
pos = 0
parts = terms.split() while pos < len(parts): if parts[pos] == "fails":
testcase.expect = False
pos += 1 elif parts[pos] == "skip":
testcase.expect = testcase.enable = False
pos += 1 elif parts[pos] == "random":
testcase.random = True
pos += 1 elif parts[pos].startswith("shell-option("): # This directive adds an extra option to pass to the shell.
option = parts[pos][len("shell-option(") : -1]
testcase.options.append(option)
pos += 1 elif parts[pos].startswith("fails-if"):
cond = parts[pos][len("fails-if(") : -1] if xul_tester.test(cond, testcase.options):
testcase.expect = False
pos += 1 elif parts[pos].startswith("asserts-if"): # This directive means we may flunk some number of # NS_ASSERTIONs in the browser. For the shell, ignore it.
pos += 1 elif parts[pos].startswith("skip-if"):
cond = parts[pos][len("skip-if(") : -1] if xul_tester.test(cond, testcase.options):
testcase.expect = testcase.enable = False
pos += 1 elif parts[pos].startswith("ignore-flag"):
flag = parts[pos][len("ignore-flag(") : -1]
testcase.ignoredflags.append(flag)
pos += 1 elif parts[pos].startswith("random-if"):
cond = parts[pos][len("random-if(") : -1] if xul_tester.test(cond, testcase.options):
testcase.random = True
pos += 1 elif parts[pos] == "slow":
testcase.slow = True
pos += 1 elif parts[pos].startswith("slow-if"):
cond = parts[pos][len("slow-if(") : -1] if xul_tester.test(cond, testcase.options):
testcase.slow = True
pos += 1 elif parts[pos] == "silentfail": # silentfails use tons of memory, and Darwin doesn't support ulimit. if xul_tester.test("cocoaWidget", testcase.options):
testcase.expect = testcase.enable = False
pos += 1 elif parts[pos].startswith("error:"): # This directive allows to specify an error type.
(_, _, errortype) = parts[pos].partition(":")
testcase.error = errortype
pos += 1 elif parts[pos] == "module": # This directive marks the test as module code.
testcase.is_module = True
pos += 1 elif parts[pos] == "test262-raw":
testcase.is_test262_raw = True
pos += 1 elif parts[pos] == "async": # This directive marks the test as async.
testcase.is_async = True
pos += 1 else:
print('warning: invalid manifest line element "{}"'.format(parts[pos]))
pos += 1
def _build_manifest_script_entry(script_name, test):
line = []
properties = [] if test.terms: # Remove jsreftest internal terms.
terms = " ".join(
[
term for term in test.terms.split() ifnot (
term == "module" or term == "async" or term.startswith("error:") or term.startswith("ignore-flag(") or term.startswith("shell-option(") or term == "test262-raw"
)
]
) if terms:
line.append(terms) if test.error:
properties.append("error=" + test.error) if test.is_module:
properties.append("module") if test.is_async:
properties.append("async") if test.is_test262_raw:
properties.append("test262_raw")
line.append("script")
script = script_name if properties:
script = ";".join([script] + properties)
line.append(script) if test.comment:
line.append("#")
line.append(test.comment) return" ".join(line)
def _map_prefixes_left(test_gen): """
Splits tests into a dictionary keyed on the first component of the test
path, aggregating tests with a common base path into a list. """
byprefix = {} for t in test_gen:
left, sep, remainder = t.path.partition(os.sep) if left notin byprefix:
byprefix[left] = [] if remainder:
t.path = remainder
byprefix[left].append(t) return byprefix
def _emit_manifest_at(location, relative, test_gen, depth): """
location - str: absolute path where we want to write the manifest
relative - str: relative path from topmost manifest directory to current
test_gen - (str): generator of all test paths and directorys
depth - int: number of dirs we are below the topmost manifest dir """
manifests = _map_prefixes_left(test_gen)
# Always present our manifest in sorted order.
manifest.sort()
# If we have tests, we have to set the url-prefix so reftest can find them. if numTestFiles > 0:
manifest = [ "url-prefix {}jsreftest.html?test={}/".format("../" * depth, relative)
] + manifest
def _find_all_js_files(location): for root, dirs, files in os.walk(location):
root = root[len(location) + 1 :] for fn in files: if fn.endswith(".js"): yield root, fn
# The pattern for test header lines.
TEST_HEADER_PATTERN = r""" # Ignore any space before the tag.
\s*
# The reftest tag is enclosed in pipes.
\|(?P<tag>.*?)\|
# Ignore any space before the options.
\s*
# Accept some options.
(?P<options>.*?)
# Ignore space before the comments.
\s*
# Accept an optional comment starting with "--".
(?: # Unless "--" is directly preceded by "(".
(?<!\()
--
# Ignore more space.
\s*
# The actual comment.
(?P<comment>.*)
)? """
TEST_HEADER_PATTERN_INLINE = re.compile(
r""" # Start a single line comment
// """
+ TEST_HEADER_PATTERN
+ r""" # Match the end of line.
$ """,
re.VERBOSE,
)
TEST_HEADER_PATTERN_MULTI = re.compile(
r""" # Start a multi line comment
/\* """
+ TEST_HEADER_PATTERN
+ r""" # Match the end of comment.
\*/ """,
re.VERBOSE,
)
def _parse_test_header(fullpath, testcase, xul_tester): """
This looks a bit weird. The reason is that it needs to be efficient, since
it has to be done on every test """ if six.PY3:
fp = open(fullpath, encoding="utf-8") else:
fp = open(fullpath) try:
buf = fp.read(512) finally:
fp.close()
# Bail early if we do not start with a single comment. ifnot buf.startswith("//"): return
def _parse_external_manifest(filename, relpath): """
Reads an external manifest file for test suites whose individual test cases
can't be decorated with reftest comments.
filename - str: name of the manifest file
relpath - str: relative path of the directory containing the manifest
within the test suite """ ifnot os.path.exists(filename): return []
entries = []
with io.open(filename, "r", encoding="utf-8") as fp:
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() ifnot line: continue
matches = manifest_re.match(line) ifnot matches:
matches = include_re.match(line) ifnot matches:
print( "warning: unrecognized line in jstests.list:" " {0}".format(line)
) continue
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 # this one is a prefix. assert path.endswith("jstests.list")
path = path[: -len("jstests.list")]
# if one directory name is a prefix of another, we want the shorter one # first
entries.sort(key=lambda x: x["path"]) return entries
def _apply_external_manifests(filename, testcase, entries, xul_tester): for entry in entries: if filename.startswith(entry["path"]): # The reftest spec would require combining the terms (failure types) # that may already be defined in the test case with the terms # specified in entry; for example, a skip overrides a random, which # overrides a fails. Since we don't necessarily know yet in which # environment the test cases will be run, we'd also have to # consider skip-if, random-if, and fails-if with as-yet unresolved # conditions. # At this point, we use external manifests only for test cases # that can't have their own failure type comments, so we simply # use the terms for the most specific path.
_append_terms_and_comment(testcase, entry["terms"], entry["comment"])
_parse_one(testcase, entry["terms"], xul_tester)
def _is_test_file(path_from_root, basename, filename, path_options): # Any file whose basename matches something in this set is ignored.
EXCLUDED = set(
( "browser.js", "shell.js", "template.js", "user.js", "js-test-driver-begin.js", "js-test-driver-end.js",
)
)
# Skip js files in the root test directory. ifnot path_from_root: returnFalse
# Skip files that we know are not tests. if basename in EXCLUDED: returnFalse
def count_tests(location, path_options):
count = 0 for root, basename in _find_all_js_files(location):
filename = os.path.join(root, basename) if _is_test_file(root, basename, filename, path_options):
count += 1 return count
def load_reftests(location, path_options, xul_tester): """
Locates all tests by walking the filesystem starting at |location|.
Uses xul_tester to evaluate any test conditions in the test header.
Failure type and comment for a test case can come from
- an external manifest entry for the test case,
- an external manifest entry for a containing directory,
- most commonly: the header of the test case itself. """
manifestFile = os.path.join(location, "jstests.list")
externalManifestEntries = _parse_external_manifest(manifestFile, "")
for root, basename in _find_all_js_files(location): # Get the full path and relative location of the file.
filename = os.path.join(root, basename) ifnot _is_test_file(root, basename, filename, path_options): continue
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.