53 lines
2.1 KiB
Python
53 lines
2.1 KiB
Python
from pathlib import Path
|
|
from zipfile import ZipFile
|
|
|
|
from deerflow.skill_knowledge import build_skill_ir, scan_skill
|
|
|
|
|
|
def test_scanner_excludes_code_blocks_source_and_sensitive_files(tmp_path: Path) -> None:
|
|
(tmp_path / "SKILL.md").write_text(
|
|
"# 示例\n本技能使用 客户画像数据。\n```python\nPASSWORD = 'must-not-enter-ir'\n```\n",
|
|
encoding="utf-8",
|
|
)
|
|
(tmp_path / "worker.py").write_text("# uses hidden system\nSECRET='never-read'", encoding="utf-8")
|
|
(tmp_path / ".env").write_text("TOKEN=super-secret-value", encoding="utf-8")
|
|
|
|
scan = scan_skill("example", tmp_path)
|
|
ir = build_skill_ir(scan)
|
|
|
|
assert scan.skipped_code_count == 1
|
|
assert scan.blocked_files == [{"path": ".env", "reason": "疑似密钥或敏感配置文件"}]
|
|
assert "must-not-enter-ir" not in str(ir)
|
|
assert "never-read" not in str(ir)
|
|
assert any(relation["predicate"] == "uses" for relation in ir["relations"])
|
|
|
|
|
|
def test_code_only_change_does_not_change_digest(tmp_path: Path) -> None:
|
|
(tmp_path / "SKILL.md").write_text("# Stable knowledge", encoding="utf-8")
|
|
code = tmp_path / "worker.py"
|
|
code.write_text("print(1)", encoding="utf-8")
|
|
before = scan_skill("example", tmp_path).source_digest
|
|
code.write_text("print(2)", encoding="utf-8")
|
|
after = scan_skill("example", tmp_path).source_digest
|
|
assert before == after
|
|
|
|
|
|
def test_zip_is_inspected_and_only_safe_knowledge_members_are_read(tmp_path: Path) -> None:
|
|
archive = tmp_path / "materials.zip"
|
|
with ZipFile(archive, "w") as output:
|
|
output.writestr("guide.md", "# 操作手册\n仅提炼这段知识。")
|
|
output.writestr("worker.py", "SECRET = 'code-must-not-be-read'")
|
|
output.writestr("../escape.md", "path traversal")
|
|
|
|
scan = scan_skill("example", tmp_path)
|
|
|
|
assert [file.path for file in scan.files] == ["materials.zip!/guide.md"]
|
|
assert scan.skipped_code_count == 1
|
|
assert scan.blocked_files == [
|
|
{
|
|
"path": "materials.zip!/../escape.md",
|
|
"reason": "压缩包包含路径穿越或符号链接",
|
|
}
|
|
]
|
|
assert "code-must-not-be-read" not in str(scan.manifest)
|