mirror of
https://github.com/3proxy/3proxy.git
synced 2026-08-26 09:55:48 +08:00
142 lines
4.8 KiB
Python
142 lines
4.8 KiB
Python
#!/usr/bin/env python3
|
|
"""Run the 3proxy regression tests.
|
|
|
|
python3 tests/run.py every case
|
|
python3 tests/run.py httpsrv cases whose name matches
|
|
python3 tests/run.py --bin build/bin/3proxy
|
|
python3 tests/run.py --keep leave the temporary files behind
|
|
|
|
Each case under tests/cases/ defines the configurations it needs and the
|
|
positive and negative scenarios expected from them.
|
|
"""
|
|
|
|
import argparse
|
|
import importlib.util
|
|
import os
|
|
import shutil
|
|
import sys
|
|
import tempfile
|
|
import traceback
|
|
|
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|
|
|
from harness import Failure, Tester # noqa: E402
|
|
|
|
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
|
|
|
|
def default_binary():
|
|
"""Find a built 3proxy: the Makefiles put it in bin/, CMake in build/bin/,
|
|
and multi-configuration generators one level below that again."""
|
|
name = "3proxy.exe" if os.name == "nt" else "3proxy"
|
|
candidates = [os.path.join(ROOT, "bin", name),
|
|
os.path.join(ROOT, "build", "bin", name)]
|
|
for config in ("Release", "Debug", "RelWithDebInfo", "MinSizeRel"):
|
|
candidates.append(os.path.join(ROOT, "build", "bin", config, name))
|
|
for candidate in candidates:
|
|
if os.path.isfile(candidate):
|
|
return candidate
|
|
return candidates[0]
|
|
|
|
|
|
def load_case(path):
|
|
name = os.path.splitext(os.path.basename(path))[0]
|
|
spec = importlib.util.spec_from_file_location("case_" + name, path)
|
|
module = importlib.util.module_from_spec(spec)
|
|
spec.loader.exec_module(module)
|
|
return name, module
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("pattern", nargs="?", default="",
|
|
help="only run cases whose name contains this")
|
|
parser.add_argument("--bin", dest="binary", default=None,
|
|
help="the 3proxy binary to test")
|
|
parser.add_argument("--keep", action="store_true",
|
|
help="keep the temporary directory")
|
|
parser.add_argument("-v", "--verbose", action="store_true",
|
|
help="print every check, not just the failures")
|
|
args = parser.parse_args()
|
|
|
|
binary = args.binary or os.environ.get("BIN") or default_binary()
|
|
binary = os.path.abspath(binary)
|
|
if not os.path.isfile(binary):
|
|
print(f"no 3proxy binary at {binary} (build first, or pass --bin)",
|
|
file=sys.stderr)
|
|
return 2
|
|
|
|
case_dir = os.path.join(ROOT, "tests", "cases")
|
|
paths = sorted(os.path.join(case_dir, f) for f in os.listdir(case_dir)
|
|
if f.endswith(".py") and not f.startswith("_"))
|
|
paths = [p for p in paths if args.pattern in os.path.basename(p)]
|
|
if not paths:
|
|
print(f"no cases matched {args.pattern!r}", file=sys.stderr)
|
|
return 2
|
|
|
|
tmpdir = tempfile.mkdtemp(prefix="3proxy-tests.")
|
|
print(f"3proxy tests: {binary}")
|
|
print(f"working in: {tmpdir}\n")
|
|
|
|
passed = failed = skipped = 0
|
|
failures = []
|
|
|
|
try:
|
|
for path in paths:
|
|
name, module = load_case(path)
|
|
print(f" {name}")
|
|
tester = Tester(binary, tmpdir, name)
|
|
error = None
|
|
try:
|
|
module.run(tester)
|
|
except Failure as exc:
|
|
error = str(exc)
|
|
except Exception:
|
|
error = traceback.format_exc()
|
|
finally:
|
|
tester.stop_all()
|
|
|
|
for status, label, expected, actual in tester.checks:
|
|
if status is None:
|
|
skipped += 1
|
|
print(f" skip {label}")
|
|
elif status:
|
|
passed += 1
|
|
if args.verbose:
|
|
print(f" ok {label}")
|
|
else:
|
|
failed += 1
|
|
failures.append(f"{name}: {label}")
|
|
print(f" FAIL {label}")
|
|
if expected is not None:
|
|
print(f" expected: {expected}")
|
|
if actual is not None:
|
|
print(f" actual: {actual}")
|
|
|
|
if error:
|
|
failed += 1
|
|
failures.append(f"{name}: case aborted")
|
|
print(" ERROR the case could not finish:")
|
|
for line in error.rstrip().splitlines():
|
|
print(f" {line}")
|
|
print()
|
|
finally:
|
|
if args.keep:
|
|
print(f"temporary files left in {tmpdir}")
|
|
else:
|
|
shutil.rmtree(tmpdir, ignore_errors=True)
|
|
|
|
print("-" * 41)
|
|
total = passed + failed
|
|
summary = f"cases: {len(paths)} checks: {total} passed: {passed} failed: {failed}"
|
|
if skipped:
|
|
summary += f" skipped: {skipped}"
|
|
print(summary)
|
|
for item in failures:
|
|
print(f" FAIL {item}")
|
|
return 1 if failed else 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|