- tests/test_compactor.py: 24 tests (estimate_tokens, extract_facts, build_summary, summarize_tool_output, compact_sections) - tests/test_key_data_extraction.py: 11 tests (extracción de tables, records, sections, modules, pages desde tool executions) - tests/test_fingerprint.py: 8 tests (deduplicación MD5, sort_keys, nested args) - tests/test_cost_calculation.py: 8 tests (pricing formula, custom pricing, rounding) - README.md: sección Tests con instrucciones de ejecución Todos offline, sin Docker/Redis/LLM. Ejecutar: python3 -m pytest tests/ -v Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
72 lines
2.3 KiB
Python
72 lines
2.3 KiB
Python
"""Tests para el calculo de costes del orquestador.
|
|
|
|
Replica la formula de coste de OrchestratorEngine._run_pipeline():
|
|
cost_usd = (input_tokens / 1_000_000) * cost_per_1m_input
|
|
+ (output_tokens / 1_000_000) * cost_per_1m_output
|
|
|
|
Defaults: cost_per_1m_input=2.50, cost_per_1m_output=15.00
|
|
"""
|
|
|
|
import pytest
|
|
|
|
|
|
def calculate_cost(
|
|
input_tokens: int,
|
|
output_tokens: int,
|
|
cost_per_1m_input: float = 2.50,
|
|
cost_per_1m_output: float = 15.00,
|
|
) -> float:
|
|
"""Replica exacta de la formula de coste en engine.py."""
|
|
return (
|
|
(input_tokens / 1_000_000) * cost_per_1m_input
|
|
+ (output_tokens / 1_000_000) * cost_per_1m_output
|
|
)
|
|
|
|
|
|
class TestCostCalculation:
|
|
def test_1m_input_tokens(self):
|
|
cost = calculate_cost(1_000_000, 0)
|
|
assert cost == pytest.approx(2.50)
|
|
|
|
def test_1m_output_tokens(self):
|
|
cost = calculate_cost(0, 1_000_000)
|
|
assert cost == pytest.approx(15.00)
|
|
|
|
def test_500k_input_100k_output(self):
|
|
cost = calculate_cost(500_000, 100_000)
|
|
# (500_000 / 1_000_000) * 2.50 + (100_000 / 1_000_000) * 15.00
|
|
# = 1.25 + 1.50 = 2.75
|
|
assert cost == pytest.approx(2.75)
|
|
|
|
def test_zero_tokens(self):
|
|
cost = calculate_cost(0, 0)
|
|
assert cost == 0.0
|
|
|
|
def test_custom_pricing(self):
|
|
cost = calculate_cost(
|
|
1_000_000, 1_000_000,
|
|
cost_per_1m_input=3.00,
|
|
cost_per_1m_output=10.00,
|
|
)
|
|
assert cost == pytest.approx(13.00)
|
|
|
|
def test_small_token_count(self):
|
|
"""Pocos tokens = coste muy bajo pero no cero."""
|
|
cost = calculate_cost(100, 50)
|
|
assert cost > 0
|
|
assert cost < 0.01
|
|
|
|
def test_round_to_6_decimals(self):
|
|
"""El engine hace round(cost_usd, 6)."""
|
|
cost = calculate_cost(1, 1)
|
|
rounded = round(cost, 6)
|
|
# (1/1M)*2.50 + (1/1M)*15.00 = 1.75e-05
|
|
# round(1.75e-05, 6) = 1.7e-05 (banker's rounding: 5 rounds to even)
|
|
assert rounded == pytest.approx(0.000017, abs=1e-7)
|
|
|
|
def test_output_more_expensive_than_input(self):
|
|
"""Con defaults, output es 6x mas caro que input."""
|
|
input_cost = calculate_cost(1_000_000, 0)
|
|
output_cost = calculate_cost(0, 1_000_000)
|
|
assert output_cost == pytest.approx(input_cost * 6.0)
|