@@ -4,9 +4,11 @@ import asyncio
|
||||
from datetime import UTC, datetime
|
||||
|
||||
from cloud.internal_api.models import HeartbeatResponse
|
||||
from cloud.internal_api.models import HostGovernancePolicyModel
|
||||
from device.manager import DeviceManager
|
||||
from host_agent.config import HostAgentConfig
|
||||
from host_agent.heartbeat import HeartbeatSynchronizer, build_device_snapshot
|
||||
from host_agent.policy_cache import HostPolicyCacheStore
|
||||
from host_agent.status import AgentStatusTracker
|
||||
|
||||
|
||||
@@ -123,3 +125,56 @@ def test_sync_once_notifies_status_tracker_and_on_sync_with_device_count() -> No
|
||||
assert last_heartbeat["device_count"] == 2
|
||||
|
||||
asyncio.run(scenario())
|
||||
|
||||
|
||||
def test_heartbeat_caches_safe_host_policy_and_reuses_its_revision(tmp_path) -> None:
|
||||
manager = DeviceManager()
|
||||
cache = HostPolicyCacheStore(tmp_path / "host_policy.json")
|
||||
revisions: list[int] = []
|
||||
|
||||
class UpdatingClient:
|
||||
async def heartbeat(self, devices, *, address=None, policy_revision=0):
|
||||
revisions.append(policy_revision)
|
||||
return HeartbeatResponse(
|
||||
host_id="host-a",
|
||||
accepted_devices=len(devices),
|
||||
received_at=datetime.now(UTC),
|
||||
policy_revision=4,
|
||||
policy=HostGovernancePolicyModel(
|
||||
revision=4,
|
||||
self_submission_enabled=False,
|
||||
max_active_tasks=2,
|
||||
daily_token_budget=900,
|
||||
),
|
||||
)
|
||||
|
||||
async def scenario() -> None:
|
||||
tracker = AgentStatusTracker()
|
||||
synchronizer = HeartbeatSynchronizer(
|
||||
manager,
|
||||
UpdatingClient(), # type: ignore[arg-type]
|
||||
_config(),
|
||||
policy_cache=cache,
|
||||
status_tracker=tracker,
|
||||
)
|
||||
await synchronizer.sync_once()
|
||||
assert tracker.snapshot()["host_policy"] == {
|
||||
"revision": 4,
|
||||
"self_submission_enabled": False,
|
||||
"max_active_tasks": 2,
|
||||
"daily_token_budget": 900,
|
||||
}
|
||||
|
||||
restarted = HeartbeatSynchronizer(
|
||||
manager,
|
||||
UpdatingClient(), # type: ignore[arg-type]
|
||||
_config(),
|
||||
policy_cache=cache,
|
||||
)
|
||||
assert restarted.policy_revision == 4
|
||||
|
||||
asyncio.run(scenario())
|
||||
assert revisions == [0]
|
||||
assert '"token":' not in (
|
||||
tmp_path / "host_policy.json"
|
||||
).read_text(encoding="utf-8")
|
||||
|
||||
Reference in New Issue
Block a user