Java Code Examples for reactor.test.util.RaceTestUtils

The following examples show how to use reactor.test.util.RaceTestUtils. These examples are extracted from open source projects. 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 Project: reactor-pool   Source File: SimpleFifoPoolTest.java    License: 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 2
Source Project: reactor-core   Source File: FluxBufferTimeoutTest.java    License: 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 3
@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 4
Source Project: reactor-core   Source File: MonoReduceSeedTest.java    License: 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 5
Source Project: reactor-core   Source File: MonoCreateTest.java    License: 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 6
Source Project: reactor-core   Source File: FluxCreateTest.java    License: 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 7
Source Project: reactor-core   Source File: FluxCreateTest.java    License: 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 8
Source Project: reactor-core   Source File: FluxScanTest.java    License: Apache License 2.0 6 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 9
Source Project: reactor-core   Source File: FluxScanSeedTest.java    License: 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 10
Source Project: reactor-core   Source File: MonoCacheTimeTest.java    License: 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 11
Source Project: reactor-core   Source File: FluxExpandTest.java    License: 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 12
Source Project: reactor-core   Source File: FluxExpandTest.java    License: 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 13
Source Project: reactor-core   Source File: MonoReduceTest.java    License: 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 Project: reactor-core   Source File: WorkerTaskTest.java    License: 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 15
Source Project: reactor-core   Source File: WorkerTaskTest.java    License: 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 16
@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 17
@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 18
Source Project: reactor-pool   Source File: CommonPoolTest.java    License: Apache License 2.0 5 votes vote down vote up
@ParameterizedTest
@MethodSource("allPools")
void invalidateRaceIdleState(Function<PoolBuilder<Integer, ?>, AbstractPool<Integer>> configAdjuster)
		throws Exception {
	AtomicInteger destroyCounter = new AtomicInteger();
	PoolBuilder<Integer, ?> builder = PoolBuilder.from(Mono.just(1))
	                                             .evictionPredicate((obj, meta) -> true)
	                                             .destroyHandler(i -> Mono.fromRunnable(destroyCounter::incrementAndGet))
	                                             .sizeBetween(0, 1)
	                                             .maxPendingAcquire(1);
	InstrumentedPool<Integer> pool = configAdjuster.apply(builder);
	int loops = 4000;

	final CountDownLatch latch = new CountDownLatch(loops * 2);

	for (int i = 0; i < loops; i++) {
		final PooledRef<Integer> pooledRef = pool.acquire().block();
		RaceTestUtils.race(() -> pooledRef.release().subscribe(v -> {}, e -> latch.countDown(),
				latch::countDown),
				() -> pooledRef.invalidate().subscribe(v -> {}, e -> latch.countDown(),
						latch::countDown));
	}

	assertThat(latch.await(5, TimeUnit.SECONDS)).isTrue();

	assertThat(destroyCounter).hasValue(4000);
}
 
Example 19
Source Project: reactor-core   Source File: MonoExpandTest.java    License: 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);

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

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

		RaceTestUtils.race(r1, r2, Schedulers.single());
	}
}
 
Example 20
Source Project: rsocket-java   Source File: RSocketResponderTest.java    License: Apache License 2.0 5 votes vote down vote up
@Test
public void checkNoLeaksOnRacingBetweenDownstreamCancelAndOnNextFromRequestResponseTest1() {
  Scheduler parallel = Schedulers.parallel();
  Hooks.onErrorDropped((e) -> {});
  ByteBufAllocator allocator = rule.alloc();
  for (int i = 0; i < 10000; i++) {
    Operators.MonoSubscriber<Payload, Payload>[] sources = new Operators.MonoSubscriber[1];

    rule.setAcceptingSocket(
        new RSocket() {
          @Override
          public Mono<Payload> requestResponse(Payload payload) {
            payload.release();
            return new Mono<Payload>() {
              @Override
              public void subscribe(CoreSubscriber<? super Payload> actual) {
                sources[0] = new Operators.MonoSubscriber<>(actual);
                actual.onSubscribe(sources[0]);
              }
            };
          }
        },
        Integer.MAX_VALUE);

    rule.sendRequest(1, REQUEST_RESPONSE);

    ByteBuf cancelFrame = CancelFrameCodec.encode(allocator, 1);
    RaceTestUtils.race(
        () -> rule.connection.addToReceivedBuffer(cancelFrame),
        () -> {
          sources[0].complete(ByteBufPayload.create("d1", "m1"));
        },
        parallel);

    Assertions.assertThat(rule.connection.getSent()).allMatch(ReferenceCounted::release);

    rule.assertHasNoLeaks();
  }
}
 
