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

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

Issue 966743003: [Cronet] Implement getOutputStream in CronetHttpURLConnection (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@chunked_support
Patch Set: Use ByteBuffer instead of ByteArrayOutputStream in CronetBufferedOutputStream 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
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.chromium.net.urlconnection;
6
7 import android.test.suitebuilder.annotation.SmallTest;
8
9 import org.chromium.base.test.util.Feature;
10
11 import org.chromium.net.CronetTestActivity;
12 import org.chromium.net.CronetTestBase;
13 import org.chromium.net.NativeTestServer;
14
15 import java.io.ByteArrayOutputStream;
16 import java.io.InputStream;
17 import java.io.OutputStream;
18 import java.net.HttpURLConnection;
19 import java.net.URL;
20
21 /**
22 * Tests the CronetBufferedOutputStream implementation.
23 */
24 public class CronetBufferedOutputStreamTest extends CronetTestBase {
25 private static final String UPLOAD_DATA_STRING = "Nifty upload data!";
26 private static final byte[] UPLOAD_DATA = UPLOAD_DATA_STRING.getBytes();
27 private static final int REPEAT_COUNT = 100000;
28 private CronetTestActivity mActivity;
29
30 @Override
31 protected void setUp() throws Exception {
32 super.setUp();
33 mActivity = launchCronetTestApp();
34 assertTrue(NativeTestServer.startNativeTestServer(
35 getInstrumentation().getTargetContext()));
36 }
37
38 @Override
39 protected void tearDown() throws Exception {
40 NativeTestServer.shutdownNativeTestServer();
41 super.tearDown();
42 }
43
44 @SmallTest
45 @Feature({"Cronet"})
46 @CompareDefaultWithCronet
47 public void testPostAfterConnectionMade() throws Exception {
mmenke 2015/03/31 18:19:32 nit: Maybe testGetOutputStreamAfter...?
xunjieli 2015/04/01 17:04:09 Done.
48 URL url = new URL(NativeTestServer.getEchoBodyURL());
49 HttpURLConnection connection =
50 (HttpURLConnection) url.openConnection();
51 connection.setDoOutput(true);
52 connection.setRequestMethod("POST");
53 assertEquals(200, connection.getResponseCode());
54 try {
55 connection.getOutputStream();
56 fail();
57 } catch (java.net.ProtocolException e) {
58 // Expected.
59 }
60 }
mmenke 2015/03/31 18:19:32 Should we have a similar test where we get the out
xunjieli 2015/04/01 17:04:09 Done.
61
62 @SmallTest
63 @Feature({"Cronet"})
64 @CompareDefaultWithCronet
65 public void testPostWithContentLength() throws Exception {
66 URL url = new URL(NativeTestServer.getEchoBodyURL());
67 HttpURLConnection connection =
68 (HttpURLConnection) url.openConnection();
69 connection.setDoOutput(true);
70 connection.setRequestMethod("POST");
71 byte[] largeData = getLargeData();
72 connection.setRequestProperty("Content-Length",
73 Integer.toString(largeData.length));
74 OutputStream out = connection.getOutputStream();
75 int totalBytesWritten = 0;
76 // Number of bytes to write each time. It is incremented by one from 0.
77 int bytesToWrite = 0;
78 while (totalBytesWritten < largeData.length) {
79 if (bytesToWrite > largeData.length - totalBytesWritten) {
80 // Do not write out of bound.
81 bytesToWrite = largeData.length - totalBytesWritten;
82 }
83 out.write(largeData, totalBytesWritten, bytesToWrite);
84 totalBytesWritten += bytesToWrite;
85 bytesToWrite++;
86 }
87 assertEquals(200, connection.getResponseCode());
88 assertEquals("OK", connection.getResponseMessage());
89 checkLargeData(getResponseAsString(connection));
90 connection.disconnect();
91 }
92
93 @SmallTest
94 @Feature({"Cronet"})
95 @CompareDefaultWithCronet
96 public void testPostWithContentLengthOneMassiveWrite() throws Exception {
97 URL url = new URL(NativeTestServer.getEchoBodyURL());
98 HttpURLConnection connection =
99 (HttpURLConnection) url.openConnection();
100 connection.setDoOutput(true);
101 connection.setRequestMethod("POST");
102 byte[] largeData = getLargeData();
103 connection.setRequestProperty("Content-Length",
104 Integer.toString(largeData.length));
105 OutputStream out = connection.getOutputStream();
106 out.write(largeData);
107 assertEquals(200, connection.getResponseCode());
108 assertEquals("OK", connection.getResponseMessage());
109 checkLargeData(getResponseAsString(connection));
110 connection.disconnect();
111 }
112
113 @SmallTest
114 @Feature({"Cronet"})
115 @CompareDefaultWithCronet
116 public void testPostWithContentLengthWriteOneByte() throws Exception {
117 URL url = new URL(NativeTestServer.getEchoBodyURL());
118 HttpURLConnection connection =
119 (HttpURLConnection) url.openConnection();
120 connection.setDoOutput(true);
121 connection.setRequestMethod("POST");
122 byte[] largeData = getLargeData();
123 connection.setRequestProperty("Content-Length",
124 Integer.toString(largeData.length));
125 OutputStream out = connection.getOutputStream();
126 for (int i = 0; i < largeData.length; i++) {
127 out.write(largeData[i]);
128 }
129 assertEquals(200, connection.getResponseCode());
130 assertEquals("OK", connection.getResponseMessage());
131 checkLargeData(getResponseAsString(connection));
132 connection.disconnect();
133 }
134
135 @SmallTest
136 @Feature({"Cronet"})
137 @CompareDefaultWithCronet
138 public void testPostWithZeroContentLength() throws Exception {
139 URL url = new URL(NativeTestServer.getEchoBodyURL());
140 HttpURLConnection connection =
141 (HttpURLConnection) url.openConnection();
142 connection.setDoOutput(true);
143 connection.setRequestMethod("POST");
144 connection.setRequestProperty("Content-Length", "0");
145 assertEquals(200, connection.getResponseCode());
146 assertEquals("OK", connection.getResponseMessage());
147 assertEquals("", getResponseAsString(connection));
148 connection.disconnect();
149 }
150
151 @SmallTest
152 @Feature({"Cronet"})
153 @CompareDefaultWithCronet
154 public void testPostZeroByteWithoutContentLength() throws Exception {
155 // Make sure both implementation sets the Content-Length header to 0.
156 URL url = new URL(NativeTestServer.getEchoHeaderURL("Content-Length"));
157 HttpURLConnection connection =
158 (HttpURLConnection) url.openConnection();
159 connection.setDoOutput(true);
160 connection.setRequestMethod("POST");
161 assertEquals(200, connection.getResponseCode());
162 assertEquals("OK", connection.getResponseMessage());
163 assertEquals("0", getResponseAsString(connection));
164 connection.disconnect();
165
166 // Make sure the server echos back empty body for both implementation.
mmenke 2015/03/31 18:19:32 nit: echoes (I'm not sure if echos is a valid alt
xunjieli 2015/04/01 17:04:09 Done. TIL "echoes" :)
167 URL echoBody = new URL(NativeTestServer.getEchoBodyURL());
168 HttpURLConnection connection2 =
169 (HttpURLConnection) echoBody.openConnection();
170 connection2.setDoOutput(true);
171 connection2.setRequestMethod("POST");
172 assertEquals(200, connection2.getResponseCode());
173 assertEquals("OK", connection2.getResponseMessage());
174 assertEquals("", getResponseAsString(connection2));
175 connection2.disconnect();
176 }
177
178 @SmallTest
179 @Feature({"Cronet"})
180 @CompareDefaultWithCronet
181 public void testPostWithoutContentLength() throws Exception {
182 URL url = new URL(NativeTestServer.getEchoBodyURL());
183 HttpURLConnection connection =
184 (HttpURLConnection) url.openConnection();
185 connection.setDoOutput(true);
186 connection.setRequestMethod("POST");
187 byte[] largeData = getLargeData();
188 OutputStream out = connection.getOutputStream();
189 int totalBytesWritten = 0;
190 // Number of bytes to write each time. It is doubled each time and is
191 // bigger than the internal buffer to make sure that the buffer grows.
192 int bytesToWrite = 2049;
193 while (totalBytesWritten < largeData.length) {
mmenke 2015/03/31 18:19:32 This loop should mirror testPostWithContentLength'
xunjieli 2015/04/01 17:04:09 Done.
194 if (bytesToWrite > largeData.length - totalBytesWritten) {
195 // Do not write out of bound.
196 bytesToWrite = largeData.length - totalBytesWritten;
197 }
198 out.write(largeData, totalBytesWritten, bytesToWrite);
199 totalBytesWritten += bytesToWrite;
200 bytesToWrite *= 2;
201 }
202 assertEquals(200, connection.getResponseCode());
203 assertEquals("OK", connection.getResponseMessage());
204 checkLargeData(getResponseAsString(connection));
205 connection.disconnect();
206 }
207
208 @SmallTest
209 @Feature({"Cronet"})
210 @CompareDefaultWithCronet
211 public void testPostWithoutContentLengthOneMassiveWrite() throws Exception {
212 URL url = new URL(NativeTestServer.getEchoBodyURL());
213 HttpURLConnection connection =
214 (HttpURLConnection) url.openConnection();
215 connection.setDoOutput(true);
216 connection.setRequestMethod("POST");
217 OutputStream out = connection.getOutputStream();
218 byte[] largeData = getLargeData();
219 out.write(largeData);
220 assertEquals(200, connection.getResponseCode());
221 assertEquals("OK", connection.getResponseMessage());
222 checkLargeData(getResponseAsString(connection));
223 connection.disconnect();
224 }
225
226 @SmallTest
227 @Feature({"Cronet"})
228 @CompareDefaultWithCronet
229 public void testPostWithoutContentLengthWriteOneByte() throws Exception {
230 URL url = new URL(NativeTestServer.getEchoBodyURL());
231 HttpURLConnection connection =
232 (HttpURLConnection) url.openConnection();
233 connection.setDoOutput(true);
234 connection.setRequestMethod("POST");
235 OutputStream out = connection.getOutputStream();
236 byte[] largeData = getLargeData();
237 for (int i = 0; i < largeData.length; i++) {
238 out.write(largeData[i]);
239 }
240 assertEquals(200, connection.getResponseCode());
241 assertEquals("OK", connection.getResponseMessage());
242 checkLargeData(getResponseAsString(connection));
243 connection.disconnect();
244 }
245
246 /**
247 * Tests write after connect. Strangely, the default implementation allows
248 * writing after being connected, so this test only runs against Cronet's
249 * implementation.
250 */
251 @SmallTest
252 @Feature({"Cronet"})
253 @OnlyRunCronetHttpURLConnection
254 public void testWriteAfterConnect() throws Exception {
255 URL url = new URL(NativeTestServer.getEchoBodyURL());
256 HttpURLConnection connection =
257 (HttpURLConnection) url.openConnection();
258 connection.setDoOutput(true);
259 connection.setRequestMethod("POST");
260 OutputStream out = connection.getOutputStream();
261 out.write(UPLOAD_DATA);
262 connection.connect();
263 try {
264 // Attemp to write some more.
265 out.write(UPLOAD_DATA);
266 fail();
267 } catch (IllegalStateException e) {
268 assertEquals("Cannot write after being connected.", e.getMessage());
269 }
270 }
271
272 /**
273 * Tests that if caller writes more than the content length provided,
274 * an exception should occur.
275 */
276 @SmallTest
277 @Feature({"Cronet"})
278 @CompareDefaultWithCronet
279 public void testWriteBufferOutOfBound() throws Exception {
280 URL url = new URL(NativeTestServer.getEchoBodyURL());
281 HttpURLConnection connection =
282 (HttpURLConnection) url.openConnection();
283 connection.setDoOutput(true);
284 connection.setRequestMethod("POST");
285 // Use a content length that is 1 byte shorter than actual data.
286 connection.setRequestProperty("Content-Length",
287 Integer.toString(UPLOAD_DATA.length - 1));
288 OutputStream out = connection.getOutputStream();
289 // Write a few bytes first.
290 out.write(UPLOAD_DATA, 0, 3);
291 try {
292 // Write remaining bytes.
293 out.write(UPLOAD_DATA, 3, UPLOAD_DATA.length - 3);
294 fail();
295 } catch (java.net.ProtocolException e) {
296 assertEquals("exceeded content-length limit of "
297 + (UPLOAD_DATA.length - 1) + " bytes", e.getMessage());
298 }
299 }
300
301 /**
302 * Same as {@code testWriteBufferOutOfBound()}, but it only writes one byte
303 * at a time.
304 */
305 @SmallTest
306 @Feature({"Cronet"})
307 @CompareDefaultWithCronet
308 public void testWriteBufferOutOfBoundWriteOneByte() throws Exception {
309 URL url = new URL(NativeTestServer.getEchoBodyURL());
310 HttpURLConnection connection =
311 (HttpURLConnection) url.openConnection();
312 connection.setDoOutput(true);
313 connection.setRequestMethod("POST");
314 // Use a content length that is 1 byte shorter than actual data.
315 connection.setRequestProperty("Content-Length",
316 Integer.toString(UPLOAD_DATA.length - 1));
317 OutputStream out = connection.getOutputStream();
318 try {
319 for (int i = 0; i < UPLOAD_DATA.length; i++) {
320 out.write(UPLOAD_DATA[i]);
321 }
322 fail();
323 } catch (java.net.ProtocolException e) {
324 assertEquals("exceeded content-length limit of "
325 + (UPLOAD_DATA.length - 1) + " bytes", e.getMessage());
326 }
327 }
328
329 /**
330 * Tests that {@link CronetBufferedOutputStream} supports rewind in a
331 * POST preserving redirect.
332 * Use {@code OnlyRunCronetHttpURLConnection} as the default implementation
333 * does not pass this test.
334 */
335 @SmallTest
336 @Feature({"Cronet"})
337 @OnlyRunCronetHttpURLConnection
338 public void testRewind() throws Exception {
339 URL url = new URL(NativeTestServer.getRedirectToEchoBody());
340 HttpURLConnection connection =
341 (HttpURLConnection) url.openConnection();
342 connection.setDoOutput(true);
343 connection.setRequestMethod("POST");
344 connection.setRequestProperty("Content-Length",
345 Integer.toString(UPLOAD_DATA.length));
346 OutputStream out = connection.getOutputStream();
347 out.write(UPLOAD_DATA);
348 assertEquals(UPLOAD_DATA_STRING, getResponseAsString(connection));
349 connection.disconnect();
350 }
351
352 /**
353 * Like {@link #testRewind} but does not set Content-Length header.
354 */
355 @SmallTest
356 @Feature({"Cronet"})
357 @OnlyRunCronetHttpURLConnection
358 public void testRewindWithoutContentLength() throws Exception {
359 URL url = new URL(NativeTestServer.getRedirectToEchoBody());
360 HttpURLConnection connection =
361 (HttpURLConnection) url.openConnection();
362 connection.setDoOutput(true);
363 connection.setRequestMethod("POST");
364 OutputStream out = connection.getOutputStream();
365 out.write(UPLOAD_DATA);
366 assertEquals(UPLOAD_DATA_STRING, getResponseAsString(connection));
367 connection.disconnect();
368 }
369
370 /**
371 * Helper method to extract response body as a string for testing.
372 */
373 private String getResponseAsString(HttpURLConnection connection)
374 throws Exception {
375 InputStream in = connection.getInputStream();
376 ByteArrayOutputStream out = new ByteArrayOutputStream();
377 int b;
378 while ((b = in.read()) != -1) {
379 out.write(b);
380 }
381 return out.toString();
382 }
383
384 /**
385 * Produces a byte array that contains {@code REPEAT_COUNT} of
386 * {@code UPLOAD_DATA_STRING}.
387 */
388 private byte[] getLargeData() {
389 byte[] largeData = new byte[REPEAT_COUNT * UPLOAD_DATA.length];
390 for (int i = 0; i < REPEAT_COUNT; i++) {
391 for (int j = 0; j < UPLOAD_DATA.length; j++) {
392 largeData[i * UPLOAD_DATA.length + j] = UPLOAD_DATA[j];
393 }
394 }
395 return largeData;
396 }
397
398 /**
399 * Helper function to check whether {@code data} is a concatenation of
400 * {@code REPEAT_COUNT} {@code UPLOAD_DATA_STRING} strings.
401 */
402 private void checkLargeData(String data) {
403 for (int i = 0; i < REPEAT_COUNT; i++) {
404 assertEquals(UPLOAD_DATA_STRING, data.substring(
405 UPLOAD_DATA_STRING.length() * i,
406 UPLOAD_DATA_STRING.length() * (i + 1)));
407 }
408 }
409 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698