From 76d7b8fceb37f7a642a26d0246c34b727ebe16bc Mon Sep 17 00:00:00 2001 From: Jeroen Ubbink Date: Wed, 26 Aug 2026 15:56:10 +0200 Subject: [PATCH] test(pricing): say once what a rate-validation test pins The failure history these tests were written against now lives in one place, `payment/rates.py`. Cut the longest test docstrings down to what the test itself pins, rather than restating that history at every boundary. No test changes behaviour. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_014X8RZzzbAuQCbavhFjTvJ4 --- .../test_admin_pricing_rate_validation.py | 18 ++++------ tests/unit/test_algorithm.py | 9 ++--- tests/unit/test_pricing_rate_validation.py | 34 ++++++------------- 3 files changed, 19 insertions(+), 42 deletions(-) diff --git a/tests/integration/test_admin_pricing_rate_validation.py b/tests/integration/test_admin_pricing_rate_validation.py index 86754544..2e9a45b9 100644 --- a/tests/integration/test_admin_pricing_rate_validation.py +++ b/tests/integration/test_admin_pricing_rate_validation.py @@ -189,12 +189,9 @@ async def test_a_rate_that_is_not_there_is_rejected( ) -> None: """A rate given as ``null``, or a required rate left out, is not a price. - The validator read both through ``dict.get``, which cannot tell an absent - key from an explicit ``null``, and skipped both. ``Pricing`` declares - ``prompt`` and ``completion`` without a default and every rate as a float, - so such a row is written with a 200 and then fails to parse on read — and - a row that will not parse is withheld from the catalog, leaving the operator - a model that was accepted and is nowhere to be seen. + ``dict.get`` cannot tell the two apart and skipped both, so a row + ``Pricing`` cannot parse was committed and the response that reads it back + raised. """ provider_id = await _make_provider(integration_session) @@ -351,12 +348,9 @@ async def test_admin_model_listing_shows_a_non_finite_stored_rate( ) -> None: """The operator must be able to see the rate that needs fixing. - The admin listing deliberately includes disabled models, so it is the one - view that still carries a row the served-catalog backstop holds back. - FastAPI's encoder rendered a stored ``Infinity`` rate as ``null``, which is - indistinguishable from a rate the row never carried — the operator could see - the row but not the reason it was withheld. Render the offending value as - text instead, as the 422 handler already does. + The admin listing is the one view that still carries a row the served + catalog holds back, and its encoder rendered a stored ``Infinity`` as + ``null`` — indistinguishable from a rate the row never carried. """ provider_id = await _make_provider(integration_session) integration_session.add( diff --git a/tests/unit/test_algorithm.py b/tests/unit/test_algorithm.py index cefc4f90..f5c875f9 100644 --- a/tests/unit/test_algorithm.py +++ b/tests/unit/test_algorithm.py @@ -1025,12 +1025,9 @@ def test_create_model_mappings_survives_an_unreadable_override_row( ) -> None: """One row that cannot be read must not empty the whole routing map. - Stored pricing is JSON from whatever wrote the row, so converting it can - raise. Converting an override while walking a provider's catalog let that - exception unwind the entire map build: at boot the node came up routing - nothing, and on a later refresh the map it already had went permanently - stale. The sibling loop over override-only rows already skips and logs such - a row. + Converting an override while walking a provider's catalog let the exception + unwind the entire map build: the node came up routing nothing. The sibling + loop over override-only rows already skips and logs such a row. """ broken = create_test_model("broken-model") healthy = create_test_model("healthy-model") diff --git a/tests/unit/test_pricing_rate_validation.py b/tests/unit/test_pricing_rate_validation.py index 895fa06e..b3e538c7 100644 --- a/tests/unit/test_pricing_rate_validation.py +++ b/tests/unit/test_pricing_rate_validation.py @@ -77,12 +77,9 @@ def _usage_response() -> dict[str, Any]: async def test_unusable_token_rate_falls_back_to_max_cost(bad_rate: float) -> None: """An unusable configured rate must not be billed on. - The "no token pricing configured" gate is a truthiness test, and ``NaN`` and - negative floats are both truthy, so an unusable rate passes the guard that - exists to catch it. It then reaches the integer conversion in the token math, - which raises ``ValueError`` for ``NaN`` and ``OverflowError`` for ``inf`` — - after the upstream response has already been served, where the streaming - handlers swallow it and the request goes unbilled. + It reached the token math, which raises after the response was already + served — where the streaming handlers swallow it and the request goes + unbilled. """ model = _model(Pricing(prompt=bad_rate, completion=1.0)) @@ -124,11 +121,8 @@ async def test_junk_cost_component_still_bills_the_reported_total(junk: Any) -> """A malformed component must not discard the upstream's real total cost. ``cost_details`` only splits the total across input and output; the total is - the authoritative billed amount. A non-finite component poisons the - proportional allocation (``inf / inf`` is ``NaN``), which raised out of the - USD path and was swallowed by the broad handler around it — so the request - silently fell through to token-estimated pricing and was billed at a small - fraction of what the upstream actually charged. + the authoritative billed amount. A non-finite component poisoned the split, + and the request fell through to token estimation for a fraction of it. """ model = _model(Pricing(prompt=1e-06, completion=2e-06)) response = { @@ -289,14 +283,9 @@ async def test_unusable_exchange_quote_does_not_set_the_node_price( ) -> None: """One exchange returning junk must not set the price the node bills at. - The feed takes the ``min()`` of the quotes it collects, so an unusable quote - does not merely join the sample — it *wins*, and poisons the rate every model - and every request is priced at until the next refresh. Zero then divides by - zero on the USD path, ``NaN`` raises out of the integer conversion, and a - negative rate produces a negative charge that settlement credits back to the - caller. - - The two healthy quotes must still price the node. + The feed takes the ``min()`` of what it collects, so an unusable quote does + not merely join the sample — it *wins*. The two healthy quotes must still + price the node. """ from routstr.payment.price import btc_usd_price @@ -351,11 +340,8 @@ async def test_an_unreadable_exchange_response_drops_only_that_quote( ) -> None: """An exchange whose response never yields a quote costs one quote. - The price is aggregated across three exchanges precisely so that one of them - having a bad day is survivable. A body that is not JSON, or whose shape moved - under the reader, raises before any number is seen; unhandled, it aborted the - whole aggregation and left the node on a stale rate even though two healthy - quotes were already in hand. + The price is aggregated across three exchanges so that one of them having a + bad day is survivable; unhandled, the raise aborted the whole aggregation. """ from routstr.payment.price import btc_usd_price