Skip to content

Commit 58e0bc8

Browse files
jcschaffclaude
andcommitted
Test JmsFailoverWatchdog terminal-handler firing on failover give-up
JmsFailoverWatchdogTest spins up an embedded ActiveMQ BrokerService on a random TCP port, opens a connection through a tightly-bounded failover URL (maxReconnectAttempts=2, 50ms initial / 100ms max backoff), attaches a watchdog with a CountDownLatch terminal handler, stops the broker, and asserts the latch fires within 10s. Tagged Fast; runs in ~0.7s. Validates that JmsFailoverWatchdog.attach correctly registers with ActiveMQConnection and that the injected Runnable runs when the failover transport reports a terminal IOException — without killing the test JVM via the production System.exit handler. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent d58cd12 commit 58e0bc8

1 file changed

Lines changed: 58 additions & 0 deletions

File tree

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package cbit.vcell.message.jms;
2+
3+
import static org.junit.jupiter.api.Assertions.assertTrue;
4+
5+
import java.util.concurrent.CountDownLatch;
6+
import java.util.concurrent.TimeUnit;
7+
8+
import javax.jms.Connection;
9+
10+
import org.apache.activemq.ActiveMQConnectionFactory;
11+
import org.apache.activemq.broker.BrokerService;
12+
import org.apache.activemq.broker.TransportConnector;
13+
import org.junit.jupiter.api.Tag;
14+
import org.junit.jupiter.api.Test;
15+
16+
@Tag("Fast")
17+
public class JmsFailoverWatchdogTest {
18+
19+
/**
20+
* Spin up an embedded broker, attach the watchdog to a connection backed by
21+
* a tightly-bounded failover URL, then stop the broker. After the failover
22+
* transport exhausts its reconnect budget, the TransportListener fires with
23+
* an IOException and the watchdog should run the injected terminal handler.
24+
*/
25+
@Test
26+
public void attach_firesTerminalHandlerWhenFailoverGivesUp() throws Exception {
27+
BrokerService broker = new BrokerService();
28+
broker.setPersistent(false);
29+
broker.setUseJmx(false);
30+
broker.setUseShutdownHook(false);
31+
TransportConnector connector = broker.addConnector("tcp://localhost:0");
32+
broker.start();
33+
broker.waitUntilStarted();
34+
int port = connector.getConnectUri().getPort();
35+
36+
String url = "failover:(tcp://localhost:" + port + ")"
37+
+ "?maxReconnectAttempts=2"
38+
+ "&startupMaxReconnectAttempts=-1"
39+
+ "&initialReconnectDelay=50"
40+
+ "&maxReconnectDelay=100";
41+
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(url);
42+
Connection connection = factory.createConnection();
43+
try {
44+
CountDownLatch terminal = new CountDownLatch(1);
45+
new JmsFailoverWatchdog(terminal::countDown).attach(connection);
46+
connection.start();
47+
48+
broker.stop();
49+
broker.waitUntilStopped();
50+
51+
assertTrue(terminal.await(10, TimeUnit.SECONDS),
52+
"watchdog terminal handler should fire after maxReconnectAttempts exhausted");
53+
} finally {
54+
try { connection.close(); } catch (Exception ignored) {}
55+
try { broker.stop(); } catch (Exception ignored) {}
56+
}
57+
}
58+
}

0 commit comments

Comments
 (0)