| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657 |
- import asyncio
- from uuid import uuid4
- import pytest
- from test_after_sales import scenario # noqa: F401
- from test_money_budget import PRICE, PROVIDER, approve, budget, setup
- from test_token_budget import sample
- from zhifu.modules.agent_runtime.budget import change_entry, mark_pending_unknown, reserve
- from zhifu.modules.agent_runtime.models import TokenAccount, TokenEntry
- from zhifu.modules.billing.models import MoneyEntry
- from zhifu.modules.identity.auth import now
- @pytest.mark.parametrize("kind", ["agent", "memory"])
- async def test_interrupted_budget_preserves_scope_and_late_settlement(scenario, kind): # noqa: F811
- sessions, tenant = scenario["app"].state.sessions, scenario["tenant"].bytes
- await setup(scenario)
- await budget(scenario, 1000000)
- await approve(scenario, PRICE)
- observed = sample()
- reference, other_reference = uuid4().bytes, uuid4().bytes
- pending, completed, other = [uuid4().bytes for _ in range(3)]
- for identifier, target in (
- (pending, reference), (completed, reference), (other, other_reference)
- ):
- await reserve(sessions, tenant, identifier, kind, target,
- PRICE["model"], 6000, provider=PROVIDER)
- await change_entry(sessions, tenant, completed, usage=observed["usage"])
- # 真实事务创建待计量记录;错误租户和调用类型不能改变其他业务的预算状态。
- await mark_pending_unknown(sessions, uuid4().bytes, kind, reference)
- await mark_pending_unknown(
- sessions, tenant, "memory" if kind == "agent" else "agent", reference)
- async with sessions() as session:
- assert (await session.get(TokenEntry, pending)).status == "PENDING"
- await asyncio.gather(*(
- mark_pending_unknown(sessions, tenant, kind, reference) for _ in range(3)))
- async with sessions() as session:
- assert (await session.get(TokenEntry, pending)).status == "UNKNOWN"
- assert (await session.get(MoneyEntry, pending)).status == "UNKNOWN"
- assert (await session.get(TokenEntry, pending)).version == 2
- assert (await session.get(TokenEntry, completed)).status == "SETTLED"
- assert (await session.get(TokenEntry, other)).status == "PENDING"
- account = await session.get(TokenAccount, (tenant, now().date()))
- assert account.reserved == 12000
- assert account.consumed == observed["usage"]["total_tokens"]
- # 使用已有供应商真实usage验证迟到结算与清理竞争,不生成模型响应。
- await asyncio.gather(
- change_entry(sessions, tenant, pending, usage=observed["usage"]),
- mark_pending_unknown(sessions, tenant, kind, reference),
- )
- async with sessions() as session:
- assert (await session.get(TokenEntry, pending)).status == "SETTLED"
- assert (await session.get(MoneyEntry, pending)).status == "SETTLED"
- account = await session.get(TokenAccount, (tenant, now().date()))
- assert account.reserved == 6000
- assert account.consumed == 2 * observed["usage"]["total_tokens"]
|