@Test public void virtualTimeSchedulerUseExactlySupplied() { VirtualTimeScheduler vts1 = VirtualTimeScheduler.create(); VirtualTimeScheduler vts2 = VirtualTimeScheduler.create(); VirtualTimeScheduler.getOrSet(vts1); StepVerifier.withVirtualTime(Mono::empty, () -> vts2, Long.MAX_VALUE) .then(() -> assertThat(VirtualTimeScheduler.get()).isSameAs(vts2)) .verifyComplete(); assertThat(vts1.isDisposed()).isFalse(); assertThat(vts2.isDisposed()).isTrue(); assertThat(VirtualTimeScheduler.isFactoryEnabled()).isFalse(); }
@Test public void timeoutEvictAll() { StepVerifier.withVirtualTime(() -> Flux.range(1, 5) .onBackpressureBuffer(Duration.ofSeconds(1), Integer.MAX_VALUE, this, VirtualTimeScheduler.get()), 0) .expectSubscription() .expectNoEvent(Duration.ofSeconds(1)) .thenAwait(Duration.ofMinutes(1)) .thenRequest(1) .verifyComplete(); assertThat(evicted).containsExactly(1, 2, 3, 4, 5); }
@Test public void timedError() throws Exception { VirtualTimeScheduler.getOrSet(); ReplayProcessor<Integer> rp = ReplayProcessor.createTimeout(Duration.ofSeconds(1)); for (int i = 0; i < 5; i++) { rp.onNext(i); } VirtualTimeScheduler.get().advanceTimeBy(Duration.ofSeconds(2)); for (int i = 5; i < 10; i++) { rp.onNext(i); } rp.onError(new Exception("test")); StepVerifier.create(rp.hide()) .expectNext(5,6,7,8,9) .verifyErrorMessage("test"); }
@Test public void disposedSchedulerIsStillCleanedUp() { VirtualTimeScheduler vts = VirtualTimeScheduler.create(); vts.dispose(); assertThat(VirtualTimeScheduler.isFactoryEnabled()).isFalse(); StepVerifier.withVirtualTime(() -> Mono.just("foo"), () -> vts, Long.MAX_VALUE) .then(() -> assertThat(VirtualTimeScheduler.isFactoryEnabled()).isTrue()) .then(() -> assertThat(VirtualTimeScheduler.get()).isSameAs(vts)) .expectNext("foo") .verifyComplete(); assertThat(VirtualTimeScheduler.isFactoryEnabled()).isFalse(); StepVerifier.withVirtualTime(() -> Mono.just("foo")) .then(() -> assertThat(VirtualTimeScheduler.isFactoryEnabled()).isTrue()) .then(() -> assertThat(VirtualTimeScheduler.get()).isNotSameAs(vts)) .expectNext("foo") .verifyComplete(); assertThat(VirtualTimeScheduler.isFactoryEnabled()).isFalse(); }
@Test public void timedFusedError() throws Exception { VirtualTimeScheduler.getOrSet(); ReplayProcessor<Integer> rp = ReplayProcessor.createTimeout(Duration.ofSeconds(1)); for (int i = 0; i < 5; i++) { rp.onNext(i); } VirtualTimeScheduler.get().advanceTimeBy(Duration.ofSeconds(2)); for (int i = 5; i < 10; i++) { rp.onNext(i); } rp.onError(new Exception("test")); StepVerifier.create(rp) .expectFusion(Fuseable.NONE) .expectNext(5,6,7,8,9) .verifyErrorMessage("test"); }
@Test public void evictCancels() { AtomicReference<Subscription> subscription = new AtomicReference<>(); TestPublisher<Integer> tp = TestPublisher.create(); StepVerifier.withVirtualTime(() -> tp.flux() .doOnSubscribe(subscription::set) .onBackpressureBuffer(Duration.ofSeconds(1), 10, i -> { evicted.add(i); subscription.get().cancel(); }, VirtualTimeScheduler.get()), 0) .then(() -> tp.emit(1, 2, 3, 4, 5)) .thenAwait(Duration.ofMinutes(1)) .verifyComplete(); tp.assertCancelled(); assertThat(evicted).containsExactly(1, 2, 3, 4, 5); }
@Test public void timedFused() throws Exception { VirtualTimeScheduler.getOrSet(); ReplayProcessor<Integer> rp = ReplayProcessor.createTimeout(Duration.ofSeconds(1)); for (int i = 0; i < 5; i++) { rp.onNext(i); } VirtualTimeScheduler.get().advanceTimeBy(Duration.ofSeconds(2)); for (int i = 5; i < 10; i++) { rp.onNext(i); } rp.onComplete(); StepVerifier.create(rp) .expectFusion(Fuseable.NONE) .expectNext(5,6,7,8,9) .verifyComplete(); }
@Test public void suppliedVirtualTimeButNoSourceDoesntEnableScheduler() { VirtualTimeScheduler vts = VirtualTimeScheduler.create(); new DefaultStepVerifierBuilder<String>(StepVerifierOptions.create() .initialRequest(Long.MAX_VALUE) .virtualTimeSchedulerSupplier(() -> vts), null) //important to avoid triggering of vts capture-and-enable .expectNoEvent(Duration.ofSeconds(4)) .expectComplete() .toSubscriber(); try { //also test the side effect case where VTS has been enabled and not reset VirtualTimeScheduler current = VirtualTimeScheduler.get(); assertThat(current).isNotSameAs(vts); } catch (IllegalStateException e) { assertThat(e).hasMessageContaining("VirtualTimeScheduler"); } }
@Test public void timed() throws Exception { VirtualTimeScheduler.getOrSet(); ReplayProcessor<Integer> rp = ReplayProcessor.createTimeout(Duration.ofSeconds(1)); for (int i = 0; i < 5; i++) { rp.onNext(i); } VirtualTimeScheduler.get().advanceTimeBy(Duration.ofSeconds(2)); for (int i = 5; i < 10; i++) { rp.onNext(i); } rp.onComplete(); StepVerifier.create(rp.hide()) .expectFusion(Fuseable.NONE) .expectNext(5,6,7,8,9) .verifyComplete(); }
@Test public void timedAndBoundFusedError() throws Exception { ReplayProcessor<Integer> rp = ReplayProcessor.createSizeAndTimeout(5, Duration.ofSeconds(1)); for (int i = 0; i < 10; i++) { rp.onNext(i); } VirtualTimeScheduler.get().advanceTimeBy(Duration.ofSeconds(2)); for (int i = 10; i < 20; i++) { rp.onNext(i); } rp.onError(new Exception("test")); StepVerifier.create(rp) .expectFusion(Fuseable.ASYNC) .expectNext(15,16,17,18,19) .verifyErrorMessage("test"); Assert.assertFalse("Has subscribers?", rp.hasDownstreams()); }
@Test(timeout = 4000) public void manuallyManagedVirtualTime() { VirtualTimeScheduler vts = VirtualTimeScheduler.create(); try { VirtualTimeScheduler.getOrSet(vts); assertThat(VirtualTimeScheduler.get()).isSameAs(vts); Flux<String> flux = Flux.just("foo").delayElements(Duration.ofSeconds(4)); DefaultVerifySubscriber<String> s = new DefaultStepVerifierBuilder<String>(StepVerifierOptions.create() .initialRequest(Long.MAX_VALUE) .virtualTimeSchedulerSupplier(() -> vts), null)//important to avoid triggering of vts capture-and-enable .thenAwait(Duration.ofSeconds(1)) .expectNext("foo") .expectComplete() .toSubscriber(); flux.subscribe(s); vts.advanceTimeBy(Duration.ofSeconds(3)); s.verify(); assertThat(s.virtualTimeScheduler()).isSameAs(vts); assertThat(VirtualTimeScheduler.get()).isSameAs(vts); } finally { VirtualTimeScheduler.reset(); } }
@Test public void timedAndBoundError() throws Exception { ReplayProcessor<Integer> rp = ReplayProcessor.createSizeAndTimeout(5, Duration.ofSeconds(1)); for (int i = 0; i < 10; i++) { rp.onNext(i); } VirtualTimeScheduler.get().advanceTimeBy(Duration.ofSeconds(2)); for (int i = 10; i < 20; i++) { rp.onNext(i); } rp.onError(new Exception("test")); StepVerifier.create(rp.hide()) .expectFusion(Fuseable.NONE) .expectNext(15,16,17,18,19) .verifyErrorMessage("test"); Assert.assertFalse("Has subscribers?", rp.hasDownstreams()); }
@Test public void allEnabled() { Assert.assertFalse(Schedulers.newParallel("") instanceof VirtualTimeScheduler); Assert.assertFalse(Schedulers.newElastic("") instanceof VirtualTimeScheduler); Assert.assertFalse(Schedulers.newSingle("") instanceof VirtualTimeScheduler); VirtualTimeScheduler.getOrSet(); Assert.assertTrue(Schedulers.newParallel("") instanceof VirtualTimeScheduler); Assert.assertTrue(Schedulers.newElastic("") instanceof VirtualTimeScheduler); Assert.assertTrue(Schedulers.newSingle("") instanceof VirtualTimeScheduler); VirtualTimeScheduler t = VirtualTimeScheduler.get(); Assert.assertSame(Schedulers.newParallel(""), t); Assert.assertSame(Schedulers.newElastic(""), t); Assert.assertSame(Schedulers.newSingle(""), t); }
@Test public void timedFusedAfter() throws Exception { ReplayProcessor<Integer> rp = ReplayProcessor.createTimeout(Duration.ofSeconds(1)); StepVerifier.create(rp) .expectFusion(Fuseable.NONE) .then(() -> { for (int i = 0; i < 5; i++) { rp.onNext(i); } VirtualTimeScheduler.get().advanceTimeBy(Duration.ofSeconds(2)); for (int i = 5; i < 10; i++) { rp.onNext(i); } rp.onComplete(); }) .expectNext(0,1,2,3,4,5,6,7,8,9) .verifyComplete(); }
@Test public void timeoutLimit() { TestPublisher<Integer> tp = TestPublisher.create(); StepVerifier.withVirtualTime(() -> tp.flux().onBackpressureBuffer(Duration.ofSeconds(1), 1, this, VirtualTimeScheduler.get()), 0) .expectSubscription() .then(() -> tp.next(1)) .expectNoEvent(Duration.ofMillis(500)) .then(() -> tp.next(2)) .expectNoEvent(Duration.ofMillis(500)) .then(() -> tp.next(3)) .expectNoEvent(Duration.ofMillis(500)) .then(() -> tp.next(4)) .expectNoEvent(Duration.ofMillis(500)) .then(() -> tp.next(5)) .expectNoEvent(Duration.ofMillis(500)) .then(tp::complete) .thenRequest(1) .expectNext(5) .verifyComplete(); assertThat(evicted).containsExactly(1, 2, 3, 4); }
@Test public void timedAfter() throws Exception { ReplayProcessor<Integer> rp = ReplayProcessor.createTimeout(Duration.ofSeconds(1)); StepVerifier.create(rp.hide()) .expectFusion(Fuseable.NONE) .then(() -> { for (int i = 0; i < 5; i++) { rp.onNext(i); } VirtualTimeScheduler.get().advanceTimeBy(Duration.ofSeconds(2)); for (int i = 5; i < 10; i++) { rp.onNext(i); } rp.onComplete(); }) .expectNext(0,1,2,3,4,5,6,7,8,9) .verifyComplete(); }
@Test public void timedAndBoundFused() throws Exception { ReplayProcessor<Integer> rp = ReplayProcessor.createSizeAndTimeout(5, Duration.ofSeconds(1)); for (int i = 0; i < 10; i++) { rp.onNext(i); } VirtualTimeScheduler.get().advanceTimeBy(Duration.ofSeconds(2)); for (int i = 10; i < 20; i++) { rp.onNext(i); } rp.onComplete(); StepVerifier.create(rp) .expectFusion(Fuseable.ASYNC) .expectNext(15,16,17,18,19) .verifyComplete(); Assert.assertFalse("Has subscribers?", rp.hasDownstreams()); }
@Test public void timedAndBound() throws Exception { ReplayProcessor<Integer> rp = ReplayProcessor.createSizeAndTimeout(5, Duration.ofSeconds(1)); for (int i = 0; i < 10; i++) { rp.onNext(i); } VirtualTimeScheduler.get().advanceTimeBy(Duration.ofSeconds(2)); for (int i = 10; i < 20; i++) { rp.onNext(i); } rp.onComplete(); StepVerifier.create(rp.hide()) .expectFusion(Fuseable.NONE) .expectNext(15,16,17,18,19) .verifyComplete(); Assert.assertFalse("Has subscribers?", rp.hasDownstreams()); }
@Test public void timedAndBoundAfter() throws Exception { ReplayProcessor<Integer> rp = ReplayProcessor.createSizeAndTimeout(5, Duration.ofSeconds(1)); StepVerifier.create(rp.hide()) .expectFusion(Fuseable.NONE) .then(() -> { for (int i = 0; i < 10; i++) { rp.onNext(i); } VirtualTimeScheduler.get().advanceTimeBy(Duration.ofSeconds(2)); for (int i = 10; i < 20; i++) { rp.onNext(i); } rp.onComplete(); }) .expectNextCount(20) .verifyComplete(); Assert.assertFalse("Has subscribers?", rp.hasDownstreams()); }