diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/websocket/WebSocketConnectionTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/websocket/WebSocketConnectionTest.java index fcd15977e..7ac63328a 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/websocket/WebSocketConnectionTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/websocket/WebSocketConnectionTest.java @@ -18,6 +18,7 @@ import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; +import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; @@ -48,6 +49,7 @@ import java.util.stream.Stream; import org.eclipse.jetty.websocket.api.UpgradeRequest; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.mockito.stubbing.Answer; import org.whispersystems.textsecuregcm.auth.AccountAuthenticator; @@ -623,10 +625,19 @@ class WebSocketConnectionTest { } private WebSocketConnection webSocketConnection(final WebSocketClient client) { - return new WebSocketConnection(receiptSender, messagesManager, new MessageMetrics(), - mock(PushNotificationManager.class), mock(PushNotificationScheduler.class), account, device, client, - Schedulers.immediate(), clientReleaseManager, - mock(MessageDeliveryLoopMonitor.class), mock(ExperimentEnrollmentManager.class)); + return new WebSocketConnection(receiptSender, + messagesManager, + new MessageMetrics(), + mock(PushNotificationManager.class), + mock(PushNotificationScheduler.class), + account, + device, + client, + Duration.ofMillis(100), + Schedulers.immediate(), + clientReleaseManager, + mock(MessageDeliveryLoopMonitor.class), + mock(ExperimentEnrollmentManager.class)); } @Test @@ -916,6 +927,40 @@ class WebSocketConnectionTest { .verify(); } + @Test + @Disabled("Slow test") + public void testClientTimeout() { + final WebSocketClient client = mock(WebSocketClient.class); + final WebSocketConnection connection = webSocketConnection(client); + + final UUID accountUuid = UUID.randomUUID(); + + when(account.getNumber()).thenReturn("+18005551234"); + when(account.getIdentifier(IdentityType.ACI)).thenReturn(accountUuid); + when(device.getId()).thenReturn(Device.PRIMARY_ID); + when(client.isOpen()).thenReturn(true); + + when(messagesManager.getMessagesForDeviceReactive(eq(accountUuid), argThat(d -> d.getId() == Device.PRIMARY_ID), anyBoolean())) + .thenReturn(Flux.just(createMessage(UUID.randomUUID(), UUID.randomUUID(), 1111, "first"))) + .thenReturn(Flux.empty()); + + final WebSocketResponseMessage successResponse = mock(WebSocketResponseMessage.class); + when(successResponse.getStatus()).thenReturn(200); + + when(client.sendRequest(eq("PUT"), eq("/api/v1/message"), any(), any())) + // This future will never complete and should time out + .thenAnswer(_ -> new CompletableFuture<>()); + + connection.start(); + + connection.handleNewMessageAvailable(); + + verify(client, timeout(30_000).times(5)) + .sendRequest(eq("PUT"), eq("/api/v1/message"), any(), any()); + + verify(client, timeout(30_000)).close(eq(1011), any()); + } + private Envelope createMessage(UUID senderUuid, UUID destinationUuid, long timestamp, String content) { return Envelope.newBuilder() .setServerGuid(UUID.randomUUID().toString())