Skip to content

Commit

Permalink
test: fix attach_when_channel_in_detaching_state
Browse files Browse the repository at this point in the history
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
  • Loading branch information
AndyTWF committed May 24, 2023
1 parent bbbcb4d commit 47e7cde
Showing 1 changed file with 30 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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));
Expand Down

0 comments on commit 47e7cde

Please sign in to comment.