reactor.test.util.RaceTestUtils Java Examples

The following examples show how to use reactor.test.util.RaceTestUtils. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: FluxScanTest.java    From reactor-core with Apache License 2.0 8 votes vote down vote up
@Test
public void onNextAndCancelRaceDontPassNullToAccumulator() {
	AtomicBoolean accumulatorCheck = new AtomicBoolean(true);
	final AssertSubscriber<Integer> testSubscriber = AssertSubscriber.create();

	FluxScan.ScanSubscriber<Integer> sub =
			new FluxScan.ScanSubscriber<>(testSubscriber, (accumulated, next) -> {
				if (accumulated == null || next == null) {
					accumulatorCheck.set(false);
				}
				return next;
			});

	sub.onSubscribe(Operators.emptySubscription());

	for (int i = 0; i < 1000; i++) {
		RaceTestUtils.race(sub::cancel, () -> sub.onNext(1));

		testSubscriber.assertNoError();
		assertThat(accumulatorCheck).as("no NPE due to onNext/cancel race in round " + i).isTrue();
	}
}
 
Example #2
Source File: FluxExpandTest.java    From reactor-core with Apache License 2.0 6 votes vote down vote up
@Test
public void depthEmitCancelRace() {
	for (int i = 0; i < 1000; i++) {

		final TestPublisher<Integer> pp = TestPublisher.create();

		final AssertSubscriber<Integer> ts = AssertSubscriber.create(1);

		Flux.just(0)
		    .expandDeep(it -> pp)
		    .subscribe(ts);

		Runnable r1 = () -> pp.next(1);
		Runnable r2 = ts::cancel;

		RaceTestUtils.race(r1, r2, Schedulers.single());
	}
}
 
Example #3
Source File: InstantPeriodicWorkerTaskTest.java    From reactor-core with Apache License 2.0 6 votes vote down vote up
@Test
public void restCancelRace() {
    ExecutorService exec = Executors.newSingleThreadExecutor();
    Disposable.Composite composit = Disposables.composite();

    try {
        for (int i = 0; i < 10000; i++) {
            final InstantPeriodicWorkerTask task = new InstantPeriodicWorkerTask(errorRunnable, exec, composit);

            final FutureTask<Void> f1 = new FutureTask<Void>(emptyRunnable, null);
            Runnable r1 = () -> task.setRest(f1);
            Runnable r2 = task::dispose;

            RaceTestUtils.race(r1, r2);

            assertTrue(f1.isCancelled());
            assertTrue(task.isDisposed());
        }
    }
    finally {
        exec.shutdownNow();
        Schedulers.resetOnHandleError();
    }
}
 
Example #4
Source File: FluxBufferTimeoutTest.java    From reactor-core with Apache License 2.0 6 votes vote down vote up
@Test
public void flushShouldNotRaceWithNext() {
	Set<Integer> seen = new HashSet<>();
	Consumer<List<Integer>> consumer = integers -> {
		for (Integer i : integers) {
			if (!seen.add(i)) {
				throw new IllegalStateException("Duplicate! " + i);
			}
		}
	};
	CoreSubscriber<List<Integer>> actual = new LambdaSubscriber<>(consumer, null, null, null);

	FluxBufferTimeout.BufferTimeoutSubscriber<Integer, List<Integer>> test = new FluxBufferTimeout.BufferTimeoutSubscriber<Integer, List<Integer>>(
			actual, 3, 1000, TimeUnit.MILLISECONDS, Schedulers.boundedElastic().createWorker(), ArrayList::new);
	test.onSubscribe(Operators.emptySubscription());

	AtomicInteger counter = new AtomicInteger();
	for (int i = 0; i < 500; i++) {
		RaceTestUtils.race(
				() -> test.onNext(counter.getAndIncrement()),
				() -> test.flushCallback(null),
				Schedulers.boundedElastic()
		);
	}
}
 
