View Javadoc
1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  
28  package org.apache.http.nio.protocol;
29  
30  import java.util.concurrent.ExecutionException;
31  
32  import org.apache.http.ConnectionClosedException;
33  import org.apache.http.ConnectionReuseStrategy;
34  import org.apache.http.HttpRequest;
35  import org.apache.http.HttpVersion;
36  import org.apache.http.message.BasicHttpRequest;
37  import org.apache.http.message.BasicHttpResponse;
38  import org.apache.http.nio.ContentDecoder;
39  import org.apache.http.nio.ContentEncoder;
40  import org.apache.http.nio.NHttpClientConnection;
41  import org.apache.http.protocol.BasicHttpContext;
42  import org.apache.http.protocol.HttpContext;
43  import org.apache.http.protocol.HttpCoreContext;
44  import org.apache.http.protocol.HttpProcessor;
45  import org.junit.After;
46  import org.junit.Assert;
47  import org.junit.Before;
48  import org.junit.Test;
49  import org.mockito.Mockito;
50  
51  public class TestBasicAsyncClientExchangeHandler {
52  
53      private HttpAsyncRequestProducer requestProducer;
54      private HttpAsyncResponseConsumer<Object> responseConsumer;
55      private HttpContext context;
56      private HttpProcessor httpProcessor;
57      private NHttpClientConnection conn;
58      private ConnectionReuseStrategy reuseStrategy;
59      private BasicAsyncClientExchangeHandler<Object> exchangeHandler;
60      private ContentEncoder encoder;
61      private ContentDecoder decoder;
62  
63      @SuppressWarnings("unchecked")
64      @Before
65      public void setUp() throws Exception {
66          this.requestProducer = Mockito.mock(HttpAsyncRequestProducer.class);
67          this.responseConsumer = Mockito.mock(HttpAsyncResponseConsumer.class);
68          this.context = new BasicHttpContext();
69          this.conn = Mockito.mock(NHttpClientConnection.class);
70          this.httpProcessor = Mockito.mock(HttpProcessor.class);
71          this.reuseStrategy = Mockito.mock(ConnectionReuseStrategy.class);
72          this.exchangeHandler = new BasicAsyncClientExchangeHandler<Object>(
73                  this.requestProducer,
74                  this.responseConsumer,
75                  null,
76                  this.context,
77                  this.conn,
78                  this.httpProcessor,
79                  this.reuseStrategy);
80          this.encoder = Mockito.mock(ContentEncoder.class);
81          this.decoder = Mockito.mock(ContentDecoder.class);
82      }
83  
84      @After
85      public void tearDown() throws Exception {
86      }
87  
88      @Test
89      public void testInvalidExecution() throws Exception {
90          try {
91              new BasicAsyncClientExchangeHandler<Object>(
92                      null,
93                      this.responseConsumer,
94                      null,
95                      this.context,
96                      this.conn,
97                      this.httpProcessor,
98                      this.reuseStrategy);
99              Assert.fail("IllegalArgumentException expected");
100         } catch (final IllegalArgumentException ex) {
101         }
102         try {
103             new BasicAsyncClientExchangeHandler<Object>(
104                     this.requestProducer,
105                     null,
106                     null,
107                     this.context,
108                     this.conn,
109                     this.httpProcessor,
110                     this.reuseStrategy);
111             Assert.fail("IllegalArgumentException expected");
112         } catch (final IllegalArgumentException ex) {
113         }
114         try {
115             new BasicAsyncClientExchangeHandler<Object>(
116                     this.requestProducer,
117                     this.responseConsumer,
118                     null,
119                     null,
120                     this.conn,
121                     this.httpProcessor,
122                     this.reuseStrategy);
123             Assert.fail("IllegalArgumentException expected");
124         } catch (final IllegalArgumentException ex) {
125         }
126         try {
127             new BasicAsyncClientExchangeHandler<Object>(
128                     this.requestProducer,
129                     this.responseConsumer,
130                     null,
131                     this.context,
132                     null,
133                     this.httpProcessor,
134                     this.reuseStrategy);
135             Assert.fail("IllegalArgumentException expected");
136         } catch (final IllegalArgumentException ex) {
137         }
138         try {
139             new BasicAsyncClientExchangeHandler<Object>(
140                     this.requestProducer,
141                     this.responseConsumer,
142                     null,
143                     this.context,
144                     this.conn,
145                     null,
146                     this.reuseStrategy);
147             Assert.fail("IllegalArgumentException expected");
148         } catch (final IllegalArgumentException ex) {
149         }
150     }
151 
152     @Test
153     public void testClose() throws Exception {
154         Assert.assertFalse(this.exchangeHandler.getFuture().isCancelled());
155         this.exchangeHandler.close();
156         Mockito.verify(this.requestProducer).close();
157         Mockito.verify(this.responseConsumer).close();
158         Assert.assertTrue(this.exchangeHandler.getFuture().isCancelled());
159     }
160 
161     @Test
162     public void testGenerateRequest() throws Exception {
163         final BasicHttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
164         Mockito.when(this.requestProducer.generateRequest()).thenReturn(request);
165 
166         final HttpRequest result = this.exchangeHandler.generateRequest();
167 
168         Assert.assertSame(request, result);
169 
170         Mockito.verify(this.requestProducer).generateRequest();
171         Assert.assertSame(request, this.context.getAttribute(HttpCoreContext.HTTP_REQUEST));
172         Assert.assertSame(this.conn, this.context.getAttribute(HttpCoreContext.HTTP_CONNECTION));
173         Mockito.verify(this.httpProcessor).process(request, this.context);
174     }
175 
176     @Test
177     public void testProduceContent() throws Exception {
178         Mockito.when(this.encoder.isCompleted()).thenReturn(false);
179 
180         this.exchangeHandler.produceContent(this.encoder, this.conn);
181 
182         Mockito.verify(this.requestProducer).produceContent(this.encoder, this.conn);
183     }
184 
185     @Test
186     public void testProduceContentCompleted() throws Exception {
187         Mockito.when(this.encoder.isCompleted()).thenReturn(true);
188 
189         this.exchangeHandler.produceContent(this.encoder, this.conn);
190 
191         Mockito.verify(this.requestProducer).produceContent(this.encoder, this.conn);
192     }
193 
194     @Test
195     public void testRequestCompleted() throws Exception {
196         this.exchangeHandler.requestCompleted();
197 
198         Mockito.verify(this.requestProducer).requestCompleted(this.context);
199     }
200 
201     @Test
202     public void testResponseReceived() throws Exception {
203         final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
204 
205         this.exchangeHandler.responseReceived(response);
206 
207         Mockito.verify(this.responseConsumer).responseReceived(response);
208         Assert.assertSame(response, this.context.getAttribute(HttpCoreContext.HTTP_RESPONSE));
209         Mockito.verify(this.httpProcessor).process(response, this.context);
210     }
211 
212     @Test
213     public void testConsumeContent() throws Exception {
214         this.exchangeHandler.consumeContent(this.decoder, this.conn);
215 
216         Mockito.verify(this.responseConsumer).consumeContent(this.decoder, this.conn);
217     }
218 
219     @Test
220     public void testFailed() throws Exception {
221         final Exception ooopsie = new Exception();
222         this.exchangeHandler.failed(ooopsie);
223 
224         Mockito.verify(this.requestProducer).failed(ooopsie);
225         Mockito.verify(this.responseConsumer).failed(ooopsie);
226         Mockito.verify(this.requestProducer).close();
227         Mockito.verify(this.responseConsumer).close();
228         try {
229             this.exchangeHandler.getFuture().get();
230         } catch (final ExecutionException ex) {
231             Assert.assertSame(ooopsie, ex.getCause());
232         }
233     }
234 
235     @Test
236     public void testFailedAfterRequest() throws Exception {
237         final Exception ooopsie = new Exception();
238         this.exchangeHandler.requestCompleted();
239         this.exchangeHandler.failed(ooopsie);
240 
241         Mockito.verify(this.requestProducer, Mockito.never()).failed(ooopsie);
242         Mockito.verify(this.responseConsumer).failed(ooopsie);
243         Mockito.verify(this.requestProducer).close();
244         Mockito.verify(this.responseConsumer).close();
245         try {
246             this.exchangeHandler.getFuture().get();
247         } catch (final ExecutionException ex) {
248             Assert.assertSame(ooopsie, ex.getCause());
249         }
250     }
251 
252     @Test
253     public void testFailedwithException() throws Exception {
254         final Exception ooopsie = new Exception();
255         Mockito.doThrow(new RuntimeException()).when(this.responseConsumer).failed(ooopsie);
256         try {
257             this.exchangeHandler.failed(ooopsie);
258             Assert.fail("RuntimeException expected");
259         } catch (final RuntimeException ex) {
260             Mockito.verify(this.requestProducer).close();
261             Mockito.verify(this.responseConsumer).close();
262             try {
263                 this.exchangeHandler.getFuture().get();
264             } catch (final ExecutionException exex) {
265                 Assert.assertSame(ooopsie, exex.getCause());
266             }
267         }
268     }
269 
270     @Test
271     public void testCancel() throws Exception {
272         this.exchangeHandler.cancel();
273 
274         Mockito.verify(this.responseConsumer).cancel();
275         Mockito.verify(this.requestProducer).close();
276         Mockito.verify(this.responseConsumer).close();
277         Assert.assertTrue(this.exchangeHandler.getFuture().isCancelled());
278     }
279 
280     @Test
281     public void testResponseCompleted() throws Exception {
282         final Object obj = new Object();
283         Mockito.when(this.responseConsumer.getResult()).thenReturn(obj);
284 
285         this.exchangeHandler.responseCompleted();
286 
287         Mockito.verify(this.responseConsumer).responseCompleted(this.context);
288         Mockito.verify(this.requestProducer).close();
289         Mockito.verify(this.responseConsumer).close();
290         final Object result = this.exchangeHandler.getFuture().get();
291         Assert.assertSame(obj, result);
292     }
293 
294     @Test
295     public void testResponseFailure() throws Exception {
296         final Exception ooopsie = new Exception();
297         Mockito.when(this.responseConsumer.getException()).thenReturn(ooopsie);
298 
299         this.exchangeHandler.responseCompleted();
300 
301         Mockito.verify(this.responseConsumer).responseCompleted(this.context);
302         Mockito.verify(this.requestProducer).close();
303         Mockito.verify(this.responseConsumer).close();
304         try {
305             this.exchangeHandler.getFuture().get();
306         } catch (final ExecutionException exex) {
307             Assert.assertSame(ooopsie, exex.getCause());
308         }
309     }
310 
311     @Test
312     public void testResponseCompletedWithException() throws Exception {
313         Mockito.doThrow(new RuntimeException()).when(this.responseConsumer).responseCompleted(this.context);
314         try {
315             this.exchangeHandler.responseCompleted();
316             Assert.fail("RuntimeException expected");
317         } catch (final RuntimeException ex) {
318             Mockito.verify(this.requestProducer).close();
319             Mockito.verify(this.responseConsumer).close();
320             try {
321                 this.exchangeHandler.getFuture().get();
322                 Assert.fail("ExecutionException expected");
323             } catch (final ExecutionException exex) {
324             }
325         }
326     }
327 
328     @Test
329     public void testResponseNoKeepAlive() throws Exception {
330         final Object obj = new Object();
331         Mockito.when(this.responseConsumer.getResult()).thenReturn(obj);
332 
333         final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
334 
335         Mockito.when(reuseStrategy.keepAlive(response, this.context)).thenReturn(Boolean.FALSE);
336 
337         this.exchangeHandler.responseReceived(response);
338         this.exchangeHandler.responseCompleted();
339 
340         Mockito.verify(this.conn).close();
341     }
342 
343     @Test
344     public void testInputTerminated() throws Exception {
345         this.exchangeHandler.inputTerminated();
346         Mockito.verify(this.responseConsumer).failed(Mockito.<ConnectionClosedException>any());
347         try {
348             this.exchangeHandler.getFuture().get();
349             Assert.fail("ExecutionException expected");
350         } catch (final ExecutionException exex) {
351         }
352     }
353 
354     @Test
355     public void testIsDone() throws Exception {
356         this.exchangeHandler.isDone();
357         Mockito.verify(this.responseConsumer).isDone();
358     }
359 
360 }