feat(ledger): quiet idle outbox polling
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
"""LedgerOutbox + LedgerWriter direct unit tests (REQ-019)."""
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from dataclasses import replace
|
||||
from datetime import UTC, datetime, timedelta
|
||||
|
||||
@@ -132,6 +133,80 @@ def test_writer_exposes_claim_and_outcome_counters():
|
||||
assert writer.counters["outcome:completed"] == 1
|
||||
|
||||
|
||||
def test_idle_day_is_silent_and_counted_per_instance(caplog):
|
||||
writers = [
|
||||
LedgerWriter(
|
||||
InMemoryLedgerOutbox(instance_key=instance_key),
|
||||
InMemoryLedger(),
|
||||
instance_key=instance_key,
|
||||
)
|
||||
for instance_key in ("instance-a", "instance-b")
|
||||
]
|
||||
|
||||
with caplog.at_level(logging.INFO, logger="trex_core.application.ledger_outbox"):
|
||||
for writer in writers:
|
||||
for _ in range(86_400):
|
||||
writer.run_once()
|
||||
|
||||
assert [
|
||||
writer.metrics_snapshot()["claims"]["empty_polls_total"]
|
||||
for writer in writers
|
||||
] == [86_400, 86_400]
|
||||
assert "claim_result=empty" not in caplog.text
|
||||
assert "correlation_ids" not in caplog.text
|
||||
|
||||
|
||||
def test_nonempty_claim_log_has_ordered_json_correlation_ids(caplog):
|
||||
outbox = InMemoryLedgerOutbox(instance_key="inst-a")
|
||||
writer = LedgerWriter(outbox, InMemoryLedger(), instance_key="inst-a")
|
||||
first = outbox.enqueue(_trade(execution_id="e-1"))
|
||||
second = outbox.enqueue(_trade(execution_id="e-2"))
|
||||
|
||||
with caplog.at_level(logging.INFO, logger="trex_core.application.ledger_outbox"):
|
||||
writer.run_once(limit=2)
|
||||
|
||||
claim_logs = [
|
||||
record.getMessage()
|
||||
for record in caplog.records
|
||||
if "ledger outbox claim:" in record.getMessage()
|
||||
]
|
||||
assert claim_logs == [
|
||||
"ledger outbox claim: instance_key=inst-a claim_result=claimed "
|
||||
f"count=2 limit=2 correlation_ids=[\"{first.correlation_id}\","
|
||||
f"\"{second.correlation_id}\"]"
|
||||
]
|
||||
|
||||
|
||||
def test_metrics_snapshot_is_complete_and_detached():
|
||||
outbox = InMemoryLedgerOutbox(instance_key="inst-a")
|
||||
writer = LedgerWriter(outbox, InMemoryLedger(), instance_key="inst-a")
|
||||
|
||||
snapshot = writer.metrics_snapshot()
|
||||
|
||||
assert snapshot == {
|
||||
"available": True,
|
||||
"scope": "process_lifetime",
|
||||
"instance_key": "inst-a",
|
||||
"claims": {
|
||||
"empty_polls_total": 0,
|
||||
"claimed_batches_total": 0,
|
||||
"unavailable_total": 0,
|
||||
"lost_total": 0,
|
||||
"foreign_instance_total": 0,
|
||||
},
|
||||
"outcomes": {
|
||||
"completed_total": 0,
|
||||
"duplicate_completed_total": 0,
|
||||
"retryable_failure_total": 0,
|
||||
"conflict_blocked_total": 0,
|
||||
"permanent_failure_total": 0,
|
||||
"dead_lettered_total": 0,
|
||||
},
|
||||
}
|
||||
snapshot["claims"]["empty_polls_total"] = 999
|
||||
assert writer.metrics_snapshot()["claims"]["empty_polls_total"] == 0
|
||||
|
||||
|
||||
@pytest.mark.parametrize("instance_key", ["", " "])
|
||||
def test_writer_rejects_explicit_empty_instance_key(instance_key):
|
||||
outbox = InMemoryLedgerOutbox(instance_key="inst-a")
|
||||
|
||||
Reference in New Issue
Block a user