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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 367 public void testRedirect301() throws Exception { 368 verifyRedirect(HttpConstants.HTTP_MOVED_PERM, "testRedirect301"); 369 } 370 371 public void testRedirect302() throws Exception { 372 verifyRedirect(HttpConstants.HTTP_MOVED_TEMP, "testRedirect302"); 373 } 374 375 public void testRedirect303() throws Exception { 376 verifyRedirect(HttpConstants.HTTP_SEE_OTHER, "testRedirect303"); 377 } 378 379 public void testRedirect307() throws Exception { 380 verifyRedirect(307, "testRedirect307"); 381 } 382 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 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 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