From 673ba72510b26514629a14e3fe14bec5c5ff367b Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Tue, 14 Apr 2026 22:22:45 -0400 Subject: [PATCH] test(host_agent): agent POST, backoff, and main loop Co-Authored-By: Claude Sonnet 4.6 --- .../host_agent/test_agent_build_payload.py | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/tests/plugins/host_agent/test_agent_build_payload.py b/tests/plugins/host_agent/test_agent_build_payload.py index 15c779e..f38f567 100644 --- a/tests/plugins/host_agent/test_agent_build_payload.py +++ b/tests/plugins/host_agent/test_agent_build_payload.py @@ -53,3 +53,65 @@ def test_build_payload_wraps_samples(): assert payload["metadata"] == metadata assert len(payload["samples"]) == 1 assert payload["samples"][0]["cpu_pct"] == 5.0 + + +import urllib.error +from unittest.mock import MagicMock, patch + + +def test_post_payload_success(): + from plugins.host_agent import agent as a + captured = {} + + class FakeResp: + status = 200 + def __enter__(self): return self + def __exit__(self, *a): return False + def read(self): return b'{"ok":true}' + + def fake_urlopen(req, timeout=10): + captured["url"] = req.full_url + captured["headers"] = dict(req.header_items()) + captured["body"] = req.data + return FakeResp() + + with patch.object(a.urllib.request, "urlopen", side_effect=fake_urlopen): + ok, status = a.post_payload("https://x", "tok", {"hello": "world"}) + assert ok is True + assert status == 200 + assert captured["url"] == "https://x/plugins/host_agent/ingest" + assert captured["headers"]["Authorization"] == "Bearer tok" + + +def test_post_payload_http_error_returns_status(): + from plugins.host_agent import agent as a + + def raise_401(req, timeout=10): + raise urllib.error.HTTPError(req.full_url, 401, "unauthorized", {}, None) + + with patch.object(a.urllib.request, "urlopen", side_effect=raise_401): + ok, status = a.post_payload("https://x", "tok", {}) + assert ok is False + assert status == 401 + + +def test_post_payload_network_error_returns_none_status(): + from plugins.host_agent import agent as a + + def raise_url(req, timeout=10): + raise urllib.error.URLError("conn refused") + + with patch.object(a.urllib.request, "urlopen", side_effect=raise_url): + ok, status = a.post_payload("https://x", "tok", {}) + assert ok is False + assert status is None + + +def test_backoff_schedule(): + from plugins.host_agent.agent import next_backoff + assert next_backoff(0) == 30 + assert next_backoff(30) == 60 + assert next_backoff(60) == 120 + assert next_backoff(120) == 240 + assert next_backoff(240) == 300 # capped + assert next_backoff(300) == 300