1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.core;
18 
19 import android.net.http.RequestHandle;
20 import android.net.http.RequestQueue;
21 import android.test.AndroidTestCase;
22 import android.test.suitebuilder.annotation.Suppress;
23 import android.util.Log;
24 import android.webkit.CookieSyncManager;
25 import com.google.android.collect.Maps;
26 
27 import java.io.ByteArrayInputStream;
28 import java.io.InputStream;
29 import java.util.HashMap;
30 import java.util.Map;
31 
32 /**
33  * Container class for all RequestAPI tests
34  */
35 //http://b/issue?id=1200337
36 @Suppress
37 public class RequestAPITest extends AndroidTestCase implements HttpConstants {
38     private static final String LOGTAG = "http";
39 
40     /*
41       Other tests to write
42       GET, HEAD, POST with differing parameters to RequestQueue
43       More reuse and pipelining tests - testing for server closing unexpectedly
44     */
45 
46     // Sync object for synchronizing end of each test that does communications
47     public static Object syncObj = new Object();
48 
49     private RequestQueue mRequestQueue;
50     private TestWebServer mTestWebServer;
51 
setUp()52     protected void setUp() throws Exception {
53         super.setUp();
54         Log.d(LOGTAG, "Base setup context = " + mContext);
55         mRequestQueue = new RequestQueue(mContext);
56         CookieSyncManager.createInstance(mContext);
57 
58         mTestWebServer = new TestWebServer();
59         mTestWebServer.initServer(8080, true);
60     }
61 
tearDown()62     protected void tearDown() throws Exception {
63         Log.d(LOGTAG, "Base tearDown");
64         mTestWebServer.close();
65         Log.d(LOGTAG, "Base teardown done");
66 
67         super.tearDown();
68     }
69 
verifyFailure(Map<String, String> headers)70     public void verifyFailure(Map<String, String> headers) {
71         try {
72             RequestHandle handle =
73                     mRequestQueue.queueRequest(
74                             "http://localhost:8080/test1", "GET", headers, null,
75                             null, 0);
76 
77             handle.waitUntilComplete();
78             fail("expected exception not thrown");
79         } catch (RuntimeException e) {
80             // expected
81         }
82     }
83 
testRequestAddNullHeader()84     public void testRequestAddNullHeader() throws Exception {
85         /**
86          * Test Request.addHeader throws a NullPointerException if a null
87          * header is attempted to be set
88          */
89         Log.d(LOGTAG, "testRequestAddNullHeader start ");
90         Map<String, String> headers = Maps.newHashMap();
91         headers.put(null, null);
92         verifyFailure(headers);
93         Log.d(LOGTAG, "testRequestAddNullHeader - returning");
94     }
95 
testRequestAddNullValue()96     public void testRequestAddNullValue() throws Exception {
97         /**
98          * Test Request.addHeader throws a RuntimeException if a null
99          * value is attempted to be set
100          */
101         Log.d(LOGTAG, "testRequestAddNullValue start ");
102         Map<String, String> headers = Maps.newHashMap();
103         headers.put("TestHeader", null);
104         verifyFailure(headers);
105         Log.d(LOGTAG, "testRequestAddNullValue - returning");
106     }
107 
testRequestAddEmptyValue()108     public void testRequestAddEmptyValue() throws Exception {
109         /**
110          * Test Request.addEmptyValue throws a RuntimeException if an empty
111          * header is attempted to be set
112          */
113         Log.d(LOGTAG, "testRequestAddEmptyValue start ");
114         Map<String, String> headers = Maps.newHashMap();
115         headers.put("TestHeader", "");
116         verifyFailure(headers);
117         Log.d(LOGTAG, "testRequestAddEmptyValue - returning");
118     }
119 
verifySuccess(Map<String, String> headers)120     public void verifySuccess(Map<String, String> headers) {
121         mTestWebServer.setKeepAlive(false);
122         RequestHandle handle = mRequestQueue.queueRequest(
123                 "http://localhost:8080/test1", "GET", headers, null,
124                 null, 0);
125         handle.waitUntilComplete();
126     }
127 
testRequestAddHeader()128     public void testRequestAddHeader() throws Exception {
129         /**
130          * Test Request.addHeader with a valid header and value can be set without
131          * generating and exception
132          */
133         Log.d(LOGTAG, "testRequestAddHeader start ");
134         Map<String, String> headers = Maps.newHashMap();
135         headers.put("TestHeader", "RequestAddHeader");
136         verifySuccess(headers);
137         Log.d(LOGTAG, "testRequestAddHeader - returning");
138     }
139 
testRequestAddMultiHeader()140     public void testRequestAddMultiHeader() throws Exception {
141         /**
142          * Test multiple calls to Request.addHeader with valid headers and values
143          * can be set without generating and exception
144          */
145         Log.d(LOGTAG, "testRequestAddMultiHeader start ");
146         Map<String, String> headers = Maps.newHashMap();
147         headers.put("TestHeader", "RequestAddMultiHeader");
148         headers.put("TestHeader2", "RequestAddMultiHeader");
149         headers.put("TestHeader3", "RequestAddMultiHeader");
150         verifySuccess(headers);
151         Log.d(LOGTAG, "testRequestAddMultiHeader - returning");
152     }
153 
testRequestAddSameHeader()154     public void testRequestAddSameHeader() throws Exception {
155         /**
156          * Test multiple calls to Request.addHeader with valid identical headers
157          * and values can be set without generating and exception
158          */
159         Log.d(LOGTAG, "testRequestAddSameHeader start ");
160         Map<String, String> headers = Maps.newHashMap();
161         headers.put("TestHeader", "RequestAddSameHeader");
162         headers.put("TestHeader", "RequestAddSameHeader");
163         headers.put("TestHeader", "RequestAddSameHeader");
164         verifySuccess(headers);
165         Log.d(LOGTAG, "testRequestAddSameHeader - returning");
166     }
167 
testRequestAddNullHeaders()168     public void testRequestAddNullHeaders() throws Exception {
169         /**
170          * Test Request.addHeaders with a null header map. This should not generate
171          * any exceptions but accept that there are no headers to add.
172          */
173         Log.d(LOGTAG, "testRequestAddNullHeaders start ");
174         verifySuccess(null);
175         Log.d(LOGTAG, "testRequestAddNullHeaders - returning");
176     }
177 
testGet()178     public void testGet() throws Exception {
179         /**
180          * Test sending a GET request. Test will pass if the events received
181          * correspond with the expected response. This should respond with the
182          * test data requested.
183          */
184         TestEventHandler testEventHandler = new TestEventHandler();
185 
186         mTestWebServer.setKeepAlive(false);
187 
188         Log.d(LOGTAG, "testGet start ");
189 
190         // Load up expected response
191         testEventHandler.expectStatus(200);
192         testEventHandler.expectHeaders();
193         testEventHandler.expectHeaderAdd(requestHeaders[REQ_CONNECTION], "Close");
194         testEventHandler.expectHeaderAdd(requestHeaders[REQ_CONTENT_LENGTH], "52");
195         testEventHandler.expectHeaderAdd(requestHeaders[REQ_CONTENT_TYPE], "text/html");
196         testEventHandler.expectData(52);
197 
198         RequestHandle handle = mRequestQueue.queueRequest(
199                 "http://localhost:8080/test1", "GET", null, testEventHandler,
200                 null, 0);
201 
202         Log.d(LOGTAG, "testGet - sent request. Waiting");
203         handle.waitUntilComplete();
204         Log.d(LOGTAG, "testGet - sent request. Notified");
205 
206         if (!testEventHandler.expectPassed()) {
207             Log.d(LOGTAG, testEventHandler.getFailureMessage());
208             fail("expectPassed was false " + testEventHandler.getFailureMessage());
209         }
210     }
211 
testReuse()212     public void testReuse() throws Exception {
213         /**
214          * Test sending two GET requests. Test will pass if the events
215          * received correspond with the expected response.
216          */
217         final String TEST_NAME = "testReuse";
218         Log.d(LOGTAG, TEST_NAME + " start ");
219 
220         TestEventHandler testEventHandler = new TestEventHandler();
221 
222         // Load up expected response
223         testEventHandler.expectStatus(200);
224         testEventHandler.expectHeaders();
225 
226         TestEventHandler testEventHandler2 = new TestEventHandler();
227         testEventHandler2.expectStatus(200);
228         testEventHandler2.expectHeaders();
229 
230         mTestWebServer.setAcceptLimit(2);
231 
232         RequestHandle handle0 = mRequestQueue.queueRequest(
233                 "http://localhost:8080/test1", "GET", null, testEventHandler,
234                 null, 0);
235         handle0.waitUntilComplete();
236         RequestHandle handle1 = mRequestQueue.queueRequest(
237                 "http://localhost:8080/test1", "GET", null, testEventHandler2,
238                 null, 0);
239         handle1.waitUntilComplete();
240 
241         /* It's not correct to use same listener for multiple
242            requests.  Otherwise there would be no distiction between
243            events delivered for either request. */
244 
245         if (!testEventHandler.expectPassed() && !testEventHandler2.expectPassed()) {
246             Log.d(LOGTAG, testEventHandler.getFailureMessage());
247             Log.d(LOGTAG, testEventHandler2.getFailureMessage());
248             fail();
249         }
250         Log.d(LOGTAG, TEST_NAME + " - sent request. Notified");
251     }
252 
testHead()253     public void testHead() throws Exception {
254         /**
255          * Test sending a HEAD request. Test will pass if the events
256          * delivered match the expected response.
257          */
258         TestEventHandler testEventHandler = new TestEventHandler();
259 
260         // Load up expected response
261         testEventHandler.expectStatus(200);
262         testEventHandler.expectHeaders();
263         testEventHandler.expectNoData();
264 
265         mTestWebServer.setKeepAlive(false);
266         mTestWebServer.setAcceptLimit(1);
267 
268 
269         Log.d(LOGTAG, "testHead start - rq = " + mRequestQueue);
270 
271         RequestHandle handle = mRequestQueue.queueRequest(
272                 "http://localhost:8080/test1", "HEAD", null, testEventHandler,
273                 null, 0);
274 
275         Log.d(LOGTAG, "testHead - sent request waiting");
276         handle.waitUntilComplete();
277 
278         if (!testEventHandler.expectPassed()) {
279             Log.d(LOGTAG, testEventHandler.getFailureMessage());
280             fail("expectPassed was false " + testEventHandler.getFailureMessage());
281         }
282     }
283 
testChunked()284     public void testChunked() throws Exception {
285         TestEventHandler testEventHandler = new TestEventHandler();
286 
287         // Load up expected response
288         testEventHandler.expectStatus(200);
289         testEventHandler.expectHeaders();
290 
291         mTestWebServer.setKeepAlive(false);
292         mTestWebServer.setChunked(true);
293         mTestWebServer.setAcceptLimit(1);
294 
295 
296         Log.d(LOGTAG, "testChunked start - rq = " + mRequestQueue);
297 
298         RequestHandle handle = mRequestQueue.queueRequest(
299                 "http://localhost:8080/test1", "GET", null, testEventHandler,
300                 null, 0);
301 
302         Log.d(LOGTAG, "testChunked - sent request waiting");
303         handle.waitUntilComplete();
304 
305         if (!testEventHandler.expectPassed()) {
306             Log.d(LOGTAG, testEventHandler.getFailureMessage());
307             fail("expectPassed was false " + testEventHandler.getFailureMessage());
308         }
309     }
310 
verifyRedirect(int statusCode, String testName)311     public void verifyRedirect(int statusCode, String testName) throws Exception {
312         final String REDIRECT_TO = "http://localhost:8081/test1";
313 
314         mTestWebServer.setKeepAlive(false);
315         TestWebServer redirectWebServer = new TestWebServer();
316         redirectWebServer.initServer(8081, true);
317         redirectWebServer.setKeepAlive(false);
318 
319         try {
320             TestEventHandler testEventHandler = new TestEventHandler();
321             // Load up expected response
322             testEventHandler.expectStatus(statusCode);
323             testEventHandler.expectHeaders();
324             testEventHandler.expectHeaderAdd(requestHeaders[REQ_LOCATION], REDIRECT_TO);
325 
326             mTestWebServer.setAcceptLimit(1);
327             mTestWebServer.setRedirect(REDIRECT_TO, statusCode);
328             redirectWebServer.setAcceptLimit(1);
329 
330             Log.d(LOGTAG, testName + " start - rq = " + mRequestQueue);
331 
332             RequestHandle requestHandle = mRequestQueue.queueRequest(
333                     "http://localhost:8080/test1", "GET", null, testEventHandler, null, 0);
334             Log.d(LOGTAG, testName + " - sent request waiting");
335 
336             requestHandle.waitUntilComplete();
337 
338             if (!testEventHandler.expectPassed()) {
339                 Log.d(LOGTAG, testEventHandler.getFailureMessage());
340                 fail("expectPassed was false " + testEventHandler.getFailureMessage());
341             }
342 
343             requestHandle.setupRedirect(REDIRECT_TO, statusCode, new HashMap<String, String>());
344 
345             testEventHandler.expectStatus(HttpConstants.HTTP_OK);
346             testEventHandler.expectHeaders();
347             testEventHandler.expectHeaderAdd(requestHeaders[REQ_CONTENT_LENGTH], "52");
348             testEventHandler.expectHeaderAdd(requestHeaders[REQ_CONTENT_TYPE], "text/html");
349             // Server name should be TestWebServer+port
350             // we ignore the server tag, so don't test it
351             // testEventHandler.expectHeaderAdd(requestHeaders[REQ_SERVER], "TestWebServer8081");
352             testEventHandler.expectData(52);
353             testEventHandler.expectEndData();
354 
355             requestHandle.waitUntilComplete();
356 
357             if (!testEventHandler.expectPassed()) {
358                 Log.d(LOGTAG, testEventHandler.getFailureMessage());
359                 fail("expectPassed was false " + testEventHandler.getFailureMessage());
360              }
361         } finally {
362             Log.d(LOGTAG, testName + " - returning");
363             redirectWebServer.close();
364         }
365     }
366 
testRedirect301()367     public void testRedirect301() throws Exception {
368         verifyRedirect(HttpConstants.HTTP_MOVED_PERM, "testRedirect301");
369     }
370 
testRedirect302()371     public void testRedirect302() throws Exception {
372         verifyRedirect(HttpConstants.HTTP_MOVED_TEMP, "testRedirect302");
373     }
374 
testRedirect303()375     public void testRedirect303() throws Exception {
376         verifyRedirect(HttpConstants.HTTP_SEE_OTHER, "testRedirect303");
377     }
378 
testRedirect307()379     public void testRedirect307() throws Exception {
380         verifyRedirect(307, "testRedirect307");
381     }
382 
testGetAndHead()383     public void testGetAndHead() throws Exception {
384         /**
385          * Test sending a GET and a HEAD request. Test will pass if the
386          * event received correspond with the expected response. The two
387          * requests should respond the same test data.
388          */
389         mTestWebServer.setKeepAlive(true);
390         mTestWebServer.setAcceptLimit(2);
391 
392         TestEventHandler testEventHandler = new TestEventHandler();
393         testEventHandler.expectStatus(200);
394         testEventHandler.expectHeaders();
395 
396         TestEventHandler leh2 = new TestEventHandler();
397         leh2.expectStatus(200);
398         leh2.expectHeaders();
399 
400         RequestHandle handle0 = mRequestQueue.queueRequest(
401                 "http://localhost:8080/test1", "GET", null, testEventHandler, null, 0);
402         handle0.waitUntilComplete();
403         RequestHandle handle1 = mRequestQueue.queueRequest(
404                 "http://localhost:8080/test1", "HEAD", null, testEventHandler, null, 0);
405 
406         Log.d(LOGTAG, "testGetAndHead - sent request. Waiting");
407         handle1.waitUntilComplete();
408 
409         if (!testEventHandler.expectPassed() && !leh2.expectPassed()) {
410             Log.d(LOGTAG, testEventHandler.getFailureMessage());
411             Log.d(LOGTAG, leh2.getFailureMessage());
412             fail();
413         }
414     }
415 
testPost()416     public void testPost() throws Exception {
417         /**
418          * Test sending a POST request with no body data. Test will pass if the event
419          * received correspond with the expected response. This should respond with
420          * the test data requested.
421          */
422         TestEventHandler testEventHandler = new TestEventHandler();
423 
424         // Load up expected response
425         testEventHandler.expectStatus(200);
426         testEventHandler.expectHeaders();
427         testEventHandler.expectData(52);
428 
429         mTestWebServer.setKeepAlive(false);
430         mTestWebServer.setAcceptLimit(1);
431 
432         Log.d(LOGTAG, "testPost start - rq = " + mRequestQueue);
433 
434         RequestHandle handle = mRequestQueue.queueRequest(
435                 "http://localhost:8080/test1", "POST", null, testEventHandler, null, 0);
436 
437         Log.d(LOGTAG, "testPost - sent request waiting");
438         handle.waitUntilComplete();
439 
440         if (!testEventHandler.expectPassed()) {
441             Log.d(LOGTAG, testEventHandler.getFailureMessage());
442             fail("expectPassed was false " + testEventHandler.getFailureMessage());
443         }
444     }
445 
446 
testPostWithData()447     public void testPostWithData() throws Exception {
448         /**
449          * Test sending a POST request with body data. Test will pass if the event
450          * received correspond with the expected response. This should respond with
451          * the test data requested.
452          */
453 
454         TestEventHandler testEventHandler = new TestEventHandler();
455         // Load up expected response
456         testEventHandler.expectStatus(200);
457         testEventHandler.expectHeaders();
458         testEventHandler.expectData(52);
459 
460         mTestWebServer.setKeepAlive(false);
461         mTestWebServer.setAcceptLimit(1);
462 
463         Log.d(LOGTAG, "testPostWithData start - rq = " + mRequestQueue);
464 
465         String mBody = TestWebData.postContent;
466         int bodyLength = mBody.length();
467         if (bodyLength > 0) {
468             Log.v(LOGTAG, "testPostWithData: body " + mBody);
469         }
470         InputStream bodyProvider = new ByteArrayInputStream(mBody.getBytes());
471 
472         RequestHandle handle = mRequestQueue.queueRequest(
473                 "http://localhost:8080/test1", "POST", null, testEventHandler, bodyProvider, bodyLength);
474 
475         Log.d(LOGTAG, "testPostWithData - sent request waiting");
476         handle.waitUntilComplete();
477 
478         if (!testEventHandler.expectPassed()) {
479             Log.d(LOGTAG, testEventHandler.getFailureMessage());
480             fail("expectPassed was false " + testEventHandler.getFailureMessage());
481         }
482     }
483 }
484