refactor(db): 清理遗留死代码并对齐文档与测试
删除 dbv2 从未挂载的 log_module.py(Flask /log/* 遗留)与纯 TCP 服务 用不到的 security_middleware.py 副本;db/README.md 按 pymsg 实现重写, requirements 去掉 flask/waitress;黑盒测试对 pymsg 服务改用 TCP 探测, 修复 check_service HTTP 探测导致的 db 测试整体假 skip。
This commit is contained in:
1 parent
dabd892601
commit
6692c9c4ee
9 files changed
+130
-818
No files matched your search
@@ -31,6 +31,7 @@ SERVICES = {
|
||||
"name": "db",
|
||||
"host": "127.0.0.1",
|
||||
"port": 8005,
|
||||
"protocol": "pymsg",
|
||||
"description": "通用数据库服务 (CRUD+集中日志)",
|
||||
"test_file": "test_db.py",
|
||||
},
|
||||
|
||||
@@ -284,6 +284,21 @@ class PymsgClient:
|
||||
# 服务可用性检查
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def check_tcp_service(host: str, port: int, timeout: float = 5.0) -> tuple:
|
||||
"""检查纯 TCP 服务(如 pymsg 协议服务 db/captcha/smtp)是否可达。
|
||||
返回 (reachable: bool, detail: str)。
|
||||
"""
|
||||
try:
|
||||
with socket.create_connection((host, port), timeout=timeout):
|
||||
return True, "TCP 连接成功"
|
||||
except ConnectionRefusedError:
|
||||
return False, "连接被拒绝 (服务未启动或端口未监听)"
|
||||
except socket.timeout:
|
||||
return False, f"TCP 连接超时 ({timeout}s)"
|
||||
except OSError as e:
|
||||
return False, f"网络错误: {e}"
|
||||
|
||||
|
||||
def check_service(url: str, timeout: float = 8.0) -> tuple:
|
||||
"""检查服务是否可达(HTTP 请求检测,与测试实际行为一致)。
|
||||
返回 (reachable: bool, detail: str)。
|
||||
|
||||
+14
-92
@@ -1,45 +1,37 @@
|
||||
"""
|
||||
db 黑盒用户模拟测试 — 集中日志: 写入 → 查询 → 统计 → 清理。
|
||||
db 黑盒用户模拟测试 — pymsg 协议 CRUD。
|
||||
|
||||
用户旅程:
|
||||
1. 通过 pymsg 协议执行 CRUD (select/insert)
|
||||
2. 通过 HTTP /log/ingest 写入日志
|
||||
3. 通过 HTTP /log/query 查询日志
|
||||
4. 通过 HTTP /log/stats 查看统计
|
||||
5. 通过 HTTP /log/health 健康检查
|
||||
1. 通过 pymsg 协议查询 Users 表
|
||||
2. 通过 pymsg 协议查询 Logs 表
|
||||
3. 通过 pymsg 协议带 where 条件查询
|
||||
4. 无效路由被拒绝
|
||||
|
||||
注意: dbv2.py (pymsg 模式) 不挂载 Flask log_module Blueprint,
|
||||
因此 HTTP /log/* 路由可能不可用。测试会优雅降级。
|
||||
注意: dbv2.py 为纯 pymsg/TCP 服务(无 HTTP 接口),日志通过
|
||||
log_client.py 走 execute 路由 INSERT 写入 Logs 表。
|
||||
"""
|
||||
|
||||
import json
|
||||
import random
|
||||
import string
|
||||
import time
|
||||
|
||||
from helpers import (
|
||||
http_get, http_post, try_parse_json,
|
||||
assert_eq, assert_status, assert_true, assert_json_key,
|
||||
skip, Counter, check_service, PymsgClient,
|
||||
assert_true, skip, Counter, PymsgClient, check_tcp_service,
|
||||
)
|
||||
from config import get_url
|
||||
|
||||
DB_URL = get_url("db")
|
||||
DB_HOST = "127.0.0.1"
|
||||
DB_PORT = 8005
|
||||
|
||||
|
||||
def run(url: str = None):
|
||||
"""db 用户模拟测试入口。返回 (passed, failed, skipped)。"""
|
||||
du = url or DB_URL
|
||||
"""db 用户模拟测试入口。返回 (passed, failed, skipped)。
|
||||
|
||||
url 参数仅为保持与其他测试模块的签名一致,db 固定走 127.0.0.1:8005。
|
||||
"""
|
||||
c = Counter()
|
||||
|
||||
print(f"\n--- db 数据库与日志流程 ---\n")
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# 0. 检查服务可用性
|
||||
# 0. 检查服务可用性(TCP 直连,db 无 HTTP 接口)
|
||||
# ------------------------------------------------------------------
|
||||
if not check_service(du)[0]:
|
||||
if not check_tcp_service(DB_HOST, DB_PORT)[0]:
|
||||
skip("全部测试", "db 服务不可达", c)
|
||||
return c.passed, c.failed, c.skipped
|
||||
|
||||
@@ -109,76 +101,6 @@ def run(url: str = None):
|
||||
"pymsg-无效路由-拒绝", c,
|
||||
)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# 第二部分: HTTP /log/* 接口 (Flask log_module)
|
||||
# ------------------------------------------------------------------
|
||||
print("\n [HTTP /log/* 接口测试]")
|
||||
|
||||
# 检查 /log/health 是否可用(Flask log_module 是否挂载)
|
||||
status, body, _ = http_get(f"{du}/log/health")
|
||||
if status == 0 or status >= 500:
|
||||
skip("HTTP /log/* 测试", "log_module 未挂载 (dbv2 使用 pymsg 模式, 非 Flask)", c)
|
||||
else:
|
||||
# 场景 5: /log/health 健康检查
|
||||
assert_eq(status, 200, "log-健康检查 (200)", c)
|
||||
|
||||
# 场景 6: /log/ingest 写入日志
|
||||
test_ts = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
|
||||
status, body, _ = http_post(f"{du}/log/ingest", {
|
||||
"logs": [{
|
||||
"service": "dnfs",
|
||||
"level": "INFO",
|
||||
"message": f"blackbox_test_{random.randint(10000, 99999)}",
|
||||
"ts": test_ts,
|
||||
}],
|
||||
})
|
||||
data = try_parse_json(body)
|
||||
assert_true(
|
||||
status == 200 and data is not None and data.get("success") is True,
|
||||
"log-写入日志", c,
|
||||
f"status={status} body={body[:150]}",
|
||||
)
|
||||
|
||||
# 场景 7: /log/ingest — 空日志列表
|
||||
status, body, _ = http_post(f"{du}/log/ingest", {"logs": []})
|
||||
assert_eq(status, 200, "log-空日志列表 (200)", c)
|
||||
|
||||
# 场景 8: /log/ingest — 缺少 logs 字段
|
||||
status, body, _ = http_post(f"{du}/log/ingest", {})
|
||||
data = try_parse_json(body)
|
||||
assert_true(
|
||||
data is not None and not data.get("success", True),
|
||||
"log-缺少logs字段-拒绝", c,
|
||||
)
|
||||
|
||||
# 场景 9: /log/query 查询日志
|
||||
status, body, _ = http_post(f"{du}/log/query", {
|
||||
"limit": 5,
|
||||
"desc": True,
|
||||
})
|
||||
data = try_parse_json(body)
|
||||
assert_true(
|
||||
status == 200 and data is not None and data.get("success") is True,
|
||||
"log-查询日志", c,
|
||||
f"status={status}",
|
||||
)
|
||||
if data and data.get("success"):
|
||||
assert_true(
|
||||
"logs" in data.get("data", {}),
|
||||
"log-查询返回logs字段", c,
|
||||
)
|
||||
|
||||
# 场景 10: /log/stats 统计
|
||||
status, body, _ = http_post(f"{du}/log/stats", {
|
||||
"group_by": "service",
|
||||
})
|
||||
data = try_parse_json(body)
|
||||
assert_true(
|
||||
status == 200 and data is not None,
|
||||
"log-统计", c,
|
||||
f"status={status}",
|
||||
)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# 汇总
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
@@ -17,7 +17,7 @@ import sys
|
||||
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
|
||||
from helpers import check_service, check_tcp_service
|
||||
|
||||
TEST_MODULES = {
|
||||
"gateway": "test_gateway",
|
||||
@@ -53,7 +53,11 @@ def run_service_test(name: str, url: str) -> tuple:
|
||||
print(f" {svc['description']} ({url})")
|
||||
print(f"{'='*60}")
|
||||
|
||||
reachable, detail = check_service(url)
|
||||
# pymsg/TCP 服务无 HTTP 接口,用 TCP 直连探测
|
||||
if svc.get("protocol") == "pymsg":
|
||||
reachable, detail = check_tcp_service(svc["host"], svc["port"])
|
||||
else:
|
||||
reachable, detail = check_service(url)
|
||||
if not reachable:
|
||||
print(f" [WARN] 服务不可达: {url}")
|
||||
if detail:
|
||||
|
||||
Reference in new issue
Block a user