2121import io .reactivex .netty .channel .BackpressureManagingHandler .BytesWriteInterceptor ;
2222import io .reactivex .netty .channel .BackpressureManagingHandler .WriteStreamSubscriber ;
2323import io .reactivex .netty .test .util .MockProducer ;
24- import org .hamcrest .Matcher ;
2524import org .junit .Rule ;
2625import org .junit .Test ;
2726import org .junit .rules .ExternalResource ;
@@ -46,23 +45,18 @@ public void testAddSubscriber() throws Exception {
4645 assertThat ("Subscriber not added." , inspectorRule .interceptor .getSubscribers (), contains (sub1 ));
4746
4847 sub1 .unsubscribe ();
49-
48+ inspectorRule . channel . runPendingTasks ();
5049 assertThat ("Subscriber not removed post unsubscribe" , inspectorRule .interceptor .getSubscribers (), is (empty ()));
5150 }
5251
5352 @ Test (timeout = 60000 )
5453 public void testRequestMore () throws Exception {
5554
5655 WriteStreamSubscriber sub1 = inspectorRule .newSubscriber ();
57- MockProducer mockProducer = InspectorRule .setupSubscriber (sub1 );
58-
56+ MockProducer mockProducer = inspectorRule .setupSubscriberAndValidate (sub1 , 1 );
5957 assertThat ("Unexpected items requested from producer." , mockProducer .getRequested (), is (defaultRequestN ()));
6058
61- assertThat ("Subscriber not added." , inspectorRule .interceptor .getSubscribers (), hasSize (1 ));
62- assertThat ("Subscriber not added." , inspectorRule .interceptor .getSubscribers (), contains (sub1 ));
63-
64- String msg = "Hello" ;
65- inspectorRule .channel .writeAndFlush (msg );
59+ inspectorRule .sendMessages (1 );
6660
6761 assertThat ("Channel not writable post write." , inspectorRule .channel .isWritable (), is (true ));
6862 assertThat ("Unexpected items requested." , mockProducer .getRequested (), is (defaultRequestN ()));
@@ -72,13 +66,9 @@ public void testRequestMore() throws Exception {
7266 public void testRequestMorePostFlush () throws Exception {
7367
7468 WriteStreamSubscriber sub1 = inspectorRule .newSubscriber ();
75- MockProducer mockProducer = InspectorRule .setupSubscriber (sub1 );
76-
69+ MockProducer mockProducer = inspectorRule .setupSubscriberAndValidate (sub1 , 1 );
7770 assertThat ("Unexpected items requested from producer." , mockProducer .getRequested (), is (defaultRequestN ()));
7871
79- assertThat ("Subscriber not added." , inspectorRule .interceptor .getSubscribers (), hasSize (1 ));
80- assertThat ("Subscriber not added." , inspectorRule .interceptor .getSubscribers (), contains (sub1 ));
81-
8272 inspectorRule .channel .config ().setWriteBufferWaterMark (new WriteBufferWaterMark (1 , 2 )); /*Make sure that the channel is not writable on writing.*/
8373
8474 String msg = "Hello" ;
@@ -97,19 +87,12 @@ public void testRequestMorePostFlush() throws Exception {
9787 @ Test (timeout = 60000 )
9888 public void testMultiSubscribers () throws Exception {
9989 WriteStreamSubscriber sub1 = inspectorRule .newSubscriber ();
100- MockProducer producer1 = InspectorRule .setupSubscriber (sub1 );
101-
102- assertThat ("Subscriber not added." , inspectorRule .interceptor .getSubscribers (), hasSize (1 ));
103- assertThat ("Subscriber not added." , inspectorRule .interceptor .getSubscribers (), contains (sub1 ));
90+ MockProducer producer1 = inspectorRule .setupSubscriberAndValidate (sub1 , 1 );
10491
10592 WriteStreamSubscriber sub2 = inspectorRule .newSubscriber ();
106- MockProducer producer2 = InspectorRule . setupSubscriber (sub2 );
93+ MockProducer producer2 = inspectorRule . setupSubscriberAndValidate (sub2 , 2 );
10794
108- assertThat ("Subscriber not added." , inspectorRule .interceptor .getSubscribers (), hasSize (2 ));
109- assertThat ("Subscriber not added." , inspectorRule .interceptor .getSubscribers (), contains (sub1 , sub2 ));
110-
111- String msg = "Hello" ;
112- inspectorRule .channel .writeAndFlush (msg );
95+ inspectorRule .sendMessages (1 );
11396
11497 assertThat ("Channel not writable post write." , inspectorRule .channel .isWritable (), is (true ));
11598 assertThat ("Unexpected items requested from first subscriber." , producer1 .getRequested (),
@@ -118,6 +101,47 @@ public void testMultiSubscribers() throws Exception {
118101 is (defaultRequestN () / 2 ));
119102 }
120103
104+ @ Test (timeout = 10000 )
105+ public void testOneLongWriteAndManySmallWrites () throws Exception {
106+ WriteStreamSubscriber sub1 = inspectorRule .newSubscriber ();
107+ MockProducer producer1 = inspectorRule .setupSubscriberAndValidate (sub1 , 1 );
108+ assertThat ("Unexpected items requested from producer." , producer1 .getRequested (), is (defaultRequestN ()));
109+ inspectorRule .setupNewSubscriberAndComplete (2 , true );
110+ inspectorRule .setupNewSubscriberAndComplete (2 , true );
111+
112+ inspectorRule .sendMessages (sub1 , 33 );
113+ assertThat ("Unexpected items requested." , producer1 .getRequested (), is (97L ));
114+ }
115+
116+ @ Test (timeout = 10000 )
117+ public void testBatchedSubscriberRemoves () throws Exception {
118+ WriteStreamSubscriber sub1 = inspectorRule .newSubscriber ();
119+ MockProducer producer1 = inspectorRule .setupSubscriberAndValidate (sub1 , 1 );
120+ assertThat ("Unexpected items requested from producer." , producer1 .getRequested (), is (defaultRequestN ()));
121+ for (int i =1 ; i < 5 ; i ++) {
122+ inspectorRule .setupNewSubscriberAndComplete (i +1 , false );
123+ }
124+
125+ inspectorRule .channel .runPendingTasks ();
126+
127+ inspectorRule .sendMessages (sub1 , 35 );
128+ assertThat ("Unexpected items requested." , producer1 .getRequested (), is (95L ));
129+ }
130+
131+ @ Test (timeout = 10000 )
132+ public void testMinRequestN () throws Exception {
133+ for (int i =1 ; i < 66 ; i ++) {
134+ inspectorRule .setupNewSubscriberAndComplete (i , false );
135+ }
136+ WriteStreamSubscriber sub1 = inspectorRule .newSubscriber ();
137+ MockProducer producer1 = inspectorRule .setupSubscriberAndValidate (sub1 , 66 );
138+ assertThat ("Unexpected items requested from producer." , producer1 .getRequested (), is (1L ));
139+
140+ inspectorRule .channel .runPendingTasks ();
141+ inspectorRule .sendMessages (sub1 , 35 );
142+ assertThat ("Unexpected items requested." , producer1 .getRequested (), greaterThan (1L ));
143+ }
144+
121145 public static class InspectorRule extends ExternalResource {
122146
123147 private BytesWriteInterceptor interceptor ;
@@ -136,18 +160,52 @@ public void evaluate() throws Throwable {
136160 }
137161
138162 WriteStreamSubscriber newSubscriber () {
139- return interceptor .newSubscriber (channel .pipeline ().firstContext (), channel .newPromise ());
163+ return interceptor .newSubscriber (channel .pipeline ().lastContext (), channel .newPromise ());
140164 }
141165
142- private static MockProducer setupSubscriber (WriteStreamSubscriber sub1 ) {
143- sub1 .onStart ();
166+ private MockProducer setupSubscriberAndValidate (WriteStreamSubscriber sub , int expectedSubCount ) {
167+ MockProducer mockProducer = setupSubscriber (sub );
168+ assertThat ("Subscriber not added." , interceptor .getSubscribers (), hasSize (expectedSubCount ));
169+ assertThat ("Subscriber not added." , interceptor .getSubscribers ().get (expectedSubCount - 1 ), equalTo (sub ));
170+ return mockProducer ;
171+ }
172+
173+ private static MockProducer setupSubscriber (WriteStreamSubscriber sub ) {
174+ sub .onStart ();
144175 MockProducer mockProducer = new MockProducer ();
145- sub1 .setProducer (mockProducer );
176+ sub .setProducer (mockProducer );
146177 return mockProducer ;
147178 }
148179
149180 public static Long defaultRequestN () {
150181 return Long .valueOf (MAX_PER_SUBSCRIBER_REQUEST );
151182 }
183+
184+ public void sendMessages (WriteStreamSubscriber subscriber , int msgCount ) {
185+ for (int i =0 ; i < msgCount ; i ++) {
186+ subscriber .onNext ("Hello" );
187+ channel .write ("Hello" );
188+ }
189+ channel .flush ();
190+ }
191+
192+ public void sendMessages (int msgCount ) {
193+ for (int i =0 ; i < msgCount ; i ++) {
194+ channel .write ("Hello" );
195+ }
196+ channel .flush ();
197+ }
198+
199+ public void setupNewSubscriberAndComplete (int expectedSubCount , boolean runPendingTasks ) {
200+ WriteStreamSubscriber sub2 = newSubscriber ();
201+ MockProducer producer2 = setupSubscriberAndValidate (sub2 , expectedSubCount );
202+ assertThat ("Unexpected items requested from producer." , producer2 .getRequested (),
203+ lessThanOrEqualTo (Math .max (1 , defaultRequestN ()/expectedSubCount )));
204+ sub2 .onCompleted ();
205+ sub2 .unsubscribe ();
206+ if (runPendingTasks ) {
207+ channel .runPendingTasks ();
208+ }
209+ }
152210 }
153211}
0 commit comments