From 47e7cde3c151c468518a7dd0f9c7eab627f087d9 Mon Sep 17 00:00:00 2001 From: Andy Ford Date: Wed, 24 May 2023 11:14:07 +0100 Subject: [PATCH] test: fix attach_when_channel_in_detaching_state The test was failing/flakey because the channel sometimes quickly cycled through detaching into attaching, before the listener had a chance to check the state. This change fixes the issue by making the assertion via a channel state listener instead of a point-in-time check of the channel state, which means transient states are also recorded. Fixes #944 --- .../test/realtime/RealtimeChannelTest.java | 36 +++++++++++++++---- 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/lib/src/test/java/io/ably/lib/test/realtime/RealtimeChannelTest.java b/lib/src/test/java/io/ably/lib/test/realtime/RealtimeChannelTest.java index 46ddaaac1..3a234380d 100644 --- a/lib/src/test/java/io/ably/lib/test/realtime/RealtimeChannelTest.java +++ b/lib/src/test/java/io/ably/lib/test/realtime/RealtimeChannelTest.java @@ -37,6 +37,7 @@ import java.util.Comparator; import java.util.HashMap; import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; @@ -1021,6 +1022,19 @@ public void detach_success_callback_detaching() throws AblyException { } } + class RealtimeChannelTestDetachingListener implements ChannelStateListener + { + public AtomicBoolean detachedReceived = new AtomicBoolean(false); + + @Override + public void onChannelStateChanged(ChannelStateChange stateChange) { + System.out.println(stateChange.current == ChannelState.detached); + if (stateChange.current == ChannelState.detached) { + detachedReceived.set(true); + } + } + } + /** * When client attaches to a channel in detaching state, verify that attach call will be done after detach @@ -1052,9 +1066,12 @@ public void attach_when_channel_in_detaching_state() throws AblyException { //block detached so we can ensure that we are in detaching state but unblock immediately after assertion transportFactory.blockReceiveProcessingAndQueueBlockedMessages(message -> message.action == ProtocolMessage.Action.detached); - /* detach */ - final Helpers.CompletionWaiter detachCompletionWaiter = new Helpers.CompletionWaiter(); - channel.detach(detachCompletionWaiter); + + // Attach a listener for the channel state and start the detach process + RealtimeChannelTestDetachingListener detachingListener = new RealtimeChannelTestDetachingListener(); + channel.on(detachingListener); + channel.detach(); + assertEquals("Verify detaching state reached", ChannelState.detaching, channel.state); //now we can send an attach as we previously blocked detaching @@ -1065,9 +1082,16 @@ public void attach_when_channel_in_detaching_state() throws AblyException { //unblock and let the queued messages arrive transportFactory.allowReceiveProcessing(message -> true); - detachCompletionWaiter.waitFor(); - assertThat(detachCompletionWaiter.success, is(true)); - assertThat(channel.state, is(ChannelState.detached)); + // Wait to receive the detached state + long timeNow = System.currentTimeMillis(); + do { + if (System.currentTimeMillis() > timeNow + 5000) { + fail("Channel did not enter detached state: " + detachingListener.detachedReceived); + return; + } + + } while (!detachingListener.detachedReceived.get()); + //verify reattach - after detach attachCompletionWaiter.waitFor(); assertThat(attachCompletionWaiter.success,is(true));