feat(tests): add comprehensive unit test suite for variables, strategy modulation, and loop health

This commit is contained in:
operator-main
2026-10-04 16:50:13 +00:00
parent a2c5832aff
commit 5b3d77fb60
5 changed files with 1475 additions and 0 deletions
+112
View File
@@ -0,0 +1,112 @@
#!/usr/bin/env python3
"""
test_modulate_strategy.py — Unit and integration tests for:
1. Hierarchical override scoping:
(input_type, subtype, agent) -> (input_type, None, agent) ->
(input_type, subtype, None) -> (input_type, None, None) -> Builtin table
2. Dynamic strategy evaluation (`modulate.py eval` / `box-ctl.py strat-get`)
3. Atomic persistence to strategy.json
4. Override resets and isolation across input types
"""
import unittest
import subprocess
import json
import os
import sys
import tempfile
import shutil
from pathlib import Path
REPO_ROOT = Path("/home/super/Projects/NetVM")
BIN_DIR = REPO_ROOT / "bin"
BOX_CTL = BIN_DIR / "box-ctl.py"
sys.path.insert(0, str(BIN_DIR))
import modulate
class TestModulationHierarchy(unittest.TestCase):
"""Test strategy lookup cascade and overrides."""
def setUp(self):
self.tmp_dir = tempfile.mkdtemp()
self.strat_file = str(Path(self.tmp_dir) / "strategy.json")
self.orig_default = modulate.DEFAULT_STRATEGY_FILE
self.orig_fallback = modulate.FALLBACK_STRATEGY_FILE
modulate.DEFAULT_STRATEGY_FILE = self.strat_file
modulate.FALLBACK_STRATEGY_FILE = self.strat_file
def tearDown(self):
modulate.DEFAULT_STRATEGY_FILE = self.orig_default
modulate.FALLBACK_STRATEGY_FILE = self.orig_fallback
shutil.rmtree(self.tmp_dir, ignore_errors=True)
def test_builtin_fallback(self):
# Default builtin policy for manual DMs
pol = modulate.modulate(modulate.InputType.MANUAL, agent="646")
self.assertIsNotNone(pol)
self.assertTrue(pol.track)
self.assertEqual(pol.timeout_s, 3600)
def test_agent_specific_override(self):
# Set override for agent 'pip' on 'manual'
modulate.set_strategy_override(
"manual",
None,
"pip",
track=False,
timeout_s=1800,
nudges=0,
escalate="none",
)
# Pip gets the custom override (track=False -> modulate returns None)
pip_pol = modulate.modulate(modulate.InputType.MANUAL, agent="pip")
self.assertIsNone(pip_pol)
# 646 gets the default builtin policy
other_pol = modulate.modulate(modulate.InputType.MANUAL, agent="646")
self.assertTrue(other_pol.track)
self.assertEqual(other_pol.timeout_s, 3600)
def test_subtype_hierarchical_resolution(self):
# Set type-level default
modulate.set_strategy_override("health", None, None, timeout_s=900)
# Set subtype override
modulate.set_strategy_override("health", "DEGRADED", None, timeout_s=3600)
# Health without subtype gets type-level
pol1 = modulate.modulate(modulate.InputType.HEALTH, subtype="OK")
self.assertEqual(pol1.timeout_s, 900)
# Health with 'DEGRADED' subtype gets subtype-specific
pol2 = modulate.modulate(modulate.InputType.HEALTH, subtype="DEGRADED")
self.assertEqual(pol2.timeout_s, 3600)
def test_override_reset(self):
modulate.set_strategy_override("wake", None, "opm", timeout_s=600)
self.assertEqual(modulate.modulate(modulate.InputType.WAKE, agent="opm", actionable=True).timeout_s, 600)
modulate.reset_strategy_override("wake", None, "opm")
# Reverts to builtin default (7200s for wake)
self.assertEqual(modulate.modulate(modulate.InputType.WAKE, agent="opm", actionable=True).timeout_s, 7200)
class TestStrategyRpc(unittest.TestCase):
"""Test box-ctl.py allowlisted RPC actions for strategy."""
def test_box_ctl_strat_list(self):
cmd = [sys.executable, str(BOX_CTL), "strat-list"]
res = subprocess.run(cmd, capture_output=True, text=True)
self.assertEqual(res.returncode, 0)
data = json.loads(res.stdout)
self.assertTrue(data.get("ok"))
self.assertIn("strategies", data)
if __name__ == "__main__":
unittest.main()