Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(92)

Side by Side Diff: components/cronet/android/test/javatests/src/org/chromium/net/MockUrlRequestJobTest.java

Issue 945843003: [Cronet] Do not call into native adapter after it is destroyed in ChromiumUrlRequest.java (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address comments Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.net; 5 package org.chromium.net;
6 6
7 import android.test.suitebuilder.annotation.LargeTest; 7 import android.test.suitebuilder.annotation.LargeTest;
8 import android.test.suitebuilder.annotation.SmallTest; 8 import android.test.suitebuilder.annotation.SmallTest;
9 9
10 import org.chromium.base.test.util.Feature; 10 import org.chromium.base.test.util.Feature;
11 11
12 import java.io.IOException; 12 import java.io.IOException;
13 import java.nio.ByteBuffer; 13 import java.nio.ByteBuffer;
14 import java.util.HashMap; 14 import java.util.HashMap;
15 import java.util.List; 15 import java.util.List;
16 import java.util.concurrent.Executors; 16 import java.util.concurrent.Executors;
17 17
18 /** 18 /**
19 * Tests that use mock URLRequestJobs to simulate URL requests. 19 * Tests that use mock URLRequestJobs to simulate URL requests.
20 */ 20 */
21 public class MockUrlRequestJobTest extends CronetTestBase { 21 public class MockUrlRequestJobTest extends CronetTestBase {
22 private static final String TAG = "MockURLRequestJobTest"; 22 private static final String TAG = "MockURLRequestJobTest";
23 23
24 private CronetTestActivity mActivity; 24 private CronetTestActivity mActivity;
25 private MockUrlRequestJobFactory mMockUrlRequestJobFactory; 25 private MockUrlRequestJobFactory mMockUrlRequestJobFactory;
26 private TestHttpUrlRequestListener mListener;
27 private HttpUrlRequest mRequest;
26 28
27 // Helper function to create a HttpUrlRequest with the specified url. 29 // Helper function to create a HttpUrlRequest with the specified url.
28 private TestHttpUrlRequestListener createRequestAndWaitForComplete( 30 private void createRequestAndWaitForComplete(
29 String url, boolean disableRedirects) { 31 String url, boolean disableRedirects) {
30 HashMap<String, String> headers = new HashMap<String, String>(); 32 HashMap<String, String> headers = new HashMap<String, String>();
31 TestHttpUrlRequestListener listener = new TestHttpUrlRequestListener(); 33 mListener = new TestHttpUrlRequestListener();
32 34 mRequest = mActivity.mRequestFactory.createRequest(
33 HttpUrlRequest request = mActivity.mRequestFactory.createRequest(
34 url, 35 url,
35 HttpUrlRequest.REQUEST_PRIORITY_MEDIUM, 36 HttpUrlRequest.REQUEST_PRIORITY_MEDIUM,
36 headers, 37 headers,
37 listener); 38 mListener);
38 if (disableRedirects) { 39 if (disableRedirects) {
39 request.disableRedirects(); 40 mRequest.disableRedirects();
40 } 41 }
41 request.start(); 42 mRequest.start();
42 listener.blockForComplete(); 43 mListener.blockForComplete();
43 return listener;
44 } 44 }
45 45
46 @Override 46 @Override
47 protected void setUp() throws Exception { 47 protected void setUp() throws Exception {
48 super.setUp(); 48 super.setUp();
49 mActivity = launchCronetTestApp(); 49 mActivity = launchCronetTestApp();
50 mMockUrlRequestJobFactory = new MockUrlRequestJobFactory( 50 mMockUrlRequestJobFactory = new MockUrlRequestJobFactory(
51 getInstrumentation().getTargetContext()); 51 getInstrumentation().getTargetContext());
52 } 52 }
53 53
54 @SmallTest 54 @SmallTest
55 @Feature({"Cronet"}) 55 @Feature({"Cronet"})
56 public void testSuccessURLRequest() throws Exception { 56 public void testSuccessURLRequest() throws Exception {
57 TestHttpUrlRequestListener listener = createRequestAndWaitForComplete( 57 createRequestAndWaitForComplete(
58 MockUrlRequestJobFactory.SUCCESS_URL, false); 58 MockUrlRequestJobFactory.SUCCESS_URL, false);
59 assertEquals(MockUrlRequestJobFactory.SUCCESS_URL, listener.mUrl); 59 assertEquals(MockUrlRequestJobFactory.SUCCESS_URL, mListener.mUrl);
60 assertEquals(200, listener.mHttpStatusCode); 60 assertEquals(200, mListener.mHttpStatusCode);
61 assertEquals("OK", listener.mHttpStatusText); 61 assertEquals("OK", mListener.mHttpStatusText);
62 assertEquals("this is a text file\n", 62 assertEquals("this is a text file\n",
63 new String(listener.mResponseAsBytes)); 63 new String(mListener.mResponseAsBytes));
64 // Test that ChromiumUrlRequest caches information which is available
65 // after the native request adapter has been destroyed.
66 assertEquals(200, mRequest.getHttpStatusCode());
67 assertEquals("OK", mRequest.getHttpStatusText());
68 assertNull(mRequest.getException());
69 try {
70 // After underlying adapter request is destroyed. getAllHeaders()
mef 2015/03/02 22:58:01 I think this test (exception thrown by recycled re
71 // will give an exception.
72 mRequest.getAllHeaders();
73 } catch (IllegalStateException e) {
74 assertEquals("Accessing recycled request", e.getMessage());
75 }
64 } 76 }
65 77
66 @SmallTest 78 @SmallTest
67 @Feature({"Cronet"}) 79 @Feature({"Cronet"})
68 public void testRedirectURLRequest() throws Exception { 80 public void testRedirectURLRequest() throws Exception {
69 TestHttpUrlRequestListener listener = createRequestAndWaitForComplete( 81 createRequestAndWaitForComplete(
70 MockUrlRequestJobFactory.REDIRECT_URL, false); 82 MockUrlRequestJobFactory.REDIRECT_URL, false);
71 83 // ChromiumUrlRequest does not expose the url after redirect.
72 // Currently Cronet does not expose the url after redirect. 84 assertEquals(MockUrlRequestJobFactory.REDIRECT_URL, mListener.mUrl);
73 assertEquals(MockUrlRequestJobFactory.REDIRECT_URL, listener.mUrl); 85 assertEquals(200, mListener.mHttpStatusCode);
74 assertEquals(200, listener.mHttpStatusCode); 86 assertEquals("OK", mListener.mHttpStatusText);
75 assertEquals("OK", listener.mHttpStatusText);
76 // Expect that the request is redirected to success.txt. 87 // Expect that the request is redirected to success.txt.
77 assertEquals("this is a text file\n", 88 assertEquals("this is a text file\n",
78 new String(listener.mResponseAsBytes)); 89 new String(mListener.mResponseAsBytes));
90 // Test that ChromiumUrlRequest caches information which is available
91 // after the native request adapter has been destroyed.
92 assertEquals(200, mRequest.getHttpStatusCode());
93 assertEquals("OK", mRequest.getHttpStatusText());
94 assertNull(mRequest.getException());
95 try {
96 // After underlying adapter request is destroyed. getAllHeaders()
97 // will give an exception.
98 mRequest.getAllHeaders();
99 } catch (IllegalStateException e) {
100 assertEquals("Accessing recycled request", e.getMessage());
101 }
79 } 102 }
80 103
81 @SmallTest 104 @SmallTest
82 @Feature({"Cronet"}) 105 @Feature({"Cronet"})
83 public void testNotFoundURLRequest() throws Exception { 106 public void testNotFoundURLRequest() throws Exception {
84 TestHttpUrlRequestListener listener = createRequestAndWaitForComplete( 107 createRequestAndWaitForComplete(
85 MockUrlRequestJobFactory.NOTFOUND_URL, false); 108 MockUrlRequestJobFactory.NOTFOUND_URL, false);
86 assertEquals(MockUrlRequestJobFactory.NOTFOUND_URL, listener.mUrl); 109 assertEquals(MockUrlRequestJobFactory.NOTFOUND_URL, mListener.mUrl);
87 assertEquals(404, listener.mHttpStatusCode); 110 assertEquals(404, mListener.mHttpStatusCode);
88 assertEquals("Not Found", listener.mHttpStatusText); 111 assertEquals("Not Found", mListener.mHttpStatusText);
89 assertEquals( 112 assertEquals(
90 "<!DOCTYPE html>\n<html>\n<head>\n<title>Not found</title>\n" 113 "<!DOCTYPE html>\n<html>\n<head>\n<title>Not found</title>\n"
91 + "<p>Test page loaded.</p>\n</head>\n</html>\n", 114 + "<p>Test page loaded.</p>\n</head>\n</html>\n",
92 new String(listener.mResponseAsBytes)); 115 new String(mListener.mResponseAsBytes));
116 // Test that ChromiumUrlRequest caches information which is available
117 // after the native request adapter has been destroyed.
118 assertEquals(404, mRequest.getHttpStatusCode());
119 assertEquals("Not Found", mRequest.getHttpStatusText());
120 assertNull(mRequest.getException());
121 try {
122 // After underlying adapter request is destroyed. getAllHeaders()
123 // will give an exception.
124 mRequest.getAllHeaders();
125 } catch (IllegalStateException e) {
126 assertEquals("Accessing recycled request", e.getMessage());
127 }
93 } 128 }
94 129
95 @SmallTest 130 @SmallTest
96 @Feature({"Cronet"}) 131 @Feature({"Cronet"})
97 public void testFailedURLRequest() throws Exception { 132 public void testFailedURLRequest() throws Exception {
98 TestHttpUrlRequestListener listener = createRequestAndWaitForComplete( 133 createRequestAndWaitForComplete(
99 MockUrlRequestJobFactory.FAILED_URL, false); 134 MockUrlRequestJobFactory.FAILED_URL, false);
100 135 assertEquals(MockUrlRequestJobFactory.FAILED_URL, mListener.mUrl);
101 assertEquals(MockUrlRequestJobFactory.FAILED_URL, listener.mUrl); 136 assertEquals("", mListener.mHttpStatusText);
102 assertEquals(null, listener.mHttpStatusText); 137 assertEquals(0, mListener.mHttpStatusCode);
103 assertEquals(0, listener.mHttpStatusCode); 138 // Test that ChromiumUrlRequest caches information which is available
139 // after the native request adapter has been destroyed.
140 assertEquals(0, mRequest.getHttpStatusCode());
141 assertEquals("", mRequest.getHttpStatusText());
142 assertEquals("System error: net::ERR_FAILED(-2)",
143 mRequest.getException().getMessage());
144 try {
145 // After underlying adapter request is destroyed. getAllHeaders()
146 // will give an exception.
147 mRequest.getAllHeaders();
148 } catch (IllegalStateException e) {
149 assertEquals("Response headers not available", e.getMessage());
150 }
104 } 151 }
105 152
106 @SmallTest 153 @SmallTest
107 @Feature({"Cronet"}) 154 @Feature({"Cronet"})
108 // Test that redirect can be disabled for a request. 155 // Test that redirect can be disabled for a request.
109 public void testDisableRedirects() throws Exception { 156 public void testDisableRedirects() throws Exception {
110 TestHttpUrlRequestListener listener = createRequestAndWaitForComplete( 157 createRequestAndWaitForComplete(
111 MockUrlRequestJobFactory.REDIRECT_URL, true); 158 MockUrlRequestJobFactory.REDIRECT_URL, true);
112 // Currently Cronet does not expose the url after redirect. 159 // Currently Cronet does not expose the url after redirect.
113 assertEquals(MockUrlRequestJobFactory.REDIRECT_URL, listener.mUrl); 160 assertEquals(MockUrlRequestJobFactory.REDIRECT_URL, mListener.mUrl);
114 assertEquals(302, listener.mHttpStatusCode); 161 assertEquals(302, mListener.mHttpStatusCode);
162 // MockUrlRequestJob somehow does not populate status text as "Found".
163 assertEquals("", mListener.mHttpStatusText);
115 // Expect that the request is not redirected to success.txt. 164 // Expect that the request is not redirected to success.txt.
116 assertNotNull(listener.mResponseHeaders); 165 assertNotNull(mListener.mResponseHeaders);
117 List<String> entry = listener.mResponseHeaders.get("redirect-header"); 166 List<String> entry = mListener.mResponseHeaders.get("redirect-header");
118 assertEquals(1, entry.size()); 167 assertEquals(1, entry.size());
119 assertEquals("header-value", entry.get(0)); 168 assertEquals("header-value", entry.get(0));
120 List<String> location = listener.mResponseHeaders.get("Location"); 169 List<String> location = mListener.mResponseHeaders.get("Location");
121 assertEquals(1, location.size()); 170 assertEquals(1, location.size());
122 assertEquals("/success.txt", location.get(0)); 171 assertEquals("/success.txt", location.get(0));
123 assertEquals("Request failed because there were too many redirects or " 172 assertEquals("Request failed because there were too many redirects or "
124 + "redirects have been disabled", 173 + "redirects have been disabled",
125 listener.mException.getMessage()); 174 mListener.mException.getMessage());
175 // Test that ChromiumUrlRequest caches information which is available
176 // after the native request adapter has been destroyed.
177 assertEquals(302, mRequest.getHttpStatusCode());
178 // MockUrlRequestJob somehow does not populate status text as "Found".
179 assertEquals("", mRequest.getHttpStatusText());
180 assertEquals("Request failed because there were too many redirects "
181 + "or redirects have been disabled",
182 mRequest.getException().getMessage());
183 try {
mef 2015/03/02 22:58:01 Not sure whether having this try/catch section in
184 // After underlying adapter request is destroyed. getAllHeaders()
185 // will give an exception.
186 mRequest.getAllHeaders();
187 } catch (IllegalStateException e) {
188 assertEquals("Accessing recycled request", e.getMessage());
189 }
126 } 190 }
127 191
128 /** 192 /**
129 * TestByteChannel is used for making sure write is not called after the 193 * TestByteChannel is used for making sure write is not called after the
130 * channel has been closed. Can synchronously cancel a request when write is 194 * channel has been closed. Can synchronously cancel a request when write is
131 * called. 195 * called.
132 */ 196 */
133 static class TestByteChannel extends ChunkedWritableByteChannel { 197 static class TestByteChannel extends ChunkedWritableByteChannel {
134 HttpUrlRequest mRequestToCancelOnWrite; 198 HttpUrlRequest mRequestToCancelOnWrite;
135 199
(...skipping 18 matching lines...) Expand all
154 * Set request that will be synchronously canceled when write is called. 218 * Set request that will be synchronously canceled when write is called.
155 */ 219 */
156 public void setRequestToCancelOnWrite(HttpUrlRequest request) { 220 public void setRequestToCancelOnWrite(HttpUrlRequest request) {
157 mRequestToCancelOnWrite = request; 221 mRequestToCancelOnWrite = request;
158 } 222 }
159 } 223 }
160 224
161 @LargeTest 225 @LargeTest
162 @Feature({"Cronet"}) 226 @Feature({"Cronet"})
163 public void testNoWriteAfterCancelOnAnotherThread() throws Exception { 227 public void testNoWriteAfterCancelOnAnotherThread() throws Exception {
164 CronetTestActivity activity = launchCronetTestApp();
165
166 // This test verifies that WritableByteChannel.write is not called after 228 // This test verifies that WritableByteChannel.write is not called after
167 // WritableByteChannel.close if request is canceled from another 229 // WritableByteChannel.close if request is canceled from another
168 // thread. 230 // thread.
169 for (int i = 0; i < 100; ++i) { 231 for (int i = 0; i < 100; ++i) {
170 HashMap<String, String> headers = new HashMap<String, String>(); 232 HashMap<String, String> headers = new HashMap<String, String>();
171 TestByteChannel channel = new TestByteChannel(); 233 TestByteChannel channel = new TestByteChannel();
172 TestHttpUrlRequestListener listener = 234 TestHttpUrlRequestListener listener =
173 new TestHttpUrlRequestListener(); 235 new TestHttpUrlRequestListener();
174 236
175 // Create request. 237 // Create request.
176 final HttpUrlRequest request = 238 final HttpUrlRequest request =
177 activity.mRequestFactory.createRequest( 239 mActivity.mRequestFactory.createRequest(
178 MockUrlRequestJobFactory.SUCCESS_URL, 240 MockUrlRequestJobFactory.SUCCESS_URL,
179 HttpUrlRequest.REQUEST_PRIORITY_LOW, headers, 241 HttpUrlRequest.REQUEST_PRIORITY_LOW, headers,
180 channel, listener); 242 channel, listener);
181 request.start(); 243 request.start();
182 listener.blockForStart(); 244 listener.blockForStart();
183 Runnable cancelTask = new Runnable() { 245 Runnable cancelTask = new Runnable() {
184 public void run() { 246 public void run() {
185 request.cancel(); 247 request.cancel();
186 } 248 }
187 }; 249 };
188 Executors.newCachedThreadPool().execute(cancelTask); 250 Executors.newCachedThreadPool().execute(cancelTask);
189 listener.blockForComplete(); 251 listener.blockForComplete();
190 assertFalse(channel.isOpen()); 252 assertFalse(channel.isOpen());
191 } 253 }
192 } 254 }
193 255
194 @SmallTest 256 @SmallTest
195 @Feature({"Cronet"}) 257 @Feature({"Cronet"})
196 public void testNoWriteAfterSyncCancel() throws Exception { 258 public void testNoWriteAfterSyncCancel() throws Exception {
197 CronetTestActivity activity = launchCronetTestApp();
198
199 HashMap<String, String> headers = new HashMap<String, String>(); 259 HashMap<String, String> headers = new HashMap<String, String>();
200 TestByteChannel channel = new TestByteChannel(); 260 TestByteChannel channel = new TestByteChannel();
201 TestHttpUrlRequestListener listener = new TestHttpUrlRequestListener(); 261 TestHttpUrlRequestListener listener = new TestHttpUrlRequestListener();
202 262
203 String data = "MyBigFunkyData"; 263 String data = "MyBigFunkyData";
204 int dataLength = data.length(); 264 int dataLength = data.length();
205 int repeatCount = 10000; 265 int repeatCount = 10000;
206 String mockUrl = mMockUrlRequestJobFactory.getMockUrlForData(data, 266 String mockUrl = mMockUrlRequestJobFactory.getMockUrlForData(data,
207 repeatCount); 267 repeatCount);
208 268
209 // Create request. 269 // Create request.
210 final HttpUrlRequest request = 270 final HttpUrlRequest request =
211 activity.mRequestFactory.createRequest( 271 mActivity.mRequestFactory.createRequest(
212 mockUrl, 272 mockUrl,
213 HttpUrlRequest.REQUEST_PRIORITY_LOW, headers, 273 HttpUrlRequest.REQUEST_PRIORITY_LOW, headers,
214 channel, listener); 274 channel, listener);
215 // Channel will cancel the request from the network thread during the 275 // Channel will cancel the request from the network thread during the
216 // first write. 276 // first write.
217 channel.setRequestToCancelOnWrite(request); 277 channel.setRequestToCancelOnWrite(request);
218 request.start(); 278 request.start();
219 listener.blockForComplete(); 279 listener.blockForComplete();
220 assertTrue(request.isCanceled()); 280 assertTrue(request.isCanceled());
221 assertFalse(channel.isOpen()); 281 assertFalse(channel.isOpen());
282 // Test that ChromiumUrlRequest caches information which is available
283 // after the native request adapter has been destroyed.
284 assertEquals(-1, request.getHttpStatusCode());
285 assertEquals("", request.getHttpStatusText());
286 try {
287 // After underlying adapter request is destroyed. getAllHeaders()
288 // will give an exception.
289 request.getAllHeaders();
290 } catch (IllegalStateException e) {
291 assertEquals("Accessing recycled request", e.getMessage());
292 }
222 } 293 }
223 294
224 @SmallTest 295 @SmallTest
225 @Feature({"Cronet"}) 296 @Feature({"Cronet"})
226 public void testBigDataSyncReadRequest() throws Exception { 297 public void testBigDataSyncReadRequest() throws Exception {
227 String data = "MyBigFunkyData"; 298 String data = "MyBigFunkyData";
228 int dataLength = data.length(); 299 int dataLength = data.length();
229 int repeatCount = 100000; 300 int repeatCount = 100000;
230 String mockUrl = mMockUrlRequestJobFactory.getMockUrlForData(data, 301 String mockUrl = mMockUrlRequestJobFactory.getMockUrlForData(data,
231 repeatCount); 302 repeatCount);
232 TestHttpUrlRequestListener listener = createRequestAndWaitForComplete( 303 createRequestAndWaitForComplete(mockUrl, false);
233 mockUrl, false); 304 assertEquals(mockUrl, mListener.mUrl);
234 assertEquals(mockUrl, listener.mUrl);
235 String responseData = new String(listener.mResponseAsBytes);
236 for (int i = 0; i < repeatCount; ++i) { 305 for (int i = 0; i < repeatCount; ++i) {
237 assertEquals(data, responseData.substring(dataLength * i, 306 assertEquals(data, mListener.mResponseAsString.substring(
238 dataLength * (i + 1))); 307 dataLength * i, dataLength * (i + 1)));
239 } 308 }
240 } 309 }
241 } 310 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698