satmachineadmin/tests/conftest.py
Padreug d9e8a04b8b feat(v2): record fee_mismatch_sats per settlement, Phase 1 (#38 4/5)
Phase-1 observability per coord-log §2026-06-01T07:00Z (option A
locked: always record, no enforce_fee_match gate):

  fee_mismatch_sats = bitspire_fee_sats - (platform_fee_sats + operator_fee_sats)

Positive = bitspire over-reported; negative = under-reported; zero =
exact match. Recorded unconditionally on every settlement; WARN-
logged via loguru only when |delta| > tolerance, where
tolerance = max(1, int(principal_sats * 0.001)) — 1-sat floor with
0.1% relative ceiling.

bitspire.py:parse_settlement:
- Computes the delta after split_principal_based returns.
- WARN log line carries bitspire_fee_sats / expected / delta /
  tolerance / principal / both fractions / tx_type / machine-npub
  prefix for triage queries.
- Always stamps fee_mismatch_sats onto CreateDcaSettlementData.
- Comment explains the pre-Layer-3 expectation: large deltas are
  expected while the ATM hardcodes 7.77% cash-out (aiolabs/lamassu-
  next#57); the data here will quiet once Layer 3 ships.

crud.py:create_settlement_idempotent: extends the INSERT to persist
the new column.

Tests:
- tests/conftest.py: `loguru_capture` fixture — loguru routes to a
  pre-bound stderr sink that pytest's caplog (stdlib only) misses and
  capsys can't see; the fixture adds a list-sink for the test's
  duration. Reusable for future log-behavior tests.
- tests/test_fee_mismatch_recording.py: 8 cases covering exact-match
  zero delta, bitspire over- and under-reporting, the pre-Layer-3
  large-delta scenario, within-tolerance silence, over-tolerance
  warning, diagnostic-fields presence in the WARN line, and the
  1-sat floor on tiny-principal settlements.

164/164 tests green. Phase 2 (reject on out-of-tolerance) lands as
a follow-up once observability data justifies the tighter posture.

Refs: aiolabs/satmachineadmin#38 (Layer 1), coord-log §2026-06-01T07:00Z
(lnbits advisory + option A lock).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-01 14:34:25 +02:00

32 lines
1,022 B
Python

"""
Pytest configuration for the satmachineadmin extension test suite.
Provides a `loguru_capture` fixture for tests that need to verify
loguru WARN/ERROR side-effects. Loguru attaches its default sink to
sys.stderr at import time, before pytest's `capsys` wraps stderr, so
neither `caplog` (stdlib logging only) nor `capsys` reliably sees
loguru output. The fixture adds a list-sink for the test's duration
and removes it on teardown.
"""
from typing import Generator, List
import pytest
from loguru import logger
@pytest.fixture
def loguru_capture() -> Generator[List[str], None, None]:
"""Capture loguru log records into a list for the test's duration.
Usage:
def test_warns_on_X(loguru_capture):
do_thing_that_warns()
assert any("expected message" in msg for msg in loguru_capture)
"""
captured: List[str] = []
handler_id = logger.add(
captured.append, level="WARNING", format="{level} {message}"
)
yield captured
logger.remove(handler_id)