d
This commit is contained in:
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user