mirror of
https://github.com/Routstr/routstr-core.git
synced 2026-10-05 12:28:22 +00:00
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 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014X8RZzzbAuQCbavhFjTvJ4
This commit is contained in:
co-authored by
Claude Opus 5
parent
59bf8f4c90
commit
76d7b8fceb
@@ -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(
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user