Example 21
Source Project: reactor-core   Source File: FluxLimitRequestTest.java    License: Apache License 2.0 5 votes vote down vote up
@Test
public void raceRequest() {
	List<Long> requests = Collections.synchronizedList(new ArrayList<>());
	final Flux<Integer> flux = Flux.range(1, 1000)
	                               .doOnRequest(requests::add)
	                               .limitRequest(81);
	BaseSubscriber<Integer> base = new BaseSubscriber<Integer>() {
		@Override
		protected void hookOnSubscribe(Subscription subscription) {
		}
	};
	flux.subscribe(base);

	for (int i = 0; i < 11; i++) {
		final int idx = i;
		RaceTestUtils.race(
				() -> base.request(idx % 2 == 0 ? 10 : 8),
				() -> base.request(8)
		);
	}

	assertThat(requests.stream().mapToLong(l -> l).sum())
			.as("total request should match the limitRequest")
			.isEqualTo(81);
	assertThat(requests.subList(0, requests.size() - 2))
			.allMatch(l -> l % 2 == 0, "all requests except last two are even");
	assertThat(requests)
			.filteredOn(l -> l % 2 == 1)
			.as("only one odd element toward end")
			.hasSize(1);
}
 
Example 22
Source Project: reactor-core   Source File: FluxSwitchOnFirstTest.java    License: Apache License 2.0 5 votes vote down vote up
@Test
public void shouldNotSubscribeTwice() {
    Throwable[] throwables = new Throwable[1];
    CountDownLatch latch = new CountDownLatch(1);
    StepVerifier.create(Flux.just(1L)
                .switchOnFirst((s, f) -> {
                    RaceTestUtils.race(
                        () -> f.subscribe(__ -> {}, t -> {
                            throwables[0] = t;
                            latch.countDown();
                        },  latch::countDown),
                        () -> f.subscribe(__ -> {}, t -> {
                            throwables[0] = t;
                            latch.countDown();
                        },  latch::countDown)
                    );

                    return Flux.empty();
                }))
                .expectSubscription()
                .expectComplete()
                .verify(Duration.ofSeconds(5));


    Assertions.assertThat(throwables[0])
              .isInstanceOf(IllegalStateException.class)
              .hasMessage("FluxSwitchOnFirst allows only one Subscriber");
}
 
Example 23
Source Project: rsocket-java   Source File: ReconnectMonoTests.java    License: Apache License 2.0 5 votes vote down vote up
@Test
public void shouldExpireValueOnRacingDisposeAndComplete() {
  Hooks.onErrorDropped(t -> {});
  for (int i = 0; i < 10000; i++) {
    final TestPublisher<String> cold =
        TestPublisher.createNoncompliant(TestPublisher.Violation.REQUEST_OVERFLOW);

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

    final MonoProcessor<String> processor = reconnectMono.subscribeWith(MonoProcessor.create());

    Assertions.assertThat(expired).isEmpty();
    Assertions.assertThat(received).isEmpty();

    cold.next("value" + i);

    RaceTestUtils.race(cold::complete, reconnectMono::dispose);

    Assertions.assertThat(processor.isTerminated()).isTrue();

    if (processor.isError()) {
      Assertions.assertThat(processor.getError())
          .isInstanceOf(CancellationException.class)
          .hasMessage("ReconnectMono has already been disposed");
    } else {
      Assertions.assertThat(received)
          .hasSize(1)
          .containsOnly(Tuples.of("value" + i, reconnectMono));
      Assertions.assertThat(processor.peek()).isEqualTo("value" + i);
    }

    Assertions.assertThat(expired).hasSize(1).containsOnly("value" + i);

    expired.clear();
    received.clear();
  }
}
 
Example 24
Source Project: reactor-core   Source File: FluxSwitchOnFirstTest.java    License: Apache License 2.0 5 votes vote down vote up
@Test
public void racingTest() throws InterruptedException {
    for (int i = 0; i < 1000; i++) {
        @SuppressWarnings("unchecked")
        CoreSubscriber<? super Integer>[] subscribers = new CoreSubscriber[1];
        Subscription[] downstreamSubscriptions = new Subscription[1];
        Subscription[] innerSubscriptions = new Subscription[1];


        AtomicLong requested = new AtomicLong();

        Flux.range(0, 3)
                .doOnRequest(requested::addAndGet)
                .switchOnFirst((s, f) -> new Flux<Integer>() {

                    @Override
                    public void subscribe(CoreSubscriber<? super Integer> actual) {
                        subscribers[0] = actual;
                        f.subscribe(actual::onNext, actual::onError, actual::onComplete, (s) -> innerSubscriptions[0] = s);
                    }
                })
                .subscribe(__ -> {
                }, __ -> {
                }, () -> {
                }, s -> downstreamSubscriptions[0] = s);

        CoreSubscriber<? super Integer> subscriber = subscribers[0];
        Subscription downstreamSubscription = downstreamSubscriptions[0];
        Subscription innerSubscription = innerSubscriptions[0];
        downstreamSubscription.request(1);

        RaceTestUtils.race(() -> subscriber.onSubscribe(innerSubscription), () -> downstreamSubscription.request(1));

        Assertions.assertThat(requested.get()).isEqualTo(2);
    }
}
 
