Source code

Revision control

Copy as Markdown

Other Tools

#!/usr/bin/env python3
# This Source Code Form is subject to the terms of the Mozilla Public
# 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/.
import argparse
import os
import site
import subprocess
import sys
from glob import glob
scriptdir = os.path.abspath(os.path.dirname(__file__))
testdir = os.path.join(scriptdir, "t")
site.addsitedir(testdir)
from testlib import Test, equal
parser = argparse.ArgumentParser(description="run hazard analysis tests")
parser.add_argument(
"--js", default=os.environ.get("JS"), help="JS binary to run the tests with"
)
parser.add_argument(
"--sixgill",
default=os.environ.get("SIXGILL", os.path.join(testdir, "sixgill")),
help="Path to root of sixgill installation",
)
parser.add_argument(
"--sixgill-bin",
default=os.environ.get("SIXGILL_BIN"),
help="Path to sixgill binary dir",
)
parser.add_argument(
"--sixgill-plugin",
default=os.environ.get("SIXGILL_PLUGIN"),
help="Full path to sixgill gcc plugin",
)
parser.add_argument(
"--gccdir", default=os.environ.get("GCCDIR"), help="Path to GCC installation dir"
)
parser.add_argument("--cc", default=os.environ.get("CC"), help="Path to gcc")
parser.add_argument("--cxx", default=os.environ.get("CXX"), help="Path to g++")
parser.add_argument(
"--verbose",
"-v",
default=0,
action="count",
help="Display verbose output, including commands executed",
)
ALL_TESTS = [
"sixgill-tree",
"suppression",
"hazards",
"exceptions",
"virtual",
"graph",
"types",
]
parser.add_argument(
"tests",
nargs="*",
default=ALL_TESTS,
help="tests to run",
)
cfg = parser.parse_args()
if not cfg.js:
sys.exit("Must specify JS binary through environment variable or --js option")
if not cfg.cc:
if cfg.gccdir:
cfg.cc = os.path.join(cfg.gccdir, "bin", "gcc")
else:
cfg.cc = "gcc"
if not cfg.cxx:
if cfg.gccdir:
cfg.cxx = os.path.join(cfg.gccdir, "bin", "g++")
else:
cfg.cxx = "g++"
if not cfg.sixgill_bin:
cfg.sixgill_bin = os.path.join(cfg.sixgill, "usr", "bin")
if not cfg.sixgill_plugin:
cfg.sixgill_plugin = os.path.join(
cfg.sixgill, "usr", "libexec", "sixgill", "gcc", "xgill.so"
)
subprocess.check_call(
[cfg.js, "-e", 'if (!getBuildConfiguration("has-ctypes")) quit(1)']
)
def binpath(prog):
return os.path.join(cfg.sixgill_bin, prog)
def make_dir(dirname, exist_ok=True):
try:
os.mkdir(dirname)
except OSError as e:
if exist_ok and e.strerror == "File exists":
pass
else:
raise
outroot = os.path.join(testdir, "out")
make_dir(outroot)
os.environ["HAZARD_RUN_INTERNAL_TESTS"] = "1"
exclude = []
tests = []
for t in cfg.tests:
if t.startswith("!"):
exclude.append(t[1:])
else:
tests.append(t)
if len(tests) == 0:
tests = filter(lambda t: t not in exclude, ALL_TESTS)
failed = set()
passed = set()
for path in tests:
name = os.path.basename(path)
indir = os.path.join(testdir, name)
outdir = os.path.join(outroot, name)
make_dir(outdir)
test = Test(indir, outdir, cfg, verbose=cfg.verbose)
os.chdir(outdir)
for xdb in glob("*.xdb"):
os.unlink(xdb)
print("START TEST {}".format(name), flush=True)
testpath = os.path.join(indir, "test.py")
testscript = open(testpath).read()
testcode = compile(testscript, testpath, "exec")
try:
exec(testcode, {"test": test, "equal": equal})
except subprocess.CalledProcessError:
print("TEST-FAILED: %s" % name)
failed.add(name)
except AssertionError:
print("TEST-FAILED: %s" % name)
failed.add(name)
raise
else:
print("TEST-PASSED: %s" % name)
passed.add(name)
if failed:
raise Exception("Failed tests: " + " ".join(failed))
print(f"All {len(passed)} tests passed.")