Files
rune/tests/test_orchestration_workers.py
T

90 lines
3.0 KiB
Python

"""Cognitive worker registry: independent toggles and isolation."""
from rune.orchestration.no_change import NoChangeGate, content_fingerprint
from rune.orchestration.proposals import ProposalSink
from rune.orchestration.records import ProposalRecord
from rune.orchestration.workers import CognitiveWorker, WorkerRegistry, WorkerResult
class _SpyWorker(CognitiveWorker):
def __init__(self, name: str, cadence: str, fail: bool = False):
self.name = name
self.cadence = cadence
self.fail = fail
self.runs = 0
def run(self, evidence, sink, gate):
self.runs += 1
if self.fail:
raise RuntimeError(f"{self.name} exploded")
fp = content_fingerprint({"evidence": evidence})
if not gate.should_run(fp):
return WorkerResult(self.name, self.cadence, 0, 1, True)
gate.record(fp)
sink.submit(ProposalRecord(worker=self.name, action="surface", confidence=0.8))
return WorkerResult(self.name, self.cadence, 1, 0, True)
def _ctx():
n1 = _SpyWorker("n1", "subconscious")
refl = _SpyWorker("reflection", "reflection")
reg = WorkerRegistry()
reg.register(n1)
reg.register(refl)
return reg, n1, refl
def test_run_all_runs_every_enabled_worker():
reg, _n1, _refl = _ctx()
results = reg.run_all(
[{"event_type": "x"}],
{"subconscious": ProposalSink(), "reflection": ProposalSink()},
{"subconscious": NoChangeGate(), "reflection": NoChangeGate()},
)
assert {r.worker for r in results} == {"n1", "reflection"}
def test_disabling_one_worker_does_not_affect_others():
reg, n1, refl = _ctx()
reg.disable("n1")
reg.run_all(
[{"event_type": "x"}],
{"subconscious": ProposalSink(), "reflection": ProposalSink()},
{"subconscious": NoChangeGate(), "reflection": NoChangeGate()},
)
assert n1.runs == 0
assert refl.runs == 1
def test_failing_worker_does_not_stop_others():
reg = WorkerRegistry()
bad = _SpyWorker("bad", "subconscious", fail=True)
ok = _SpyWorker("ok", "reflection")
reg.register(bad)
reg.register(ok)
results = reg.run_all(
[{"event_type": "x"}],
{"subconscious": ProposalSink(), "reflection": ProposalSink()},
{"subconscious": NoChangeGate(), "reflection": NoChangeGate()},
)
by_name = {r.worker: r for r in results}
assert by_name["bad"].ok is False
assert "bad exploded" in by_name["bad"].error
assert by_name["ok"].ok is True
assert ok.runs == 1
def test_run_all_is_deterministic_in_order():
reg, _n1, _refl = _ctx()
r1 = reg.run_all(
[{"event_type": "x"}],
{"subconscious": ProposalSink(), "reflection": ProposalSink()},
{"subconscious": NoChangeGate(), "reflection": NoChangeGate()},
)
r2 = reg.run_all(
[{"event_type": "x"}],
{"subconscious": ProposalSink(), "reflection": ProposalSink()},
{"subconscious": NoChangeGate(), "reflection": NoChangeGate()},
)
assert [x.worker for x in r1] == [x.worker for x in r2]