Example #5
Source File: InstantPeriodicWorkerTaskTest.java    From reactor-core with Apache License 2.0 6 votes vote down vote up
@Test
public void firstCancelRace() {
    ExecutorService exec = Executors.newSingleThreadExecutor();
    Disposable.Composite composit = Disposables.composite();

    try {
        for (int i = 0; i < 10000; i++) {
            final InstantPeriodicWorkerTask task = new InstantPeriodicWorkerTask(errorRunnable, exec, composit);

            final FutureTask<Void>
              f1 = new FutureTask<Void>(emptyRunnable, null);
            Runnable r1 = () -> task.setFirst(f1);
            Runnable r2 = task::dispose;

            RaceTestUtils.race(r1, r2);

            assertTrue(f1.isCancelled());
            assertTrue(task.isDisposed());
        }
    }
    finally {
        exec.shutdownNow();
        Schedulers.resetOnHandleError();
    }
}
 
Example #6
Source File: RSocketRequesterSubscribersTest.java    From rsocket-java with Apache License 2.0 6 votes vote down vote up
@ParameterizedTest
@MethodSource("allInteractions")
void singleSubscriberInCaseOfRacing(Function<RSocket, Publisher<?>> interaction) {
  for (int i = 1; i < 20000; i += 2) {
    Flux<?> response = Flux.from(interaction.apply(rSocketRequester));
    AssertSubscriber assertSubscriberA = AssertSubscriber.create();
    AssertSubscriber assertSubscriberB = AssertSubscriber.create();

    RaceTestUtils.race(
        () -> response.subscribe(assertSubscriberA), () -> response.subscribe(assertSubscriberB));

    connection.addToReceivedBuffer(PayloadFrameCodec.encodeComplete(connection.alloc(), i));

    assertSubscriberA.assertTerminated();
    assertSubscriberB.assertTerminated();

    Assertions.assertThat(new AssertSubscriber[] {assertSubscriberA, assertSubscriberB})
        .anySatisfy(as -> as.assertError(IllegalStateException.class));

    Assertions.assertThat(connection.getSent())
        .hasSize(1)
        .first()
        .matches(bb -> REQUEST_TYPES.contains(FrameHeaderCodec.frameType(bb)));
    connection.clearSendReceiveBuffers();
  }
}
 
Example #7
Source File: MonoCreateTest.java    From reactor-core with Apache License 2.0 6 votes vote down vote up
@Test
public void ensuresElementsIsDiscarded() {
	for (int i = 0; i < 10000; i++) {
		final ArrayList<Object> collector = new ArrayList<>();
		Hooks.onNextDropped(collector::add);
		AssertSubscriber<Object> assertSubscriber = new AssertSubscriber<>(Operators.enableOnDiscard(null, collector::add), 1);

		@SuppressWarnings("unchecked")
		MonoSink<Object>[] sinks = new MonoSink[1];

		Mono.create(sink -> sinks[0] = sink)
				.subscribe(assertSubscriber);

		Object testObject = new Object();
		RaceTestUtils.race(() -> sinks[0].success(testObject), () -> assertSubscriber.cancel());

		if (assertSubscriber.values().isEmpty()) {
			Assertions.assertThat(collector)
					.containsExactly(testObject);
		} else {
			assertSubscriber.awaitAndAssertNextValues(testObject);
		}
		Hooks.resetOnNextDropped();
	}
}
 
Example #8
Source File: MonoReduceSeedTest.java    From reactor-core with Apache License 2.0 6 votes vote down vote up
@Test
public void onNextAndCancelRace() {
	List<Integer> list = new ArrayList<>();
	final AssertSubscriber<Object> testSubscriber = AssertSubscriber.create();

	MonoReduceSeed.ReduceSeedSubscriber<Integer, List<Integer>> sub =
			new MonoReduceSeed.ReduceSeedSubscriber<>(testSubscriber,
					(l, next) -> {
						l.add(next);
						return l;
					}, list);

	sub.onSubscribe(Operators.emptySubscription());

	//the race alone _could_ previously produce a NPE
	RaceTestUtils.race(() -> sub.onNext(1), sub::cancel);
	testSubscriber.assertNoError();

	//to be even more sure, we try an onNext AFTER the cancel
	sub.onNext(2);
	testSubscriber.assertNoError();
}
 
