@Test(timeout = 10000) public void testOnBackpressureDropSynchronous() { for (int i = 0; i < 100; i++) { int NUM = (int) (RxRingBuffer.SIZE * 1.1); // > 1 so that take doesn't prevent buffer overflow AtomicInteger c = new AtomicInteger(); TestSubscriber<Integer> ts = new TestSubscriber<Integer>(); firehose(c).onBackpressureDrop().map(SLOW_PASS_THRU).take(NUM).subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); List<Integer> onNextEvents = ts.getOnNextEvents(); assertEquals(NUM, onNextEvents.size()); Integer lastEvent = onNextEvents.get(NUM - 1); System.out.println( "testOnBackpressureDrop => Received: " + onNextEvents.size() + " Emitted: " + c.get() + " Last value: " + lastEvent); // it drop, so we should get some number far higher than what would have sequentially // incremented assertTrue(NUM - 1 <= lastEvent.intValue()); } }
@Test public void testFlatMapSync() { int NUM = (int) (RxRingBuffer.SIZE * 2.1); AtomicInteger c = new AtomicInteger(); TestSubscriber<Integer> ts = new TestSubscriber<Integer>(); incrementingIntegers(c) .flatMap( new Func1<Integer, Observable<Integer>>() { @Override public Observable<Integer> call(Integer i) { return incrementingIntegers(new AtomicInteger()).take(10); } }) .take(NUM) .subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); System.out.println( "testFlatMapSync => Received: " + ts.getOnNextEvents().size() + " Emitted: " + c.get()); assertEquals(NUM, ts.getOnNextEvents().size()); // expect less than 1 buffer since the flatMap is emitting 10 each time, so it is NUM/10 that // will be taken. assertTrue(c.get() < RxRingBuffer.SIZE); }
@Test public void testZipAsync() { int NUM = (int) (RxRingBuffer.SIZE * 2.1); AtomicInteger c1 = new AtomicInteger(); AtomicInteger c2 = new AtomicInteger(); TestSubscriber<Integer> ts = new TestSubscriber<Integer>(); Observable<Integer> zipped = Observable.zip( incrementingIntegers(c1).subscribeOn(Schedulers.computation()), incrementingIntegers(c2).subscribeOn(Schedulers.computation()), new Func2<Integer, Integer, Integer>() { @Override public Integer call(Integer t1, Integer t2) { return t1 + t2; } }); zipped.take(NUM).subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); System.out.println( "testZipAsync => Received: " + ts.getOnNextEvents().size() + " Emitted: " + c1.get() + " / " + c2.get()); assertEquals(NUM, ts.getOnNextEvents().size()); assertTrue(c1.get() < RxRingBuffer.SIZE * 3); assertTrue(c2.get() < RxRingBuffer.SIZE * 3); }
@Test public void testMergeAsyncThenObserveOnLoop() { for (int i = 0; i < 500; i++) { if (i % 10 == 0) { System.out.println("testMergeAsyncThenObserveOnLoop >> " + i); } // Verify there is no MissingBackpressureException int NUM = (int) (RxRingBuffer.SIZE * 4.1); AtomicInteger c1 = new AtomicInteger(); AtomicInteger c2 = new AtomicInteger(); TestSubscriber<Integer> ts = new TestSubscriber<Integer>(); Observable<Integer> merged = Observable.merge( incrementingIntegers(c1).subscribeOn(Schedulers.computation()), incrementingIntegers(c2).subscribeOn(Schedulers.computation())); merged.observeOn(Schedulers.io()).take(NUM).subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); System.out.println( "testMergeAsyncThenObserveOn => Received: " + ts.getOnNextEvents().size() + " Emitted: " + c1.get() + " / " + c2.get()); assertEquals(NUM, ts.getOnNextEvents().size()); } }
@Test public void testMergeAsyncThenObserveOn() { int NUM = (int) (RxRingBuffer.SIZE * 4.1); AtomicInteger c1 = new AtomicInteger(); AtomicInteger c2 = new AtomicInteger(); TestSubscriber<Integer> ts = new TestSubscriber<Integer>(); Observable<Integer> merged = Observable.merge( incrementingIntegers(c1).subscribeOn(Schedulers.computation()), incrementingIntegers(c2).subscribeOn(Schedulers.computation())); merged.observeOn(Schedulers.newThread()).take(NUM).subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); System.out.println( "testMergeAsyncThenObserveOn => Received: " + ts.getOnNextEvents().size() + " Emitted: " + c1.get() + " / " + c2.get()); assertEquals(NUM, ts.getOnNextEvents().size()); // either one can starve the other, but neither should be capable of doing more than 5 batches // (taking 4.1) // TODO is it possible to make this deterministic rather than one possibly starving the other? // benjchristensen => In general I'd say it's not worth trying to make it so, as "fair" // algoritms generally take a performance hit // akarnokd => run this in a loop over 10k times and never saw values get as high as 7*SIZE, but // since observeOn delays the unsubscription non-deterministically, the test will remain // unreliable assertTrue(c1.get() < RxRingBuffer.SIZE * 7); assertTrue(c2.get() < RxRingBuffer.SIZE * 7); }
@Test(timeout = 2000) public void testOnBackpressureBuffer() { int NUM = (int) (RxRingBuffer.SIZE * 1.1); // > 1 so that take doesn't prevent buffer overflow AtomicInteger c = new AtomicInteger(); TestSubscriber<Integer> ts = new TestSubscriber<Integer>(); firehose(c) .takeWhile( new Func1<Integer, Boolean>() { @Override public Boolean call(Integer t1) { return t1 < 100000; } }) .onBackpressureBuffer() .observeOn(Schedulers.computation()) .map(SLOW_PASS_THRU) .take(NUM) .subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); System.out.println( "testOnBackpressureBuffer => Received: " + ts.getOnNextEvents().size() + " Emitted: " + c.get()); assertEquals(NUM, ts.getOnNextEvents().size()); // it buffers, so we should get the right value sequentially assertEquals(NUM - 1, ts.getOnNextEvents().get(NUM - 1).intValue()); }
@Test @SuppressWarnings("unchecked") public void testOrdering() throws InterruptedException { Observable<String> obs = Observable.just("one", null, "two", "three", "four"); Observer<String> observer = mock(Observer.class); InOrder inOrder = inOrder(observer); TestSubscriber<String> ts = new TestSubscriber<String>(observer); obs.observeOn(Schedulers.computation()).subscribe(ts); ts.awaitTerminalEvent(1000, TimeUnit.MILLISECONDS); if (ts.getOnErrorEvents().size() > 0) { for (Throwable t : ts.getOnErrorEvents()) { t.printStackTrace(); } fail("failed with exception"); } inOrder.verify(observer, times(1)).onNext("one"); inOrder.verify(observer, times(1)).onNext(null); inOrder.verify(observer, times(1)).onNext("two"); inOrder.verify(observer, times(1)).onNext("three"); inOrder.verify(observer, times(1)).onNext("four"); inOrder.verify(observer, times(1)).onCompleted(); inOrder.verifyNoMoreInteractions(); }
@Test public void testBackpressureWithTakeBefore() { final AtomicInteger generated = new AtomicInteger(); Observable<Integer> observable = Observable.from( new Iterable<Integer>() { @Override public Iterator<Integer> iterator() { return new Iterator<Integer>() { @Override public void remove() {} @Override public Integer next() { return generated.getAndIncrement(); } @Override public boolean hasNext() { return true; } }; } }); TestSubscriber<Integer> testSubscriber = new TestSubscriber<Integer>(); observable.take(7).observeOn(Schedulers.newThread()).subscribe(testSubscriber); testSubscriber.awaitTerminalEvent(); testSubscriber.assertReceivedOnNext(Arrays.asList(0, 1, 2, 3, 4, 5, 6)); assertEquals(7, generated.get()); }
/** * Make sure we get a MissingBackpressureException propagated through when we have a fast temporal * (hot) producer. */ @Test public void testHotOperatorBackpressure() { TestSubscriber<String> ts = new TestSubscriber<String>(); Observable.timer(0, 1, TimeUnit.MICROSECONDS) .observeOn(Schedulers.computation()) .map( new Func1<Long, String>() { @Override public String call(Long t1) { System.out.println(t1); try { Thread.sleep(100); } catch (InterruptedException e) { } return t1 + " slow value"; } }) .subscribe(ts); ts.awaitTerminalEvent(); System.out.println("Errors: " + ts.getOnErrorEvents()); assertEquals(1, ts.getOnErrorEvents().size()); assertEquals(MissingBackpressureException.class, ts.getOnErrorEvents().get(0).getClass()); }
@Test public void testMergeSync() { int NUM = (int) (RxRingBuffer.SIZE * 4.1); AtomicInteger c1 = new AtomicInteger(); AtomicInteger c2 = new AtomicInteger(); TestSubscriber<Integer> ts = new TestSubscriber<Integer>(); Observable<Integer> merged = Observable.merge(incrementingIntegers(c1), incrementingIntegers(c2)); merged.take(NUM).subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); System.out.println("Expected: " + NUM + " got: " + ts.getOnNextEvents().size()); System.out.println( "testMergeSync => Received: " + ts.getOnNextEvents().size() + " Emitted: " + c1.get() + " / " + c2.get()); assertEquals(NUM, ts.getOnNextEvents().size()); // either one can starve the other, but neither should be capable of doing more than 5 batches // (taking 4.1) // TODO is it possible to make this deterministic rather than one possibly starving the other? // benjchristensen => In general I'd say it's not worth trying to make it so, as "fair" // algoritms generally take a performance hit assertTrue(c1.get() < RxRingBuffer.SIZE * 5); assertTrue(c2.get() < RxRingBuffer.SIZE * 5); }
@Test public void requestLocation_Success() throws SecurityException { final Location expectedLocation = buildFakeLocation(provider); // set provider enabled setIsProviderEnabled(provider, true); // answer Mockito.doAnswer( new Answer() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { final Object[] args = invocation.getArguments(); final LocationListener l = (LocationListener) args[1]; l.onLocationChanged(expectedLocation); return null; } }) .when(locationManager) .requestSingleUpdate( Mockito.eq(provider), Mockito.any(LocationListener.class), Mockito.any(Looper.class)); final RxLocationManager rxLocationManager = getDefaullRxLocationManager(); final TestSubscriber<Location> subscriber = new TestSubscriber<>(); rxLocationManager.requestLocation(provider).subscribe(subscriber); subscriber.awaitTerminalEvent(); subscriber.assertCompleted(); subscriber.assertValue(expectedLocation); }
@Test public void testCallRequest() throws Exception { RestfitClient client = new RestfitClient.Builder() .userAgent("RestfitTest/1.0") .httpStack( new RestfitHttpStack() { @NonNull @Override public Single<RestfitResponse> perform(@NonNull RestfitRequest request) { return Single.just(response); } }) .build(); final RestfitRequest.Builder requestBuilder = client.requestBuilder().method("GET").url("http://example.com/"); response = new RestfitResponse.Builder().request(requestBuilder.build()).build(); TestSubscriber<RestfitResponse> testSubscriber = TestSubscriber.create(); client.call(requestBuilder).subscribe(testSubscriber); testSubscriber.awaitTerminalEvent(10, TimeUnit.MILLISECONDS); testSubscriber.assertCompleted(); testSubscriber.assertReceivedOnNext(Collections.singletonList(response)); }
@Test public void testFlatMapMaxConcurrent() { final int m = 4; final AtomicInteger subscriptionCount = new AtomicInteger(); Observable<Integer> source = Observable.range(1, 10) .flatMap( new Func1<Integer, Observable<Integer>>() { @Override public Observable<Integer> call(Integer t1) { return compose(Observable.range(t1 * 10, 2), subscriptionCount, m) .subscribeOn(Schedulers.computation()); } }, m); TestSubscriber<Integer> ts = new TestSubscriber<Integer>(); source.subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); Set<Integer> expected = new HashSet<Integer>( Arrays.asList( 10, 11, 20, 21, 30, 31, 40, 41, 50, 51, 60, 61, 70, 71, 80, 81, 90, 91, 100, 101)); Assert.assertEquals(expected.size(), ts.getOnNextEvents().size()); Assert.assertTrue(expected.containsAll(ts.getOnNextEvents())); }
@Test public void testObserveOnWithSlowConsumer() { int NUM = (int) (RxRingBuffer.SIZE * 0.2); AtomicInteger c = new AtomicInteger(); TestSubscriber<Integer> ts = new TestSubscriber<Integer>(); incrementingIntegers(c) .observeOn(Schedulers.computation()) .map( new Func1<Integer, Integer>() { @Override public Integer call(Integer i) { try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } return i; } }) .take(NUM) .subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); System.out.println( "testObserveOnWithSlowConsumer => Received: " + ts.getOnNextEvents().size() + " Emitted: " + c.get()); assertEquals(NUM, ts.getOnNextEvents().size()); assertTrue(c.get() < RxRingBuffer.SIZE * 2); }
@Test(groups = "standalone") public void testObserveMultiple() { final TestSubscriber<Response> tester = new TestSubscriber<>(); try (AsyncHttpClient client = asyncHttpClient()) { Observable<Response> o1 = AsyncHttpObservable.observe(() -> client.prepareGet("http://gatling.io")); Observable<Response> o2 = AsyncHttpObservable.observe( () -> client.prepareGet("http://www.wisc.edu").setFollowRedirect(true)); Observable<Response> o3 = AsyncHttpObservable.observe( () -> client.prepareGet("http://www.umn.edu").setFollowRedirect(true)); Observable<Response> all = Observable.merge(o1, o2, o3); all.subscribe(tester); tester.awaitTerminalEvent(); tester.assertTerminalEvent(); tester.assertCompleted(); tester.assertNoErrors(); List<Response> responses = tester.getOnNextEvents(); assertNotNull(responses); assertEquals(responses.size(), 3); for (Response response : responses) { assertEquals(response.getStatusCode(), 200); } } catch (Exception e) { Thread.currentThread().interrupt(); } }
@Test public void testAsyncChild() { TestSubscriber<Integer> ts = new TestSubscriber<Integer>(); Observable.range(0, 100000) .observeOn(Schedulers.newThread()) .observeOn(Schedulers.newThread()) .subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); }
private static void waitForStoreToStart(final String storeId) { TestSubscriber testSubscriber = new TestSubscriber(); sc.getDataService() .storeStarted(storeId) .timeout(3, TimeUnit.MINUTES) .subscribe(testSubscriber); testSubscriber.awaitTerminalEvent(); testSubscriber.assertNoErrors(); testSubscriber.assertCompleted(); }
@Test public void testQueueFullEmitsError() { final CountDownLatch latch = new CountDownLatch(1); Observable<Integer> observable = Observable.create( new OnSubscribe<Integer>() { @Override public void call(Subscriber<? super Integer> o) { for (int i = 0; i < RxRingBuffer.SIZE + 10; i++) { o.onNext(i); } latch.countDown(); o.onCompleted(); } }); TestSubscriber<Integer> testSubscriber = new TestSubscriber<Integer>( new Observer<Integer>() { @Override public void onCompleted() {} @Override public void onError(Throwable e) {} @Override public void onNext(Integer t) { // force it to be slow and wait until we have queued everything try { latch.await(500, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { e.printStackTrace(); } } }); observable.observeOn(Schedulers.newThread()).subscribe(testSubscriber); testSubscriber.awaitTerminalEvent(); List<Throwable> errors = testSubscriber.getOnErrorEvents(); assertEquals(1, errors.size()); System.out.println("Errors: " + errors); Throwable t = errors.get(0); if (t instanceof MissingBackpressureException) { // success, we expect this } else { if (t.getCause() instanceof MissingBackpressureException) { // this is also okay } else { fail("Expecting MissingBackpressureException"); } } }
/** https://github.com/ReactiveX/RxJava/issues/1147 */ @Test public void testRaceForTerminalState() { final List<Integer> expected = Arrays.asList(1); for (int i = 0; i < 100000; i++) { TestSubscriber<Integer> ts = new TestSubscriber<Integer>(); Observable.just(1).subscribeOn(Schedulers.computation()).cache().subscribe(ts); ts.awaitTerminalEvent(); ts.assertReceivedOnNext(expected); ts.assertTerminalEvent(); } }
@Test(timeout = 10000) public void testOnBackpressureDropWithAction() { for (int i = 0; i < 100; i++) { final AtomicInteger emitCount = new AtomicInteger(); final AtomicInteger dropCount = new AtomicInteger(); final AtomicInteger passCount = new AtomicInteger(); final int NUM = RxRingBuffer.SIZE * 3; // > 1 so that take doesn't prevent buffer overflow TestSubscriber<Integer> ts = new TestSubscriber<Integer>(); firehose(emitCount) .onBackpressureDrop( new Action1<Integer>() { @Override public void call(Integer i) { dropCount.incrementAndGet(); } }) .doOnNext( new Action1<Integer>() { @Override public void call(Integer integer) { passCount.incrementAndGet(); } }) .observeOn(Schedulers.computation()) .map(SLOW_PASS_THRU) .take(NUM) .subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); List<Integer> onNextEvents = ts.getOnNextEvents(); Integer lastEvent = onNextEvents.get(NUM - 1); System.out.println( testName.getMethodName() + " => Received: " + onNextEvents.size() + " Passed: " + passCount.get() + " Dropped: " + dropCount.get() + " Emitted: " + emitCount.get() + " Last value: " + lastEvent); assertEquals(NUM, onNextEvents.size()); // in reality, NUM < passCount assertTrue(NUM <= passCount.get()); // it drop, so we should get some number far higher than what would have sequentially // incremented assertTrue(NUM - 1 <= lastEvent.intValue()); assertTrue(0 < dropCount.get()); assertEquals(emitCount.get(), passCount.get() + dropCount.get()); } }
/** Test that request location throw Exception if provider disabled */ @Test public void requestLocation_ProviderDisabled() { // set provider disabled setIsProviderEnabled(provider, false); final RxLocationManager rxLocationManager = getDefaullRxLocationManager(); final TestSubscriber<Location> subscriber = new TestSubscriber<>(); rxLocationManager.requestLocation(provider).subscribe(subscriber); subscriber.awaitTerminalEvent(); subscriber.assertError(ProviderDisabledException.class); }
@Test public void testObserveOn() { int NUM = (int) (RxRingBuffer.SIZE * 2.1); AtomicInteger c = new AtomicInteger(); TestSubscriber<Integer> ts = new TestSubscriber<Integer>(); incrementingIntegers(c).observeOn(Schedulers.computation()).take(NUM).subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); System.out.println( "testObserveOn => Received: " + ts.getOnNextEvents().size() + " Emitted: " + c.get()); assertEquals(NUM, ts.getOnNextEvents().size()); assertTrue(c.get() < RxRingBuffer.SIZE * 4); }
/** * Test that all fine * * @throws SecurityException */ @Test public void getLastLocation_Success() throws SecurityException { final Location expectedLocation = buildFakeLocation(provider); Mockito.when(locationManager.getLastKnownLocation(provider)).thenReturn(expectedLocation); final RxLocationManager rxLocationManager = getDefaullRxLocationManager(); final TestSubscriber<Location> subscriber = new TestSubscriber<>(); rxLocationManager.getLastLocation(provider).subscribe(subscriber); subscriber.awaitTerminalEvent(); subscriber.assertCompleted(); subscriber.assertValue(expectedLocation); }
@Test public void builder_Success3() throws SecurityException { final Location location1 = buildFakeLocation(provider); final LocationRequestBuilder locationRequestBuilder = getDefaultLocationRequestBuilder(); final Observable<Location> createdObservable = locationRequestBuilder.setDefaultLocation(location1).create(); final TestSubscriber<Location> subscriber = new TestSubscriber<>(); createdObservable.subscribe(subscriber); subscriber.awaitTerminalEvent(); subscriber.assertValue(location1); }
/** Test that request location throw TimeOutException */ @Test public void requestLocation_TimeOutError() { // set provider enabled setIsProviderEnabled(provider, true); final RxLocationManager rxLocationManager = getDefaullRxLocationManager(); final TestSubscriber<Location> subscriber = new TestSubscriber<>(); rxLocationManager .requestLocation(provider, new LocationTime(5, TimeUnit.SECONDS)) .subscribe(subscriber); subscriber.awaitTerminalEvent(); subscriber.assertError(TimeoutException.class); }
@Test(timeout = 2000) public void testFirehoseFailsAsExpected() { AtomicInteger c = new AtomicInteger(); TestSubscriber<Integer> ts = new TestSubscriber<Integer>(); firehose(c).observeOn(Schedulers.computation()).map(SLOW_PASS_THRU).subscribe(ts); ts.awaitTerminalEvent(); System.out.println( "testFirehoseFailsAsExpected => Received: " + ts.getOnNextEvents().size() + " Emitted: " + c.get()); assertEquals(1, ts.getOnErrorEvents().size()); assertTrue(ts.getOnErrorEvents().get(0) instanceof MissingBackpressureException); }
/** * Test that getLastLocation throw ElderLocationException if howOldCanBe is provided * * @throws SecurityException */ @Test public void getLastLocation_Old() throws SecurityException { final Location expectedLocation = buildFakeLocation(provider); expectedLocation.setTime(System.currentTimeMillis() - TimeUnit.HOURS.toMillis(1)); Mockito.when(locationManager.getLastKnownLocation(provider)).thenReturn(expectedLocation); final RxLocationManager rxLocationManager = getDefaullRxLocationManager(); final TestSubscriber<Location> subscriber = new TestSubscriber<>(); rxLocationManager .getLastLocation(provider, new LocationTime(30, TimeUnit.MINUTES)) .subscribe(subscriber); subscriber.awaitTerminalEvent(); subscriber.assertError(ElderLocationException.class); }
@Test public void testBackpressureWithTakeAfter() { final AtomicInteger generated = new AtomicInteger(); Observable<Integer> observable = Observable.from( new Iterable<Integer>() { @Override public Iterator<Integer> iterator() { return new Iterator<Integer>() { @Override public void remove() {} @Override public Integer next() { return generated.getAndIncrement(); } @Override public boolean hasNext() { return true; } }; } }); TestSubscriber<Integer> testSubscriber = new TestSubscriber<Integer>() { @Override public void onNext(Integer t) { System.err.println("c t = " + t + " thread " + Thread.currentThread()); super.onNext(t); try { Thread.sleep(10); } catch (InterruptedException e) { } } }; observable.observeOn(Schedulers.newThread()).take(3).subscribe(testSubscriber); testSubscriber.awaitTerminalEvent(); System.err.println(testSubscriber.getOnNextEvents()); testSubscriber.assertReceivedOnNext(Arrays.asList(0, 1, 2)); // it should be between the take num and requested batch size across the async boundary System.out.println("Generated: " + generated.get()); assertTrue(generated.get() >= 3 && generated.get() <= RxRingBuffer.SIZE); }
@Test public void testErrorPropagatesWhenNoOutstandingRequests() { Observable<Long> timer = Observable.timer(0, 1, TimeUnit.MICROSECONDS) .doOnEach( new Action1<Notification<? super Long>>() { @Override public void call(Notification<? super Long> n) { // System.out.println("BEFORE " + // n); } }) .observeOn(Schedulers.newThread()) .doOnEach( new Action1<Notification<? super Long>>() { @Override public void call(Notification<? super Long> n) { try { Thread.sleep(100); } catch (InterruptedException e) { } // System.out.println("AFTER " + // n); } }); TestSubscriber<Long> ts = new TestSubscriber<Long>(); Observable.combineLatest( timer, Observable.<Integer>never(), new Func2<Long, Integer, Long>() { @Override public Long call(Long t1, Integer t2) { return t1; } }) .take(RxRingBuffer.SIZE * 2) .subscribe(ts); ts.awaitTerminalEvent(); assertEquals(1, ts.getOnErrorEvents().size()); assertEquals(MissingBackpressureException.class, ts.getOnErrorEvents().get(0).getClass()); }
@Test public void testBackpressureWithTakeAfterAndMultipleBatches() { int numForBatches = RxRingBuffer.SIZE * 3 + 1; // should be 4 batches == ((3*n)+1) items final AtomicInteger generated = new AtomicInteger(); Observable<Integer> observable = Observable.from( new Iterable<Integer>() { @Override public Iterator<Integer> iterator() { return new Iterator<Integer>() { @Override public void remove() {} @Override public Integer next() { return generated.getAndIncrement(); } @Override public boolean hasNext() { return true; } }; } }); TestSubscriber<Integer> testSubscriber = new TestSubscriber<Integer>() { @Override public void onNext(Integer t) { // System.err.println("c t = " + t + " thread " + // Thread.currentThread()); super.onNext(t); } }; observable.observeOn(Schedulers.newThread()).take(numForBatches).subscribe(testSubscriber); testSubscriber.awaitTerminalEvent(); System.err.println(testSubscriber.getOnNextEvents()); // it should be between the take num and requested batch size across the async boundary System.out.println("Generated: " + generated.get()); assertTrue( generated.get() >= numForBatches && generated.get() <= numForBatches + RxRingBuffer.SIZE); }