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

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: typo 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 }
45
46 /**
47 * Helper method to check that we are not calling methods on the native
48 * adapter after it has been destroyed.
49 */
50 private static void checkAfterAdapterDestroyed(HttpUrlRequest request) {
51 try {
52 request.getAllHeaders();
53 fail();
54 } catch (IllegalStateException e) {
55 assertEquals("Adapter has been destroyed", e.getMessage());
56 }
57 try {
58 request.getHeader("foo");
59 fail();
60 } catch (IllegalStateException e) {
61 assertEquals("Adapter has been destroyed", e.getMessage());
62 }
63 try {
64 request.getNegotiatedProtocol();
65 fail();
66 } catch (IllegalStateException e) {
67 assertEquals("Adapter has been destroyed", e.getMessage());
68 }
44 } 69 }
45 70
46 @Override 71 @Override
47 protected void setUp() throws Exception { 72 protected void setUp() throws Exception {
48 super.setUp(); 73 super.setUp();
49 mActivity = launchCronetTestApp(); 74 mActivity = launchCronetTestApp();
50 mMockUrlRequestJobFactory = new MockUrlRequestJobFactory( 75 mMockUrlRequestJobFactory = new MockUrlRequestJobFactory(
51 getInstrumentation().getTargetContext()); 76 getInstrumentation().getTargetContext());
52 } 77 }
53 78
54 @SmallTest 79 @SmallTest
55 @Feature({"Cronet"}) 80 @Feature({"Cronet"})
56 public void testSuccessURLRequest() throws Exception { 81 public void testSuccessURLRequest() throws Exception {
57 TestHttpUrlRequestListener listener = createRequestAndWaitForComplete( 82 createRequestAndWaitForComplete(
58 MockUrlRequestJobFactory.SUCCESS_URL, false); 83 MockUrlRequestJobFactory.SUCCESS_URL, false);
59 assertEquals(MockUrlRequestJobFactory.SUCCESS_URL, listener.mUrl); 84 assertEquals(MockUrlRequestJobFactory.SUCCESS_URL, mListener.mUrl);
60 assertEquals(200, listener.mHttpStatusCode); 85 assertEquals(200, mListener.mHttpStatusCode);
61 assertEquals("OK", listener.mHttpStatusText); 86 assertEquals("OK", mListener.mHttpStatusText);
62 assertEquals("this is a text file\n", 87 assertEquals("this is a text file\n",
63 new String(listener.mResponseAsBytes)); 88 new String(mListener.mResponseAsBytes));
89 // Test that ChromiumUrlRequest caches information which is available
90 // after the native request adapter has been destroyed.
91 assertEquals(200, mRequest.getHttpStatusCode());
92 assertEquals("OK", mRequest.getHttpStatusText());
93 assertNull(mRequest.getException());
94 checkAfterAdapterDestroyed(mRequest);
64 } 95 }
65 96
66 @SmallTest 97 @SmallTest
67 @Feature({"Cronet"}) 98 @Feature({"Cronet"})
68 public void testRedirectURLRequest() throws Exception { 99 public void testRedirectURLRequest() throws Exception {
69 TestHttpUrlRequestListener listener = createRequestAndWaitForComplete( 100 createRequestAndWaitForComplete(
70 MockUrlRequestJobFactory.REDIRECT_URL, false); 101 MockUrlRequestJobFactory.REDIRECT_URL, false);
71 102 // ChromiumUrlRequest does not expose the url after redirect.
72 // Currently Cronet does not expose the url after redirect. 103 assertEquals(MockUrlRequestJobFactory.REDIRECT_URL, mListener.mUrl);
73 assertEquals(MockUrlRequestJobFactory.REDIRECT_URL, listener.mUrl); 104 assertEquals(200, mListener.mHttpStatusCode);
74 assertEquals(200, listener.mHttpStatusCode); 105 assertEquals("OK", mListener.mHttpStatusText);
75 assertEquals("OK", listener.mHttpStatusText);
76 // Expect that the request is redirected to success.txt. 106 // Expect that the request is redirected to success.txt.
77 assertEquals("this is a text file\n", 107 assertEquals("this is a text file\n",
78 new String(listener.mResponseAsBytes)); 108 new String(mListener.mResponseAsBytes));
109 // Test that ChromiumUrlRequest caches information which is available
110 // after the native request adapter has been destroyed.
111 assertEquals(200, mRequest.getHttpStatusCode());
112 assertEquals("OK", mRequest.getHttpStatusText());
113 assertNull(mRequest.getException());
114 checkAfterAdapterDestroyed(mRequest);
79 } 115 }
80 116
81 @SmallTest 117 @SmallTest
82 @Feature({"Cronet"}) 118 @Feature({"Cronet"})
83 public void testNotFoundURLRequest() throws Exception { 119 public void testNotFoundURLRequest() throws Exception {
84 TestHttpUrlRequestListener listener = createRequestAndWaitForComplete( 120 createRequestAndWaitForComplete(
85 MockUrlRequestJobFactory.NOTFOUND_URL, false); 121 MockUrlRequestJobFactory.NOTFOUND_URL, false);
86 assertEquals(MockUrlRequestJobFactory.NOTFOUND_URL, listener.mUrl); 122 assertEquals(MockUrlRequestJobFactory.NOTFOUND_URL, mListener.mUrl);
87 assertEquals(404, listener.mHttpStatusCode); 123 assertEquals(404, mListener.mHttpStatusCode);
88 assertEquals("Not Found", listener.mHttpStatusText); 124 assertEquals("Not Found", mListener.mHttpStatusText);
89 assertEquals( 125 assertEquals(
90 "<!DOCTYPE html>\n<html>\n<head>\n<title>Not found</title>\n" 126 "<!DOCTYPE html>\n<html>\n<head>\n<title>Not found</title>\n"
91 + "<p>Test page loaded.</p>\n</head>\n</html>\n", 127 + "<p>Test page loaded.</p>\n</head>\n</html>\n",
92 new String(listener.mResponseAsBytes)); 128 new String(mListener.mResponseAsBytes));
129 // Test that ChromiumUrlRequest caches information which is available
130 // after the native request adapter has been destroyed.
131 assertEquals(404, mRequest.getHttpStatusCode());
132 assertEquals("Not Found", mRequest.getHttpStatusText());
133 assertNull(mRequest.getException());
134 checkAfterAdapterDestroyed(mRequest);
93 } 135 }
94 136
95 @SmallTest 137 @SmallTest
96 @Feature({"Cronet"}) 138 @Feature({"Cronet"})
97 public void testFailedURLRequest() throws Exception { 139 public void testFailedURLRequest() throws Exception {
98 TestHttpUrlRequestListener listener = createRequestAndWaitForComplete( 140 createRequestAndWaitForComplete(
99 MockUrlRequestJobFactory.FAILED_URL, false); 141 MockUrlRequestJobFactory.FAILED_URL, false);
100 142 assertEquals(MockUrlRequestJobFactory.FAILED_URL, mListener.mUrl);
101 assertEquals(MockUrlRequestJobFactory.FAILED_URL, listener.mUrl); 143 assertEquals("", mListener.mHttpStatusText);
102 assertEquals(null, listener.mHttpStatusText); 144 assertEquals(0, mListener.mHttpStatusCode);
103 assertEquals(0, listener.mHttpStatusCode); 145 // Test that ChromiumUrlRequest caches information which is available
146 // after the native request adapter has been destroyed.
147 assertEquals(0, mRequest.getHttpStatusCode());
148 assertEquals("", mRequest.getHttpStatusText());
149 assertEquals("System error: net::ERR_FAILED(-2)",
150 mRequest.getException().getMessage());
151 checkAfterAdapterDestroyed(mRequest);
104 } 152 }
105 153
106 @SmallTest 154 @SmallTest
107 @Feature({"Cronet"}) 155 @Feature({"Cronet"})
108 // Test that redirect can be disabled for a request. 156 // Test that redirect can be disabled for a request.
109 public void testDisableRedirects() throws Exception { 157 public void testDisableRedirects() throws Exception {
110 TestHttpUrlRequestListener listener = createRequestAndWaitForComplete( 158 createRequestAndWaitForComplete(
111 MockUrlRequestJobFactory.REDIRECT_URL, true); 159 MockUrlRequestJobFactory.REDIRECT_URL, true);
112 // Currently Cronet does not expose the url after redirect. 160 // Currently Cronet does not expose the url after redirect.
113 assertEquals(MockUrlRequestJobFactory.REDIRECT_URL, listener.mUrl); 161 assertEquals(MockUrlRequestJobFactory.REDIRECT_URL, mListener.mUrl);
114 assertEquals(302, listener.mHttpStatusCode); 162 assertEquals(302, mListener.mHttpStatusCode);
163 // MockUrlRequestJob somehow does not populate status text as "Found".
164 assertEquals("", mListener.mHttpStatusText);
115 // Expect that the request is not redirected to success.txt. 165 // Expect that the request is not redirected to success.txt.
116 assertNotNull(listener.mResponseHeaders); 166 assertNotNull(mListener.mResponseHeaders);
117 List<String> entry = listener.mResponseHeaders.get("redirect-header"); 167 List<String> entry = mListener.mResponseHeaders.get("redirect-header");
118 assertEquals(1, entry.size()); 168 assertEquals(1, entry.size());
119 assertEquals("header-value", entry.get(0)); 169 assertEquals("header-value", entry.get(0));
120 List<String> location = listener.mResponseHeaders.get("Location"); 170 List<String> location = mListener.mResponseHeaders.get("Location");
121 assertEquals(1, location.size()); 171 assertEquals(1, location.size());
122 assertEquals("/success.txt", location.get(0)); 172 assertEquals("/success.txt", location.get(0));
123 assertEquals("Request failed because there were too many redirects or " 173 assertEquals("Request failed because there were too many redirects or "
124 + "redirects have been disabled", 174 + "redirects have been disabled",
125 listener.mException.getMessage()); 175 mListener.mException.getMessage());
176 // Test that ChromiumUrlRequest caches information which is available
177 // after the native request adapter has been destroyed.
178 assertEquals(302, mRequest.getHttpStatusCode());
179 // MockUrlRequestJob somehow does not populate status text as "Found".
180 assertEquals("", mRequest.getHttpStatusText());
181 assertEquals("Request failed because there were too many redirects "
182 + "or redirects have been disabled",
183 mRequest.getException().getMessage());
184 checkAfterAdapterDestroyed(mRequest);
126 } 185 }
127 186
128 /** 187 /**
129 * TestByteChannel is used for making sure write is not called after the 188 * 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 189 * channel has been closed. Can synchronously cancel a request when write is
131 * called. 190 * called.
132 */ 191 */
133 static class TestByteChannel extends ChunkedWritableByteChannel { 192 static class TestByteChannel extends ChunkedWritableByteChannel {
134 HttpUrlRequest mRequestToCancelOnWrite; 193 HttpUrlRequest mRequestToCancelOnWrite;
135 194
(...skipping 18 matching lines...) Expand all
154 * Set request that will be synchronously canceled when write is called. 213 * Set request that will be synchronously canceled when write is called.
155 */ 214 */
156 public void setRequestToCancelOnWrite(HttpUrlRequest request) { 215 public void setRequestToCancelOnWrite(HttpUrlRequest request) {
157 mRequestToCancelOnWrite = request; 216 mRequestToCancelOnWrite = request;
158 } 217 }
159 } 218 }
160 219
161 @LargeTest 220 @LargeTest
162 @Feature({"Cronet"}) 221 @Feature({"Cronet"})
163 public void testNoWriteAfterCancelOnAnotherThread() throws Exception { 222 public void testNoWriteAfterCancelOnAnotherThread() throws Exception {
164 CronetTestActivity activity = launchCronetTestApp();
165
166 // This test verifies that WritableByteChannel.write is not called after 223 // This test verifies that WritableByteChannel.write is not called after
167 // WritableByteChannel.close if request is canceled from another 224 // WritableByteChannel.close if request is canceled from another
168 // thread. 225 // thread.
169 for (int i = 0; i < 100; ++i) { 226 for (int i = 0; i < 100; ++i) {
170 HashMap<String, String> headers = new HashMap<String, String>(); 227 HashMap<String, String> headers = new HashMap<String, String>();
171 TestByteChannel channel = new TestByteChannel(); 228 TestByteChannel channel = new TestByteChannel();
172 TestHttpUrlRequestListener listener = 229 TestHttpUrlRequestListener listener =
173 new TestHttpUrlRequestListener(); 230 new TestHttpUrlRequestListener();
174 231
175 // Create request. 232 // Create request.
176 final HttpUrlRequest request = 233 final HttpUrlRequest request =
177 activity.mRequestFactory.createRequest( 234 mActivity.mRequestFactory.createRequest(
178 MockUrlRequestJobFactory.SUCCESS_URL, 235 MockUrlRequestJobFactory.SUCCESS_URL,
179 HttpUrlRequest.REQUEST_PRIORITY_LOW, headers, 236 HttpUrlRequest.REQUEST_PRIORITY_LOW, headers,
180 channel, listener); 237 channel, listener);
181 request.start(); 238 request.start();
182 listener.blockForStart(); 239 listener.blockForStart();
183 Runnable cancelTask = new Runnable() { 240 Runnable cancelTask = new Runnable() {
184 public void run() { 241 public void run() {
185 request.cancel(); 242 request.cancel();
186 } 243 }
187 }; 244 };
188 Executors.newCachedThreadPool().execute(cancelTask); 245 Executors.newCachedThreadPool().execute(cancelTask);
189 listener.blockForComplete(); 246 listener.blockForComplete();
190 assertFalse(channel.isOpen()); 247 assertFalse(channel.isOpen());
248 // Since getAllHeaders and other methods in
249 // checkAfterAdapterDestroyed() acquire mLock, so this will happen
250 // after the adapter is destroyed.
251 checkAfterAdapterDestroyed(request);
191 } 252 }
192 } 253 }
193 254
194 @SmallTest 255 @SmallTest
195 @Feature({"Cronet"}) 256 @Feature({"Cronet"})
196 public void testNoWriteAfterSyncCancel() throws Exception { 257 public void testNoWriteAfterSyncCancel() throws Exception {
197 CronetTestActivity activity = launchCronetTestApp();
198
199 HashMap<String, String> headers = new HashMap<String, String>(); 258 HashMap<String, String> headers = new HashMap<String, String>();
200 TestByteChannel channel = new TestByteChannel(); 259 TestByteChannel channel = new TestByteChannel();
201 TestHttpUrlRequestListener listener = new TestHttpUrlRequestListener(); 260 TestHttpUrlRequestListener listener = new TestHttpUrlRequestListener();
202 261
203 String data = "MyBigFunkyData"; 262 String data = "MyBigFunkyData";
204 int dataLength = data.length(); 263 int dataLength = data.length();
205 int repeatCount = 10000; 264 int repeatCount = 10000;
206 String mockUrl = mMockUrlRequestJobFactory.getMockUrlForData(data, 265 String mockUrl = mMockUrlRequestJobFactory.getMockUrlForData(data,
207 repeatCount); 266 repeatCount);
208 267
209 // Create request. 268 // Create request.
210 final HttpUrlRequest request = 269 final HttpUrlRequest request =
211 activity.mRequestFactory.createRequest( 270 mActivity.mRequestFactory.createRequest(
212 mockUrl, 271 mockUrl,
213 HttpUrlRequest.REQUEST_PRIORITY_LOW, headers, 272 HttpUrlRequest.REQUEST_PRIORITY_LOW, headers,
214 channel, listener); 273 channel, listener);
215 // Channel will cancel the request from the network thread during the 274 // Channel will cancel the request from the network thread during the
216 // first write. 275 // first write.
217 channel.setRequestToCancelOnWrite(request); 276 channel.setRequestToCancelOnWrite(request);
218 request.start(); 277 request.start();
219 listener.blockForComplete(); 278 listener.blockForComplete();
220 assertTrue(request.isCanceled()); 279 assertTrue(request.isCanceled());
221 assertFalse(channel.isOpen()); 280 assertFalse(channel.isOpen());
281 // Test that ChromiumUrlRequest caches information which is available
282 // after the native request adapter has been destroyed.
283 assertEquals(-1, request.getHttpStatusCode());
284 assertEquals("", request.getHttpStatusText());
285 checkAfterAdapterDestroyed(request);
222 } 286 }
223 287
224 @SmallTest 288 @SmallTest
225 @Feature({"Cronet"}) 289 @Feature({"Cronet"})
226 public void testBigDataSyncReadRequest() throws Exception { 290 public void testBigDataSyncReadRequest() throws Exception {
227 String data = "MyBigFunkyData"; 291 String data = "MyBigFunkyData";
228 int dataLength = data.length(); 292 int dataLength = data.length();
229 int repeatCount = 100000; 293 int repeatCount = 100000;
230 String mockUrl = mMockUrlRequestJobFactory.getMockUrlForData(data, 294 String mockUrl = mMockUrlRequestJobFactory.getMockUrlForData(data,
231 repeatCount); 295 repeatCount);
232 TestHttpUrlRequestListener listener = createRequestAndWaitForComplete( 296 createRequestAndWaitForComplete(mockUrl, false);
233 mockUrl, false); 297 assertEquals(mockUrl, mListener.mUrl);
234 assertEquals(mockUrl, listener.mUrl);
235 String responseData = new String(listener.mResponseAsBytes);
236 for (int i = 0; i < repeatCount; ++i) { 298 for (int i = 0; i < repeatCount; ++i) {
237 assertEquals(data, responseData.substring(dataLength * i, 299 assertEquals(data, mListener.mResponseAsString.substring(
238 dataLength * (i + 1))); 300 dataLength * i, dataLength * (i + 1)));
239 } 301 }
240 } 302 }
241 } 303 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698