|
34 | 34 | import java.util.concurrent.atomic.AtomicInteger;
|
35 | 35 | import java.util.concurrent.atomic.AtomicLong;
|
36 | 36 |
|
| 37 | +import org.junit.Ignore; |
37 | 38 | import org.junit.Test;
|
38 | 39 | import org.mockito.InOrder;
|
39 | 40 |
|
| 41 | +import rx.Notification; |
40 | 42 | import rx.Observable;
|
41 | 43 | import rx.Observable.OnSubscribe;
|
42 | 44 | import rx.Observer;
|
|
48 | 50 | import rx.functions.Action0;
|
49 | 51 | import rx.functions.Action1;
|
50 | 52 | import rx.functions.Func1;
|
| 53 | +import rx.functions.Func2; |
51 | 54 | import rx.internal.util.RxRingBuffer;
|
52 | 55 | import rx.observers.TestSubscriber;
|
53 | 56 | import rx.schedulers.Schedulers;
|
@@ -391,7 +394,7 @@ public void testDelayedErrorDeliveryWhenSafeSubscriberUnsubscribes() {
|
391 | 394 | inOrder.verify(o, never()).onNext(anyInt());
|
392 | 395 | inOrder.verify(o, never()).onCompleted();
|
393 | 396 | }
|
394 |
| - |
| 397 | + |
395 | 398 | @Test
|
396 | 399 | public void testAfterUnsubscribeCalledThenObserverOnNextNeverCalled() {
|
397 | 400 | final TestScheduler testScheduler = new TestScheduler();
|
@@ -647,6 +650,71 @@ public void onNext(Long t) {
|
647 | 650 | assertTrue(ts.getOnNextEvents().size() == ts.getOnNextEvents().get(ts.getOnNextEvents().size() - 1) + 1);
|
648 | 651 | // we should emit the error without emitting the full buffer size
|
649 | 652 | assertTrue(ts.getOnNextEvents().size() < RxRingBuffer.SIZE);
|
| 653 | + } |
| 654 | + |
| 655 | + /** |
| 656 | + * Make sure we get a MissingBackpressureException propagated through when we have a fast temporal (hot) producer. |
| 657 | + */ |
| 658 | + @Test |
| 659 | + public void testHotOperatorBackpressure() { |
| 660 | + TestSubscriber<String> ts = new TestSubscriber<String>(); |
| 661 | + Observable.timer(0, 1, TimeUnit.MICROSECONDS) |
| 662 | + .observeOn(Schedulers.computation()) |
| 663 | + .map(new Func1<Long, String>() { |
| 664 | + |
| 665 | + @Override |
| 666 | + public String call(Long t1) { |
| 667 | + System.out.println(t1); |
| 668 | + try { |
| 669 | + Thread.sleep(100); |
| 670 | + } catch (InterruptedException e) { |
| 671 | + } |
| 672 | + return t1 + " slow value"; |
| 673 | + } |
650 | 674 |
|
| 675 | + }).subscribe(ts); |
| 676 | + |
| 677 | + ts.awaitTerminalEvent(); |
| 678 | + System.out.println("Errors: " + ts.getOnErrorEvents()); |
| 679 | + assertEquals(1, ts.getOnErrorEvents().size()); |
| 680 | + assertEquals(MissingBackpressureException.class, ts.getOnErrorEvents().get(0).getClass()); |
651 | 681 | }
|
| 682 | + |
| 683 | + @Test |
| 684 | + public void testErrorPropagatesWhenNoOutstandingRequests() { |
| 685 | + Observable<Long> timer = Observable.timer(0, 1, TimeUnit.MICROSECONDS) |
| 686 | + .doOnEach(new Action1<Notification<? super Long>>() { |
| 687 | + |
| 688 | + @Override |
| 689 | + public void call(Notification<? super Long> n) { |
| 690 | + // System.out.println("BEFORE " + n); |
| 691 | + } |
| 692 | + |
| 693 | + }) |
| 694 | + .observeOn(Schedulers.newThread()) |
| 695 | + .doOnEach(new Action1<Notification<? super Long>>() { |
| 696 | + |
| 697 | + @Override |
| 698 | + public void call(Notification<? super Long> n) { |
| 699 | + // System.out.println("AFTER " + n); |
| 700 | + } |
| 701 | + |
| 702 | + }); |
| 703 | + |
| 704 | + TestSubscriber<Long> ts = new TestSubscriber<Long>(); |
| 705 | + |
| 706 | + Observable.combineLatest(timer, Observable.<Integer> never(), new Func2<Long, Integer, Long>() { |
| 707 | + |
| 708 | + @Override |
| 709 | + public Long call(Long t1, Integer t2) { |
| 710 | + return t1; |
| 711 | + } |
| 712 | + |
| 713 | + }).take(RxRingBuffer.SIZE * 2).subscribe(ts); |
| 714 | + |
| 715 | + ts.awaitTerminalEvent(); |
| 716 | + assertEquals(1, ts.getOnErrorEvents().size()); |
| 717 | + assertEquals(MissingBackpressureException.class, ts.getOnErrorEvents().get(0).getClass()); |
| 718 | + } |
| 719 | + |
652 | 720 | }
|
0 commit comments