OLD | NEW |
---|---|
(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 import org.chromium.net.UploadDataSink; | |
15 import org.chromium.net.UrlRequestContext; | |
16 | |
17 import java.io.ByteArrayOutputStream; | |
18 import java.io.InputStream; | |
19 import java.io.OutputStream; | |
20 import java.net.HttpURLConnection; | |
21 import java.net.URL; | |
22 import java.nio.ByteBuffer; | |
23 import java.util.Arrays; | |
24 | |
25 /** | |
26 * Tests the CronetBufferedOutputStream implementation. | |
27 */ | |
28 public class CronetBufferedOutputStreamTest extends CronetTestBase { | |
29 private static final String UPLOAD_DATA_STRING = "Nifty upload data!"; | |
30 private static final byte[] UPLOAD_DATA = UPLOAD_DATA_STRING.getBytes(); | |
31 private static final int REPEAT_COUNT = 100000; | |
32 private CronetTestActivity mActivity; | |
33 private UrlRequestContext mUrlRequestContext; | |
34 | |
35 @Override | |
36 protected void setUp() throws Exception { | |
37 super.setUp(); | |
38 mActivity = launchCronetTestApp(); | |
39 mUrlRequestContext = mActivity.mUrlRequestContext; | |
40 assertTrue(NativeTestServer.startNativeTestServer( | |
41 getInstrumentation().getTargetContext())); | |
42 } | |
43 | |
44 @Override | |
45 protected void tearDown() throws Exception { | |
46 NativeTestServer.shutdownNativeTestServer(); | |
47 super.tearDown(); | |
48 } | |
49 | |
50 @SmallTest | |
51 @Feature({"Cronet"}) | |
52 @CompareDefaultWithCronet | |
53 public void testPostAfterConnectionMade() throws Exception { | |
54 URL url = new URL(NativeTestServer.getEchoBodyURL()); | |
55 HttpURLConnection connection = | |
56 (HttpURLConnection) url.openConnection(); | |
57 connection.setDoOutput(true); | |
58 connection.setRequestMethod("POST"); | |
59 assertEquals(200, connection.getResponseCode()); | |
60 try { | |
61 connection.getOutputStream(); | |
62 fail(); | |
63 } catch (java.net.ProtocolException e) { | |
64 // Expected. | |
65 } | |
66 } | |
67 | |
68 @SmallTest | |
69 @Feature({"Cronet"}) | |
70 @CompareDefaultWithCronet | |
71 public void testPostWithContentLength() throws Exception { | |
72 URL url = new URL(NativeTestServer.getEchoBodyURL()); | |
73 HttpURLConnection connection = | |
74 (HttpURLConnection) url.openConnection(); | |
75 connection.setDoOutput(true); | |
76 connection.setRequestMethod("POST"); | |
77 connection.setRequestProperty("Content-Length", | |
78 Integer.toString(UPLOAD_DATA.length * REPEAT_COUNT)); | |
79 byte[] largeData = new byte[REPEAT_COUNT * UPLOAD_DATA.length]; | |
80 for (int i = 0; i < REPEAT_COUNT; i++) { | |
81 for (int j = 0; j < UPLOAD_DATA.length; j++) { | |
82 largeData[i * UPLOAD_DATA.length + j] = UPLOAD_DATA[j]; | |
83 } | |
84 } | |
85 OutputStream out = connection.getOutputStream(); | |
86 int totalBytesWritten = 0; | |
87 // Number of bytes to write each time. It is incremented by one from 0. | |
88 int bytesToWrite = 0; | |
89 while (totalBytesWritten < largeData.length) { | |
90 if (bytesToWrite > largeData.length - totalBytesWritten) { | |
91 // Do not write out of bound. | |
92 bytesToWrite = largeData.length - totalBytesWritten; | |
93 } | |
94 out.write(largeData, totalBytesWritten, bytesToWrite); | |
95 totalBytesWritten += bytesToWrite; | |
96 bytesToWrite++; | |
97 } | |
98 assertEquals(200, connection.getResponseCode()); | |
99 assertEquals("OK", connection.getResponseMessage()); | |
100 checkLargeData(getResponseAsString(connection)); | |
101 connection.disconnect(); | |
102 } | |
103 | |
104 @SmallTest | |
105 @Feature({"Cronet"}) | |
106 @CompareDefaultWithCronet | |
107 public void testPostWithContentLengthWriteOneByte() throws Exception { | |
108 URL url = new URL(NativeTestServer.getEchoBodyURL()); | |
109 HttpURLConnection connection = | |
110 (HttpURLConnection) url.openConnection(); | |
111 connection.setDoOutput(true); | |
112 connection.setRequestMethod("POST"); | |
113 connection.setRequestProperty("Content-Length", | |
114 Integer.toString(UPLOAD_DATA.length * REPEAT_COUNT)); | |
115 OutputStream out = connection.getOutputStream(); | |
116 for (int i = 0; i < REPEAT_COUNT; i++) { | |
117 for (int j = 0; j < UPLOAD_DATA.length; j++) { | |
118 // Write one byte at a time. | |
119 out.write(UPLOAD_DATA[j]); | |
120 } | |
121 } | |
122 assertEquals(200, connection.getResponseCode()); | |
123 assertEquals("OK", connection.getResponseMessage()); | |
124 checkLargeData(getResponseAsString(connection)); | |
125 connection.disconnect(); | |
126 } | |
127 | |
128 @SmallTest | |
129 @Feature({"Cronet"}) | |
130 @CompareDefaultWithCronet | |
131 public void testPostWithZeroContentLength() throws Exception { | |
mmenke
2015/03/25 18:34:57
Maybe a zero length upload without a content lengt
xunjieli
2015/03/27 17:46:45
Done.
| |
132 URL url = new URL(NativeTestServer.getEchoBodyURL()); | |
133 HttpURLConnection connection = | |
134 (HttpURLConnection) url.openConnection(); | |
135 connection.setDoOutput(true); | |
136 connection.setRequestMethod("POST"); | |
137 connection.setRequestProperty("Content-Length", "0"); | |
138 assertEquals(200, connection.getResponseCode()); | |
139 assertEquals("OK", connection.getResponseMessage()); | |
140 assertEquals("", getResponseAsString(connection)); | |
141 connection.disconnect(); | |
142 } | |
143 | |
144 @SmallTest | |
145 @Feature({"Cronet"}) | |
146 @CompareDefaultWithCronet | |
147 public void testPostWithoutContentLength() throws Exception { | |
148 URL url = new URL(NativeTestServer.getEchoBodyURL()); | |
149 HttpURLConnection connection = | |
150 (HttpURLConnection) url.openConnection(); | |
151 connection.setDoOutput(true); | |
152 connection.setRequestMethod("POST"); | |
153 OutputStream out = connection.getOutputStream(); | |
154 for (int i = 0; i < REPEAT_COUNT; i++) { | |
155 out.write(UPLOAD_DATA); | |
156 } | |
157 assertEquals(200, connection.getResponseCode()); | |
158 assertEquals("OK", connection.getResponseMessage()); | |
159 checkLargeData(getResponseAsString(connection)); | |
160 connection.disconnect(); | |
161 } | |
162 | |
163 /** | |
164 * Tests that if caller writes more than the content length provided, | |
165 * an exception should occur. | |
166 */ | |
167 @SmallTest | |
168 @Feature({"Cronet"}) | |
169 @CompareDefaultWithCronet | |
170 public void testWriteBufferOutOfBound() throws Exception { | |
171 URL url = new URL(NativeTestServer.getEchoBodyURL()); | |
172 HttpURLConnection connection = | |
173 (HttpURLConnection) url.openConnection(); | |
174 connection.setDoOutput(true); | |
175 connection.setRequestMethod("POST"); | |
176 // Use a content length that is 1 byte shorter than actual data. | |
177 connection.setRequestProperty("Content-Length", | |
178 Integer.toString(UPLOAD_DATA.length - 1)); | |
179 OutputStream out = connection.getOutputStream(); | |
180 try { | |
181 out.write(UPLOAD_DATA); | |
mmenke
2015/03/25 18:34:57
Suggest a test like this that does two writes.
xunjieli
2015/03/27 17:46:45
Done.
| |
182 fail(); | |
183 } catch (java.net.ProtocolException e) { | |
184 assertEquals("exceeded content-length limit of " | |
185 + (UPLOAD_DATA.length - 1) + " bytes", e.getMessage()); | |
186 } | |
187 } | |
188 | |
189 /** | |
190 * Same as {@code testWriteBufferOutOfBound()}, but it only writes one byte | |
191 * at a time. | |
192 */ | |
193 @SmallTest | |
194 @Feature({"Cronet"}) | |
195 @CompareDefaultWithCronet | |
196 public void testWriteBufferOutOfBoundWriteOneByte() throws Exception { | |
197 URL url = new URL(NativeTestServer.getEchoBodyURL()); | |
198 HttpURLConnection connection = | |
199 (HttpURLConnection) url.openConnection(); | |
200 connection.setDoOutput(true); | |
201 connection.setRequestMethod("POST"); | |
202 // Use a content length that is 1 byte shorter than actual data. | |
203 connection.setRequestProperty("Content-Length", | |
204 Integer.toString(UPLOAD_DATA.length - 1)); | |
205 OutputStream out = connection.getOutputStream(); | |
206 try { | |
207 for (int i = 0; i < UPLOAD_DATA.length; i++) { | |
208 out.write(UPLOAD_DATA[i]); | |
209 } | |
210 fail(); | |
211 } catch (java.net.ProtocolException e) { | |
212 assertEquals("exceeded content-length limit of " | |
213 + (UPLOAD_DATA.length - 1) + " bytes", e.getMessage()); | |
214 } | |
215 } | |
216 | |
217 /** | |
218 * Tests that {@link CronetBufferedOutputStream} supports rewind. | |
219 */ | |
220 @SmallTest | |
221 @Feature({"Cronet"}) | |
222 @OnlyRunCronetHttpURLConnection | |
223 public void testRewind() throws Exception { | |
224 URL url = new URL(NativeTestServer.getEchoBodyURL()); | |
225 CronetHttpURLConnection conn = new CronetHttpURLConnection(url, | |
226 mUrlRequestContext); | |
227 CronetBufferedOutputStream out = | |
228 new CronetBufferedOutputStream(conn, UPLOAD_DATA.length); | |
229 out.write(UPLOAD_DATA); | |
230 TestUploadDataSink sink = new TestUploadDataSink(); | |
231 out.rewind(sink); | |
232 assertTrue(sink.mRewindSucceededCalled); | |
233 ByteBuffer byteBuffer = ByteBuffer.allocate(UPLOAD_DATA.length); | |
234 out.read(sink, byteBuffer); | |
235 assertTrue(sink.mReadSucceededCalled); | |
236 assertTrue(Arrays.equals(UPLOAD_DATA, byteBuffer.array())); | |
mmenke
2015/03/25 18:34:57
Rather than doing all this manually, can we just u
xunjieli
2015/03/27 17:46:45
Done. Good idea! But the default implementation re
| |
237 } | |
238 | |
239 private static class TestUploadDataSink implements UploadDataSink { | |
240 boolean mReadSucceededCalled = false; | |
241 boolean mRewindSucceededCalled = false; | |
242 | |
243 @Override | |
244 public void onReadSucceeded(boolean finalChunk) { | |
245 mReadSucceededCalled = true; | |
246 } | |
247 | |
248 @Override | |
249 public void onReadError(Exception exception) { | |
250 // Left blank. | |
251 } | |
252 | |
253 @Override | |
254 public void onRewindSucceeded() { | |
255 mRewindSucceededCalled = true; | |
256 } | |
257 | |
258 @Override | |
259 public void onRewindError(Exception e) { | |
260 // Left blank. | |
261 } | |
262 } | |
263 | |
264 /** | |
265 * Helper method to extract response body as a string for testing. | |
266 */ | |
267 private String getResponseAsString(HttpURLConnection connection) | |
268 throws Exception { | |
269 InputStream in = connection.getInputStream(); | |
270 ByteArrayOutputStream out = new ByteArrayOutputStream(); | |
271 int b; | |
272 while ((b = in.read()) != -1) { | |
273 out.write(b); | |
274 } | |
275 return out.toString(); | |
276 } | |
277 | |
278 /** | |
279 * Helper function to check whether {@code data} is a concatenation of | |
280 * {@code REPEAT_COUNT} {@code UPLOAD_DATA_STRING} strings. | |
281 */ | |
282 private void checkLargeData(String data) { | |
283 for (int i = 0; i < REPEAT_COUNT; i++) { | |
284 assertEquals(UPLOAD_DATA_STRING, data.substring( | |
285 UPLOAD_DATA_STRING.length() * i, | |
286 UPLOAD_DATA_STRING.length() * (i + 1))); | |
287 } | |
288 } | |
289 } | |
OLD | NEW |