测试模块初步完成
This commit is contained in:
1 parent
4ad3fbfca8
commit
d06546f6bf
13 files changed
+2162
No files matched your search
@@ -0,0 +1,188 @@
|
||||
"""
|
||||
micro_servers 黑盒测试 — 统一运行入口。
|
||||
|
||||
用法:
|
||||
python3 test_runner.py # 运行全部测试
|
||||
python3 test_runner.py --url http://127.0.0.1:8443 # 测试指定服务
|
||||
python3 test_runner.py --list # 列出可用测试
|
||||
python3 test_runner.py --service gateway # 按服务名运行
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import importlib
|
||||
import os
|
||||
import sys
|
||||
|
||||
# 确保当前目录在 path 中
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
from config import SERVICES, PORT_MAP, detect_service, get_url
|
||||
from helpers import check_service
|
||||
|
||||
TEST_MODULES = {
|
||||
"gateway": "test_gateway",
|
||||
"captcha": "test_captcha",
|
||||
"smtp": "test_smtp",
|
||||
"dnfs": "test_dnfs",
|
||||
"db": "test_db",
|
||||
"ai_review": "test_ai_review",
|
||||
"static": "test_static",
|
||||
"waf": "test_waf",
|
||||
}
|
||||
|
||||
|
||||
def run_service_test(name: str, url: str) -> tuple:
|
||||
"""运行单个服务的测试,返回 (passed, failed, skipped)。"""
|
||||
module_name = TEST_MODULES.get(name)
|
||||
if not module_name:
|
||||
print(f"未知服务: {name}")
|
||||
return 0, 0, 0
|
||||
|
||||
try:
|
||||
mod = importlib.import_module(module_name)
|
||||
except ImportError as e:
|
||||
print(f"无法加载测试模块 {module_name}: {e}")
|
||||
return 0, 0, 0
|
||||
|
||||
if not hasattr(mod, "run"):
|
||||
print(f"模块 {module_name} 缺少 run(url) 函数")
|
||||
return 0, 0, 0
|
||||
|
||||
svc = SERVICES[name]
|
||||
print(f"\n{'='*60}")
|
||||
print(f" {svc['description']} ({url})")
|
||||
print(f"{'='*60}")
|
||||
|
||||
reachable, detail = check_service(url)
|
||||
if not reachable:
|
||||
print(f" [WARN] 服务不可达: {url}")
|
||||
if detail:
|
||||
print(f" 原因: {detail}")
|
||||
print(f" 所有测试将被跳过。请先启动服务。\n")
|
||||
return 0, 0, 0
|
||||
|
||||
passed, failed, skipped = mod.run(url)
|
||||
return passed, failed, skipped
|
||||
|
||||
|
||||
def run_all():
|
||||
"""运行全部服务的测试。"""
|
||||
total_passed = 0
|
||||
total_failed = 0
|
||||
total_skipped = 0
|
||||
|
||||
for name in SERVICES:
|
||||
url = get_url(name)
|
||||
p, f, s = run_service_test(name, url)
|
||||
total_passed += p
|
||||
total_failed += f
|
||||
total_skipped += s
|
||||
|
||||
total = total_passed + total_failed + total_skipped
|
||||
print(f"\n{'='*60}")
|
||||
print(f" 全部测试完成: {total} total, "
|
||||
f"{total_passed} passed, {total_failed} failed, {total_skipped} skipped")
|
||||
print(f"{'='*60}")
|
||||
|
||||
return total_failed
|
||||
|
||||
|
||||
def run_by_url(url: str):
|
||||
"""以 URL 为入口,测试全部可代理服务,内部服务自动回退 localhost。
|
||||
|
||||
可代理服务 (通过 WAF→gateway 代理链): waf, gateway, static, dnfs
|
||||
内部服务 (仅 localhost 直连): db, ai_review, captcha, smtp
|
||||
"""
|
||||
from urllib.parse import urlparse
|
||||
|
||||
hostname = urlparse(url).hostname or ""
|
||||
is_remote = hostname not in ("127.0.0.1", "localhost", "::1")
|
||||
|
||||
if is_remote:
|
||||
print(f" 入口: {url}")
|
||||
print(f" 可代理服务 (waf/gateway/static/dnfs) 通过入口测试")
|
||||
print(f" 内部服务 (db/ai_review/captcha/smtp) 回退到 localhost")
|
||||
print()
|
||||
|
||||
# 可通过入口 URL 访问的服务
|
||||
proxyable = {"waf", "gateway", "static", "dnfs"}
|
||||
total_passed = 0
|
||||
total_failed = 0
|
||||
total_skipped = 0
|
||||
|
||||
for name in SERVICES:
|
||||
if name in proxyable:
|
||||
service_url = url
|
||||
else:
|
||||
service_url = get_url(name)
|
||||
|
||||
p, f, s = run_service_test(name, service_url)
|
||||
total_passed += p
|
||||
total_failed += f
|
||||
total_skipped += s
|
||||
|
||||
total = total_passed + total_failed + total_skipped
|
||||
print(f"\n{'='*60}")
|
||||
print(f" 全部测试完成: {total} total, "
|
||||
f"{total_passed} passed, {total_failed} failed, {total_skipped} skipped")
|
||||
print(f"{'='*60}")
|
||||
|
||||
return total_failed
|
||||
|
||||
|
||||
def run_by_name(name: str):
|
||||
"""按服务名运行测试。"""
|
||||
svc = SERVICES.get(name)
|
||||
if not svc:
|
||||
print(f"未知服务: {name}")
|
||||
print(f"可用服务: {', '.join(SERVICES.keys())}")
|
||||
return 1
|
||||
|
||||
url = get_url(name)
|
||||
p, f, s = run_service_test(name, url)
|
||||
return f
|
||||
|
||||
|
||||
def list_tests():
|
||||
"""列出所有可用测试。"""
|
||||
print("可用的黑盒测试:\n")
|
||||
for name, svc in SERVICES.items():
|
||||
print(f" {name:12s} 端口 {svc['port']:<5d} {svc['description']}")
|
||||
print()
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="micro_servers 黑盒用户模拟测试",
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
epilog="""
|
||||
示例:
|
||||
%(prog)s # 全部服务 localhost 测试
|
||||
%(prog)s --url https://qsont.me # 公网入口测试全部可代理服务
|
||||
%(prog)s --url http://127.0.0.1:8443 # 本地入口测试全部
|
||||
%(prog)s --service gateway # 仅测试指定服务
|
||||
%(prog)s --list # 列出可用测试
|
||||
""",
|
||||
)
|
||||
parser.add_argument("--url", help="入口 URL,通过它测试全部可代理服务(内部服务回退 localhost)")
|
||||
parser.add_argument("--service", help="按服务名称运行测试")
|
||||
parser.add_argument("--list", action="store_true", help="列出所有可用测试")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.list:
|
||||
list_tests()
|
||||
return 0
|
||||
|
||||
if args.url:
|
||||
return run_by_url(args.url)
|
||||
|
||||
if args.service:
|
||||
return run_by_name(args.service)
|
||||
|
||||
# 默认:运行全部
|
||||
return run_all()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in new issue
Block a user