Chromium Code Reviews| Index: components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/urlconnection/CronetHttpURLConnectionTest.java |
| diff --git a/components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/urlconnection/CronetHttpURLConnectionTest.java b/components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/urlconnection/CronetHttpURLConnectionTest.java |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..1f344dd929f725ec866517daf07cb8832be00dbc |
| --- /dev/null |
| +++ b/components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/urlconnection/CronetHttpURLConnectionTest.java |
| @@ -0,0 +1,315 @@ |
| +// Copyright 2014 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +package org.chromium.cronet_test_apk.urlconnection; |
| + |
| +import android.test.suitebuilder.annotation.SmallTest; |
| + |
| +import org.chromium.base.test.util.Feature; |
| +import org.chromium.cronet_test_apk.CronetTestActivity; |
| +import org.chromium.cronet_test_apk.CronetTestBase; |
| +import org.chromium.cronet_test_apk.MockUrlRequestJobFactory; |
| +import org.chromium.cronet_test_apk.UploadTestServer; |
| + |
| +import java.io.ByteArrayOutputStream; |
| +import java.io.InputStream; |
| +import java.net.HttpURLConnection; |
| +import java.net.URL; |
| +import java.util.ArrayList; |
| +import java.util.Arrays; |
| +import java.util.List; |
| +import java.util.regex.Matcher; |
| +import java.util.regex.Pattern; |
| + |
| +/** |
| + * Basic tests of Cronet's HttpURLConnection implementation. |
| + * Tests annotated with {@code CompareDefaultWithCronet} will run once with the |
| + * default HttpURLConnection implementation and then with Cronet's |
| + * HttpURLConnection implementation. Tests annotated with |
| + * {@code OnlyRunCronetHttpURLConnection} only run Cronet's implementation. |
| + * See {@link CronetTestBase#runTest()} for details. |
| + */ |
| +public class CronetHttpURLConnectionTest extends CronetTestBase { |
| + private CronetTestActivity mActivity; |
| + |
| + @Override |
| + protected void setUp() throws Exception { |
| + super.setUp(); |
| + mActivity = launchCronetTestApp(); |
| + waitForActiveShellToBeDoneLoading(); |
| + assertTrue(UploadTestServer.startUploadTestServer()); |
| + } |
| + |
| + @Override |
| + protected void tearDown() { |
| + UploadTestServer.shutdownUploadTestServer(); |
| + } |
| + |
| + @SmallTest |
| + @Feature({"Cronet"}) |
| + @CompareDefaultWithCronet |
| + public void testBasicGet() throws Exception { |
| + URL url = new URL(UploadTestServer.getEchoMethodURL()); |
| + HttpURLConnection urlConnection = |
| + (HttpURLConnection) url.openConnection(); |
| + assertEquals(200, urlConnection.getResponseCode()); |
| + assertEquals("OK", urlConnection.getResponseMessage()); |
| + assertEquals("GET", getResponseAsString(urlConnection)); |
| + urlConnection.disconnect(); |
| + } |
| + |
| + @SmallTest |
| + @Feature({"Cronet"}) |
| + @OnlyRunCronetHttpURLConnection |
| + // Mock UrlRequestJobs only work for chromium network stack. |
| + public void testNotFoundURLRequest() throws Exception { |
| + MockUrlRequestJobFactory mockFactory = new MockUrlRequestJobFactory( |
| + getInstrumentation().getTargetContext()); |
| + mockFactory.setUp(); |
| + URL url = new URL(MockUrlRequestJobFactory.NOTFOUND_URL); |
| + HttpURLConnection urlConnection = |
| + (HttpURLConnection) url.openConnection(); |
| + assertEquals(404, urlConnection.getResponseCode()); |
| + assertEquals("Not Found", urlConnection.getResponseMessage()); |
| + assertEquals("<!DOCTYPE html>\n<html>\n<head>\n" |
| + + "<title>Not found</title>\n<p>Test page loaded.</p>\n" |
| + + "</head>\n</html>\n", |
| + getResponseAsString(urlConnection)); |
| + urlConnection.disconnect(); |
| + mockFactory.tearDown(); |
|
mmenke
2014/12/02 19:01:49
Should be able to use the test server with ServeFi
xunjieli
2014/12/02 20:35:34
Acknowledged. Since the support is not ready, I ha
|
| + } |
| + |
| + @SmallTest |
| + @Feature({"Cronet"}) |
| + @CompareDefaultWithCronet |
| + public void testDisconnectBeforeConnectionIsMade() throws Exception { |
| + URL url = new URL(UploadTestServer.getEchoMethodURL()); |
| + HttpURLConnection urlConnection = |
| + (HttpURLConnection) url.openConnection(); |
| + // Close connection before connection is made has no effect. |
| + // Default implementation passes this test. |
| + urlConnection.disconnect(); |
| + assertEquals(200, urlConnection.getResponseCode()); |
| + assertEquals("OK", urlConnection.getResponseMessage()); |
| + assertEquals("GET", getResponseAsString(urlConnection)); |
|
mmenke
2014/12/02 19:01:49
What happens if we try to read from both implement
xunjieli
2014/12/02 20:35:34
I don't understand. I thought we are reading from
mmenke
2014/12/02 20:48:10
Sorry, misread the test...was thinking we were dis
|
| + } |
| + |
| + @SmallTest |
| + @Feature({"Cronet"}) |
| + // TODO(xunjieli): Currently our wrapper does not throw an exception, and |
| + // we need to change the behavior. |
|
mmenke
2014/12/02 19:01:49
nit: Don't use our or we in comments. Alternativ
xunjieli
2014/12/02 20:35:34
Done.
|
| + // @CompareDefaultWithCronet |
| + public void testDisconnectAfterConnectionIsMade() throws Exception { |
| + URL url = new URL(UploadTestServer.getEchoMethodURL()); |
| + HttpURLConnection urlConnection = |
| + (HttpURLConnection) url.openConnection(); |
| + // Close connection before connection is made has no effect. |
| + urlConnection.connect(); |
| + urlConnection.disconnect(); |
| + try { |
| + urlConnection.getResponseCode(); |
| + fail(); |
| + } catch (Exception e) { |
| + // Ignored. |
| + } |
| + } |
| + |
| + @SmallTest |
| + @Feature({"Cronet"}) |
| + @CompareDefaultWithCronet |
| + public void testAddRequestProperty() throws Exception { |
| + URL url = new URL(UploadTestServer.getEchoAllHeadersURL()); |
| + HttpURLConnection urlConnection = |
| + (HttpURLConnection) url.openConnection(); |
| + urlConnection.addRequestProperty("foo-header", "foo"); |
| + urlConnection.addRequestProperty("bar-header", "bar"); |
| + assertEquals(200, urlConnection.getResponseCode()); |
| + assertEquals("OK", urlConnection.getResponseMessage()); |
| + String headers = getResponseAsString(urlConnection); |
| + List<String> fooHeaderValues = |
| + getRequestHeaderValues(headers, "foo-header"); |
| + List<String> barHeaderValues = |
| + getRequestHeaderValues(headers, "bar-header"); |
| + assertEquals(1, fooHeaderValues.size()); |
| + assertEquals("foo", fooHeaderValues.get(0)); |
| + assertEquals(1, fooHeaderValues.size()); |
| + assertEquals("bar", barHeaderValues.get(0)); |
| + urlConnection.disconnect(); |
| + } |
| + |
| + @SmallTest |
| + @Feature({"Cronet"}) |
| + @OnlyRunCronetHttpURLConnection |
| + // TODO(xunjieli): change the annotation once crbug.com/432719 is fixed. |
|
mmenke
2014/12/02 19:01:49
nit: Comments should be capitalized.
xunjieli
2014/12/02 20:35:34
Done.
|
| + public void testAddRequestPropertyWithSameKey() throws Exception { |
| + URL url = new URL(UploadTestServer.getEchoAllHeadersURL()); |
| + HttpURLConnection urlConnection = |
| + (HttpURLConnection) url.openConnection(); |
| + urlConnection.addRequestProperty("header-name", "value1"); |
| + urlConnection.addRequestProperty("header-name", "value2"); |
| + assertEquals(200, urlConnection.getResponseCode()); |
| + assertEquals("OK", urlConnection.getResponseMessage()); |
| + String headers = getResponseAsString(urlConnection); |
| + List<String> actualValues = |
| + getRequestHeaderValues(headers, "header-name"); |
| + // TODO(xunjieli): Currently Cronet only sends the last header value |
| + // if there are multiple entries with the same header key, see |
| + // crbug/432719. Fix this test once the bug is fixed. |
| + assertEquals(1, actualValues.size()); |
| + assertEquals("value2", actualValues.get(0)); |
| + urlConnection.disconnect(); |
| + } |
| + |
| + @SmallTest |
| + @Feature({"Cronet"}) |
| + @CompareDefaultWithCronet |
| + public void testSetRequestProperty() throws Exception { |
| + URL url = new URL(UploadTestServer.getEchoAllHeadersURL()); |
| + HttpURLConnection urlConnection = |
| + (HttpURLConnection) url.openConnection(); |
| + urlConnection.setRequestProperty("header-name", "header-value"); |
| + assertEquals(200, urlConnection.getResponseCode()); |
| + assertEquals("OK", urlConnection.getResponseMessage()); |
| + String headers = getResponseAsString(urlConnection); |
| + List<String> actualValues = |
| + getRequestHeaderValues(headers, "header-name"); |
| + assertEquals(1, actualValues.size()); |
| + assertEquals("header-value", actualValues.get(0)); |
| + urlConnection.disconnect(); |
| + } |
| + |
| + @SmallTest |
| + @Feature({"Cronet"}) |
| + @CompareDefaultWithCronet |
| + public void testAddAndSetRequestProperty() throws Exception { |
|
mmenke
2014/12/02 19:01:49
Should we do a test with two set calls for the sam
xunjieli
2014/12/02 20:35:34
Done.
|
| + URL url = new URL(UploadTestServer.getEchoAllHeadersURL()); |
| + HttpURLConnection urlConnection = |
| + (HttpURLConnection) url.openConnection(); |
| + urlConnection.addRequestProperty("header-name", "value1"); |
| + urlConnection.setRequestProperty("header-name", "value2"); |
| + assertEquals(200, urlConnection.getResponseCode()); |
| + assertEquals("OK", urlConnection.getResponseMessage()); |
| + String headers = getResponseAsString(urlConnection); |
| + List<String> actualValues = |
| + getRequestHeaderValues(headers, "header-name"); |
| + assertEquals(1, actualValues.size()); |
| + assertEquals("value2", actualValues.get(0)); |
| + urlConnection.disconnect(); |
| + } |
| + |
| + @SmallTest |
| + @Feature({"Cronet"}) |
| + @CompareDefaultWithCronet |
| + public void testInputStreamReadOneByte() throws Exception { |
| + String testInputString = "this is a really long header"; |
| + URL url = new URL(UploadTestServer.getEchoHeaderURL("foo")); |
| + HttpURLConnection urlConnection = |
| + (HttpURLConnection) url.openConnection(); |
| + urlConnection.addRequestProperty("foo", testInputString); |
| + assertEquals(200, urlConnection.getResponseCode()); |
| + assertEquals("OK", urlConnection.getResponseMessage()); |
| + InputStream in = urlConnection.getInputStream(); |
| + ByteArrayOutputStream out = new ByteArrayOutputStream(); |
| + int b; |
| + while ((b = in.read()) != -1) { |
| + out.write(b); |
| + } |
| + urlConnection.disconnect(); |
| + assertTrue(Arrays.equals( |
| + testInputString.getBytes(), out.toByteArray())); |
| + } |
| + |
| + @SmallTest |
| + @Feature({"Cronet"}) |
| + @CompareDefaultWithCronet |
| + public void testInputStreamReadMoreBytesThanAvailable() throws Exception { |
| + String testInputString = "this is a really long header"; |
| + byte[] testInputBytes = testInputString.getBytes(); |
| + URL url = new URL(UploadTestServer.getEchoHeaderURL("foo")); |
| + HttpURLConnection urlConnection = |
| + (HttpURLConnection) url.openConnection(); |
| + urlConnection.addRequestProperty("foo", testInputString); |
| + assertEquals(200, urlConnection.getResponseCode()); |
| + assertEquals("OK", urlConnection.getResponseMessage()); |
| + InputStream in = urlConnection.getInputStream(); |
| + byte[] actualOutput = new byte[testInputBytes.length + 256]; |
| + int bytesRead = in.read(actualOutput, 0, actualOutput.length); |
|
mmenke
2014/12/02 19:01:50
Should check that the next read (Using the same re
xunjieli
2014/12/02 20:35:34
Done. Great suggestion! I actually found a bug in
|
| + urlConnection.disconnect(); |
| + assertEquals(testInputBytes.length, bytesRead); |
| + for (int i = 0; i < bytesRead; i++) { |
| + assertEquals(testInputBytes[i], actualOutput[i]); |
| + } |
| + } |
| + |
| + @SmallTest |
| + @Feature({"Cronet"}) |
| + @CompareDefaultWithCronet |
| + public void testInputStreamReadExactBytesAvailable() throws Exception { |
| + String testInputString = "this is a really long header"; |
| + byte[] testInputBytes = testInputString.getBytes(); |
| + URL url = new URL(UploadTestServer.getEchoHeaderURL("foo")); |
| + HttpURLConnection urlConnection = |
| + (HttpURLConnection) url.openConnection(); |
| + urlConnection.addRequestProperty("foo", testInputString); |
| + assertEquals(200, urlConnection.getResponseCode()); |
| + assertEquals("OK", urlConnection.getResponseMessage()); |
| + InputStream in = urlConnection.getInputStream(); |
| + byte[] actualOutput = new byte[testInputBytes.length]; |
| + int bytesRead = in.read(actualOutput, 0, actualOutput.length); |
| + urlConnection.disconnect(); |
| + assertEquals(testInputBytes.length, bytesRead); |
| + assertTrue(Arrays.equals(testInputBytes, actualOutput)); |
| + } |
| + |
| + @SmallTest |
| + @Feature({"Cronet"}) |
| + @CompareDefaultWithCronet |
| + public void testInputStreamReadLessBytesThanAvailable() throws Exception { |
| + String testInputString = "this is a really long header"; |
| + byte[] testInputBytes = testInputString.getBytes(); |
| + URL url = new URL(UploadTestServer.getEchoHeaderURL("foo")); |
| + HttpURLConnection urlConnection = |
| + (HttpURLConnection) url.openConnection(); |
| + urlConnection.addRequestProperty("foo", testInputString); |
| + assertEquals(200, urlConnection.getResponseCode()); |
| + assertEquals("OK", urlConnection.getResponseMessage()); |
| + InputStream in = urlConnection.getInputStream(); |
| + byte[] actualOutput = new byte[testInputBytes.length]; |
| + int bytesRead = in.read(actualOutput, 0, actualOutput.length - 10); |
| + assertEquals(testInputBytes.length - 10, bytesRead); |
| + bytesRead = in.read(actualOutput, actualOutput.length - 10, 10); |
|
mmenke
2014/12/02 19:01:49
Should use different destination buffers for the t
xunjieli
2014/12/02 20:35:34
Done.
|
| + assertEquals(10, bytesRead); |
| + assertTrue(Arrays.equals(testInputBytes, actualOutput)); |
| + urlConnection.disconnect(); |
| + } |
| + |
| + /** |
| + * Helper method to extract response body as a string for testing. |
| + */ |
| + private String getResponseAsString(HttpURLConnection connection) |
| + throws Exception { |
| + InputStream in = connection.getInputStream(); |
| + ByteArrayOutputStream out = new ByteArrayOutputStream(); |
| + int b; |
| + while ((b = in.read()) != -1) { |
| + out.write(b); |
| + } |
| + return out.toString(); |
| + } |
| + |
| + /** |
| + * Helper method to extract a list of header values with the give header |
| + * name. |
| + */ |
| + private List<String> getRequestHeaderValues(String allHeaders, |
| + String headerName) { |
| + Pattern pattern = Pattern.compile(headerName + ":\\s(.*)\\r\\n"); |
| + Matcher matcher = pattern.matcher(allHeaders); |
| + List<String> headerValues = new ArrayList<String>(); |
| + while (matcher.find()) { |
| + headerValues.add(matcher.group(1)); |
| + } |
| + return headerValues; |
| + } |
| +} |