Example #9
Source File: FluxCreateTest.java    From reactor-core with Apache License 2.0 6 votes vote down vote up
@Test
void bufferSinkRaceNextCancel() {
	AtomicInteger discarded = new AtomicInteger();
	final Context context = Operators.discardLocalAdapter(String.class, s -> discarded.incrementAndGet()).apply(Context.empty());

	BufferAsyncSink<String> sink = new BufferAsyncSink<>(new BaseSubscriber<String>() {
		@Override
		protected void hookOnSubscribe(Subscription subscription) {
			//do not request
		}

		@Override
		public Context currentContext() {
			return context;
		}
	}, 10);

	RaceTestUtils.race(sink::cancel,
			() -> sink.next("foo"));

	assertThat(sink.queue.poll()).as("internal queue empty").isNull();
	assertThat(discarded).as("discarded").hasValue(1);
}
 
Example #10
Source File: WorkerTaskTest.java    From reactor-core with Apache License 2.0 6 votes vote down vote up
@Test
public void runFuture() {
	for (int i = 0; i < RACE_DEFAULT_LOOPS; i++) {
		Disposable.Composite set = Disposables.composite();
		final WorkerTask run = new WorkerTask(() -> {}, set);
		set.add(run);

		final FutureTask<Void> ft = new FutureTask<>(() -> {
		}, null);

		Runnable r1 = run::call;

		Runnable r2 = () -> run.setFuture(ft);

		RaceTestUtils.race(r1, r2);
	}
}
 
Example #11
Source File: FluxCreateTest.java    From reactor-core with Apache License 2.0 6 votes vote down vote up
@Test
void latestSinkRaceNextCancel() {
	AtomicInteger discarded = new AtomicInteger();
	final Context context = Operators.discardLocalAdapter(String.class, s -> discarded.incrementAndGet()).apply(Context.empty());

	LatestAsyncSink<String> sink = new LatestAsyncSink<>(new BaseSubscriber<String>() {
		@Override
		protected void hookOnSubscribe(Subscription subscription) {
			//do not request
		}

		@Override
		public Context currentContext() {
			return context;
		}
	});

	RaceTestUtils.race(sink::cancel,
			() -> sink.next("foo"));

	assertThat(sink.queue).as("internal queue empty").hasValue(null);
	assertThat(discarded).as("discarded").hasValue(1);
}
 
Example #12
Source File: WorkerTaskTest.java    From reactor-core with Apache License 2.0 6 votes vote down vote up
@Test
public void setFutureRunRace() {
	for (int i = 0; i < RACE_DEFAULT_LOOPS; i++) {
		Disposable.Composite set = Disposables.composite();
		final WorkerTask run = new WorkerTask(() -> {}, set);
		set.add(run);

		final FutureTask<Object> ft = new FutureTask<>(() -> {
		}, 0);

		Runnable r1 = () -> run.setFuture(ft);

		Runnable r2 = run::run;

		RaceTestUtils.race(r1, r2);

		assertThat(set.size()).isZero();
	}
}
 
Example #13
Source File: MonoReduceTest.java    From reactor-core with Apache License 2.0 6 votes vote down vote up
@Test
public void onNextAndCancelRace() {
	final AssertSubscriber<Integer> testSubscriber = AssertSubscriber.create();

	MonoReduce.ReduceSubscriber<Integer> sub =
			new MonoReduce.ReduceSubscriber<>(testSubscriber, (current, next) -> current + next);

	sub.onSubscribe(Operators.emptySubscription());

	//the race alone _could_ previously produce a NPE
	RaceTestUtils.race(() -> sub.onNext(1), sub::cancel);
	testSubscriber.assertNoError();

	//to be even more sure, we try an onNext AFTER the cancel
	sub.onNext(2);
	testSubscriber.assertNoError();
}
 
