Files
sentiment-engine/MALKHUT/malkhut/tests/test_concurrency.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

159 lines
5.1 KiB
Python

"""
Concurrency / race condition tests.
Verifies Zinc SHM IPC is safe under concurrent reader/writer access.
Uses threading to simulate real multi-process patterns.
"""
import threading
import time
import pytest
from malkhut.ipc.zinc_plane import MalkhutZincPlane
from malkhut.ipc.control_plane import MalkhutControlPlane, ControlPlaneFrame
class TestZincSHMConcurrency:
def test_writer_reader_concurrent(self):
"""Writer and reader operate concurrently without corruption."""
plane = MalkhutZincPlane(prefix="concurrent_test")
errors = []
def writer():
try:
for i in range(20):
plane.publish_book({"seq": i, "ts": time.time_ns()})
time.sleep(0.001)
except Exception as e:
errors.append(("writer", e))
def reader():
try:
for _ in range(20):
try:
data, seq = plane.read_book(timeout_ms=50)
except Exception:
pass # timeout is acceptable
time.sleep(0.002)
except Exception as e:
errors.append(("reader", e))
t1 = threading.Thread(target=writer)
t2 = threading.Thread(target=reader)
t1.start()
t2.start()
t1.join(timeout=5)
t2.join(timeout=5)
plane.close_all()
assert len(errors) == 0, f"Errors: {errors}"
def test_multiple_readers(self):
"""Multiple readers can read from the same region without conflict."""
plane = MalkhutZincPlane(prefix="multi_reader_test")
plane.publish_book({"test": "data"})
results = []
errors = []
def reader(idx):
try:
for _ in range(10):
try:
data, seq = plane.read_book(timeout_ms=50)
results.append((idx, seq))
except Exception:
pass
time.sleep(0.001)
except Exception as e:
errors.append((idx, e))
threads = [threading.Thread(target=reader, args=(i,)) for i in range(3)]
for t in threads:
t.start()
for t in threads:
t.join(timeout=5)
plane.close_all()
assert len(errors) == 0
assert len(results) > 0
def test_rapid_write_read_cycles(self):
"""Rapid write/read cycles don't corrupt the region."""
plane = MalkhutZincPlane(prefix="rapid_test")
for i in range(100):
plane.publish_book({"cycle": i})
data, seq = plane.read_book(timeout_ms=50)
assert data["cycle"] == i
plane.close_all()
class TestControlPlaneConcurrency:
def test_command_write_read(self):
"""Control plane commands can be written and read."""
cp = MalkhutControlPlane()
frame = ControlPlaneFrame(
command="START", ts_ns=time.time_ns(),
target_symbols=("BTCUSDT",), source="test",
)
cp.publish_command(frame)
cmd = cp.read_command(timeout_ms=50)
assert cmd is not None
assert cmd.command == "START"
assert cmd.target_symbols == ("BTCUSDT",)
cp.close()
def test_ack_write_read(self):
"""ACK frames can be written and read."""
cp = MalkhutControlPlane()
cp.publish_ack("START", time.time_ns(), "ok", "engine started")
cmd = cp.read_command(timeout_ms=50)
assert cmd is not None
assert "ACK_START" in cmd.command
cp.close()
def test_emergency_stop(self):
"""Emergency stop command is processed."""
cp = MalkhutControlPlane()
frame = ControlPlaneFrame(
command="EMERGENCY_STOP", ts_ns=time.time_ns(), source="test",
)
cp.publish_command(frame)
cmd = cp.read_command(timeout_ms=50)
assert cmd is not None
assert cmd.command == "EMERGENCY_STOP"
cp.close()
class TestZincRegionIsolation:
def test_different_prefixes_independent(self):
"""Different prefixes create independent regions."""
p1 = MalkhutZincPlane(prefix="iso_a")
p2 = MalkhutZincPlane(prefix="iso_b")
p1.publish_book({"source": "a"})
p2.publish_book({"source": "b"})
d1, _ = p1.read_book()
d2, _ = p2.read_book()
assert d1["source"] == "a"
assert d2["source"] == "b"
p1.close_all()
p2.close_all()
def test_multiple_region_types(self):
"""Different region types (book, account, fulfilment, risk) are independent."""
plane = MalkhutZincPlane(prefix="multi_region")
plane.publish_book({"type": "book"})
plane.publish_account({"type": "account"})
plane.publish_fulfilment({"type": "fulfilment"})
plane.publish_risk({"type": "risk"})
b, _ = plane.read_book()
a, _ = plane.read_account()
f, _ = plane.read_fulfilment()
r, _ = plane.read_risk()
assert b["type"] == "book"
assert a["type"] == "account"
assert f["type"] == "fulfilment"
assert r["type"] == "risk"
plane.close_all()