83 lines
2.6 KiB
Python
83 lines
2.6 KiB
Python
"""Observability is bounded and cannot become model ownership/readiness."""
|
|
|
|
import json
|
|
import threading
|
|
|
|
from k1link.perception.realtime_contract import StreamStart
|
|
from k1link.perception.runtime_telemetry import MAX_BYTES, RuntimeTelemetryPublisher, observation
|
|
from k1link.perception.streaming_lifecycle import StreamingLifecycle
|
|
from k1link.perception.streaming_queue import StreamMailbox
|
|
|
|
|
|
def test_observation_tracks_wait_without_renewing_or_stopping_runtime(tmp_path):
|
|
start = StreamStart(
|
|
"run",
|
|
"source",
|
|
"worker-006",
|
|
"epoch",
|
|
1,
|
|
"a" * 64,
|
|
"b" * 64,
|
|
"c" * 64,
|
|
"d" * 64,
|
|
"clock",
|
|
"live",
|
|
)
|
|
runtime = StreamingLifecycle(
|
|
start,
|
|
tmp_path / "lease",
|
|
StreamMailbox(),
|
|
threading.Event(),
|
|
recover_input=True,
|
|
source_clock_ns=lambda: 1000,
|
|
)
|
|
try:
|
|
runtime.ready()
|
|
before = runtime.lease.renewals
|
|
assert observation(runtime, "Profile")["service_state"] == "running"
|
|
runtime.pause_input(start, "input-timeout")
|
|
waiting = observation(runtime, "Profile")
|
|
assert waiting["service_state"] == "waiting"
|
|
assert waiting["input_pauses"] == 1
|
|
assert waiting["actuation_allowed"] is False
|
|
assert len(json.dumps(waiting).encode()) < MAX_BYTES
|
|
assert runtime.lease.renewals == before and not runtime.stop_event.is_set()
|
|
runtime.begin_input(start)
|
|
assert observation(runtime, "Profile")["service_state"] == "synchronizing"
|
|
publisher = RuntimeTelemetryPublisher(runtime, tmp_path / "current.json", "Profile")
|
|
try:
|
|
runtime.renew(start)
|
|
assert runtime.close()
|
|
finally:
|
|
assert publisher.close()
|
|
assert json.loads((tmp_path / "current.json").read_text())["service_state"] == "stopped"
|
|
finally:
|
|
runtime.close()
|
|
|
|
|
|
def test_export_failure_is_lossy_not_terminal(tmp_path):
|
|
start = StreamStart(
|
|
"run",
|
|
"source",
|
|
"worker-006",
|
|
"epoch",
|
|
1,
|
|
"a" * 64,
|
|
"b" * 64,
|
|
"c" * 64,
|
|
"d" * 64,
|
|
"clock",
|
|
"live",
|
|
)
|
|
runtime = StreamingLifecycle(start, tmp_path / "lease", StreamMailbox(), threading.Event())
|
|
(tmp_path / "current.json").mkdir() # os.replace cannot replace this directory.
|
|
publisher = RuntimeTelemetryPublisher(runtime, tmp_path / "current.json", "Profile")
|
|
try:
|
|
assert publisher.close()
|
|
assert publisher.failures > 0
|
|
runtime.ready()
|
|
runtime.renew(start)
|
|
assert not runtime.stop_event.is_set()
|
|
finally:
|
|
runtime.close()
|