Example 25
Source Project: reactor-core   Source File: FluxSwitchOnFirstTest.java    License: Apache License 2.0 5 votes vote down vote up
@SuppressWarnings("rawtypes")
@Test
public void unitRequestRacingTest() {
    @SuppressWarnings("unchecked")
    BiFunction<FluxSwitchOnFirst.AbstractSwitchOnFirstMain, CoreSubscriber, InnerOperator>[] factories = new BiFunction[] {
            (parent, assertSubscriber) -> new FluxSwitchOnFirst.SwitchOnFirstControlSubscriber((FluxSwitchOnFirst.AbstractSwitchOnFirstMain) parent, (CoreSubscriber) assertSubscriber, true),
            (parent, assertSubscriber) -> new FluxSwitchOnFirst.SwitchOnFirstConditionalControlSubscriber((FluxSwitchOnFirst.AbstractSwitchOnFirstMain) parent, (Fuseable.ConditionalSubscriber) assertSubscriber, true)
    };
    for (BiFunction<FluxSwitchOnFirst.AbstractSwitchOnFirstMain, CoreSubscriber, InnerOperator> factory : factories) {
        for (int i = 0; i < 10000; i++) {
            FluxSwitchOnFirst.AbstractSwitchOnFirstMain mockParent = Mockito.mock(FluxSwitchOnFirst.AbstractSwitchOnFirstMain.class);
            Mockito.doNothing().when(mockParent).request(Mockito.anyLong());
            Mockito.doNothing().when(mockParent).cancel();
            Subscription mockSubscription = Mockito.mock(Subscription.class);
            ArgumentCaptor<Long> longArgumentCaptor = ArgumentCaptor.forClass(Long.class);
            Mockito.doNothing().when(mockSubscription).request(longArgumentCaptor.capture());
            Mockito.doNothing().when(mockSubscription).cancel();
            AssertSubscriber<Object> subscriber = AssertSubscriber.create(0);
            InnerOperator switchOnFirstControlSubscriber = factory.apply(mockParent, Operators.toConditionalSubscriber(subscriber));

            switchOnFirstControlSubscriber.request(10);
            RaceTestUtils.race(() -> switchOnFirstControlSubscriber.request(10), () -> switchOnFirstControlSubscriber.onSubscribe(mockSubscription), Schedulers.parallel());

            Assertions.assertThat(longArgumentCaptor.getAllValues().size()).isBetween(1, 2);
            if (longArgumentCaptor.getAllValues().size() == 1) {
                Assertions.assertThat(longArgumentCaptor.getValue()).isEqualTo(20L);
            }
            else if (longArgumentCaptor.getAllValues().size() == 2) {
                Assertions.assertThat(longArgumentCaptor.getAllValues()).containsExactly(10L, 10L);
            }
            else {
                Assertions.fail("Unexpected number of calls");
            }
        }
    }
}
 
