Skip to content

Commit 74a7583

Browse files
committed
Fixes JAVA-6033
1 parent abdf56a commit 74a7583

File tree

1 file changed

+61
-0
lines changed

1 file changed

+61
-0
lines changed

driver-core/src/test/unit/com/mongodb/internal/connection/DefaultServerMonitorTest.java

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.bson.BsonDocument;
3535
import org.bson.ByteBufNIO;
3636
import org.junit.jupiter.api.AfterEach;
37+
import org.junit.jupiter.api.Assertions;
3738
import org.junit.jupiter.api.Test;
3839
import org.opentest4j.AssertionFailedError;
3940

@@ -254,6 +255,66 @@ public void serverHeartbeatFailed(final ServerHeartbeatFailedEvent event) {
254255
assertEquals(expectedEvents, events);
255256
}
256257

258+
@Test
259+
void shouldSendHeartbeatEventAfterInitialConnectionInPollMode() throws Exception {
260+
// This test verifies that in POLL mode with a long heartbeat frequency,
261+
// the monitor still fires a ServerHeartbeatSucceededEvent shortly after initial connection.
262+
// This is critical for some unified tests like backpressure-network-error-fail.yml that rely on
263+
// receiving an initial heartbeat event even with very long polling intervals.
264+
265+
// Given
266+
ConnectionDescription connectionDescription = createDefaultConnectionDescription();
267+
ServerDescription initialServerDescription = createDefaultServerDescription();
268+
String helloResponse = "{"
269+
+ LEGACY_HELLO_LOWER + ": true,"
270+
+ "maxBsonObjectSize : 16777216, "
271+
+ "maxMessageSizeBytes : 48000000, "
272+
+ "maxWriteBatchSize : 1000, "
273+
+ "localTime : ISODate(\"2016-04-05T20:36:36.082Z\"), "
274+
+ "maxWireVersion : 4, "
275+
+ "minWireVersion : 0, "
276+
+ "ok : 1 "
277+
+ "}";
278+
279+
InternalConnection mockConnection = mock(InternalConnection.class);
280+
when(mockConnection.getDescription()).thenReturn(connectionDescription);
281+
when(mockConnection.getInitialServerDescription()).thenReturn(initialServerDescription);
282+
when(mockConnection.getBuffer(anyInt())).thenReturn(new ByteBufNIO(ByteBuffer.allocate(1024)));
283+
when(mockConnection.receive(any(), any())).thenReturn(BsonDocument.parse(helloResponse));
284+
285+
// When
286+
TestServerMonitorListener listener = createTestServerMonitorListener();
287+
// Create monitor explicitly in POLL mode with long heartbeat frequency
288+
DefaultServerMonitor monitor = new DefaultServerMonitor(
289+
new ServerId(new ClusterId(), new ServerAddress()),
290+
ServerSettings.builder()
291+
.heartbeatFrequency(10000, TimeUnit.MILLISECONDS)
292+
.serverMonitoringMode(com.mongodb.connection.ServerMonitoringMode.POLL)
293+
.addServerMonitorListener(listener)
294+
.build(),
295+
createConnectionFactory(mockConnection),
296+
ClusterConnectionMode.SINGLE,
297+
null,
298+
false,
299+
SameObjectProvider.initialized(mock(SdamServerDescriptionManager.class)),
300+
OPERATION_CONTEXT_FACTORY);
301+
monitor.start();
302+
this.monitor = monitor;
303+
304+
// Wait for heartbeat event - should happen quickly despite long heartbeatFrequency
305+
listener.waitForEvents(ServerHeartbeatSucceededEvent.class, event -> true, 1, Duration.ofSeconds(2));
306+
ServerHeartbeatStartedEvent startedEvent = getEvent(ServerHeartbeatStartedEvent.class, listener);
307+
ServerHeartbeatSucceededEvent succeededEvent = getEvent(ServerHeartbeatSucceededEvent.class, listener);
308+
309+
// Then
310+
assertEquals(connectionDescription.getConnectionId(), startedEvent.getConnectionId());
311+
assertEquals(connectionDescription.getConnectionId(), succeededEvent.getConnectionId());
312+
assertEquals(BsonDocument.parse(helloResponse), succeededEvent.getReply());
313+
assertTrue(succeededEvent.getElapsedTime(TimeUnit.NANOSECONDS) > 0);
314+
// The event should not be awaited in POLL mode
315+
Assertions.assertFalse(succeededEvent.isAwaited());
316+
}
317+
257318

258319
private InternalConnectionFactory createConnectionFactory(final InternalConnection connection) {
259320
InternalConnectionFactory factory = mock(InternalConnectionFactory.class);

0 commit comments

Comments
 (0)