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:
259
MALKHUT/malkhut/tests/test_prod_tooling.py
Normal file
259
MALKHUT/malkhut/tests/test_prod_tooling.py
Normal file
@@ -0,0 +1,259 @@
|
||||
"""
|
||||
Tests for cognition launcher, news sources, and monitor.
|
||||
"""
|
||||
import json
|
||||
import os
|
||||
import tempfile
|
||||
import time
|
||||
import pytest
|
||||
from malkhut.cognition_launcher import CognitionLauncher, CognitionConfig
|
||||
from malkhut.training.news_sources import NewsSourceRepository, SourceMetadata
|
||||
from malkhut.training.monitor import CognitionMonitor, CognitionMetrics
|
||||
|
||||
|
||||
# ══════════════════════════════════════════════════════════════════════════════
|
||||
# COGNITION LAUNCHER (8 tests)
|
||||
# ══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
class TestCognitionLauncher:
|
||||
def test_launcher_creates(self):
|
||||
launcher = CognitionLauncher()
|
||||
assert launcher._running is False
|
||||
assert launcher._total_fetched == 0
|
||||
|
||||
def test_launcher_config(self):
|
||||
cfg = CognitionConfig(rate_limit_rpm=10, fetch_interval_s=5)
|
||||
launcher = CognitionLauncher(config=cfg)
|
||||
assert launcher.config.rate_limit_rpm == 10
|
||||
|
||||
def test_launcher_loads_regimes(self):
|
||||
path = '/tmp/test_regimes_e2e.json'
|
||||
with open(path, 'w') as f:
|
||||
json.dump({"flash_crash": {"source": "test"}}, f)
|
||||
try:
|
||||
launcher = CognitionLauncher(CognitionConfig(regime_db_path=path))
|
||||
assert launcher._total_regimes == 1
|
||||
finally:
|
||||
os.unlink(path)
|
||||
|
||||
def test_launcher_saves_regimes(self):
|
||||
with tempfile.NamedTemporaryFile(suffix=".json", delete=False) as f:
|
||||
path = f.name
|
||||
try:
|
||||
launcher = CognitionLauncher(CognitionConfig(regime_db_path=path))
|
||||
launcher._discovered_regimes["test"] = {"source": "test"}
|
||||
launcher._save_regimes()
|
||||
with open(path) as f:
|
||||
data = json.load(f)
|
||||
assert "test" in data
|
||||
finally:
|
||||
os.unlink(path)
|
||||
|
||||
|
||||
# ══════════════════════════════════════════════════════════════════════════════
|
||||
# NEWS SOURCE REPOSITORY (15 tests)
|
||||
# ══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
class TestNewsSourceRepository:
|
||||
def test_register_source(self):
|
||||
with tempfile.NamedTemporaryFile(suffix=".json", delete=False) as f:
|
||||
path = f.name
|
||||
try:
|
||||
repo = NewsSourceRepository(path)
|
||||
repo.register("s1", "Test", "https://example.com", "news", 0.8, 0.9, 1.0)
|
||||
assert repo.source_count == 1
|
||||
finally:
|
||||
os.unlink(path)
|
||||
|
||||
def test_rank_by_relevance(self):
|
||||
with tempfile.NamedTemporaryFile(suffix=".json", delete=False) as f:
|
||||
path = f.name
|
||||
try:
|
||||
repo = NewsSourceRepository(path)
|
||||
repo.register("s1", "Low", "https://a.com", "news", 0.3, 0.8, 1.0)
|
||||
repo.register("s2", "High", "https://b.com", "news", 0.9, 0.9, 1.0)
|
||||
ranked = repo.rank_by_relevance()
|
||||
assert ranked[0].source_id == "s2"
|
||||
finally:
|
||||
os.unlink(path)
|
||||
|
||||
def test_rank_by_health(self):
|
||||
with tempfile.NamedTemporaryFile(suffix=".json", delete=False) as f:
|
||||
path = f.name
|
||||
try:
|
||||
repo = NewsSourceRepository(path)
|
||||
repo.register("s1", "Good", "https://a.com", reliability=0.95)
|
||||
repo.register("s2", "Bad", "https://b.com", reliability=0.5)
|
||||
ranked = repo.rank_by_health()
|
||||
assert ranked[0].source_id == "s1"
|
||||
finally:
|
||||
os.unlink(path)
|
||||
|
||||
def test_get_by_type(self):
|
||||
with tempfile.NamedTemporaryFile(suffix=".json", delete=False) as f:
|
||||
path = f.name
|
||||
try:
|
||||
repo = NewsSourceRepository(path)
|
||||
repo.register("s1", "News", "https://news.com", "news")
|
||||
repo.register("s2", "Data", "https://data.com", "data")
|
||||
assert len(repo.get_by_type("news")) == 1
|
||||
assert len(repo.get_by_type("data")) == 1
|
||||
finally:
|
||||
os.unlink(path)
|
||||
|
||||
def test_get_by_tag(self):
|
||||
with tempfile.NamedTemporaryFile(suffix=".json", delete=False) as f:
|
||||
path = f.name
|
||||
try:
|
||||
repo = NewsSourceRepository(path)
|
||||
repo.register("s1", "Test", "https://example.com", tags=("crypto", "news"))
|
||||
assert len(repo.get_by_tag("crypto")) == 1
|
||||
finally:
|
||||
os.unlink(path)
|
||||
|
||||
def test_disable_enable(self):
|
||||
with tempfile.NamedTemporaryFile(suffix=".json", delete=False) as f:
|
||||
path = f.name
|
||||
try:
|
||||
repo = NewsSourceRepository(path)
|
||||
repo.register("s1", "Test", "https://example.com")
|
||||
assert repo.enabled_count == 1
|
||||
repo.disable("s1")
|
||||
assert repo.enabled_count == 0
|
||||
repo.enable("s1")
|
||||
assert repo.enabled_count == 1
|
||||
finally:
|
||||
os.unlink(path)
|
||||
|
||||
def test_persistence(self):
|
||||
with tempfile.NamedTemporaryFile(suffix=".json", delete=False) as f:
|
||||
path = f.name
|
||||
try:
|
||||
repo1 = NewsSourceRepository(path)
|
||||
repo1.register("s1", "Test", "https://example.com")
|
||||
repo1.record_fetch("s1", success=True)
|
||||
|
||||
repo2 = NewsSourceRepository(path)
|
||||
assert repo2.source_count == 1
|
||||
assert repo2.get_enabled()[0].fetch_count == 1
|
||||
finally:
|
||||
os.unlink(path)
|
||||
|
||||
def test_seed_defaults(self):
|
||||
with tempfile.NamedTemporaryFile(suffix=".json", delete=False) as f:
|
||||
path = f.name
|
||||
try:
|
||||
repo = NewsSourceRepository(path)
|
||||
repo.seed_defaults()
|
||||
assert repo.source_count >= 10
|
||||
finally:
|
||||
os.unlink(path)
|
||||
|
||||
def test_health_score(self):
|
||||
s = SourceMetadata(source_id="s1", name="Test", url="https://x.com",
|
||||
source_type="news", regime_relevance=0.5, reliability=0.9,
|
||||
freshness_hours=1.0, fetch_count=10, error_count=1)
|
||||
assert s.health_score > 0
|
||||
assert s.health_score < 1.0
|
||||
|
||||
|
||||
# ══════════════════════════════════════════════════════════════════════════════
|
||||
# COGNITION MONITOR (10 tests)
|
||||
# ══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
class TestCognitionMonitor:
|
||||
def test_record_fetch(self):
|
||||
with tempfile.NamedTemporaryFile(suffix=".log", delete=False) as f:
|
||||
path = f.name
|
||||
try:
|
||||
mon = CognitionMonitor(path)
|
||||
mon.record_fetch("s1", success=True)
|
||||
assert mon.total_fetched == 1
|
||||
finally:
|
||||
os.unlink(path)
|
||||
|
||||
def test_record_error(self):
|
||||
with tempfile.NamedTemporaryFile(suffix=".log", delete=False) as f:
|
||||
path = f.name
|
||||
try:
|
||||
mon = CognitionMonitor(path)
|
||||
mon.record_fetch("s1", success=False)
|
||||
assert mon.total_errors == 1
|
||||
finally:
|
||||
os.unlink(path)
|
||||
|
||||
def test_record_regime(self):
|
||||
with tempfile.NamedTemporaryFile(suffix=".log", delete=False) as f:
|
||||
path = f.name
|
||||
try:
|
||||
mon = CognitionMonitor(path)
|
||||
mon.record_regime(3)
|
||||
assert mon.discovered_regimes == 3
|
||||
finally:
|
||||
os.unlink(path)
|
||||
|
||||
def test_snapshot(self):
|
||||
with tempfile.NamedTemporaryFile(suffix=".log", delete=False) as f:
|
||||
path = f.name
|
||||
try:
|
||||
mon = CognitionMonitor(path)
|
||||
mon.record_fetch("s1", success=True)
|
||||
metrics = mon.snapshot(total_sources=5, enabled_sources=4)
|
||||
assert isinstance(metrics, CognitionMetrics)
|
||||
assert metrics.total_fetched == 1
|
||||
finally:
|
||||
os.unlink(path)
|
||||
|
||||
def test_metrics_logged(self):
|
||||
with tempfile.NamedTemporaryFile(suffix=".log", delete=False) as f:
|
||||
path = f.name
|
||||
try:
|
||||
mon = CognitionMonitor(path)
|
||||
mon.snapshot(total_sources=5, enabled_sources=4)
|
||||
with open(path) as f:
|
||||
lines = f.readlines()
|
||||
assert len(lines) == 1
|
||||
record = json.loads(lines[0])
|
||||
assert "sources" in record
|
||||
finally:
|
||||
os.unlink(path)
|
||||
|
||||
def test_check_alerts_high_error(self):
|
||||
with tempfile.NamedTemporaryFile(suffix=".log", delete=False) as f:
|
||||
path = f.name
|
||||
try:
|
||||
mon = CognitionMonitor(path)
|
||||
for _ in range(20):
|
||||
mon.record_fetch("s1", success=False)
|
||||
mon.record_fetch("s1", success=True)
|
||||
mon.snapshot(total_sources=1, enabled_sources=1)
|
||||
alerts = mon.check_alerts()
|
||||
assert len(alerts) > 0
|
||||
finally:
|
||||
os.unlink(path)
|
||||
|
||||
def test_check_alerts_low_fetch_rate(self):
|
||||
with tempfile.NamedTemporaryFile(suffix=".log", delete=False) as f:
|
||||
path = f.name
|
||||
try:
|
||||
mon = CognitionMonitor(path)
|
||||
mon._start_time = time.time() - 600 # 10 min ago
|
||||
mon.record_fetch("s1", success=True) # only 1 fetch in 10 min
|
||||
mon.snapshot(total_sources=1, enabled_sources=1)
|
||||
alerts = mon.check_alerts()
|
||||
assert any("LOW_FETCH_RATE" in a for a in alerts)
|
||||
finally:
|
||||
os.unlink(path)
|
||||
|
||||
def test_check_alerts_clean(self):
|
||||
with tempfile.NamedTemporaryFile(suffix=".log", delete=False) as f:
|
||||
path = f.name
|
||||
try:
|
||||
mon = CognitionMonitor(path)
|
||||
for _ in range(100):
|
||||
mon.record_fetch("s1", success=True)
|
||||
mon.snapshot(total_sources=1, enabled_sources=1)
|
||||
alerts = mon.check_alerts()
|
||||
assert len(alerts) == 0
|
||||
finally:
|
||||
os.unlink(path)
|
||||
Reference in New Issue
Block a user