Files
chongming-core/test/verify_example_plugin.py
T

111 lines
4.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""验证 example 插件 global_var.py / __init__.py 改造效果"""
import sys
from pathlib import Path
SRC = Path(__file__).resolve().parent.parent / "src" # 仓库 src/(plugins 包源码所在)
sys.path.insert(0, str(SRC))
failures = []
def check(name, cond, detail=""):
status = "PASS" if cond else "FAIL"
print(f"[{status}] {name}" + (f" — {detail}" if detail else ""))
if not cond:
failures.append(name)
# ========== 1. global_var 白名单 / require / __all__ ==========
from plugins.example import global_var as gv # noqa: E402
check("global_var.__all__ 包含 db", "db" in gv.__all__)
check("global_var.__all__ 包含 set_global_var", "set_global_var" in gv.__all__)
check("global_var.__all__ 包含 require", "require" in gv.__all__)
check("global_var 不再污染模型命名空间", not hasattr(gv, "AddGetRequest"))
# 拼错变量名应抛 KeyError(改造前会静默创建新变量)
try:
gv.set_global_var("db2", object())
check("set_global_var 未知变量应抛 KeyError", False, "未抛错,静默创建了 db2")
except KeyError:
check("set_global_var 未知变量应抛 KeyError", True, "db2 被拒绝")
# require 在未初始化时应抛清晰错误
try:
gv.require("db")
check("require 未初始化应抛 RuntimeError", False, "未抛错")
except RuntimeError:
check("require 未初始化应抛 RuntimeError", True)
# set 后 require 应返回同一个对象
marker = object()
gv.set_global_var("db", marker)
check("set 后 require 返回同一对象", gv.require("db") is marker)
check("模块属性 db 已被更新", gv.db is marker)
# ========== 2. __init__.py 导入链(router + Plugin 基类)==========
import plugins.example as plug # noqa: E402
check("plugins.example 导入成功", True)
check("create_workers 存在", callable(getattr(plug, "create_workers", None)))
check("cleanup 存在", callable(getattr(plug, "cleanup", None)))
check("plugin 实例存在", getattr(plug, "plugin", None) is not None)
check("plugin._initialized 默认 False", plug.plugin._initialized is False)
# ========== 3. create_workers 幂等性(mock session/config)==========
import asyncio # noqa: E402
# 用桩替代 Plugin 基类的 worker 创建实现,避免真实 zenoh 会话
calls = []
def _stub_create_workers(session, config, count=1, worker_manager=None):
calls.append((session, config, count, worker_manager))
return ["task-stub"]
plug.plugin._create_workers_impl = _stub_create_workers # type: ignore[method-assign]
async def main():
cfg = {"data_dir": "/tmp/example_data"}
# 第一次调用:应初始化 db
t1 = await plug.create_workers(session="s1", config=cfg, count=2)
check("首次 create_workers 调用桩", t1 == ["task-stub"])
check("plugin._initialized 置 True", plug.plugin._initialized is True)
from plugins.example.global_var import db as gv_db
check("global_var.db 已初始化", gv_db is not None)
# 第二次调用:幂等跳过,不重复初始化(桩仍被调用来建 task,但 db 不重建)
t2 = await plug.create_workers(session="s2", config=cfg, count=2)
check("二次 create_workers 幂等返回", t2 == ["task-stub"])
check("桩被调用两次(建 task)", len(calls) == 2)
from plugins.example.global_var import db as gv_db2
check("db 对象未重建", gv_db2 is gv_db)
# cleanup 后复位
await plug.cleanup("worker/example/worker-i-1")
check("cleanup 后 plugin._initialized 复位 False", plug.plugin._initialized is False)
from plugins.example.global_var import db as gv_db3
check("cleanup 后 db 为 None", gv_db3 is None)
# cleanup 后再启动:可重新初始化
t3 = await plug.create_workers(session="s3", config=cfg, count=1)
check("cleanup 后可再次 create_workers", t3 == ["task-stub"])
from plugins.example.global_var import db as gv_db4
check("再次初始化后 db 非 None", gv_db4 is not None)
check("再次初始化 db 为新对象", gv_db4 is not gv_db)
await plug.cleanup("worker/example/worker-i-1")
asyncio.run(main())
print("\n" + ("=" * 40))
if failures:
print(f"❌ {len(failures)} 项未通过: {failures}")
sys.exit(1)
print("✅ 全部通过")