1#!/usr/bin/env python3
2# This Source Code Form is subject to the terms of the Mozilla Public
3# License, v. 2.0. If a copy of the MPL was not distributed with this
4# file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
6from __future__ import print_function
7
8import os
9import site
10import subprocess
11import argparse
12
13from glob import glob
14
15scriptdir = os.path.abspath(os.path.dirname(__file__))
16testdir = os.path.join(scriptdir, "t")
17
18site.addsitedir(testdir)
19from testlib import Test, equal
20
21parser = argparse.ArgumentParser(description="run hazard analysis tests")
22parser.add_argument(
23    "--js", default=os.environ.get("JS"), help="JS binary to run the tests with"
24)
25parser.add_argument(
26    "--sixgill",
27    default=os.environ.get("SIXGILL", os.path.join(testdir, "sixgill")),
28    help="Path to root of sixgill installation",
29)
30parser.add_argument(
31    "--sixgill-bin",
32    default=os.environ.get("SIXGILL_BIN"),
33    help="Path to sixgill binary dir",
34)
35parser.add_argument(
36    "--sixgill-plugin",
37    default=os.environ.get("SIXGILL_PLUGIN"),
38    help="Full path to sixgill gcc plugin",
39)
40parser.add_argument(
41    "--gccdir", default=os.environ.get("GCCDIR"), help="Path to GCC installation dir"
42)
43parser.add_argument("--cc", default=os.environ.get("CC"), help="Path to gcc")
44parser.add_argument("--cxx", default=os.environ.get("CXX"), help="Path to g++")
45parser.add_argument(
46    "--verbose",
47    "-v",
48    action="store_true",
49    help="Display verbose output, including commands executed",
50)
51parser.add_argument(
52    "tests",
53    nargs="*",
54    default=[
55        "sixgill-tree",
56        "suppression",
57        "hazards",
58        "exceptions",
59        "virtual",
60        "graph",
61    ],
62    help="tests to run",
63)
64
65cfg = parser.parse_args()
66
67if not cfg.js:
68    exit("Must specify JS binary through environment variable or --js option")
69if not cfg.cc:
70    if cfg.gccdir:
71        cfg.cc = os.path.join(cfg.gccdir, "bin", "gcc")
72    else:
73        cfg.cc = "gcc"
74if not cfg.cxx:
75    if cfg.gccdir:
76        cfg.cxx = os.path.join(cfg.gccdir, "bin", "g++")
77    else:
78        cfg.cxx = "g++"
79if not cfg.sixgill_bin:
80    cfg.sixgill_bin = os.path.join(cfg.sixgill, "usr", "bin")
81if not cfg.sixgill_plugin:
82    cfg.sixgill_plugin = os.path.join(
83        cfg.sixgill, "usr", "libexec", "sixgill", "gcc", "xgill.so"
84    )
85
86subprocess.check_call(
87    [cfg.js, "-e", 'if (!getBuildConfiguration()["has-ctypes"]) quit(1)']
88)
89
90
91def binpath(prog):
92    return os.path.join(cfg.sixgill_bin, prog)
93
94
95def make_dir(dirname, exist_ok=True):
96    try:
97        os.mkdir(dirname)
98    except OSError as e:
99        if exist_ok and e.strerror == "File exists":
100            pass
101        else:
102            raise
103
104
105outroot = os.path.join(testdir, "out")
106make_dir(outroot)
107
108os.environ["HAZARD_RUN_INTERNAL_TESTS"] = "1"
109
110failed = set()
111passed = set()
112for name in cfg.tests:
113    name = os.path.basename(name)
114    indir = os.path.join(testdir, name)
115    outdir = os.path.join(outroot, name)
116    make_dir(outdir)
117
118    test = Test(indir, outdir, cfg, verbose=cfg.verbose)
119
120    os.chdir(outdir)
121    for xdb in glob("*.xdb"):
122        os.unlink(xdb)
123    print("START TEST {}".format(name), flush=True)
124    testpath = os.path.join(indir, "test.py")
125    testscript = open(testpath).read()
126    testcode = compile(testscript, testpath, "exec")
127    try:
128        exec(testcode, {"test": test, "equal": equal})
129    except subprocess.CalledProcessError:
130        print("TEST-FAILED: %s" % name)
131        failed.add(name)
132    except AssertionError:
133        print("TEST-FAILED: %s" % name)
134        failed.add(name)
135        raise
136    else:
137        print("TEST-PASSED: %s" % name)
138        passed.add(name)
139
140if failed:
141    raise Exception("Failed tests: " + " ".join(failed))
142
143print(f"All {len(passed)} tests passed.")
144