Files
AgentLab/backend/tests/test_blueprint_template_run.py
T
ThearchyHelios 7739340607 普通用户建应用集成收尾:
- 问数据和个人应用的图放行绑定只读查询等合规工具的调用工具节点,只读和遮罩在这条路径上生效;被治理成写入的工具在只读运行里直接拒;知识库范围在工具层固定(图级默认值、参数名纠错、Agent 都改不了)
- 个人应用的刷新和个人蓝图的试运行只有拥有者能读:运行、事件、证据、工件、文件、运行与审批列表、对比、可验证报告、质询、假设分析、提取工作流一并收紧;个人蓝图的试运行不论谁发起都按个人应用约束
- 共享蓝图只给拥有者、对应应用的管理者、管理员,看不到的一律 404;审核副本归审核人;管理员看别人的个人应用只有元数据、可以归档
- 记录表跨版本汇总(只读挂载旧版本、按当前列 UNION ALL、各版本各自固定高水位,缺的版本照实写进印章);停用前发起的运行可以继续写旧版本;更正沿用原提交人、更正人记审计
- 约定收口:待办种类 review、事件 file.extracted、表单错误 file、模板定义带示例与预置;前端类型一次补齐、去掉临时的局部类型;审核待办卡不再给打不开的链接;读附件事件有中文说法;检查脚本补断言
2026-10-15 13:55:19 +08:00

74 lines
3.0 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.
"""场景模板实例化出来的图真的能运行(docs/design/normal-user-apps.md §3.3「实例化 + 检查 + 运行」):周期看板按示例蓝图
实例化、生成关节填上之后,在一个小库上跑一次,口径卡用 cell() 取到格,成果按指标完整出具。库和数字都是编的。
"""
from __future__ import annotations
import asyncio
import sqlite3
import uuid
import pytest
from app.blueprints.instantiate import instantiate
from app.blueprints.templates import get_template
from app.data.engine import engines
from app.db.base import SessionLocal
from app.db.models import DataSource, Run
from app.engine.runner import run_manager
@pytest.fixture(autouse=True)
async def engine_up():
await run_manager.setup()
yield
await run_manager.shutdown()
@pytest.fixture
async def shop(tmp_path):
path = tmp_path / "shop.db"
with sqlite3.connect(path) as db:
db.executescript("CREATE TABLE orders (id INTEGER PRIMARY KEY, amount REAL, paid_at TEXT, refunded INTEGER);")
db.executemany("INSERT INTO orders VALUES (?, ?, ?, ?)", [
(1, 100.0, "2026-10-05", 0), (2, 300.0, "2026-10-08", 1), (3, 600.0, "2026-10-11", 0),
(4, 999.0, "2026-10-12", 0)]) # 统计期外
name = f"bprun_{uuid.uuid4().hex[:6]}"
async with SessionLocal() as session:
row = DataSource(name=name, kind="sqlite", database=str(path), readonly=True, enabled=True)
session.add(row)
await session.commit()
source_id = row.id
yield name
async with SessionLocal() as session:
await session.delete(await session.get(DataSource, source_id))
await session.commit()
await engines.invalidate(source_id)
async def test_the_board_template_runs_and_issues_by_metrics(shop):
from app.blueprints.templates._common import safe_id
extras = get_template("periodic_board")
spec = extras.example()
for item in spec["data"]:
item["table"]["value"]["source"] = shop
node = f"fetch_{safe_id(shop)}"
fill = {k.replace("fetch_shop", node): v.replace("fetch_shop", node) for k, v in extras.example_fill().items()}
inst = instantiate(spec, filled=fill)
assert inst.problems == []
run = await run_manager.start(graph=inst.graph, input_payload={
"period": "2026-W41", "period_start": "2026-10-05", "period_end": "2026-10-11"})
for _ in range(400):
await asyncio.sleep(0.05)
async with SessionLocal() as session:
row = await session.get(Run, run.id)
if row.status in ("succeeded", "failed") and row.manifest_seq is not None:
break
assert row.status == "succeeded", row.error
output = row.output or {}
issuance = output["_issuance"]
assert (issuance["tier"], issuance["mode"]) == ("formal", "metrics"), issuance
# 销售额不含已退款的那一单;订单数、退款率按全部订单
assert output["销售额(元)"] == "700.0" and output["订单数(单)"] == "3"
assert output["退款率(%)"] == "33.33"