Example #14
Source File: FluxScanSeedTest.java    From reactor-core with Apache License 2.0 6 votes vote down vote up
@Test
public void onNextAndCancelRaceDontPassNullToAccumulator() {
	AtomicBoolean accumulatorCheck = new AtomicBoolean(true);
	final AssertSubscriber<Object> testSubscriber = AssertSubscriber.create();

	FluxScanSeed.ScanSeedSubscriber<Integer, Integer> sub =
			new FluxScanSeed.ScanSeedSubscriber<>(testSubscriber,
					(accumulated, next) -> {
						if (accumulated == null || next == null) accumulatorCheck.set(false);
						return next;
					}, 0);

	sub.onSubscribe(Operators.emptySubscription());

	for (int i = 0; i < 1000; i++) {
		RaceTestUtils.race(sub::cancel, () -> sub.onNext(1));

		testSubscriber.assertNoError();
		assertThat(accumulatorCheck).as("no NPE due to onNext/cancel race in round " + i).isTrue();
	}
}
 
Example #15
Source File: MonoCacheTimeTest.java    From reactor-core with Apache License 2.0 6 votes vote down vote up
@Test
public void raceSubscribeAndCache() {
	AtomicInteger count = new AtomicInteger();
	Mono<Integer> source = Mono.fromCallable(count::getAndIncrement);

	for (int i = 0; i < 500; i++) {
		Mono<Integer> cached;
		if (i == 0) {
			cached = source.log().cache(Duration.ofSeconds(2));
		}
		else {
			cached = source.cache(Duration.ofSeconds(2));
		}
		RaceTestUtils.race(cached::subscribe, cached::subscribe);
	}

	assertThat(count.get()).isEqualTo(500);
}
 
Example #16
Source File: FluxExpandTest.java    From reactor-core with Apache License 2.0 6 votes vote down vote up
@Test
public void depthCompleteCancelRace() {
	for (int i = 0; i < 1000; i++) {

		final TestPublisher<Integer> pp = TestPublisher.create();

		final AssertSubscriber<Integer> ts = AssertSubscriber.create(1);
		Flux.just(0)
		    .expandDeep(it -> pp)
		    .subscribe(ts);

		Runnable r1 = pp::complete;
		Runnable r2 = ts::cancel;

		RaceTestUtils.race(r1, r2, Schedulers.single());
	}
}
 
Example #17
Source File: SimpleFifoPoolTest.java    From reactor-pool with Apache License 2.0 6 votes vote down vote up
@Test
@Tag("loops")
void acquireReleaseRaceWithMinSize_loop() {
    final Scheduler racer = Schedulers.fromExecutorService(Executors.newFixedThreadPool(2));
    AtomicInteger newCount = new AtomicInteger();
    try {
        PoolConfig<PoolableTest> testConfig = from(Mono.fromCallable(() -> new PoolableTest(newCount.getAndIncrement())))
                .sizeBetween(4, 5)
                .buildConfig();
        SimpleFifoPool<PoolableTest> pool = new SimpleFifoPool<>(testConfig);

        for (int i = 0; i < 100; i++) {
            RaceTestUtils.race(() -> pool.acquire().block().release().block(),
                    () -> pool.acquire().block().release().block(),
                    racer);
        }
        //we expect that only 3 element was created
        assertThat(newCount).as("elements created in total").hasValue(4);
    }
    finally {
        racer.dispose();
    }
}
 
Example #18
Source File: DisposablesTest.java    From reactor-core with Apache License 2.0 5 votes vote down vote up
@Test
public void disposeRace() {
	for (int i = 0; i < 500; i++) {

		TestDisposable r = new TestDisposable() {
			@Override
			public void run() {
				Disposables.dispose(DISPOSABLE_UPDATER, this);
			}
		};

		RaceTestUtils.race(r, r, Schedulers.boundedElastic());
	}
}
 
