Search in sources :

Example 11 with TestPublisherSubscriber

use of io.servicetalk.concurrent.test.internal.TestPublisherSubscriber in project servicetalk by apple.

the class ScanWithPublisherTest method cancelStillAllowsMaps.

@ParameterizedTest(name = "{displayName} [{index}] {arguments}")
@MethodSource("cancelStillAllowsMapsParams")
void cancelStillAllowsMaps(boolean onError, boolean cancelBefore, boolean withLifetime) {
    final AtomicInteger finalizations = new AtomicInteger(0);
    TestPublisher<Integer> publisher = new TestPublisher<>();
    TestPublisherSubscriber<Integer> subscriber = new TestPublisherSubscriber<>();
    toSource(scanWithOperator(publisher, withLifetime, new ScanWithLifetimeMapper<Integer, Integer>() {

        private int sum;

        @Nullable
        @Override
        public Integer mapOnNext(@Nullable final Integer next) {
            if (next != null) {
                sum += next;
            }
            return next;
        }

        @Override
        public Integer mapOnError(final Throwable cause) {
            return sum;
        }

        @Override
        public Integer mapOnComplete() {
            return sum;
        }

        @Override
        public boolean mapTerminal() {
            return true;
        }

        @Override
        public void afterFinally() {
            finalizations.incrementAndGet();
        }
    })).subscribe(subscriber);
    Subscription s = subscriber.awaitSubscription();
    if (cancelBefore) {
        s.request(4);
        s.cancel();
    } else {
        s.request(3);
    }
    publisher.onNext(1, 2, 3);
    if (!cancelBefore) {
        s.cancel();
        s.request(1);
    }
    if (onError) {
        publisher.onError(DELIBERATE_EXCEPTION);
    } else {
        publisher.onComplete();
    }
    if (!withLifetime) {
        assertThat(subscriber.takeOnNext(4), contains(1, 2, 3, 6));
        subscriber.awaitOnComplete();
    }
    if (withLifetime) {
        assertThat(finalizations.get(), is(1));
    }
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) TestPublisherSubscriber(io.servicetalk.concurrent.test.internal.TestPublisherSubscriber) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Subscription(io.servicetalk.concurrent.PublisherSource.Subscription) Nullable(javax.annotation.Nullable) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) MethodSource(org.junit.jupiter.params.provider.MethodSource)

Example 12 with TestPublisherSubscriber

use of io.servicetalk.concurrent.test.internal.TestPublisherSubscriber in project servicetalk by apple.

the class PublisherProcessorConcurrencyTest method concurrentEmissionAndConsumption.

@Test
void concurrentEmissionAndConsumption() throws Exception {
    final int items = 10_000;
    final Collection<Integer> expected = Publisher.range(0, items).toFuture().get();
    final CountDownLatch done = new CountDownLatch(1);
    PublisherSource.Processor<Integer, Integer> processor = newPublisherProcessor(fixedSize(items));
    TestPublisherSubscriber<Integer> subscriber = new TestPublisherSubscriber<>();
    toSource(fromSource(processor).afterFinally(done::countDown)).subscribe(subscriber);
    CyclicBarrier barrier = new CyclicBarrier(2);
    Future<Object> producerFuture = executorService.submit(() -> {
        barrier.await();
        for (int i = 0; i < items; i++) {
            processor.onNext(i);
        }
        processor.onComplete();
        return null;
    });
    Future<Object> requesterFuture = executorService.submit(() -> {
        barrier.await();
        for (int i = 0; i < items; i++) {
            subscriber.awaitSubscription().request(1);
        }
        return null;
    });
    producerFuture.get();
    requesterFuture.get();
    done.await();
    assertThat(subscriber.takeOnNext(expected.size()), contains(expected.toArray()));
    subscriber.awaitOnComplete();
}
Also used : PublisherSource(io.servicetalk.concurrent.PublisherSource) TestPublisherSubscriber(io.servicetalk.concurrent.test.internal.TestPublisherSubscriber) CountDownLatch(java.util.concurrent.CountDownLatch) CyclicBarrier(java.util.concurrent.CyclicBarrier) Test(org.junit.jupiter.api.Test)

Example 13 with TestPublisherSubscriber

use of io.servicetalk.concurrent.test.internal.TestPublisherSubscriber in project servicetalk by apple.

the class BeforeFinallyHttpOperatorTest method cancelBeforeOnNextThenTerminate.

