mirror of
https://github.com/Routstr/routstr-core.git
synced 2026-10-06 12:38:23 +00:00
Three independent tester subagents found 12 defects (1 critical, 2 high,
9 medium/low). This commit fixes all of them and adds 56 regression tests.
Critical (CLI dead on arrival):
- certify_upstream_url() called sats_usd_price() which raises ValueError
in any fresh process (the module global is only set by the app lifespan
task). Now resolves via _resolve_sats_usd_price(): module global → BTC
global → exchange feed → None (warn row, not a crash). Adds
--sats-usd-price CLI flag for explicit override.
High (non-finite tokens crash the billing path):
- parse_token_count() crashed on Infinity/NaN (json.loads accepts both).
Fixed to reject non-finite values → 0. This was a shared-code bug in
routstr/payment/usage.py, reachable from the main billing path too.
- usage_capture_row and cost_prompt_completion_row now guard normalize_usage
in try/except via safe_row(), so a raising check becomes a fail row
instead of a 500.
Medium:
- certification_row now coerces non-dict evidence to {} (was stored verbatim)
- endpoint_validity_row checks .hostname not .netloc (http://:8080 rejected)
- models_payload_row rejects empty-string ids (agrees with CLI discovery)
- models_payload_row / usage_capture_row guard against non-dict payloads
- _reported_usd_cost uses coerce_rate for parity with the engine
- _expected_token_msats raises ValueError on non-finite rates (not OverflowError)
- get_candidates() call in admin endpoint wrapped in try/except
- Admin timeout clamped to [1, 60] seconds
- Explicit --prompt-price validated via coerce_rate (negatives rejected)
- CLI --json-out flag writes strictly parseable JSON to a file
- CLI logs routed to stderr so stdout is the report's channel
Test plan: 1749 passed, 1 skipped (no regressions); ruff clean; mypy clean.
FastAPI Async Unit Tests
This directory contains async unit tests for the Routstr proxy FastAPI application.
Installation
First, ensure you have the development dependencies installed:
uv pip install -e ".[dev]"
Running Tests
To run all tests:
pytest
To run tests with coverage:
pytest --cov=routstr --cov-report=html
To run specific test files:
pytest tests/test_main.py
pytest tests/test_models.py
pytest tests/test_proxy.py
To run only async tests:
pytest -m asyncio
Test Structure
conftest.py- Pytest fixtures and configurationtest_main.py- Tests for main app endpointstest_account.py- Tests for wallet/account management endpointstest_proxy.py- Tests for the proxy functionality with mocked upstreamtest_models.py- Tests for model pricing and data structures
Key Fixtures
async_client- Async HTTP client for testing FastAPI endpointstest_session- In-memory SQLite database session for teststest_api_key- Pre-configured API key with balanceapi_key_with_balance- API key with sufficient balance for proxy tests
Environment Variables
The tests automatically set up required environment variables in conftest.py. No manual configuration needed.
Writing New Tests
- Use
@pytest.mark.asynciofor async tests - Use the provided fixtures for database and client access
- Mock external dependencies (like upstream API calls)
- Test both success and error cases
- Verify database state changes when applicable