Example #19
Source File: DisposablesTest.java    From reactor-core with Apache License 2.0 5 votes vote down vote up
@Test
public void setRace() {
	for (int i = 0; i < 500; i++) {
		TestDisposable r = new TestDisposable() {
			@Override
			public void run() {
				Disposables.set(DISPOSABLE_UPDATER, this, Disposables.single());
			}
		};

		RaceTestUtils.race(r, r, Schedulers.boundedElastic());
	}
}
 
Example #20
Source File: DisposablesTest.java    From reactor-core with Apache License 2.0 5 votes vote down vote up
@Test
public void setReplace() {
	for (int i = 0; i < 500; i++) {

		TestDisposable r = new TestDisposable() {
			@Override
			public void run() {
				Disposables.replace(DISPOSABLE_UPDATER, this, Disposables.single());
			}
		};

		RaceTestUtils.race(r, r, Schedulers.boundedElastic());
	}
}
 
Example #21
Source File: ReconnectMonoTests.java    From rsocket-java with Apache License 2.0 5 votes vote down vote up
@Test
public void shouldExpireValueExactlyOnceOnRacingBetweenInvalidateAndDispose() {
  for (int i = 0; i < 10000; i++) {
    final TestPublisher<String> cold = TestPublisher.createCold();
    cold.next("value");
    final int timeout = 10000;

    final ReconnectMono<String> reconnectMono =
        cold.mono().as(source -> new ReconnectMono<>(source, onExpire(), onValue()));

    StepVerifier.create(reconnectMono.subscribeOn(Schedulers.elastic()))
        .expectSubscription()
        .expectNext("value")
        .expectComplete()
        .verify(Duration.ofSeconds(timeout));

    Assertions.assertThat(expired).isEmpty();
    Assertions.assertThat(received).hasSize(1).containsOnly(Tuples.of("value", reconnectMono));

    RaceTestUtils.race(reconnectMono::invalidate, reconnectMono::dispose);

    Assertions.assertThat(expired).hasSize(1).containsOnly("value");
    Assertions.assertThat(received).hasSize(1).containsOnly(Tuples.of("value", reconnectMono));

    StepVerifier.create(reconnectMono.subscribeOn(Schedulers.elastic()))
        .expectSubscription()
        .expectError(CancellationException.class)
        .verify(Duration.ofSeconds(timeout));

    Assertions.assertThat(expired).hasSize(1).containsOnly("value");
    Assertions.assertThat(received).hasSize(1).containsOnly(Tuples.of("value", reconnectMono));

    Assertions.assertThat(cold.subscribeCount()).isEqualTo(1);

    expired.clear();
    received.clear();
  }
}
 
Example #22
Source File: FluxBufferPredicateTest.java    From reactor-core with Apache License 2.0 5 votes vote down vote up
@Test
public void onNextRaceWithRequestOfTwo() {
	AtomicLong requested = new AtomicLong();
	TestPublisher<Integer> testPublisher = TestPublisher.create();
	FluxBufferPredicate<Integer, List<Integer>> bufferPredicate = new FluxBufferPredicate<>(
			testPublisher.flux().doOnRequest(requested::addAndGet),
			i -> true, ArrayList::new, FluxBufferPredicate.Mode.UNTIL);

	BaseSubscriber<List<Integer>> subscriber = new BaseSubscriber<List<Integer>>() {
		@Override
		protected void hookOnSubscribe(Subscription subscription) {
			request(1);
		}
	};
	bufferPredicate.subscribe(subscriber);
	@SuppressWarnings("unchecked")
	final FluxBufferPredicate.BufferPredicateSubscriber<Integer, List<Integer>> bufferPredicateSubscriber =
			(FluxBufferPredicate.BufferPredicateSubscriber<Integer, List<Integer>>) subscriber.subscription;

	for (int i = 0; i < 10; i++) {
		final int value = i;
		RaceTestUtils.race(() -> testPublisher.next(value), () -> subscriber.request(2));
	}
	for (int i = 0; i < bufferPredicateSubscriber.requestedFromSource; i++) {
		testPublisher.next(100 + i);
	}
	testPublisher.complete();

	assertThat(requested).as("total upstream request").hasValue(2 * 10 + 1);
}
 
