1616
1717package com .google .cloud .pubsub .v1 ;
1818
19+ import static org .awaitility .Awaitility .await ;
1920import static org .junit .Assert .*;
2021import static org .mockito .ArgumentMatchers .any ;
2122import static org .mockito .ArgumentMatchers .argThat ;
2223import static org .mockito .Mockito .*;
2324
2425import com .google .api .core .ApiFutures ;
26+ import com .google .api .core .ApiService ;
2527import com .google .api .core .SettableApiFuture ;
2628import com .google .api .gax .batching .FlowControlSettings ;
2729import com .google .api .gax .batching .FlowController ;
5557import java .util .concurrent .atomic .AtomicInteger ;
5658import org .junit .After ;
5759import org .junit .Before ;
58- import org .junit .Ignore ;
5960import org .junit .Rule ;
6061import org .junit .Test ;
6162import org .junit .rules .TestName ;
@@ -164,15 +165,14 @@ public void testRunShutdown_TimeoutMet() throws Exception {
164165 streamingSubscriberConnection .awaitTerminated (1 , TimeUnit .SECONDS );
165166 }
166167
167- @ Ignore ("https://github.com/googleapis/google-cloud-java/issues/13706" )
168168 @ Test
169169 public void testRunShutdown_TimeoutExceeded () throws Exception {
170170 final SettableApiFuture <com .google .protobuf .Empty > ackFuture = SettableApiFuture .create ();
171171 when (mockSubscriberStub .acknowledgeCallable ().futureCall (any (AcknowledgeRequest .class )))
172172 .thenReturn (ackFuture );
173173
174174 SubscriberShutdownSettings shutdownSettings =
175- SubscriberShutdownSettings .newBuilder ().setTimeout (Duration .ofSeconds ( 2 )).build ();
175+ SubscriberShutdownSettings .newBuilder ().setTimeout (Duration .ofMillis ( 500 )).build ();
176176 StreamingSubscriberConnection .Builder builder =
177177 StreamingSubscriberConnection .newBuilder (
178178 mock (MessageReceiverWithAckResponse .class , withSettings ().withoutAnnotations ()));
@@ -195,25 +195,30 @@ public void testRunShutdown_TimeoutExceeded() throws Exception {
195195 });
196196 t .start ();
197197
198- Thread t2 =
199- new Thread (
200- () -> {
201- try {
202- streamingSubscriberConnection .awaitTerminated (1 , TimeUnit .SECONDS );
203- fail ("Should have timed out" );
204- } catch (TimeoutException e ) {
205- // expected
206- }
207- });
208- t2 .start ();
209- t2 .join ();
198+ // Wait until the stop thread is blocked in tryWait (waiting for pending operations).
199+ await ()
200+ .atMost (Duration .ofSeconds (5 ))
201+ .pollInterval (Duration .ofMillis (10 ))
202+ .until (() -> t .getState () == Thread .State .TIMED_WAITING );
203+
204+ // Connection should be in STOPPING state, not TERMINATED yet.
205+ assertEquals (ApiService .State .STOPPING , streamingSubscriberConnection .state ());
206+
207+ // Verify awaitTerminated times out since the shutdown timeout has not elapsed yet.
208+ try {
209+ streamingSubscriberConnection .awaitTerminated (10 , TimeUnit .MILLISECONDS );
210+ fail ("Should have timed out" );
211+ } catch (TimeoutException e ) {
212+ // expected
213+ }
210214
211215 // Advance the clock past the shutdown timeout.
212- clock .advance (3 , TimeUnit .SECONDS );
213- t .join ();
216+ clock .advance (1 , TimeUnit .SECONDS );
217+ t .join (5000 );
218+ assertFalse ("Stop thread should have finished" , t .isAlive ());
214219
215220 // Now it should terminate.
216- streamingSubscriberConnection .awaitTerminated ();
221+ streamingSubscriberConnection .awaitTerminated (5 , TimeUnit . SECONDS );
217222 assertFalse (streamingSubscriberConnection .isRunning ());
218223 assertFalse (messageFuture .isDone ());
219224 }
@@ -748,7 +753,7 @@ public void testClientPinger_pingSent() {
748753 }
749754
750755 @ Test
751- public void testClientPinger_pingsNotSentWhenDisabled () {
756+ public void testClientPinger_pingsNotSentWhenDisabled () throws TimeoutException {
752757 ClientStream <StreamingPullRequest > mockClientStream =
753758 mock (ClientStream .class , withSettings ().withoutAnnotations ());
754759 when (mockStreamingCallable .splitCall (any (ResponseObserver .class ), any ()))
@@ -768,10 +773,13 @@ public void testClientPinger_pingsNotSentWhenDisabled() {
768773 systemExecutor .advanceTime (CLIENT_PING_INTERVAL );
769774
770775 verify (mockClientStream , times (1 )).send (any (StreamingPullRequest .class ));
776+
777+ streamingSubscriberConnection .stopAsync ();
778+ streamingSubscriberConnection .awaitTerminated (5 , TimeUnit .SECONDS );
771779 }
772780
773781 @ Test
774- public void testServerMonitor_timesOut () {
782+ public void testServerMonitor_timesOut () throws TimeoutException {
775783 ClientStream <StreamingPullRequest > mockClientStream =
776784 mock (ClientStream .class , withSettings ().withoutAnnotations ());
777785 ArgumentCaptor <ResponseObserver <StreamingPullResponse >> observerCaptor =
@@ -815,10 +823,13 @@ public void testServerMonitor_timesOut() {
815823 StatusException exception = (StatusException ) exceptionCaptor .getValue ();
816824 assertEquals (Code .UNAVAILABLE , exception .getStatus ().getCode ());
817825 assertEquals ("Keepalive timeout with server" , exception .getStatus ().getDescription ());
826+
827+ streamingSubscriberConnection .stopAsync ();
828+ streamingSubscriberConnection .awaitTerminated (5 , TimeUnit .SECONDS );
818829 }
819830
820831 @ Test
821- public void testServerMonitor_doesNotTimeOutIfResponseReceived () {
832+ public void testServerMonitor_doesNotTimeOutIfResponseReceived () throws TimeoutException {
822833 ClientStream <StreamingPullRequest > mockClientStream =
823834 mock (ClientStream .class , withSettings ().withoutAnnotations ());
824835 ArgumentCaptor <ResponseObserver <StreamingPullResponse >> observerCaptor =
@@ -847,6 +858,9 @@ public void testServerMonitor_doesNotTimeOutIfResponseReceived() {
847858 observer .onResponse (StreamingPullResponse .getDefaultInstance ());
848859
849860 verify (mockClientStream , never ()).closeSendWithError (any (Exception .class ));
861+
862+ streamingSubscriberConnection .stopAsync ();
863+ streamingSubscriberConnection .awaitTerminated (5 , TimeUnit .SECONDS );
850864 }
851865
852866 private StreamingSubscriberConnection getStreamingSubscriberConnection (
0 commit comments