Files
chongming-core/test_build_plugin.py
T

118 lines
4.2 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.
"""
build_plugin 打包命令冒烟测试
验证进程插件打包产物的完整性与错误路径:
1. demo 插件打包成功,zip 内含代码/配置/最小根配置/依赖清单/可执行 start.sh
2. 插件代码目录缺失时报 FileNotFoundError
3. 插件 config.toml 缺失时报 FileNotFoundError
运行: uv run python test_build_plugin.py
"""
import shutil
import sys
import tempfile
import tomllib
import zipfile
from pathlib import Path
SRC = Path(__file__).parent
sys.path.insert(0, str(SRC / "src"))
from chongming.scripts import build_plugin as bp # noqa: E402
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)
tmp = Path(tempfile.mkdtemp(prefix="build_plugin_test_"))
# ========== 1. demo 插件打包 ==========
zip_path = bp.build_plugin_package("demo", output_dir=tmp / "dist")
check("zip 产物生成", zip_path.exists(), str(zip_path))
with zipfile.ZipFile(zip_path) as z:
names = set(z.namelist())
check("包含插件代码 workers/demo/__init__.py", "workers/demo/__init__.py" in names)
check("包含插件配置 config/workers/demo/config.toml", "config/workers/demo/config.toml" in names)
check("包含 Zenoh 配置", "config/zenoh_config.json5" in names)
check("包含最小根配置 config.toml", "config.toml" in names)
check("包含依赖清单 pyproject.toml", "pyproject.toml" in names)
check("包含 start.sh", "start.sh" in names)
check("不包含 __pycache__", not any("__pycache__" in n for n in names))
# 最小根配置:仅 [zenoh] 节,不含网关侧敏感配置
root_conf = tomllib.loads(z.read("config.toml").decode())
check("根配置仅含 [zenoh] 节", set(root_conf.keys()) == {"zenoh"}, str(sorted(root_conf)))
check(
"根配置不泄露网关 [security] 密钥",
"secret_key" not in z.read("config.toml").decode(),
)
# 依赖清单:chongming-worker 内网 git 源 + worker_serve 入口
pyproject = tomllib.loads(z.read("pyproject.toml").decode())
deps = pyproject["project"]["dependencies"]
check("pyproject 依赖包含 chongming-worker", "chongming-worker" in deps)
check("pyproject 依赖包含 orjson(SDK 运行时依赖)", "orjson" in deps)
check(
"pyproject 声明 worker_serve 入口",
pyproject["project"]["scripts"].get("worker_serve") == "chongming_worker.process:worker_serve",
)
check(
"pyproject 声明 chongming-worker git 源",
pyproject["tool"]["uv"]["sources"]["chongming-worker"]["git"] == bp.CHONGMING_WORKER_GIT,
)
# start.sh:可执行 + 指向正确的插件 type
start_sh = z.read("start.sh").decode()
check("start.sh 以 --type demo 启动", "--type demo" in start_sh)
perms = (z.getinfo("start.sh").external_attr >> 16) & 0o777
check("start.sh 可执行(0o755)", perms == 0o755, oct(perms))
# ========== 2. 错误路径:插件代码目录缺失 ==========
orig_workers = bp.WORKERS_DIR
bp.WORKERS_DIR = tmp / "no_workers"
try:
bp.build_plugin_package("ghost", output_dir=tmp / "dist")
check("缺插件代码目录应抛 FileNotFoundError", False)
except FileNotFoundError:
check("缺插件代码目录应抛 FileNotFoundError", True)
finally:
bp.WORKERS_DIR = orig_workers
# ========== 3. 错误路径:插件配置缺失 ==========
orig_conf_dir = bp.PLUGINS_CONFIG_DIR
bp.PLUGINS_CONFIG_DIR = tmp / "no_config"
try:
bp.build_plugin_package("demo", output_dir=tmp / "dist")
check("缺插件配置应抛 FileNotFoundError", False)
except FileNotFoundError:
check("缺插件配置应抛 FileNotFoundError", True)
finally:
bp.PLUGINS_CONFIG_DIR = orig_conf_dir
# ========== 4. 错误路径:插件名不合法 ==========
try:
bp.build_plugin_package("Bad-Name", output_dir=tmp / "dist")
check("非法插件名应抛 ValueError", False)
except ValueError:
check("非法插件名应抛 ValueError", True)
shutil.rmtree(tmp, ignore_errors=True)
print("\n" + ("=" * 40))
if failures:
print(f"❌ {len(failures)} 项未通过: {failures}")
sys.exit(1)
print("✅ 全部通过")