Example #23
Source File: ListCompositeDisposableTest.java    From reactor-core with Apache License 2.0 5 votes vote down vote up
@Test
public void disposeConcurrent() {
	for (int i = 0; i < 500; i++) {
		final Disposable d1 = new FakeDisposable();
		final Disposable.Composite cd = new ListCompositeDisposable(d1);

		RaceTestUtils.race(cd::dispose, cd::dispose, Schedulers.boundedElastic());
	}
}
 
Example #24
Source File: FluxBufferPredicateTest.java    From reactor-core with Apache License 2.0 5 votes vote down vote up
@Test
public void onNextRaceWithRequest() {
	AtomicLong requested = new AtomicLong();
	TestPublisher<Integer> testPublisher = TestPublisher.create();
	FluxBufferPredicate<Integer, List<Integer>> bufferPredicate = new FluxBufferPredicate<>(
			testPublisher.flux().doOnRequest(requested::addAndGet),
			i -> true, ArrayList::new, FluxBufferPredicate.Mode.UNTIL);

	BaseSubscriber<List<Integer>> subscriber = new BaseSubscriber<List<Integer>>() {
		@Override
		protected void hookOnSubscribe(Subscription subscription) {
			request(1);
		}
	};
	bufferPredicate.subscribe(subscriber);
	@SuppressWarnings("unchecked")
	final FluxBufferPredicate.BufferPredicateSubscriber<Integer, List<Integer>> bufferPredicateSubscriber =
			(FluxBufferPredicate.BufferPredicateSubscriber<Integer, List<Integer>>) subscriber.subscription;

	for (int i = 0; i < 10; i++) {
		final int value = i;
		RaceTestUtils.race(() -> testPublisher.next(value), () -> subscriber.request(1));
	}
	for (int i = 0; i < bufferPredicateSubscriber.requestedFromSource; i++) {
		testPublisher.next(100 + i);
	}
	testPublisher.complete();

	assertThat(requested).as("total upstream request").hasValue(10 + 1);
}
 
Example #25
Source File: FluxBufferPredicateTest.java    From reactor-core with Apache License 2.0 5 votes vote down vote up
@Test
public void requestRaceWithOnNext() {
	AtomicLong requested = new AtomicLong();
	TestPublisher<Integer> testPublisher = TestPublisher.create();
	FluxBufferPredicate<Integer, List<Integer>> bufferPredicate = new FluxBufferPredicate<>(
			testPublisher.flux().doOnRequest(requested::addAndGet),
			i -> true, ArrayList::new, FluxBufferPredicate.Mode.UNTIL);

	BaseSubscriber<List<Integer>> subscriber = new BaseSubscriber<List<Integer>>() {
		@Override
		protected void hookOnSubscribe(Subscription subscription) {
			request(1);
		}
	};
	bufferPredicate.subscribe(subscriber);
	@SuppressWarnings("unchecked")
	final FluxBufferPredicate.BufferPredicateSubscriber<Integer, List<Integer>> bufferPredicateSubscriber =
			(FluxBufferPredicate.BufferPredicateSubscriber<Integer, List<Integer>>) subscriber.subscription;

	for (int i = 0; i < 10; i++) {
		final int value = i;
		RaceTestUtils.race(() -> subscriber.request(1), () -> testPublisher.next(value));
	}
	for (int i = 0; i < bufferPredicateSubscriber.requestedFromSource; i++) {
		testPublisher.next(100 + i);
	}
	testPublisher.complete();

	assertThat(requested).as("total upstream request").hasValue(10 + 1);
}
 
Example #26
Source File: ListCompositeDisposableTest.java    From reactor-core with Apache License 2.0 5 votes vote down vote up
@Test
public void removeConcurrent() {
	for (int i = 0; i < 500; i++) {
		final Disposable d1 = new FakeDisposable();
		final Disposable.Composite cd = new ListCompositeDisposable(d1);

		RaceTestUtils.race(() -> cd.remove(d1), cd::dispose, Schedulers.boundedElastic());
	}
}
 