@ParameterizedTest(name = "{displayName} [{index}] discardEventsAfterCancel={0} payloadTerminal={1}")
@MethodSource("booleanTerminalNotification")
void cancelBeforeOnNextThenTerminate(boolean discardEventsAfterCancel, TerminalNotification payloadTerminal) {
    TestPublisher<Buffer> payload = new TestPublisher.Builder<Buffer>().disableAutoOnSubscribe().build();
    TestSubscription payloadSubscription = new TestSubscription();
    TestPublisherSubscriber<Buffer> payloadSubscriber = new TestPublisherSubscriber<>();
    LegacyTestSingle<StreamingHttpResponse> responseSingle = new LegacyTestSingle<>(true);
    final ResponseSubscriber subscriber = new ResponseSubscriber();
    toSource(responseSingle.liftSync(new BeforeFinallyHttpOperator(beforeFinally, discardEventsAfterCancel))).subscribe(subscriber);
    assertThat("onSubscribe not called.", subscriber.cancellable, is(notNullValue()));
    responseSingle.onSuccess(reqRespFactory.ok().payloadBody(payload));
    verifyNoInteractions(beforeFinally);
    responseSingle.verifyNotCancelled();
    subscriber.verifyResponseReceived();
    subscriber.cancellable.cancel();
    verifyNoInteractions(beforeFinally);
    // We unconditionally cancel and let the original single handle the cancel post terminate
    responseSingle.verifyCancelled();
    assert subscriber.response != null;
    toSource(subscriber.response.payloadBody()).subscribe(payloadSubscriber);
    payload.onSubscribe(payloadSubscription);
    payloadSubscriber.awaitSubscription().request(MAX_VALUE);
    assertThat("Payload was prematurely cancelled", payloadSubscription.isCancelled(), is(false));
    payloadSubscriber.awaitSubscription().cancel();
    assertThat("Payload was not cancelled", payloadSubscription.isCancelled(), is(true));
    payload.onNext(EMPTY_BUFFER);
    if (payloadTerminal.cause() == null) {
        payload.onComplete();
    } else {
        payload.onError(payloadTerminal.cause());
    }
    if (discardEventsAfterCancel) {
        assertThat("Unexpected payload body items", payloadSubscriber.pollAllOnNext(), empty());
        assertThat("Payload body terminated unexpectedly", payloadSubscriber.pollTerminal(100, MILLISECONDS), is(nullValue()));
    } else {
        assertThat("Unexpected payload body items", payloadSubscriber.pollAllOnNext(), contains(EMPTY_BUFFER));
        if (payloadTerminal.cause() == null) {
            payloadSubscriber.awaitOnComplete();
        } else {
            assertThat(payloadSubscriber.awaitOnError(), is(DELIBERATE_EXCEPTION));
        }
    }
}
Also used : Buffer(io.servicetalk.buffer.api.Buffer) TestSubscription(io.servicetalk.concurrent.api.TestSubscription) TestPublisherSubscriber(io.servicetalk.concurrent.test.internal.TestPublisherSubscriber) StreamingHttpResponse(io.servicetalk.http.api.StreamingHttpResponse) LegacyTestSingle(io.servicetalk.concurrent.api.LegacyTestSingle) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) MethodSource(org.junit.jupiter.params.provider.MethodSource)

Example 14 with TestPublisherSubscriber

use of io.servicetalk.concurrent.test.internal.TestPublisherSubscriber in project servicetalk by apple.

the class MulticastExactlyPublisherTest method concurrentRequestN.

@Test
void concurrentRequestN() throws InterruptedException {
    final int expectedSubscribers = 50;
    Publisher<Integer> multicast = source.multicastToExactly(expectedSubscribers, expectedSubscribers);
    @SuppressWarnings("unchecked") TestPublisherSubscriber<Integer>[] subscribers = (TestPublisherSubscriber<Integer>[]) new TestPublisherSubscriber[expectedSubscribers];
    final int expectedSubscribersMinus1 = expectedSubscribers - 1;
    for (int i = 0; i < expectedSubscribersMinus1; ++i) {
        subscribers[i] = new TestPublisherSubscriber<>();
        toSource(multicast).subscribe(subscribers[i]);
    }
    subscribers[expectedSubscribersMinus1] = new TestPublisherSubscriber<>();
    toSource(multicast).subscribe(subscribers[expectedSubscribersMinus1]);
    for (int i = 0; i < expectedSubscribersMinus1; ++i) {
        subscribers[i].awaitSubscription();
    }
    source.onSubscribe(subscription);
    ExecutorService executorService = new ThreadPoolExecutor(0, expectedSubscribers, 1, SECONDS, new SynchronousQueue<>());
    try {
        CyclicBarrier barrier = new CyclicBarrier(expectedSubscribers);
        CountDownLatch doneLatch = new CountDownLatch(expectedSubscribers);
        AtomicReference<Throwable> throwableRef = new AtomicReference<>();
        for (int i = 1; i <= expectedSubscribers; ++i) {
            executorService.execute(requestIRunnable(subscribers, i, barrier, throwableRef, doneLatch));
        }
        doneLatch.await();
        assertThat(throwableRef.get(), is(nullValue()));
        assertThat(subscription.requested(), is(1L));
        assertThat(subscription.isCancelled(), is(false));
    } finally {
        executorService.shutdown();
    }
}
Also used : TestPublisherSubscriber(io.servicetalk.concurrent.test.internal.TestPublisherSubscriber) AtomicReference(java.util.concurrent.atomic.AtomicReference) CountDownLatch(java.util.concurrent.CountDownLatch) CyclicBarrier(java.util.concurrent.CyclicBarrier) ExecutorService(java.util.concurrent.ExecutorService) ThreadPoolExecutor(java.util.concurrent.ThreadPoolExecutor) Test(org.junit.jupiter.api.Test)

