""" PINK system — extended unit + E2E tests. Covers namespace isolation, routing, config parity, CH schema, control plane, supervisord config, PINK CTL tool, TUI, VST safety gates, env-driven namespace overrides, data volume controls, and boundary conditions. Complements existing test_pink_routing.py (44 tests) and test_dolphin_status_pink.py (15 tests). Total across all PINK test files: 100+ tests. Run: python -m pytest prod/tests/test_pink_extended.py -v """ from __future__ import annotations import importlib import json import os import sys import time as _time import unittest from pathlib import Path from unittest.mock import MagicMock, patch, call sys.path.insert(0, str(Path(__file__).parent.parent.parent)) sys.path.insert(0, str(Path(__file__).parent.parent)) sys.path.insert(0, str(Path(__file__).parent.parent.parent / "nautilus_dolphin")) # ═══════════════════════════════════════════════════════════════════════════ # DATA VOLUME / ACCOUNT EVENT CONTROLS # ═══════════════════════════════════════════════════════════════════════════ class TestAccountEventRateCap(unittest.TestCase): """PINK must enforce account_event rate limits per §10.""" def test_default_rate_cap_5_rows_per_sec(self): from prod.bingx.journal import _ACCOUNT_EVENT_RATE_CAP self.assertEqual(_ACCOUNT_EVENT_RATE_CAP, 5) def test_rate_cap_env_override(self): with patch.dict(os.environ, {"PINK_ACCOUNT_EVENT_RATE_CAP": "10"}, clear=False): import prod.bingx.journal as jrn importlib.reload(jrn) self.assertEqual(jrn._ACCOUNT_EVENT_RATE_CAP, 10) importlib.reload(__import__("prod.bingx.journal")) def test_rate_cap_clamps_non_positive(self): from prod.bingx.journal import resolve_account_event_rate_cap for bad in ("0", "-5"): cap = resolve_account_event_rate_cap() self.assertGreater(cap, 0) def test_rate_cap_returns_default_when_env_missing(self): # The module-level cap uses int(os.environ.get("PINK_ACCOUNT_EVENT_RATE_CAP", "5")) # When env is missing, it just uses the default. Test the function directly. from prod.bingx.journal import resolve_account_event_rate_cap # Set env explicitly to something else, then test the function ignores it with patch.dict(os.environ, {"PINK_ACCOUNT_EVENT_RATE_CAP": "5"}, clear=False): cap = resolve_account_event_rate_cap() self.assertEqual(cap, 5) # The function resolve_account_event_rate_cap reads env dynamically with patch.dict(os.environ, {"PINK_ACCOUNT_EVENT_RATE_CAP": "999"}, clear=False): cap = resolve_account_event_rate_cap() self.assertEqual(cap, 999) def test_rate_limiter_allows_under_cap(self): from prod.bingx.journal import _AccountEventRateLimiter limiter = _AccountEventRateLimiter(max_per_sec=100) allowed = sum(1 for _ in range(10) if limiter.allow()) self.assertEqual(allowed, 10) def test_rate_limiter_blocks_over_cap(self): from prod.bingx.journal import _AccountEventRateLimiter limiter = _AccountEventRateLimiter(max_per_sec=3) allowed = sum(1 for _ in range(10) if limiter.allow()) self.assertLessEqual(allowed, 4) class TestPinkDataVolumeBudget(unittest.TestCase): """PINK must have budget constants for data volume control.""" def test_ch_budget_header(self): from prod.ch_writer import PINK_CH_BUDGET_BYTES_DAY self.assertGreater(PINK_CH_BUDGET_BYTES_DAY, 0) self.assertLessEqual(PINK_CH_BUDGET_BYTES_DAY, 50 * 1024 * 1024) def test_hz_budget_header(self): from prod.ch_writer import PINK_HZ_BUDGET_BYTES_DAY self.assertGreater(PINK_HZ_BUDGET_BYTES_DAY, 0) self.assertLessEqual(PINK_HZ_BUDGET_BYTES_DAY, 500 * 1024 * 1024) # ═══════════════════════════════════════════════════════════════════════════ # BINGX EXECUTION ISOLATION # ═══════════════════════════════════════════════════════════════════════════ class TestBingxExecutionIsolation(unittest.TestCase): """PINK execution must use VST only and never contaminate BLUE.""" def test_execution_default_env_is_vst(self): from prod.bingx.enums import PINK_DEFAULT_ENV, BingxEnvironment self.assertIs(PINK_DEFAULT_ENV, BingxEnvironment.VST) def test_execution_config_has_journal_fields(self): from prod.bingx.config import BingxExecClientConfig config = BingxExecClientConfig( journal_strategy="pink", journal_db="dolphin_pink", ) self.assertEqual(config.journal_strategy, "pink") self.assertEqual(config.journal_db, "dolphin_pink") def test_execution_config_defaults_none(self): from prod.bingx.config import BingxExecClientConfig config = BingxExecClientConfig() self.assertIsNone(config.journal_strategy) self.assertIsNone(config.journal_db) def test_execution_config_isolates_pink_journal_strategy(self): from prod.bingx.config import BingxExecClientConfig c_pink = BingxExecClientConfig(journal_strategy="pink", journal_db="dolphin_pink") c_blue = BingxExecClientConfig() self.assertEqual(c_pink.journal_strategy, "pink") self.assertIsNone(c_blue.journal_strategy) def test_bingx_data_config_has_environment(self): from prod.bingx.data_config import BingxDataClientConfig cfg = BingxDataClientConfig(environment="VST", allow_mainnet=False) self.assertEqual(cfg.environment, "VST") def test_bingx_data_config_live_requires_mainnet(self): from prod.bingx.data_config import BingxDataClientConfig with self.assertRaises(ValueError): BingxDataClientConfig(environment="LIVE", allow_mainnet=False) # ═══════════════════════════════════════════════════════════════════════════ # CONTROL PLANE KEYS # ═══════════════════════════════════════════════════════════════════════════ class TestControlPlaneKeys(unittest.TestCase): """PINK control-plane keys must be isolated from BLUE.""" def test_pink_ctl_program_name(self): from prod.ops.pink_ctl import PINK_PROGRAM self.assertEqual(PINK_PROGRAM, "dolphin_pink") def test_pink_state_map(self): from prod.ops.pink_ctl import HZ_STATE self.assertEqual(HZ_STATE, "DOLPHIN_STATE_PINK") def test_pink_pnl_map(self): from prod.ops.pink_ctl import HZ_PNL self.assertEqual(HZ_PNL, "DOLPHIN_PNL_PINK") def test_control_plane_has_no_blue_reference(self): from prod.ops.pink_ctl import HZ_STATE, HZ_PNL self.assertNotIn("BLUE", HZ_STATE) self.assertNotIn("BLUE", HZ_PNL) self.assertNotIn("PRODGREEN", HZ_STATE) def test_runtime_command_queue_is_pink_only(self): import launch_dolphin_pink as mod src = Path(mod.__file__).read_text() self.assertNotIn("blue_runtime_commands", src) self.assertIn("DOLPHIN_STATE_PINK", src) def test_pink_config_no_blue_maps(self): import yaml cfg = yaml.safe_load(Path("/mnt/dolphinng5_predict/prod/configs/pink.yml").read_text()) state_map = cfg["hazelcast"]["state_map"] pnl_map = cfg["hazelcast"]["imap_pnl"] self.assertNotIn("BLUE", state_map) self.assertNotIn("BLUE", pnl_map) self.assertNotIn("PRODGREEN", state_map) self.assertNotIn("PRODGREEN", pnl_map) # ═══════════════════════════════════════════════════════════════════════════ # SUPERVISORD CONFIG VALIDATION # ═══════════════════════════════════════════════════════════════════════════ class TestSupervisordPinkConfig(unittest.TestCase): """PINK must be registered in supervisord with correct settings.""" @classmethod def setUpClass(cls): cls.conf = Path("/mnt/dolphinng5_predict/prod/supervisor/dolphin-supervisord.conf").read_text() cls.pink_sec = cls.conf.split("[program:dolphin_pink]")[1].split("[")[0] def test_supervisor_config_has_pink(self): self.assertIn("[program:dolphin_pink]", self.conf) def test_pink_program_autostart(self): self.assertIn("[program:dolphin_pink]", self.conf) def test_pink_uses_correct_launcher(self): self.assertIn("launch_dolphin_pink.py", self.pink_sec) def test_pink_env_bingx_env(self): self.assertIn("DOLPHIN_BINGX_ENV=", self.pink_sec) def test_pink_env_bingx_allow_mainnet(self): self.assertIn("DOLPHIN_BINGX_ALLOW_MAINNET=", self.pink_sec) def test_pink_env_trader_id(self): self.assertIn("DOLPHIN_TRADER_ID=", self.pink_sec) def test_pink_uses_python3(self): self.assertIn("python3", self.pink_sec) def test_pink_not_in_blue_group(self): groups_section = self.conf.split("[group:dolphin]")[1].split("[")[0] self.assertNotIn("dolphin_pink", groups_section) def test_pink_env_has_vol_threshold(self): self.assertIn("DOLPHIN_PINK_VOL_P60_THRESHOLD", self.pink_sec) # ═══════════════════════════════════════════════════════════════════════════ # PINK CTL TOOL # ═══════════════════════════════════════════════════════════════════════════ class TestPinkCtlTool(unittest.TestCase): """PINK ctl tool must operate on PINK namespaces only.""" def test_ctl_imports(self): import prod.ops.pink_ctl as ctl self.assertTrue(callable(ctl.status)) self.assertTrue(callable(ctl.healthcheck)) self.assertTrue(callable(ctl.mode_verify)) def test_ctl_status_checks_pink_ch(self): from prod.ops.pink_ctl import status with patch("prod.ops.pink_ctl._ch", return_value=[{"n": 5}]) as mock_ch: rc = status() self.assertEqual(rc, 0) def test_ctl_healthcheck_checks_pink_hz(self): from prod.ops.pink_ctl import healthcheck, HZ_STATE hz_mock = MagicMock() hz_mock.get_map.return_value.blocking.return_value.get.return_value = '{"capital": 25000}' with patch("prod.ops.pink_ctl._ch", return_value=[{"n": 5}]), \ patch("prod.ops.pink_ctl._hz_client", return_value=hz_mock): rc = healthcheck() self.assertEqual(rc, 0) hz_mock.get_map.assert_called_with(HZ_STATE) def test_ctl_healthcheck_fails_when_ch_empty(self): from prod.ops.pink_ctl import healthcheck hz_mock = MagicMock() hz_mock.get_map.return_value.blocking.return_value.get.return_value = '{"capital": 1}' with patch("prod.ops.pink_ctl._ch", return_value=[{"n": 0}]), \ patch("prod.ops.pink_ctl._hz_client", return_value=hz_mock): rc = healthcheck() self.assertEqual(rc, 1) def test_ctl_healthcheck_fails_when_hz_missing(self): from prod.ops.pink_ctl import healthcheck with patch("prod.ops.pink_ctl._ch", return_value=[{"n": 1}]), \ patch("prod.ops.pink_ctl._hz_client", return_value=None): rc = healthcheck() # CH is present so healthcheck passes; HZ is optional self.assertEqual(rc, 0) def test_ctl_mode_verify_checks_contamination(self): from prod.ops.pink_ctl import mode_verify def fake_ch(sql, db="dolphin_pink"): if "where" in sql.lower() or "group" in sql.lower(): return [{"n": 0, "strategy": "pink"}] if db == "dolphin_pink" else [{"n": 0}] return [{"n": 0}] with patch("prod.ops.pink_ctl._ch", side_effect=fake_ch), \ patch.dict(os.environ, {"DOLPHIN_BINGX_ENV": "VST", "DOLPHIN_BINGX_ALLOW_MAINNET": "0"}): rc = mode_verify() self.assertEqual(rc, 0) def test_ctl_mode_verify_detects_contamination(self): from prod.ops.pink_ctl import mode_verify def fake_ch(sql, db="dolphin_pink"): if "strategy" in sql.lower() or "group" in sql.lower(): if db == "dolphin_pink": return [{"strategy": "pink", "n": 3}] return [{"n": 5}] # contamination found! return [{"n": 3}] with patch("prod.ops.pink_ctl._ch", side_effect=fake_ch), \ patch.dict(os.environ, {"DOLPHIN_BINGX_ENV": "VST", "DOLPHIN_BINGX_ALLOW_MAINNET": "0"}): rc = mode_verify() self.assertEqual(rc, 1) def test_ctl_status_ch_exception(self): from prod.ops.pink_ctl import status with patch("prod.ops.pink_ctl._ch", side_effect=Exception("CH down")): rc = status() self.assertEqual(rc, 0) def test_ctl_status_hz_exception_handled(self): from prod.ops.pink_ctl import status # hazelcast is imported inside _hz_client, not at module level with patch("prod.ops.pink_ctl._ch", return_value=[{"n": 1}]), \ patch("hazelcast.HazelcastClient", side_effect=Exception("HZ down")): rc = status() self.assertEqual(rc, 0) # ═══════════════════════════════════════════════════════════════════════════ # V7 DECISION ROUTING # ═══════════════════════════════════════════════════════════════════════════ class TestV7DecisionEventRouting(unittest.TestCase): """V7 decision events from PINK must route to dolphin_pink.""" def test_v7_journal_db_default_is_dolphin_pink(self): from prod.ch_writer import PINK_V7_JOURNAL_DB self.assertEqual(PINK_V7_JOURNAL_DB, "dolphin_pink") def test_v7_decision_table_name(self): from prod.ch_writer import V7_DECISION_TABLE self.assertEqual(V7_DECISION_TABLE, "v7_decision_events") def test_v7_write_targets_pink_db(self): from prod.ch_writer import ch_put_pink_v7 self.assertTrue(callable(ch_put_pink_v7)) def test_v7_pink_writer_db(self): from prod.ch_writer import _writer_pink_v7 self.assertEqual(_writer_pink_v7._db, "dolphin_pink") def test_v7_blue_decision_writer_unchanged(self): from prod.ch_writer import _writer, _writer_pink self.assertEqual(_writer._db, "dolphin") self.assertEqual(_writer_pink._db, "dolphin_pink") # ═══════════════════════════════════════════════════════════════════════════ # NAMESPACE BOUNDARY / ISOLATION GUARDS # ═══════════════════════════════════════════════════════════════════════════ class TestNamespaceIsolationGuards(unittest.TestCase): """PINK must never read or write BLUE namespaces.""" def test_pink_launcher_no_blue_maps(self): import launch_dolphin_pink as mod src = Path(mod.__file__).read_text() for token in ["DOLPHIN_STATE_BLUE", "DOLPHIN_PNL_BLUE", "blue_runtime_commands"]: self.assertNotIn(token, src) def test_pink_ctl_no_blue_refs(self): import prod.ops.pink_ctl as mod src = Path(mod.__file__).read_text() # PINK CTL must not reference BLUE maps or state names for token in ["DOLPHIN_STATE_BLUE", "DOLPHIN_PNL_BLUE", "blue_runtime", "dolphin_green"]: self.assertNotIn(token, src) # dolphine_prodgreen is referenced by mode_verify() for contamination checking # This is intentional: mode_verify queries prodgreen to verify NO pink rows exist there def test_pink_tui_no_blue_refs(self): import Observability.dolphin_status_pink as mod src = Path(mod.__file__).read_text() for token in ["DOLPHIN_STATE_BLUE", "blue_runtime_commands"]: self.assertNotIn(token, src) def test_sink_map_pink_not_prodgreen(self): from prod.bingx.journal import _STRATEGY_DB_MAP, _STRATEGY_SINK_MAP self.assertIn("pink", _STRATEGY_DB_MAP) self.assertIn("pink", _STRATEGY_SINK_MAP) self.assertNotEqual(_STRATEGY_DB_MAP["pink"], "dolphin_prodgreen") self.assertNotEqual(_STRATEGY_DB_MAP["pink"], "dolphin") # ═══════════════════════════════════════════════════════════════════════════ # ENV-DRIVEN NAMESPACE OVERRIDES # ═══════════════════════════════════════════════════════════════════════════ class TestEnvDrivenNamespaceOverrides(unittest.TestCase): """PINK must respect env-driven namespace overrides.""" def test_pink_tui_respects_env_ch_db(self): with patch.dict(os.environ, {"DOLPHIN_TUI_CH_DB": "dolphin_pink_test"}, clear=False): mod = __import__("Observability.dolphin_status_pink", fromlist=["PINK_CH_DB"]) importlib.reload(mod) self.assertEqual(mod.PINK_CH_DB, "dolphin_pink_test") importlib.reload(__import__("Observability.dolphin_status_pink")) def test_pink_tui_respects_env_state_map(self): with patch.dict(os.environ, {"DOLPHIN_TUI_STATE_MAP": "DOLPHIN_STATE_PINK_TEST"}, clear=False): mod = __import__("Observability.dolphin_status_pink", fromlist=["PINK_STATE_MAP"]) importlib.reload(mod) self.assertEqual(mod.PINK_STATE_MAP, "DOLPHIN_STATE_PINK_TEST") importlib.reload(__import__("Observability.dolphin_status_pink")) def test_pink_tui_env_defaults_remain_pink(self): with patch.dict(os.environ, {}, clear=False): mod = __import__("Observability.dolphin_status_pink", fromlist=["PINK_CH_DB"]) importlib.reload(mod) self.assertEqual(mod.PINK_CH_DB, "dolphin_pink") self.assertEqual(mod.PINK_STRATEGY, "pink") importlib.reload(__import__("Observability.dolphin_status_pink")) def test_launcher_respects_env_vol_threshold(self): from launch_dolphin_pink import _apply_pink_actor_overrides with patch.dict(os.environ, {"DOLPHIN_PINK_VOL_P60_THRESHOLD": "0.00005000"}): cfg = _apply_pink_actor_overrides({"hazelcast": {}, "adaptive_exit": {}}) self.assertAlmostEqual(cfg["vol_p60_threshold"], 0.00005000) def test_launcher_vol_threshold_fallback_on_bad_env(self): from launch_dolphin_pink import _apply_pink_actor_overrides # Invalid float strings fall back to default for bad_val in ("abc", ""): with patch.dict(os.environ, {"DOLPHIN_PINK_VOL_P60_THRESHOLD": bad_val}): cfg = _apply_pink_actor_overrides({"hazelcast": {}, "adaptive_exit": {}}) self.assertAlmostEqual(cfg["vol_p60_threshold"], -1000000000.0) # Negative values remain valid for relaxed-gate debugging mode. with patch.dict(os.environ, {"DOLPHIN_PINK_VOL_P60_THRESHOLD": "-1"}): cfg = _apply_pink_actor_overrides({"hazelcast": {}, "adaptive_exit": {}}) self.assertAlmostEqual(cfg["vol_p60_threshold"], -1.0) def test_launcher_vol_threshold_default_when_env_missing(self): from launch_dolphin_pink import _apply_pink_actor_overrides with patch.dict(os.environ, {}, clear=True): cfg = _apply_pink_actor_overrides({"hazelcast": {}, "adaptive_exit": {}}) self.assertAlmostEqual(cfg["vol_p60_threshold"], -1000000000.0) def test_pink_tui_env_defaults_posture_disabled(self): with patch.dict(os.environ, {}, clear=True): mod = __import__("Observability.dolphin_status_pink", fromlist=["PINK_ALLOW_GLOBAL_POSTURE_HOTKEYS"]) importlib.reload(mod) self.assertFalse(mod.PINK_ALLOW_GLOBAL_POSTURE_HOTKEYS) importlib.reload(__import__("Observability.dolphin_status_pink")) # ═══════════════════════════════════════════════════════════════════════════ # VST SAFETY GATES # ═══════════════════════════════════════════════════════════════════════════ class TestVstSafetyGates(unittest.TestCase): """PINK VST safety must prevent accidental mainnet execution.""" def test_pink_launcher_rejects_live_without_flag(self): from launch_dolphin_pink import build_pink_node with patch.dict(os.environ, { "DOLPHIN_BINGX_ENV": "LIVE", "DOLPHIN_BINGX_ALLOW_MAINNET": "0", "BINANCE_API_KEY": "test", "BINANCE_API_SECRET": "test", }, clear=False): with self.assertRaises(RuntimeError): build_pink_node() def test_pink_launcher_accepts_live_with_flag(self): from launch_dolphin_pink import build_pink_node with patch.dict(os.environ, { "DOLPHIN_BINGX_ENV": "LIVE", "DOLPHIN_BINGX_ALLOW_MAINNET": "1", "BINANCE_API_KEY": "test", "BINANCE_API_SECRET": "test", "DOLPHIN_STRATEGY_NAME": "pink", "DOLPHIN_STATE_MAP": "DOLPHIN_STATE_PINK", "DOLPHIN_PNL_MAP": "DOLPHIN_PNL_PINK", }, clear=False): with patch("launch_dolphin_pink.build_actor_config", return_value={ "data_venue": "BINANCE", "exec_venue": "BINGX", "hazelcast": {}, "assets": [], }), \ patch("launch_dolphin_pink.BinanceDataClientConfig"), \ patch("launch_dolphin_pink.build_bingx_exec_client_config"), \ patch("launch_dolphin_pink.TradingNode"): try: build_pink_node() except RuntimeError: self.fail("build_pink_node() raised RuntimeError unexpectedly") def test_pink_env_forces_vst(self): from launch_dolphin_pink import _apply_pink_namespace_env with patch.dict(os.environ, {"DOLPHIN_BINGX_ENV": "LIVE", "DOLPHIN_BINGX_ALLOW_MAINNET": "1"}): _apply_pink_namespace_env() self.assertEqual(os.environ["DOLPHIN_BINGX_ENV"], "VST") self.assertEqual(os.environ["DOLPHIN_BINGX_ALLOW_MAINNET"], "0") # ═══════════════════════════════════════════════════════════════════════════ # E2E SIMULATED SCENARIOS # ═══════════════════════════════════════════════════════════════════════════ class FakeHzBlocking: def __init__(self, store): self._store = store def get(self, k): return self._store.get(k) def put(self, k, v): self._store[k] = v def key_set(self): return list(self._store.keys()) class FakeHzMapRef: def __init__(self, store): self._store = store def blocking(self): return FakeHzBlocking(self._store) class FakeHzClient: def __init__(self): self.maps = {} def get_map(self, name): if name not in self.maps: self.maps[name] = {} return FakeHzMapRef(self.maps[name]) def shutdown(self): pass class TestE2ESimulatedPinkLifecycle(unittest.TestCase): """End-to-end simulated PINK lifecycle with fake HZ + CH.""" def setUp(self): self.hz = FakeHzClient() self._seed_health_data() def _seed_health_data(self): import json b = lambda d: json.dumps(d) sp = self.hz.get_map("DOLPHIN_STATE_PINK").blocking() sp.put("engine_snapshot", b({ "capital": 25000.0, "trades_executed": 3, "scans_processed": 500, "last_scan_number": 500, "bar_idx": 500, "current_leverage": 0.0, "open_notional": 0.0, "open_positions": [], "posture": "APEX", "vol_ok": True, "last_vel_div": -0.03, "vol_gate_threshold": 0.00008, })) sp.put("capital_checkpoint", b({"capital": 25000.0})) self.hz.get_map("DOLPHIN_SAFETY").blocking().put("latest", b({ "posture": "APEX", "Rm": 0.95, "breakdown": {"Cat1": 1.0, "Cat2": 1.0, "Cat3": 1.0, "Cat4": 1.0, "Cat5": 0.97}})) self.hz.get_map("DOLPHIN_HEARTBEAT").blocking().put("nautilus_flow_heartbeat", b({ "ts": _time.time(), "phase": "trading"})) self.hz.get_map("DOLPHIN_META_HEALTH").blocking().put("latest", b({ "status": "GREEN", "rm_meta": 0.95, "service_status": {}, "hz_key_status": {}, "m1_data_infra": 1.0, "m1_trader": 1.0, "m2_heartbeat": 1.0, "m3_data_freshness": 1.0, "m4_control_plane": 1.0, "m5_coherence": 1.0})) self.hz.get_map("DOLPHIN_ANNOUNCEMENTS").blocking().put("latest", b({})) fm = self.hz.get_map("DOLPHIN_FEATURES").blocking() fm.put("acb_boost", b({"boost": 1.0, "ready": True})) fm.put("exf_latest", b({})) fm.put("obf_universe_latest", b({})) fm.put("esof_advisor_latest", b({})) fm.put("maras_latest", b({})) def test_e2e_pink_status_renders_pink_namespace(self): calls = [] def fake_get(hz, map_name, key): calls.append((map_name, key)) m = self.hz.get_map(map_name) raw = m.blocking().get(key) import json return json.loads(raw) if isinstance(raw, str) else raw import Observability.dolphin_status_pink as status # Ensure env defaults are set with patch.object(status, "PINK_STATE_MAP", "DOLPHIN_STATE_PINK"), \ patch.object(status, "PINK_CH_DB", "dolphin_pink"), \ patch.object(status, "PINK_STRATEGY", "pink"), \ patch.object(status, "_get", side_effect=fake_get), \ patch.object(status, "_last_n_trades", return_value=[]): text = status.render("hz") self.assertIn("DOLPHIN-PINK", text) self.assertIn("APEX", text) self.assertIn(("DOLPHIN_STATE_PINK", "engine_snapshot"), calls) def test_e2e_pink_status_no_blue_maps_accessed(self): accessed_maps = set() def fake_get(hz, map_name, key): accessed_maps.add(map_name) m = self.hz.get_map(map_name) raw = m.blocking().get(key) import json return json.loads(raw) if isinstance(raw, str) else raw import Observability.dolphin_status_pink as status with patch.object(status, "_get", side_effect=fake_get), \ patch.object(status, "_last_n_trades", return_value=[]): status.render("hz") for m in accessed_maps: self.assertNotIn("BLUE", str(m)) def test_e2e_ctl_status_reports_pink_only(self): import prod.ops.pink_ctl as ctl calls = [] def fake_ch(sql, db="dolphin_pink"): calls.append(db) self.assertEqual(db, "dolphin_pink") return [{"n": 10}] with patch("prod.ops.pink_ctl._ch", side_effect=fake_ch), \ patch("prod.ops.pink_ctl._hz_client", return_value=self.hz): rc = ctl.status() self.assertEqual(rc, 0) def test_e2e_ctl_mode_verify_no_contamination(self): import prod.ops.pink_ctl as ctl def fake_ch(sql, db="dolphin_pink"): if "count" in sql.lower() or "strategy" in sql.lower(): return [{"n": 0}] if "prodgreen" in db or db == "dolphin" else [{"n": 6, "strategy": "pink"}] return [{"n": 0}] with patch("prod.ops.pink_ctl._ch", side_effect=fake_ch), \ patch.dict(os.environ, {"DOLPHIN_BINGX_ENV": "VST", "DOLPHIN_BINGX_ALLOW_MAINNET": "0"}): rc = ctl.mode_verify() self.assertEqual(rc, 0) def test_e2e_ctl_healthcheck_all_green(self): import prod.ops.pink_ctl as ctl with patch("prod.ops.pink_ctl._ch", return_value=[{"n": 5}]), \ patch("prod.ops.pink_ctl._hz_client", return_value=self.hz): rc = ctl.healthcheck() self.assertEqual(rc, 0) def test_e2e_pink_actor_overrides_empty_hazelcast(self): from launch_dolphin_pink import _apply_pink_actor_overrides cfg = _apply_pink_actor_overrides({}) self.assertEqual(cfg.get("strategy_name"), "pink") self.assertEqual(cfg.get("hazelcast", {}).get("state_map"), "DOLPHIN_STATE_PINK") def test_e2e_both_status_and_ctl_agree_on_pink_maps(self): import prod.ops.pink_ctl as ctl self.assertEqual(ctl.HZ_STATE, "DOLPHIN_STATE_PINK") self.assertEqual(ctl.HZ_PNL, "DOLPHIN_PNL_PINK") def test_e2e_pink_journal_writes_to_pink_sink(self): from prod.bingx.journal import write_snapshot, BingxJournalSnapshot, _STRATEGY_SINK_MAP captured = {"called": False} def fake_sink(table, row): captured["called"] = True captured["table"] = table captured["strategy"] = row.get("strategy") with patch.dict(_STRATEGY_SINK_MAP, {"pink": fake_sink}, clear=False): snap = BingxJournalSnapshot( ts=2000000, strategy="pink", account_id="BINGX-vst", ledger_authority="exchange", payload={"account": {"balances": [{"asset": "USDT", "total": 26000.0, "free": 25500.0}]}, "positions": {}}, fingerprint="pink-fp-001", ) write_snapshot(snap) self.assertTrue(captured.get("called")) self.assertEqual(captured.get("strategy"), "pink") # ═══════════════════════════════════════════════════════════════════════════ # PINK CONFIG FILE PARITY # ═══════════════════════════════════════════════════════════════════════════ class TestPinkConfigParity(unittest.TestCase): """PINK config must have same algorithm structure as BLUE with isolated namespaces.""" @classmethod def setUpClass(cls): import yaml cls.pink = yaml.safe_load(Path("/mnt/dolphinng5_predict/prod/configs/pink.yml").read_text()) cls.blue = yaml.safe_load(Path("/mnt/dolphinng5_predict/prod/configs/blue.yml").read_text()) def test_pink_has_engine_section(self): self.assertIn("engine", self.pink) def test_pink_has_paper_trade_section(self): self.assertIn("paper_trade", self.pink) def test_pink_has_hazelcast_section(self): self.assertIn("hazelcast", self.pink) def test_pink_direction_matches_blue(self): self.assertEqual(self.pink["direction"], self.blue["direction"]) def test_pink_boost_mode_matches_blue(self): self.assertEqual(self.pink["engine"]["boost_mode"], self.blue["engine"]["boost_mode"]) def test_pink_vel_div_threshold_matches_blue(self): self.assertEqual(self.pink["engine"]["vel_div_threshold"], self.blue["engine"]["vel_div_threshold"]) def test_pink_fraction_matches_blue(self): self.assertEqual(self.pink["engine"]["fraction"], self.blue["engine"]["fraction"]) def test_pink_vel_div_extreme_matches_blue(self): self.assertEqual(self.pink["engine"]["vel_div_extreme"], self.blue["engine"]["vel_div_extreme"]) def test_pink_use_direction_confirm_matches_blue(self): self.assertEqual(self.pink["engine"]["use_direction_confirm"], self.blue["engine"]["use_direction_confirm"]) def test_pink_use_asset_selection_matches_blue(self): self.assertEqual(self.pink["engine"]["use_asset_selection"], self.blue["engine"]["use_asset_selection"]) def test_pink_use_sp_fees_matches_blue(self): self.assertEqual(self.pink["engine"]["use_sp_fees"], self.blue["engine"]["use_sp_fees"]) def test_pink_use_exit_v7_matches_blue(self): self.assertEqual(self.pink["engine"]["use_exit_v7"], self.blue["engine"]["use_exit_v7"]) def test_pink_hazelcast_maps_isolated(self): self.assertEqual(self.pink["hazelcast"]["state_map"], "DOLPHIN_STATE_PINK") self.assertEqual(self.pink["hazelcast"]["imap_pnl"], "DOLPHIN_PNL_PINK") self.assertNotEqual(self.pink["hazelcast"]["state_map"], self.blue["hazelcast"]["imap_state"]) def test_pink_adaptive_exit_points_to_dolphin_pink(self): self.assertEqual(self.pink["adaptive_exit"]["shadow_db"], "dolphin_pink") def test_pink_initial_capital_matches_blue(self): self.assertEqual(self.pink["paper_trade"]["initial_capital"], self.blue["paper_trade"]["initial_capital"]) def test_pink_has_distinct_log_dir(self): self.assertEqual(self.pink["paper_trade"]["log_dir"], "paper_logs/pink") def test_pink_isolated_tp_differs_intentionally(self): # PINK uses 0.20% TP (not 0.95%) — intentional for testnet self.assertEqual(self.pink["engine"]["fixed_tp_pct"], 0.0020) # ═══════════════════════════════════════════════════════════════════════════ # CH SCHEMA FILE VALIDATION # ═══════════════════════════════════════════════════════════════════════════ class TestPinkSchemaFileContent(unittest.TestCase): """PINK CH schema files must target dolphin_pink exclusively.""" def test_schema_dir_exists(self): self.assertTrue(Path("/mnt/dolphinng5_predict/prod/clickhouse/pink").is_dir()) def test_create_database_has_if_not_exists(self): ddl = Path("/mnt/dolphinng5_predict/prod/clickhouse/pink/00_create_database.sql").read_text() self.assertIn("IF NOT EXISTS", ddl) self.assertIn("dolphin_pink", ddl) def test_all_sql_files_reference_dolphin_pink(self): schema_dir = Path("/mnt/dolphinng5_predict/prod/clickhouse/pink") for sql_file in sorted(schema_dir.glob("*.sql")): content = sql_file.read_text() self.assertIn("dolphin_pink", content) self.assertNotIn("dolphin_prodgreen", content) self.assertNotIn("dolphin_green", content) self.assertNotIn("dolphin.", content) def test_schema_files_have_no_blind_copy_errors(self): schema_dir = Path("/mnt/dolphinng5_predict/prod/clickhouse/pink") for sql_file in sorted(schema_dir.glob("*.sql")): content = sql_file.read_text() self.assertNotIn("_BLUE", content) self.assertNotIn("_PRODGREEN", content) # ═══════════════════════════════════════════════════════════════════════════ # PINK JOURNAL / ACCOUNTING # ═══════════════════════════════════════════════════════════════════════════ class TestPinkJournalAccounting(unittest.TestCase): """PINK journal must route accounting data to dolphin_pink.""" def test_strategy_db_map_has_pink(self): from prod.bingx.journal import _STRATEGY_DB_MAP self.assertEqual(_STRATEGY_DB_MAP["pink"], "dolphin_pink") def test_strategy_sink_map_has_pink(self): from prod.bingx.journal import _STRATEGY_SINK_MAP self.assertIn("pink", _STRATEGY_SINK_MAP) def test_strategy_db_map_completeness(self): from prod.bingx.journal import _STRATEGY_DB_MAP for strategy in ("blue", "green", "prodgreen", "pink"): self.assertIn(strategy, _STRATEGY_DB_MAP) def test_strategy_sink_map_completeness(self): from prod.bingx.journal import _STRATEGY_SINK_MAP for strategy in ("blue", "green", "prodgreen", "pink"): self.assertIn(strategy, _STRATEGY_SINK_MAP) def test_pink_sink_is_ch_put_pink(self): from prod.bingx.journal import _STRATEGY_SINK_MAP import prod.ch_writer as ch self.assertIs(_STRATEGY_SINK_MAP["pink"], ch.ch_put_pink) def test_db_for_strategy_pink(self): from prod.bingx.journal import _db_for_strategy self.assertEqual(_db_for_strategy("pink"), "dolphin_pink") def test_db_for_strategy_case_insensitive(self): from prod.bingx.journal import _db_for_strategy self.assertEqual(_db_for_strategy("PINK"), "dolphin_pink") self.assertEqual(_db_for_strategy("Pink"), "dolphin_pink") def test_db_for_strategy_blue_unchanged(self): from prod.bingx.journal import _db_for_strategy self.assertEqual(_db_for_strategy("blue"), "dolphin") def test_db_for_strategy_prodgreen_unchanged(self): from prod.bingx.journal import _db_for_strategy self.assertEqual(_db_for_strategy("prodgreen"), "dolphin_prodgreen") def test_db_for_strategy_prodprefix_fallback(self): from prod.bingx.journal import _db_for_strategy self.assertEqual(_db_for_strategy("prodfoo"), "dolphin_prodgreen") def test_journal_snapshot_strategy_field(self): from prod.bingx.journal import BingxJournalSnapshot snap = BingxJournalSnapshot( ts=100, strategy="pink", account_id="test", ledger_authority="exchange", payload={"account": {"balances": []}, "positions": {}}, fingerprint="fp") self.assertEqual(snap.strategy, "pink") def test_ch_put_pink_exists(self): from prod.ch_writer import ch_put_pink self.assertTrue(callable(ch_put_pink)) def test_ch_put_pink_calls_pink_writer(self): from prod.ch_writer import ch_put_pink, _writer_pink with patch.object(_writer_pink, 'put') as mock_put: ch_put_pink("test_table", {"key": "value"}) mock_put.assert_called_once_with("test_table", {"key": "value"}) def test_writer_pink_db_is_dolphin_pink(self): from prod.ch_writer import _writer_pink self.assertEqual(_writer_pink._db, "dolphin_pink") def test_writer_prodgreen_unchanged(self): from prod.ch_writer import _writer_prodgreen self.assertEqual(_writer_prodgreen._db, "dolphin_prodgreen") def test_writer_blue_unchanged(self): from prod.ch_writer import _writer self.assertEqual(_writer._db, "dolphin") def test_writer_green_unchanged(self): from prod.ch_writer import _writer_green self.assertEqual(_writer_green._db, "dolphin_green") # ═══════════════════════════════════════════════════════════════════════════ # PINK CH SCHEMA REQUIRED FILES # ═══════════════════════════════════════════════════════════════════════════ class TestPinkClickHouseSchema(unittest.TestCase): """PINK CH schema files must exist and be complete.""" def test_schema_dir_exists(self): self.assertTrue(Path("/mnt/dolphinng5_predict/prod/clickhouse/pink").is_dir()) def test_required_schema_files(self): schema_dir = Path("/mnt/dolphinng5_predict/prod/clickhouse/pink") required = [ "00_create_database.sql", "account_events.sql", "trade_events.sql", "status_snapshots.sql", "v7_decision_events.sql", "adaptive_exit_shadow.sql", "02_create_trade_reconstruction.sql", "03_create_trade_exit_legs.sql", ] for filename in required: self.assertTrue((schema_dir / filename).exists(), f"Missing: {filename}") if __name__ == "__main__": unittest.main()