/** Timed offer reports drops if saturated */ public void testDroppedTimedOffer() { SubmissionPublisher<Integer> p = new SubmissionPublisher<Integer>(basicExecutor, 4); TestSubscriber s1 = new TestSubscriber(); s1.request = false; TestSubscriber s2 = new TestSubscriber(); s2.request = false; p.subscribe(s1); p.subscribe(s2); s2.awaitSubscribe(); s1.awaitSubscribe(); long delay = timeoutMillis(); for (int i = 1; i <= 4; ++i) assertTrue(p.offer(i, delay, MILLISECONDS, null) >= 0); long startTime = System.nanoTime(); assertTrue(p.offer(5, delay, MILLISECONDS, null) < 0); s1.sn.request(64); assertTrue(p.offer(6, delay, MILLISECONDS, null) < 0); // 2 * delay should elapse but check only 1 * delay to allow timer slop assertTrue(millisElapsedSince(startTime) >= delay); s2.sn.request(64); p.close(); s2.awaitComplete(); assertTrue(s2.nexts >= 2); s1.awaitComplete(); assertTrue(s1.nexts >= 2); }
/** Timed offer invokes drop handler if saturated */ public void testHandledDroppedTimedOffer() { AtomicInteger calls = new AtomicInteger(); SubmissionPublisher<Integer> p = new SubmissionPublisher<Integer>(basicExecutor, 4); TestSubscriber s1 = new TestSubscriber(); s1.request = false; TestSubscriber s2 = new TestSubscriber(); s2.request = false; p.subscribe(s1); p.subscribe(s2); s2.awaitSubscribe(); s1.awaitSubscribe(); long delay = timeoutMillis(); for (int i = 1; i <= 4; ++i) assertTrue(p.offer(i, delay, MILLISECONDS, (s, x) -> noopHandle(calls)) >= 0); long startTime = System.nanoTime(); assertTrue(p.offer(5, delay, MILLISECONDS, (s, x) -> noopHandle(calls)) < 0); s1.sn.request(64); assertTrue(p.offer(6, delay, MILLISECONDS, (s, x) -> noopHandle(calls)) < 0); assertTrue(millisElapsedSince(startTime) >= delay); s2.sn.request(64); p.close(); s2.awaitComplete(); s1.awaitComplete(); assertTrue(calls.get() >= 2); }
/** Timed offer succeeds if drop handler forces request */ public void testRecoveredHandledDroppedTimedOffer() { AtomicInteger calls = new AtomicInteger(); SubmissionPublisher<Integer> p = new SubmissionPublisher<Integer>(basicExecutor, 4); TestSubscriber s1 = new TestSubscriber(); s1.request = false; TestSubscriber s2 = new TestSubscriber(); s2.request = false; p.subscribe(s1); p.subscribe(s2); s2.awaitSubscribe(); s1.awaitSubscribe(); int n = 0; long delay = timeoutMillis(); long startTime = System.nanoTime(); for (int i = 1; i <= 6; ++i) { int d = p.offer(i, delay, MILLISECONDS, (s, x) -> reqHandle(calls, s)); n = n + 2 + (d < 0 ? d : 0); } assertTrue(millisElapsedSince(startTime) >= delay); p.close(); s2.awaitComplete(); s1.awaitComplete(); assertEquals(n, s1.nexts + s2.nexts); assertTrue(calls.get() >= 2); }
/** * Upon subscription, the subscriber's onSubscribe is called, no other Subscriber methods are * invoked, the publisher hasSubscribers, isSubscribed is true, and existing subscriptions are * unaffected. */ public void testSubscribe1() { TestSubscriber s = new TestSubscriber(); SubmissionPublisher<Integer> p = basicPublisher(); p.subscribe(s); assertTrue(p.hasSubscribers()); assertEquals(1, p.getNumberOfSubscribers()); assertTrue(p.getSubscribers().contains(s)); assertTrue(p.isSubscribed(s)); s.awaitSubscribe(); assertNotNull(s.sn); assertEquals(0, s.nexts); assertEquals(0, s.errors); assertEquals(0, s.completes); TestSubscriber s2 = new TestSubscriber(); p.subscribe(s2); assertTrue(p.hasSubscribers()); assertEquals(2, p.getNumberOfSubscribers()); assertTrue(p.getSubscribers().contains(s)); assertTrue(p.getSubscribers().contains(s2)); assertTrue(p.isSubscribed(s)); assertTrue(p.isSubscribed(s2)); s2.awaitSubscribe(); assertNotNull(s2.sn); assertEquals(0, s2.nexts); assertEquals(0, s2.errors); assertEquals(0, s2.completes); p.close(); }
/** submit returns number of lagged items, compatible with result of estimateMaximumLag. */ public void testLaggedSubmit() { SubmissionPublisher<Integer> p = basicPublisher(); TestSubscriber s1 = new TestSubscriber(); s1.request = false; TestSubscriber s2 = new TestSubscriber(); s2.request = false; p.subscribe(s1); p.subscribe(s2); s2.awaitSubscribe(); s1.awaitSubscribe(); assertEquals(1, p.submit(1)); assertTrue(p.estimateMaximumLag() >= 1); assertTrue(p.submit(2) >= 2); assertTrue(p.estimateMaximumLag() >= 2); s1.sn.request(4); assertTrue(p.submit(3) >= 3); assertTrue(p.estimateMaximumLag() >= 3); s2.sn.request(4); p.submit(4); p.close(); s2.awaitComplete(); assertEquals(4, s2.nexts); s1.awaitComplete(); assertEquals(4, s2.nexts); }
/** If closed, upon subscription, the subscriber's onComplete method is invoked */ public void testSubscribe2() { TestSubscriber s = new TestSubscriber(); SubmissionPublisher<Integer> p = basicPublisher(); p.close(); p.subscribe(s); s.awaitComplete(); assertEquals(0, s.nexts); assertEquals(0, s.errors); assertEquals(1, s.completes, 1); }
/** consume returns a CompletableFuture that is done when publisher completes */ public void testConsume() { AtomicInteger sum = new AtomicInteger(); SubmissionPublisher<Integer> p = basicPublisher(); CompletableFuture<Void> f = p.consume( (Integer x) -> { sum.getAndAdd(x.intValue()); }); int n = 20; for (int i = 1; i <= n; ++i) p.submit(i); p.close(); f.join(); assertEquals((n * (n + 1)) / 2, sum.get()); }
/** onNext items are issued in the same order to each subscriber */ public void testOrder() { SubmissionPublisher<Integer> p = basicPublisher(); TestSubscriber s1 = new TestSubscriber(); TestSubscriber s2 = new TestSubscriber(); p.subscribe(s1); p.subscribe(s2); for (int i = 1; i <= 20; ++i) p.submit(i); p.close(); s2.awaitComplete(); s1.awaitComplete(); assertEquals(20, s2.nexts); assertEquals(1, s2.completes); assertEquals(20, s1.nexts); assertEquals(1, s1.completes); }
/** * A publisher closedExceptionally reports isClosed with the closedException and throws ISE upon * attempted submission; a subsequent close or closeExceptionally has no additional effect. */ public void testCloseExceptionally() { SubmissionPublisher<Integer> p = basicPublisher(); checkInitialState(p); Throwable ex = new SPException(); p.closeExceptionally(ex); assertTrue(p.isClosed()); assertSame(p.getClosedException(), ex); try { p.submit(1); shouldThrow(); } catch (IllegalStateException success) { } p.close(); assertTrue(p.isClosed()); assertSame(p.getClosedException(), ex); }
/** Throwing an exception in onNext causes onError */ public void testThrowOnNext() { SubmissionPublisher<Integer> p = basicPublisher(); TestSubscriber s1 = new TestSubscriber(); TestSubscriber s2 = new TestSubscriber(); p.subscribe(s1); p.subscribe(s2); s1.awaitSubscribe(); p.submit(1); s1.throwOnCall = true; p.submit(2); p.close(); s2.awaitComplete(); assertEquals(2, s2.nexts); s1.awaitComplete(); assertEquals(1, s1.errors); }
/** Closing a publisher causes onComplete to subscribers */ public void testCloseCompletes() { SubmissionPublisher<Integer> p = basicPublisher(); TestSubscriber s1 = new TestSubscriber(); TestSubscriber s2 = new TestSubscriber(); p.subscribe(s1); p.subscribe(s2); p.submit(1); p.close(); assertTrue(p.isClosed()); assertNull(p.getClosedException()); s1.awaitComplete(); assertEquals(1, s1.nexts); assertEquals(1, s1.completes); s2.awaitComplete(); assertEquals(1, s2.nexts); assertEquals(1, s2.completes); }
/** Cancelling a subscription eventually causes no more onNexts to be issued */ public void testCancel() { SubmissionPublisher<Integer> p = basicPublisher(); TestSubscriber s1 = new TestSubscriber(); TestSubscriber s2 = new TestSubscriber(); p.subscribe(s1); p.subscribe(s2); s1.awaitSubscribe(); p.submit(1); s1.sn.cancel(); for (int i = 2; i <= 20; ++i) p.submit(i); p.close(); s2.awaitComplete(); assertEquals(20, s2.nexts); assertEquals(1, s2.completes); assertTrue(s1.nexts < 20); assertFalse(p.isSubscribed(s1)); }
/** submit eventually issues requested items when buffer capacity is 1 */ public void testCap1Submit() { SubmissionPublisher<Integer> p = new SubmissionPublisher<Integer>(basicExecutor, 1); TestSubscriber s1 = new TestSubscriber(); TestSubscriber s2 = new TestSubscriber(); p.subscribe(s1); p.subscribe(s2); for (int i = 1; i <= 20; ++i) { assertTrue(p.estimateMinimumDemand() <= 1); assertTrue(p.submit(i) >= 0); } p.close(); s2.awaitComplete(); s1.awaitComplete(); assertEquals(20, s2.nexts); assertEquals(1, s2.completes); assertEquals(20, s1.nexts); assertEquals(1, s1.completes); }
/** onNext is not issued when requests become zero */ public void testRequest2() { SubmissionPublisher<Integer> p = basicPublisher(); TestSubscriber s1 = new TestSubscriber(); TestSubscriber s2 = new TestSubscriber(); p.subscribe(s1); p.subscribe(s2); s2.awaitSubscribe(); s1.awaitSubscribe(); s1.request = false; p.submit(1); p.submit(2); p.close(); s2.awaitComplete(); assertEquals(2, s2.nexts); assertEquals(1, s2.completes); s1.awaitNext(1); assertEquals(1, s1.nexts); }
/** Negative request causes error */ public void testRequest3() { SubmissionPublisher<Integer> p = basicPublisher(); TestSubscriber s1 = new TestSubscriber(); TestSubscriber s2 = new TestSubscriber(); p.subscribe(s1); p.subscribe(s2); s2.awaitSubscribe(); s1.awaitSubscribe(); s1.sn.request(-1L); p.submit(1); p.submit(2); p.close(); s2.awaitComplete(); assertEquals(2, s2.nexts); assertEquals(1, s2.completes); s1.awaitError(); assertEquals(1, s1.errors); assertTrue(s1.lastError instanceof IllegalArgumentException); }
/** * If a handler is supplied in constructor, it is invoked when subscriber throws an exception in * onNext */ public void testThrowOnNextHandler() { AtomicInteger calls = new AtomicInteger(); SubmissionPublisher<Integer> p = new SubmissionPublisher<Integer>(basicExecutor, 8, (s, e) -> calls.getAndIncrement()); TestSubscriber s1 = new TestSubscriber(); TestSubscriber s2 = new TestSubscriber(); p.subscribe(s1); p.subscribe(s2); s1.awaitSubscribe(); p.submit(1); s1.throwOnCall = true; p.submit(2); p.close(); s2.awaitComplete(); assertEquals(2, s2.nexts); assertEquals(1, s2.completes); s1.awaitError(); assertEquals(1, s1.errors); assertEquals(1, calls.get()); }
/** offer succeeds if drop handler forces request */ public void testRecoveredHandledDroppedOffer() { AtomicInteger calls = new AtomicInteger(); SubmissionPublisher<Integer> p = new SubmissionPublisher<Integer>(basicExecutor, 4); TestSubscriber s1 = new TestSubscriber(); s1.request = false; TestSubscriber s2 = new TestSubscriber(); s2.request = false; p.subscribe(s1); p.subscribe(s2); s2.awaitSubscribe(); s1.awaitSubscribe(); int n = 0; for (int i = 1; i <= 8; ++i) { int d = p.offer(i, (s, x) -> reqHandle(calls, s)); n = n + 2 + (d < 0 ? d : 0); } p.close(); s2.awaitComplete(); s1.awaitComplete(); assertEquals(n, s1.nexts + s2.nexts); assertTrue(calls.get() >= 2); }
/** offer invokes drop handler if saturated */ public void testHandledDroppedOffer() { AtomicInteger calls = new AtomicInteger(); SubmissionPublisher<Integer> p = new SubmissionPublisher<Integer>(basicExecutor, 4); TestSubscriber s1 = new TestSubscriber(); s1.request = false; TestSubscriber s2 = new TestSubscriber(); s2.request = false; p.subscribe(s1); p.subscribe(s2); s2.awaitSubscribe(); s1.awaitSubscribe(); for (int i = 1; i <= 4; ++i) assertTrue(p.offer(i, (s, x) -> noopHandle(calls)) >= 0); p.offer(4, (s, x) -> noopHandle(calls)); assertTrue(p.offer(6, (s, x) -> noopHandle(calls)) < 0); s1.sn.request(64); assertTrue(p.offer(7, (s, x) -> noopHandle(calls)) < 0); s2.sn.request(64); p.close(); s2.awaitComplete(); s1.awaitComplete(); assertTrue(calls.get() >= 4); }
/** offer reports drops if saturated */ public void testDroppedOffer() { SubmissionPublisher<Integer> p = new SubmissionPublisher<Integer>(basicExecutor, 4); TestSubscriber s1 = new TestSubscriber(); s1.request = false; TestSubscriber s2 = new TestSubscriber(); s2.request = false; p.subscribe(s1); p.subscribe(s2); s2.awaitSubscribe(); s1.awaitSubscribe(); for (int i = 1; i <= 4; ++i) assertTrue(p.offer(i, null) >= 0); p.offer(5, null); assertTrue(p.offer(6, null) < 0); s1.sn.request(64); assertTrue(p.offer(7, null) < 0); s2.sn.request(64); p.close(); s2.awaitComplete(); assertTrue(s2.nexts >= 4); s1.awaitComplete(); assertTrue(s1.nexts >= 4); }
/** offer returns number of lagged items if not saturated */ public void testLaggedOffer() { SubmissionPublisher<Integer> p = basicPublisher(); TestSubscriber s1 = new TestSubscriber(); s1.request = false; TestSubscriber s2 = new TestSubscriber(); s2.request = false; p.subscribe(s1); p.subscribe(s2); s2.awaitSubscribe(); s1.awaitSubscribe(); assertTrue(p.offer(1, null) >= 1); assertTrue(p.offer(2, null) >= 2); s1.sn.request(4); assertTrue(p.offer(3, null) >= 3); s2.sn.request(4); p.offer(4, null); p.close(); s2.awaitComplete(); assertEquals(4, s2.nexts); s1.awaitComplete(); assertEquals(4, s2.nexts); }
/** onNext is issued only if requested */ public void testRequest1() { SubmissionPublisher<Integer> p = basicPublisher(); TestSubscriber s1 = new TestSubscriber(); s1.request = false; p.subscribe(s1); s1.awaitSubscribe(); assertTrue(p.estimateMinimumDemand() == 0); TestSubscriber s2 = new TestSubscriber(); p.subscribe(s2); p.submit(1); p.submit(2); s2.awaitNext(1); assertEquals(0, s1.nexts); s1.sn.request(3); p.submit(3); p.close(); s2.awaitComplete(); assertEquals(3, s2.nexts); assertEquals(1, s2.completes); s1.awaitComplete(); assertTrue(s1.nexts > 0); assertEquals(1, s1.completes); }
/** Timed offer returns number of lagged items if not saturated */ public void testLaggedTimedOffer() { SubmissionPublisher<Integer> p = basicPublisher(); TestSubscriber s1 = new TestSubscriber(); s1.request = false; TestSubscriber s2 = new TestSubscriber(); s2.request = false; p.subscribe(s1); p.subscribe(s2); s2.awaitSubscribe(); s1.awaitSubscribe(); long startTime = System.nanoTime(); assertTrue(p.offer(1, LONG_DELAY_MS, MILLISECONDS, null) >= 1); assertTrue(p.offer(2, LONG_DELAY_MS, MILLISECONDS, null) >= 2); s1.sn.request(4); assertTrue(p.offer(3, LONG_DELAY_MS, MILLISECONDS, null) >= 3); s2.sn.request(4); p.offer(4, LONG_DELAY_MS, MILLISECONDS, null); p.close(); s2.awaitComplete(); assertEquals(4, s2.nexts); s1.awaitComplete(); assertEquals(4, s2.nexts); assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS / 2); }