Search in sources :

Example 1 with RaceTestUtils

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());
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) TestPublisher(reactor.test.publisher.TestPublisher) RepeatedTest(org.junit.jupiter.api.RepeatedTest) Scannable(reactor.core.Scannable) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) AtomicReference(java.util.concurrent.atomic.AtomicReference) Nullable(reactor.util.annotation.Nullable) Answer(org.mockito.stubbing.Answer) InvocationOnMock(org.mockito.invocation.InvocationOnMock) Loggers(reactor.util.Loggers) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Duration(java.time.Duration) Logger(reactor.util.Logger) Schedulers(reactor.core.scheduler.Schedulers) Assertions(org.assertj.core.api.Assertions) Tag(org.junit.jupiter.api.Tag) RaceTestUtils(reactor.test.util.RaceTestUtils) ArgumentMatchers.anyInt(org.mockito.ArgumentMatchers.anyInt) Operators(reactor.core.publisher.Operators) Mono(reactor.core.publisher.Mono) Mockito.times(org.mockito.Mockito.times) Signal(reactor.core.publisher.Signal) TimeUnit(java.util.concurrent.TimeUnit) Test(org.junit.jupiter.api.Test) CountDownLatch(java.util.concurrent.CountDownLatch) Mockito(org.mockito.Mockito) Flux(reactor.core.publisher.Flux) List(java.util.List) Fuseable(reactor.core.Fuseable) Subscription(org.reactivestreams.Subscription) Timeout(org.junit.jupiter.api.Timeout) Signal(reactor.core.publisher.Signal) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) CountDownLatch(java.util.concurrent.CountDownLatch) Fuseable(reactor.core.Fuseable) RepeatedTest(org.junit.jupiter.api.RepeatedTest) Test(org.junit.jupiter.api.Test) Tag(org.junit.jupiter.api.Tag)

Aggregations

Duration (java.time.Duration)1 List (java.util.List)1 CountDownLatch (java.util.concurrent.CountDownLatch)1 TimeUnit (java.util.concurrent.TimeUnit)1 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 AtomicReference (java.util.concurrent.atomic.AtomicReference)1 Assertions (org.assertj.core.api.Assertions)1 RepeatedTest (org.junit.jupiter.api.RepeatedTest)1 Tag (org.junit.jupiter.api.Tag)1 Test (org.junit.jupiter.api.Test)1 Timeout (org.junit.jupiter.api.Timeout)1 ArgumentMatchers.anyInt (org.mockito.ArgumentMatchers.anyInt)1 Mockito (org.mockito.Mockito)1 Mockito.times (org.mockito.Mockito.times)1 InvocationOnMock (org.mockito.invocation.InvocationOnMock)1 Answer (org.mockito.stubbing.Answer)1 Subscription (org.reactivestreams.Subscription)1 Fuseable (reactor.core.Fuseable)1 Scannable (reactor.core.Scannable)1