Example 15 with TestPublisherSubscriber

use of io.servicetalk.concurrent.test.internal.TestPublisherSubscriber in project servicetalk by apple.

the class DefaultAsyncContextProviderTest method testSubscriptionIsWrapped.

@Test
void testSubscriptionIsWrapped() throws Exception {
    TestSubscription testSubscription = new TestSubscription();
    TestPublisherSubscriber<Integer> testSubscriber = new TestPublisherSubscriber<>();
    TestPublisher<Integer> testPublisher = new TestPublisher.Builder<Integer>().disableAutoOnSubscribe().build(sub -> {
        sub.onSubscribe(testSubscription);
        return sub;
    });
    toSource(testPublisher.map(x -> {
        AsyncContext.put(K1, "v1");
        return x;
    }).liftSync((PublisherOperator<Integer, Integer>) subscriber -> new Subscriber<Integer>() {

        @Nullable
        private Subscription upstreamSubscription;

        private boolean isSubscribed;

        private boolean queuedItemDelivered;

        @Nullable
        private Integer queuedItem;

        @Override
        public void onSubscribe(final Subscription subscription) {
            assert upstreamSubscription == null;
            upstreamSubscription = subscription;
            subscription.request(1);
        }

        @Override
        public void onNext(@Nullable final Integer integer) {
            if (isSubscribed) {
                subscriber.onNext(integer);
            } else {
                queuedItem = integer;
                trySubscribeToQueue();
            }
        }

        @Override
        public void onError(final Throwable t) {
            trySubscribeToQueue();
            subscriber.onError(t);
        }

        @Override
        public void onComplete() {
            trySubscribeToQueue();
            subscriber.onComplete();
        }

        private void trySubscribeToQueue() {
            assert upstreamSubscription != null;
            if (isSubscribed) {
                return;
            }
            isSubscribed = true;
            subscriber.onSubscribe(new Subscription() {

                @Override
                public void request(final long n) {
                    if (!SubscriberUtils.isRequestNValid(n)) {
                        upstreamSubscription.request(n);
                        return;
                    }
                    if (!queuedItemDelivered) {
                        queuedItemDelivered = true;
                        subscriber.onNext(queuedItem);
                        if (n > 1) {
                            upstreamSubscription.request(n - 1);
                        }
                    } else {
                        upstreamSubscription.request(n);
                    }
                }

                @Override
                public void cancel() {
                    upstreamSubscription.cancel();
                }
            });
        }
    }).map(x -> {
        assertEquals("v1", AsyncContext.get(K1));
        return x;
    })).subscribe(testSubscriber);
    // Operator delivers demand before giving the Subscription downstream, wait for implicit demand first.
    testSubscription.awaitRequestN(1);
    testPublisher.onNext(1);
    Subscription subscription = testSubscriber.awaitSubscription();
    executor.submit(() -> {
        try {
            subscription.request(1);
        } catch (Throwable cause) {
            testPublisher.onError(cause);
        }
    }).get();
    testPublisher.onComplete();
    assertThat(testSubscriber.takeOnNext(), is(1));
    testSubscriber.awaitOnComplete();
}
Also used : TestPublisherSubscriber(io.servicetalk.concurrent.test.internal.TestPublisherSubscriber) Subscription(io.servicetalk.concurrent.PublisherSource.Subscription) Nullable(javax.annotation.Nullable) Test(org.junit.jupiter.api.Test)

Aggregations

TestPublisherSubscriber (io.servicetalk.concurrent.test.internal.TestPublisherSubscriber)30 Test (org.junit.jupiter.api.Test)16 CountDownLatch (java.util.concurrent.CountDownLatch)13 Subscription (io.servicetalk.concurrent.PublisherSource.Subscription)10 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)10 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)10 PublisherSource (io.servicetalk.concurrent.PublisherSource)9 Nullable (javax.annotation.Nullable)7 ConcurrentLinkedQueue (java.util.concurrent.ConcurrentLinkedQueue)6 Buffer (io.servicetalk.buffer.api.Buffer)5 TestCompletable (io.servicetalk.concurrent.api.TestCompletable)5 CyclicBarrier (java.util.concurrent.CyclicBarrier)4 ExecutorService (java.util.concurrent.ExecutorService)4 MethodSource (org.junit.jupiter.params.provider.MethodSource)4 TestCancellable (io.servicetalk.concurrent.api.TestCancellable)3 Thread.currentThread (java.lang.Thread.currentThread)3 ArrayList (java.util.ArrayList)3 ThreadPoolExecutor (java.util.concurrent.ThreadPoolExecutor)3 AtomicReference (java.util.concurrent.atomic.AtomicReference)3 LegacyTestSingle (io.servicetalk.concurrent.api.LegacyTestSingle)2