Example 26
Source Project: reactor-core   Source File: FluxSwitchOnFirstTest.java    License: Apache License 2.0 5 votes vote down vote up
@SuppressWarnings("rawtypes")
@Test
public void unitRequestsAreSerialTest() {
    @SuppressWarnings("unchecked")
    BiFunction<FluxSwitchOnFirst.AbstractSwitchOnFirstMain, CoreSubscriber, InnerOperator>[] factories = new BiFunction[] {
            (parent, assertSubscriber) -> new FluxSwitchOnFirst.SwitchOnFirstControlSubscriber((FluxSwitchOnFirst.AbstractSwitchOnFirstMain) parent, (CoreSubscriber) assertSubscriber, true),
            (parent, assertSubscriber) -> new FluxSwitchOnFirst.SwitchOnFirstConditionalControlSubscriber((FluxSwitchOnFirst.AbstractSwitchOnFirstMain) parent, (Fuseable.ConditionalSubscriber) assertSubscriber, true)
    };
    for (BiFunction<FluxSwitchOnFirst.AbstractSwitchOnFirstMain, CoreSubscriber, InnerOperator> factory : factories) {
        for (int i = 0; i < 100000; i++) {
            long[] valueHolder = new long[] { 0 };
            FluxSwitchOnFirst.AbstractSwitchOnFirstMain mockParent = Mockito.mock(FluxSwitchOnFirst.AbstractSwitchOnFirstMain.class);
            Mockito.doNothing().when(mockParent).request(Mockito.anyLong());
            Mockito.doNothing().when(mockParent).cancel();
            Subscription mockSubscription = Mockito.mock(Subscription.class);
            Mockito.doAnswer((a) -> valueHolder[0] += (long) a.getArgument(0)).when(mockSubscription).request(Mockito.anyLong());
            Mockito.doNothing().when(mockSubscription).cancel();
            AssertSubscriber<Object> subscriber = AssertSubscriber.create(0);
            InnerOperator switchOnFirstControlSubscriber = factory.apply(mockParent, Operators.toConditionalSubscriber(subscriber));

            switchOnFirstControlSubscriber.request(10);
            RaceTestUtils.race(() -> {
                        switchOnFirstControlSubscriber.request(10);
                        switchOnFirstControlSubscriber.request(10);
                        switchOnFirstControlSubscriber.request(10);
                        switchOnFirstControlSubscriber.request(10);
                    },
                    () -> switchOnFirstControlSubscriber.onSubscribe(mockSubscription),
                    Schedulers.parallel());

            switchOnFirstControlSubscriber.request(10);
            Assertions.assertThat(valueHolder[0])
                      .isEqualTo(60L);
            mockSubscription.toString();
        }
    }
}
 
Example 27
Source Project: reactor-core   Source File: FluxSwitchOnFirstTest.java    License: Apache License 2.0 5 votes vote down vote up
@SuppressWarnings("rawtypes")
@Test
public void unitCancelRacingTest() {
    @SuppressWarnings("unchecked")
    BiFunction<FluxSwitchOnFirst.AbstractSwitchOnFirstMain, CoreSubscriber, InnerOperator>[] factories = new BiFunction[] {
            (parent, assertSubscriber) -> new FluxSwitchOnFirst.SwitchOnFirstControlSubscriber((FluxSwitchOnFirst.AbstractSwitchOnFirstMain) parent, (CoreSubscriber) assertSubscriber, true),
            (parent, assertSubscriber) -> new FluxSwitchOnFirst.SwitchOnFirstConditionalControlSubscriber((FluxSwitchOnFirst.AbstractSwitchOnFirstMain) parent, (Fuseable.ConditionalSubscriber) assertSubscriber, true)
    };
    for (BiFunction<FluxSwitchOnFirst.AbstractSwitchOnFirstMain, CoreSubscriber, InnerOperator> factory : factories) {
        for (int i = 0; i < 10000; i++) {
            FluxSwitchOnFirst.AbstractSwitchOnFirstMain mockParent = Mockito.mock(FluxSwitchOnFirst.AbstractSwitchOnFirstMain.class);
            Mockito.doNothing().when(mockParent).request(Mockito.anyLong());
            Mockito.doNothing().when(mockParent).cancel();
            Subscription mockSubscription = Mockito.mock(Subscription.class);
            ArgumentCaptor<Long> longArgumentCaptor = ArgumentCaptor.forClass(Long.class);
            Mockito.doNothing().when(mockSubscription).request(longArgumentCaptor.capture());
            Mockito.doNothing().when(mockSubscription).cancel();
            AssertSubscriber<Object> subscriber = AssertSubscriber.create(0);
            InnerOperator switchOnFirstControlSubscriber = factory.apply(mockParent, Operators.toConditionalSubscriber(subscriber));

            switchOnFirstControlSubscriber.request(10);
            RaceTestUtils.race(() -> switchOnFirstControlSubscriber.cancel(), () -> switchOnFirstControlSubscriber.onSubscribe(mockSubscription), Schedulers.parallel());

            Assertions.assertThat(longArgumentCaptor.getAllValues().size()).isBetween(0, 1);
            Mockito.verify(mockParent).cancel();
            if (longArgumentCaptor.getAllValues().size() == 1) {
                Assertions.assertThat(longArgumentCaptor.getValue()).isEqualTo(10L);
            }
            else if (longArgumentCaptor.getAllValues().size() > 1) {
                Assertions.fail("Unexpected number of calls");
            }
        }
    }
}
 
Example 28
Source Project: reactor-core   Source File: FluxBufferWhenTest.java    License: 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();
}
 
Example 29
Source Project: reactor-core   Source File: FluxFlatMapTest.java    License: 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 Project: reactor-core   Source File: FluxExpandTest.java    License: 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());
	}
}