use of reactor.test.util.RaceTestUtils in project reactor-core by reactor.
the class DefaultTestSubscriberTest method drainAsyncBadOnErrorDuringPollNotifiesAndClears.
@Test
// potentially slow due to timeout 10s
@Tag("slow")
void drainAsyncBadOnErrorDuringPollNotifiesAndClears() {
TestSubscriber<Integer> testSubscriber = TestSubscriber.builder().requireFusion(Fuseable.ASYNC).build();
@SuppressWarnings("unchecked") Fuseable.QueueSubscription<Integer> queueSubscription = Mockito.mock(Fuseable.QueueSubscription.class);
Mockito.when(queueSubscription.requestFusion(Mockito.anyInt())).thenReturn(Fuseable.ASYNC);
final AtomicInteger count = new AtomicInteger();
final CountDownLatch waitForPoll = new CountDownLatch(1);
final CountDownLatch waitForOnError = new CountDownLatch(1);
Mockito.when(queueSubscription.poll()).thenAnswer(args -> {
int answer = count.incrementAndGet();
if (answer == 3) {
waitForPoll.countDown();
waitForOnError.await(1, TimeUnit.SECONDS);
}
if (answer == 5) {
return null;
}
return answer;
});
testSubscriber.onSubscribe(queueSubscription);
// we only use RaceTestUtils for the convenience of blocking until both tasks have finished,
// since we're doing our own artificial synchronization
RaceTestUtils.race(() -> testSubscriber.onNext(null), () -> {
try {
if (waitForPoll.await(1, TimeUnit.SECONDS)) {
testSubscriber.onError(new IllegalStateException("expected"));
waitForOnError.countDown();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
assertThatCode(() -> testSubscriber.block(Duration.ofSeconds(10))).as("block(10s)").doesNotThrowAnyException();
Mockito.verify(queueSubscription).clear();
Mockito.verify(queueSubscription, times(5)).poll();
assertThat(testSubscriber.getReceivedOnNext()).as("receivedOnNext").containsExactly(1, 2, 3, 4);
assertThat(testSubscriber.getProtocolErrors()).as("protocol errors").singleElement().matches(Signal::isOnError, "isOnError").satisfies(s -> assertThat(s.getThrowable()).isInstanceOf(IllegalStateException.class).hasMessage("expected")).isSameAs(// that last assertion ensures we registered the terminal signal
testSubscriber.getTerminalSignal());
}
Aggregations