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
This commit is contained in:
80
MALKHUT/malkhut/tests/test_storage_ch.py
Normal file
80
MALKHUT/malkhut/tests/test_storage_ch.py
Normal file
@@ -0,0 +1,80 @@
|
||||
"""
|
||||
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
|
||||
Reference in New Issue
Block a user