@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 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 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 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(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(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 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(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 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 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 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 shouldEmmitGroundOverlay() throws Exception { TestSubscriber<GroundOverlay> testSubscriber = new TestSubscriber<>(); new GroundOverlayClickFunc().call(googleMap).subscribe(testSubscriber); verify(googleMap).setOnGroundOverlayClickListener(argumentCaptor.capture()); argumentCaptor.getValue().onGroundOverlayClick(null); testSubscriber.assertNoErrors(); testSubscriber.assertValueCount(1); testSubscriber.assertValue(null); }
@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 public void testGetArticles() throws Exception { final int articleNumPerPage = 30; TestSubscriber<Article> testSubscriber = new TestSubscriber<>(); webApi.getArticles(1, articleNumPerPage).subscribe(testSubscriber); testSubscriber.assertNoErrors(); List<Article> articleList = testSubscriber.getOnNextEvents(); assertThat(articleList, hasSize(greaterThan(0))); assertThat(articleList, hasSize(lessThan(articleNumPerPage + 1))); }
@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 public void lightService_turnOff() { LightModel light = mockLightModel(); mockClient(); TestSubscriber<LightModel> tester = new TestSubscriber<>(); lightService.turnOff(light).subscribe(tester); verify(commonService).findClient(GATEWAY_UUID); tester.assertValue(light); tester.assertCompleted(); tester.assertNoErrors(); }
@Test public void lightService_update() { LightModel lightModel = new LightModel(); when(lightRepository.update(lightModel)).thenReturn(Observable.just(null)); TestSubscriber<Void> tester = new TestSubscriber<>(); lightService.update(lightModel).subscribe(tester); verify(lightRepository).update(lightModel); tester.assertCompleted(); tester.assertNoErrors(); }
@Test public void lightService_delete() { String LIGHT_UUID = "myUuid"; when(lightRepository.delete(LIGHT_UUID)).thenReturn(Observable.just(null)); TestSubscriber<Void> tester = new TestSubscriber<>(); lightService.delete(LIGHT_UUID).subscribe(tester); verify(lightRepository).delete(LIGHT_UUID); tester.assertCompleted(); tester.assertNoErrors(); }
@Test public void test() { TestSubscriber<Long> tester = new TestSubscriber<>(); TestScheduler scheduler = Schedulers.test(); Observable.switchOnNext( Observable.interval(100, TimeUnit.MILLISECONDS, scheduler) .map(i -> Observable.interval(30, TimeUnit.MILLISECONDS, scheduler).map(i2 -> i))) .distinctUntilChanged() .subscribe(tester); scheduler.advanceTimeBy(500, TimeUnit.MILLISECONDS); tester.assertReceivedOnNext(Arrays.asList(0L, 1L, 2L, 3L)); tester.assertNoErrors(); assertEquals(tester.getOnCompletedEvents().size(), 0); }
@Test public void lightService_add() { String LIGHT_UUID = "myUuid"; LightModel lightModel = new LightModel(); when(lightRepository.add(lightModel)).thenReturn(Observable.just(LIGHT_UUID)); TestSubscriber<String> tester = new TestSubscriber<>(); lightService.add(lightModel).subscribe(tester); verify(lightRepository).add(lightModel); tester.assertValue(LIGHT_UUID); tester.assertCompleted(); tester.assertNoErrors(); }
@Test public void testSimpleObject() { TestSubscriber<Person> subscriber = new TestSubscriber<>(); observable.lift(new GsonConverter<Person>()).subscribe(subscriber); subscriber.assertNoErrors(); subscriber.assertTerminalEvent(); List<Person> persons = subscriber.getOnNextEvents(); assertEquals(1, persons.size()); Person person = persons.get(0); assertEquals("John", person.name); assertEquals(25, person.age); assertTrue(person.isDev); }
@Test(timeout = 30000) public void flatMapRangeMixedAsyncLoop() { for (int i = 0; i < 2000; i++) { if (i % 10 == 0) { System.out.println("flatMapRangeAsyncLoop > " + i); } TestSubscriber<Integer> ts = new TestSubscriber<Integer>(); Observable.range(0, 1000) .flatMap( new Func1<Integer, Observable<Integer>>() { final Random rnd = new Random(); @Override public Observable<Integer> call(Integer t) { Observable<Integer> r = Observable.just(t); if (rnd.nextBoolean()) { r = r.asObservable(); } return r; } }) .observeOn(Schedulers.computation()) .subscribe(ts); ts.awaitTerminalEvent(2500, TimeUnit.MILLISECONDS); if (ts.getOnCompletedEvents().isEmpty()) { System.out.println(ts.getOnNextEvents().size()); } ts.assertTerminalEvent(); ts.assertNoErrors(); List<Integer> list = ts.getOnNextEvents(); if (list.size() < 1000) { Set<Integer> set = new HashSet<Integer>(list); for (int j = 0; j < 1000; j++) { if (!set.contains(j)) { System.out.println(j + " missing"); } } } assertEquals(1000, list.size()); } }
@Test(groups = "standalone") public void testObserveError() { final TestSubscriber<Response> tester = new TestSubscriber<>(); try (AsyncHttpClient client = asyncHttpClient()) { Observable<Response> o1 = AsyncHttpObservable.observe(() -> client.prepareGet("http://gatling.io/ttfn")); o1.subscribe(tester); tester.awaitTerminalEvent(); tester.assertTerminalEvent(); tester.assertCompleted(); tester.assertNoErrors(); List<Response> responses = tester.getOnNextEvents(); assertNotNull(responses); assertEquals(responses.size(), 1); assertEquals(responses.get(0).getStatusCode(), 404); } catch (Exception e) { Thread.currentThread().interrupt(); } }
@Test public void testSubscribeOnScheduling() { // in a loop for repeating the concurrency in this to increase chance of failure for (int i = 0; i < 100; i++) { int NUM = (int) (RxRingBuffer.SIZE * 2.1); AtomicInteger c = new AtomicInteger(); ConcurrentLinkedQueue<Thread> threads = new ConcurrentLinkedQueue<Thread>(); TestSubscriber<Integer> ts = new TestSubscriber<Integer>(); // observeOn is there to make it async and need backpressure incrementingIntegers(c, threads) .subscribeOn(Schedulers.computation()) .observeOn(Schedulers.computation()) .take(NUM) .subscribe(ts); ts.awaitTerminalEvent(); ts.assertNoErrors(); System.out.println( "testSubscribeOnScheduling => Received: " + ts.getOnNextEvents().size() + " Emitted: " + c.get()); assertEquals(NUM, ts.getOnNextEvents().size()); assertTrue(c.get() < RxRingBuffer.SIZE * 4); Thread first = null; for (Thread t : threads) { System.out.println("testSubscribeOnScheduling => thread: " + t); if (first == null) { first = t; } else { if (!first.equals(t)) { fail("Expected to see the same thread"); } } } System.out.println( "testSubscribeOnScheduling => Number of batch requests seen: " + threads.size()); assertTrue(threads.size() > 1); System.out.println( "-------------------------------------------------------------------------------------------"); } }
@Test public void flatMapTwoNestedSync() { for (final int n : new int[] {1, 1000, 1000000}) { TestSubscriber<Integer> ts = new TestSubscriber<Integer>(); Observable.just(1, 2) .flatMap( new Func1<Integer, Observable<Integer>>() { @Override public Observable<Integer> call(Integer t) { return Observable.range(1, n); } }) .subscribe(ts); System.out.println("flatMapTwoNestedSync >> @ " + n); ts.assertNoErrors(); ts.assertCompleted(); ts.assertValueCount(n * 2); } }
public void testDelete() throws Exception { // arrange E entity = getFakeEntity(); insertFakeToRealm(); RealmQuery<V> query = realm.where(getRealmObjClass()); assertThat(query.findFirst(), is(notNullValue())); TestSubscriber<Boolean> subscriber = new TestSubscriber<>(); // act Observable<Boolean> result = realmCache.delete(entity); result.subscribe(subscriber); // assert subscriber.assertCompleted(); subscriber.assertNoErrors(); subscriber.assertValue(true); query = realm.where(getRealmObjClass()); assertThat(query.findFirst(), is(nullValue())); }
@Test public void flatMapIntPassthruAsync() { for (int i = 0; i < 1000; i++) { TestSubscriber<Integer> ts = new TestSubscriber<Integer>(); Observable.range(1, 1000) .flatMap( new Func1<Integer, Observable<Integer>>() { @Override public Observable<Integer> call(Integer t) { return Observable.just(1).subscribeOn(Schedulers.computation()); } }) .subscribe(ts); ts.awaitTerminalEvent(5, TimeUnit.SECONDS); ts.assertNoErrors(); ts.assertCompleted(); ts.assertValueCount(1000); } }
@Ignore // don't care for any reordering @Test(timeout = 10000) public void flatMapRangeAsyncLoop() { for (int i = 0; i < 2000; i++) { if (i % 10 == 0) { System.out.println("flatMapRangeAsyncLoop > " + i); } TestSubscriber<Integer> ts = new TestSubscriber<Integer>(); Observable.range(0, 1000) .flatMap( new Func1<Integer, Observable<Integer>>() { @Override public Observable<Integer> call(Integer t) { return Observable.just(t); } }) .observeOn(Schedulers.computation()) .subscribe(ts); ts.awaitTerminalEvent(2500, TimeUnit.MILLISECONDS); if (ts.getOnCompletedEvents().isEmpty()) { System.out.println(ts.getOnNextEvents().size()); } ts.assertTerminalEvent(); ts.assertNoErrors(); List<Integer> list = ts.getOnNextEvents(); assertEquals(1000, list.size()); boolean f = false; for (int j = 0; j < list.size(); j++) { if (list.get(j) != j) { System.out.println(j + " " + list.get(j)); f = true; } } if (f) { Assert.fail("Results are out of order!"); } } }
@Test(timeout = 10000) public void testOnBackpressureDrop() { long t = System.currentTimeMillis(); for (int i = 0; i < 100; i++) { // stop the test if we are getting close to the timeout because slow machines // may not get through 100 iterations if (System.currentTimeMillis() - t > TimeUnit.SECONDS.toMillis(9)) { break; } 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() .observeOn(Schedulers.computation()) .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()); } }