Files
sentiment-engine/MALKHUT/malkhut/tests/test_storage_ch.py
Codex 4c239f7774 malkhut(tests): 1140 test functions across 46 test files
CWM (103): core mechanics, exhaustive edge cases, numba, exchange mechanics
Replay (118): exhaustive verification, microstructure, trajectory
Training (190): asset classification, phase0 extensive, pipeline, exhaustive
DSL (102): v2 syntax, expanded, new features
ASEx (33): validate-before-mutate, single-writer
Planner (48): MCTS, alternatives, hooks
Counterparties (19): 9 adversarial agent policies
Clock (30): event-driven reactor
BingX (28): venue adapter
IPC (8): Zinc SHM
Storage (9): ClickHouse
Risk (4): hard invariants
State (17): frozen dataclass invariants
Integration: E2E, concurrency, sync/async seams, hypothesis, fuzz, adversarial
2026-07-11 10:46:12 +02:00

81 lines
2.5 KiB
Python

"""
ClickHouse persistence — store, retrieve, table creation.
"""
import json
import time
import pytest
from malkhut.storage.ch_store import MalkhutCHStore
@pytest.fixture(scope="module")
def store():
s = MalkhutCHStore()
s.ensure_tables()
return s
class TestClickHouseTables:
def test_tables_exist(self, store):
result = store.query("SHOW TABLES")
tables = result.strip().split("\n")
assert "replay_steps" in tables
assert "fulfilment_decisions" in tables
assert "self_play_episodes" in tables
assert "policy_snapshots" in tables
assert "live_discrepancies" in tables
def test_table_idempotent(self, store):
store.ensure_tables()
store.ensure_tables()
result = store.query("SHOW TABLES")
assert "replay_steps" in result
class TestClickHouseInsert:
def test_store_fulfilment_decision(self, store):
store.store_fulfilment_decision(
ts_ns=time.time_ns(), exchange="bingx", symbol="BTCUSDT",
intent_id="test_intent", state_hash="abc123",
selected_action="PLACE", root_distribution="[0.5, 0.5]",
risk_decision="True:approved", policy_version="v0.1",
latency_ms=5.0,
)
def test_store_episode(self, store):
store.store_episode(
policy_version="v0.1", scenario_id="test_scenario",
seed=42, pnl_bps=10.0, max_drawdown_bps=-5.0,
fill_ratio=0.8, adverse_fill_ratio=0.1,
avg_slippage_bps=1.5, liq_near_misses=0,
cancel_count=3, diagnostics="{}",
)
def test_store_policy_snapshot(self, store):
store.store_policy_snapshot(
version="v0.1_test", score=5.0,
params_str="test_params", evaluation_summary="{}",
)
def test_store_discrepancy(self, store):
store.store_discrepancy(
ts_ns=time.time_ns(), exchange="bingx", symbol="BTCUSDT",
predicted="PLACE", actual="FILL", severity="warning",
)
def test_store_replay_step(self, store):
store.store_replay_step(
symbol="BTCUSDT", ts_ns=time.time_ns(), step_index=0,
before="{}", action="{}", after="{}",
)
class TestClickHouseQuery:
def test_query_returns_string(self, store):
result = store.query("SELECT 1")
assert result.strip() == "1"
def test_query_with_format(self, store):
result = store.query("SELECT 1 AS val FORMAT JSONEachRow")
row = json.loads(result.strip())
assert row["val"] == 1