This commit is contained in:
Your Name
2026-04-22 14:13:21 +08:00
parent e0406b5d0e
commit 7cbde2aa78
145 changed files with 23086 additions and 2243 deletions

View File

@@ -20,6 +20,111 @@ class NodeAgentDeliveryQueueTests(unittest.TestCase):
self.assertEqual(0, delivery_queue["pending_count"])
self.assertEqual(0, delivery_queue["dead_letter_count"])
def test_base_payload_prefers_non_loopback_identity(self) -> None:
with tempfile.TemporaryDirectory() as temp_dir:
with patch.object(node_agent, "AGENT_QUEUE_DIR", temp_dir), patch.object(
node_agent,
"CONTROL_PLANE_BASE_URL",
"http://152.53.37.118:8100",
), patch.object(
node_agent.socket,
"gethostname",
return_value="localhost",
), patch.object(
node_agent.socket,
"getfqdn",
return_value="localhost.localdomain",
), patch.object(
node_agent.os,
"uname",
return_value=type("Uname", (), {"nodename": "localhost"})(),
), patch.object(
node_agent,
"NODE_CODE",
"mainland-controller-01",
), patch.object(
node_agent.socket,
"getaddrinfo",
return_value=[(None, None, None, None, ("127.0.0.1", 0))],
), patch.object(
node_agent.socket,
"gethostbyname",
return_value="127.0.0.1",
):
class FakeSocket:
def connect(self, target):
self.target = target
def getsockname(self):
return ("121.204.244.188", 12345)
def close(self):
return None
with patch.object(node_agent.socket, "socket", return_value=FakeSocket()):
payload = node_agent._base_payload()
self.assertNotIn(payload["hostname"], {"", "localhost", "localhost.localdomain"})
self.assertEqual("121.204.244.188", payload["ip"])
def test_detect_runtime_snapshot_degrades_to_worker_runtime_when_detect_status_fails(self) -> None:
with patch.dict(os.environ, {}, clear=False):
with patch(
"app.services.worker_control_service.detect_worker_runtime",
return_value={
"running": True,
"process_count": 1,
"latest_start_time": "2026-04-20 18:00:00",
"message": "active/running",
},
), patch(
"app.services.detect_service.get_detect_status",
side_effect=RuntimeError('connection to server at "127.0.0.1", port 5432 failed'),
):
snapshot = node_agent._detect_runtime_snapshot()
self.assertTrue(snapshot["worker_online"])
self.assertTrue(snapshot["service_running"])
self.assertFalse(snapshot["detecting"])
self.assertEqual("active/running", snapshot["phase_detail"])
self.assertEqual("2026-04-20 18:00:00", snapshot["updated_at"])
self.assertIn("127.0.0.1", snapshot["error"])
def test_detect_runtime_snapshot_infers_worker_online_from_active_threads(self) -> None:
with patch.dict(os.environ, {}, clear=False):
with patch(
"app.services.worker_control_service.detect_worker_runtime",
return_value={
"running": False,
"process_count": 0,
"latest_start_time": "",
"message": "",
},
), patch(
"app.services.detect_service.get_detect_status",
return_value={
"worker_online": False,
"detecting": False,
"active_thread_count": 19,
"max_thread_count": 1200,
"phase_label": "检测中",
"phase_detail": "Worker 正在处理 162 个检测任务",
"runtime_state": {
"service_running": False,
"updated_at": "2026-04-21 00:00:06",
},
"active_job": {"items_running": 0},
},
):
snapshot = node_agent._detect_runtime_snapshot()
self.assertTrue(snapshot["worker_online"])
self.assertTrue(snapshot["service_running"])
self.assertTrue(snapshot["detecting"])
self.assertTrue(snapshot["detect_participating"])
self.assertEqual(19, snapshot["active_threads"])
self.assertEqual(19, snapshot["current_load"])
def test_job_event_network_failure_is_queued_for_retry(self) -> None:
with tempfile.TemporaryDirectory() as temp_dir:
with patch.object(node_agent, "AGENT_QUEUE_DIR", temp_dir), patch.object(
@@ -279,6 +384,63 @@ class NodeAgentDeliveryQueueTests(unittest.TestCase):
self.assertEqual("failed_local", event_payload["start_delivery_state"])
self.assertIn("temporary offline", event_payload["start_delivery_error"])
def test_register_heartbeat_and_pull_use_configured_timeouts(self) -> None:
with patch.object(node_agent, "_post", return_value={"code": 0, "message": "ok", "data": {"jobs": []}}) as mock_post, patch.object(
node_agent,
"AGENT_REGISTER_TIMEOUT_SECONDS",
91,
), patch.object(
node_agent,
"AGENT_HEARTBEAT_TIMEOUT_SECONDS",
92,
), patch.object(
node_agent,
"AGENT_PULL_TIMEOUT_SECONDS",
93,
):
node_agent._register()
node_agent._heartbeat()
jobs = node_agent._pull_jobs()
self.assertEqual([], jobs)
self.assertEqual(3, mock_post.call_count)
self.assertEqual(91, mock_post.call_args_list[0].kwargs["timeout"])
self.assertEqual(92, mock_post.call_args_list[1].kwargs["timeout"])
self.assertEqual(93, mock_post.call_args_list[2].kwargs["timeout"])
def test_job_delivery_uses_configured_timeouts(self) -> None:
with patch.object(
node_agent,
"_deliver_or_queue",
side_effect=lambda **kwargs: {"state": "queued", "timeout": kwargs["timeout"]},
) as mock_deliver, patch.object(
node_agent,
"AGENT_JOB_COMPLETE_TIMEOUT_SECONDS",
94,
), patch.object(
node_agent,
"AGENT_JOB_EVENT_TIMEOUT_SECONDS",
47,
):
complete_result = node_agent._job_complete(
11,
status="success",
stdout="ok",
stderr="",
result={"ok": True},
)
event_result = node_agent._job_event(
11,
event_type="executor_received",
message="accepted",
)
self.assertEqual("queued", complete_result["state"])
self.assertEqual("queued", event_result["state"])
self.assertEqual(2, mock_deliver.call_count)
self.assertEqual(94, mock_deliver.call_args_list[0].kwargs["timeout"])
self.assertEqual(47, mock_deliver.call_args_list[1].kwargs["timeout"])
if __name__ == "__main__":
unittest.main()