Example #27
Source File: ListCompositeDisposableTest.java    From reactor-core with Apache License 2.0 5 votes vote down vote up
@Test
public void sizeConcurrent() {
	for (int i = 0; i < 500; i++) {
		final Disposable d1 = new FakeDisposable();
		final Disposable.Composite cd = new ListCompositeDisposable(d1);

		RaceTestUtils.race(cd::size, cd::dispose, Schedulers.boundedElastic());
	}
}
 
Example #28
Source File: FluxExpandTest.java    From reactor-core with Apache License 2.0 5 votes vote down vote up
@Test
public void depthCancelRace() {
	for (int i = 0; i < 1000; i++) {
		final AssertSubscriber<Integer> ts = AssertSubscriber.create(0);

		Flux.just(0)
		    .expandDeep(countDown)
		    .subscribe(ts);

		Runnable r1 = () -> ts.request(1);
		Runnable r2 = ts::cancel;

		RaceTestUtils.race(r1, r2, Schedulers.single());
	}
}
 
Example #29
Source File: FluxFlatMapTest.java    From reactor-core with Apache License 2.0 5 votes vote down vote up
@Test
public void errorModeContinueInternalErrorStopStrategyAsync() {
	for (int iterations = 0; iterations < 1000; iterations++) {
		AtomicInteger i = new AtomicInteger();
		TestPublisher<Integer>[] inners = new TestPublisher[]{
			TestPublisher.createNoncompliant(TestPublisher.Violation.CLEANUP_ON_TERMINATE),
			TestPublisher.createNoncompliant(TestPublisher.Violation.CLEANUP_ON_TERMINATE)
		};
		Flux<Integer> test = Flux
				.just(0, 1)
				.hide()
				.flatMap(f -> inners[i.getAndIncrement()].flux().map(n -> n / f).onErrorStop())
				.onErrorContinue(OnNextFailureStrategyTest::drop);

		StepVerifier.Assertions assertions = StepVerifier
				.create(test)
				.expectNoFusionSupport()
				.then(() -> RaceTestUtils.race(() -> inners[0].next(1).complete(), () -> inners[1].next(1).complete()))
				.expectNext(1)
				.expectComplete()
				.verifyThenAssertThat();

		Awaitility.with().pollDelay(org.awaitility.Duration.ZERO).pollInterval(org.awaitility.Duration.ONE_MILLISECOND)
				.await()
				.atMost(org.awaitility.Duration.ONE_SECOND)
				.untilAsserted(() -> assertions.hasNotDroppedElements().hasDroppedErrors(1));
	}
}
 
Example #30
Source File: FluxBufferWhenTest.java    From reactor-core with Apache License 2.0 5 votes vote down vote up
@Test(timeout = 5000)
public void cancelWinsOverDrain() {
	Queue<List<Integer>> queue = Queues.<List<Integer>>small().get();
	queue.offer(Arrays.asList(1, 2, 3));

	AssertSubscriber<List<Integer>> actual = AssertSubscriber.create();

	BufferWhenMainSubscriber<Integer, String, Void, List<Integer>> main =
			new BufferWhenMainSubscriber<>(actual,
					ArrayList::new,
					() -> queue,
					Mono.just("open"),
					i -> Mono.never());
	main.onSubscribe(Operators.emptySubscription());

	RaceTestUtils.race(main,
			m -> {
				m.cancel();
				m.drain();
				return m;
			},
			m -> m.cancelled,
			(m1, m2) -> /* ignored */ true);

	assertThat(main.cancelled).as("cancelled").isTrue();
	//TODO windows went as far up as 3, verify if that is indeed concurrent cancels
	assertThat(main.windows).as("windows").isLessThan(4);
	assertThat(queue).as("queue was cleared").isEmpty();

	//we also check no values were drained to the actual
	assertThat(actual.values())
			.as("no buffer should be drained")
			.isEmpty();
}