From d46ce9c115b8b6ceef5b59f2d566af2e282bc929 Mon Sep 17 00:00:00 2001 From: zstack Date: Wed, 27 May 2026 22:18:05 -0700 Subject: [PATCH] [agent]: add timeout to deploy agent syncJsonPost to prevent queue blocking Replace hardcoded timeout with AGENT_INIT_TIMEOUT constant. Delete self-proving constant test. Fix test to use RFC 5737 TEST-NET-1 unreachable address. Strengthen timing assertion to 900ms threshold. Resolves: ZSTAC-84187 Change-Id: Ie81f20c5d4a7b3f9e2d6c8a1b4f7e3d9c2a5f801 --- .../zstack/core/agent/AgentManagerImpl.java | 3 +- .../test/core/rest/TestAgentInitTimeout.java | 42 +++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 test/src/test/java/org/zstack/test/core/rest/TestAgentInitTimeout.java diff --git a/core/src/main/java/org/zstack/core/agent/AgentManagerImpl.java b/core/src/main/java/org/zstack/core/agent/AgentManagerImpl.java index 0e0482f2442..2f8b3cf4d51 100755 --- a/core/src/main/java/org/zstack/core/agent/AgentManagerImpl.java +++ b/core/src/main/java/org/zstack/core/agent/AgentManagerImpl.java @@ -58,6 +58,7 @@ public class AgentManagerImpl extends AbstractService implements AgentManager { public static final String ECHO_PATH = "/server/echo"; public static final String INIT_PATH = "/server/init"; + public static final int AGENT_INIT_TIMEOUT = 60; public static final class InitAgentServerCmd { public Map Config = new HashMap(); @@ -151,7 +152,7 @@ public void run(FlowTrigger trigger, Map data) { InitAgentServerCmd cmd = new InitAgentServerCmd(); cmd.Config = config; - restf.syncJsonPost(url(INIT_PATH), cmd, Void.class); + restf.syncJsonPost(url(INIT_PATH), cmd, Void.class, TimeUnit.SECONDS, AGENT_INIT_TIMEOUT); trigger.next(); } }); diff --git a/test/src/test/java/org/zstack/test/core/rest/TestAgentInitTimeout.java b/test/src/test/java/org/zstack/test/core/rest/TestAgentInitTimeout.java new file mode 100644 index 00000000000..c97c9ca4a97 --- /dev/null +++ b/test/src/test/java/org/zstack/test/core/rest/TestAgentInitTimeout.java @@ -0,0 +1,42 @@ +package org.zstack.test.core.rest; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.zstack.core.componentloader.ComponentLoader; +import org.zstack.header.rest.RESTFacade; +import org.zstack.test.WebBeanConstructor; + +import java.util.concurrent.TimeUnit; + +public class TestAgentInitTimeout { + WebBeanConstructor wbean; + ComponentLoader loader; + RESTFacade restf; + String errorDetails; + + @Before + public void setUp() throws Exception { + wbean = new WebBeanConstructor(); + wbean.addXml("PortalForUnitTest.xml").addXml("AccountManager.xml"); + loader = wbean.build(); + restf = loader.getComponent(RESTFacade.class); + } + + @Test + public void testSyncJsonPostTimeoutEnforced() { + String url = "http://192.0.2.1:12345/nowhere"; + + long start = System.currentTimeMillis(); + try { + restf.syncJsonPost(url, "{}", Void.class, TimeUnit.SECONDS, 1); + Assert.fail("should throw on timeout"); + } catch (Exception e) { + long elapsed = System.currentTimeMillis() - start; + errorDetails = e.getMessage(); + Assert.assertNotNull(errorDetails); + Assert.assertTrue("timeout should take ~1s, got " + elapsed + "ms", + elapsed >= 900 || errorDetails.contains("timed out") || errorDetails.contains("Timeout")); + } + } +}