Files

73 lines
2.7 KiB
Python
Raw Permalink 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.
"""任务成本预估单元测试(mock 数据,不依赖数据库)。"""
from types import SimpleNamespace
from unittest.mock import patch
from app.cost_estimate import estimate_campaign_cost
class _PlannedSession:
"""按顺序返回 exec 查询结果:segments → usage_events → llm_calls。"""
def __init__(self, queues):
self.queues = list(queues)
def exec(self, *_a, **_k):
return SimpleNamespace(all=lambda: self.queues.pop(0) if self.queues else [])
def _campaign(segments=3):
return SimpleNamespace(id=1, organization_id=1, owner_user_id=7)
def _event(in_toks, out_toks, in_rate=2.0, out_rate=8.0):
return SimpleNamespace(status="measured", input_quantity=in_toks, output_quantity=out_toks,
input_rate=in_rate, output_rate=out_rate)
def test_no_segments_not_ready():
session = _PlannedSession([[]])
report = estimate_campaign_cost(session, _campaign())
assert report["ready"] is False
def test_fallback_estimate_without_history():
session = _PlannedSession([[_segment_stub() for _ in range(3)], [], []])
report = estimate_campaign_cost(session, _campaign())
assert report["ready"] is True
assert report["source"] == "fallback"
# 3 段 × (6000+2500) × 1.6 = 40800
assert report["estimated_tokens"] == 40800
assert report["estimated_points"] == 408000
assert report["estimated_amount_minor"] == 0
def _segment_stub():
return SimpleNamespace(id=1)
def test_history_based_estimate():
events = [_event(5000, 2000), _event(7000, 3000)]
session = _PlannedSession([[_segment_stub() for _ in range(2)], events, []])
report = estimate_campaign_cost(session, _campaign())
assert report["source"] == "history"
# 均值 (6000, 2500) × 2 段 × 1.6 = 27200
assert report["estimated_tokens"] == 27200
# 费率均值 in=2.0 out=8.0:(12000/1e6*2 + 5000/1e6*8) 元 = 0.064 元 → 6 分
assert report["estimated_amount_minor"] == 6
def test_duration_from_llm_calls():
calls = [SimpleNamespace(duration_ms=10000), SimpleNamespace(duration_ms=20000)]
session = _PlannedSession([[_segment_stub()], [], calls])
report = estimate_campaign_cost(session, _campaign())
# 平均 15s × 3 + 15 = 60s 单段;1 段 + 20 = 80s
assert report["estimated_seconds"] == 80
assert report["estimated_duration_text"] == "1 分 20 秒"
def test_estimate_scales_with_segments():
one = estimate_campaign_cost(_PlannedSession([[_segment_stub()], [], []]), _campaign())
four = estimate_campaign_cost(_PlannedSession([[_segment_stub() for _ in range(4)], [], []]), _campaign())
assert four["estimated_tokens"] == one["estimated_tokens"] * 4
assert four["estimated_points"] > one["estimated_points"]