From 90b9f6db1e4ec8e45ff4fb3dd3ba36d34943c19d Mon Sep 17 00:00:00 2001 From: Sylvester Kaczmarek <16242628+sylvesterkaczmarek@users.noreply.github.com> Date: Sat, 15 Aug 2026 23:36:02 +0100 Subject: [PATCH] Scope snapshot tests to numeric hardening --- .../tests/test_snapshot_invalid_numerics.py | 54 +++++++++---------- 1 file changed, 24 insertions(+), 30 deletions(-) diff --git a/backend/services/infonet/tests/test_snapshot_invalid_numerics.py b/backend/services/infonet/tests/test_snapshot_invalid_numerics.py index d727e16..cf2f7a7 100644 --- a/backend/services/infonet/tests/test_snapshot_invalid_numerics.py +++ b/backend/services/infonet/tests/test_snapshot_invalid_numerics.py @@ -1,14 +1,22 @@ -"""Regression coverage for malformed/non-finite market snapshot inputs.""" +"""Regression coverage for malformed/non-finite market snapshot numerics.""" import math +from typing import Any import pytest -from services.infonet.markets.snapshot import build_snapshot, find_snapshot +from services.infonet.markets.snapshot import build_snapshot -def _prediction(node, side, stake, *, timestamp, sequence): - payload = {"market_id": "m1", "side": side} +def _prediction( + node: str, + side: str, + stake: Any, + *, + timestamp: float, + sequence: int, +) -> dict[str, Any]: + payload: dict[str, Any] = {"market_id": "m1", "side": side} if stake is not None: payload["stake_amount"] = stake return { @@ -20,10 +28,11 @@ def _prediction(node, side, stake, *, timestamp, sequence): } -def test_nonfinite_paid_stake_does_not_poison_snapshot(): +@pytest.mark.parametrize("invalid_stake", [float("nan"), float("inf"), "not-a-number", -1.0, 0.0]) +def test_invalid_paid_stake_does_not_poison_or_count_snapshot(invalid_stake: Any) -> None: chain = [ _prediction("alice", "yes", None, timestamp=100.0, sequence=1), - _prediction("mallory", "no", float("inf"), timestamp=101.0, sequence=2), + _prediction("mallory", "no", invalid_stake, timestamp=101.0, sequence=2), ] snapshot = build_snapshot("m1", chain, frozen_at=200.0) @@ -35,36 +44,21 @@ def test_nonfinite_paid_stake_does_not_poison_snapshot(): assert all(math.isfinite(v) for v in snapshot["frozen_probability_state"].values()) -def test_malformed_ordering_metadata_does_not_break_snapshot_build(): +def test_finite_numeric_string_stake_is_preserved() -> None: chain = [ - _prediction("alice", "yes", 5.0, timestamp="bad", sequence="bad"), - _prediction("bob", "no", 5.0, timestamp=100.0, sequence=1), + _prediction("alice", "yes", "2.5", timestamp=100.0, sequence=1), + _prediction("bob", "no", "7.5", timestamp=101.0, sequence=2), ] - snapshot = build_snapshot("m1", chain, frozen_at=200.0) + snapshot = build_snapshot("m1", chain, frozen_at="200.5") assert snapshot["frozen_participant_count"] == 2 assert snapshot["frozen_total_stake"] == 10.0 - assert snapshot["frozen_probability_state"] == {"yes": 0.5, "no": 0.5} + assert snapshot["frozen_probability_state"] == {"yes": 0.25, "no": 0.75} + assert snapshot["frozen_at"] == 200.5 -def test_invalid_snapshot_ordering_does_not_outrank_valid_snapshot(): - invalid = { - "event_type": "market_snapshot", - "timestamp": "bad", - "sequence": "bad", - "payload": {"market_id": "m1", "marker": "invalid"}, - } - valid = { - "event_type": "market_snapshot", - "timestamp": 100.0, - "sequence": 1, - "payload": {"market_id": "m1", "marker": "valid"}, - } - - assert find_snapshot("m1", [invalid, valid])["marker"] == "valid" - - -def test_nonfinite_frozen_at_is_rejected(): +@pytest.mark.parametrize("invalid_frozen_at", [float("nan"), float("inf"), "not-a-time"]) +def test_nonfinite_or_malformed_frozen_at_is_rejected(invalid_frozen_at: Any) -> None: with pytest.raises(ValueError, match="frozen_at must be finite"): - build_snapshot("m1", [], frozen_at=float("nan")) + build_snapshot("m1", [], frozen_at=invalid_frozen_at)