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

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

Issue 1412243012: Initial implementation of CronetBidirectionalStream. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Little cleanup. Created 5 years 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 2015 The Chromium Authors. All rights reserved. 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 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.os.ConditionVariable;
7 import android.test.suitebuilder.annotation.SmallTest; 8 import android.test.suitebuilder.annotation.SmallTest;
8 9
9 import org.chromium.base.test.util.Feature; 10 import org.chromium.base.test.util.Feature;
11 import org.chromium.net.TestBidirectionalStreamCallback.FailureType;
12 import org.chromium.net.TestBidirectionalStreamCallback.ResponseStep;
10 13
11 import java.nio.ByteBuffer; 14 import java.nio.ByteBuffer;
12 import java.util.concurrent.Executor; 15 import java.util.ArrayList;
13 import java.util.concurrent.ExecutorService; 16 import java.util.List;
14 import java.util.concurrent.Executors; 17 import java.util.regex.Matcher;
15 import java.util.concurrent.ThreadFactory; 18 import java.util.regex.Pattern;
16
17 /** 19 /**
18 * Test functionality of BidirectionalStream interface. 20 * Test functionality of BidirectionalStream interface.
19 */ 21 */
20 public class BidirectionalStreamTest extends CronetTestBase { 22 public class BidirectionalStreamTest extends CronetTestBase {
23 // Empty array of CERTS chages MockCertVerifier default to net::OK.
24 private static final String[] CERTS_USED = {};
21 private CronetTestFramework mTestFramework; 25 private CronetTestFramework mTestFramework;
26 // URL used for base tests.
27 private static final String TEST_URL = "https://127.0.0.1:8443";
22 28
23 @Override 29 @Override
24 protected void setUp() throws Exception { 30 protected void setUp() throws Exception {
25 super.setUp(); 31 super.setUp();
26 mTestFramework = startCronetTestFramework(); 32 // Load library first to create MockCertVerifier.
33 System.loadLibrary("cronet_tests");
34
35 CronetEngine.Builder builder = new CronetEngine.Builder(getContext());
36
37 builder.setMockCertVerifierForTesting(MockCertVerifier.createMockCertVer ifier(CERTS_USED));
38 mTestFramework = startCronetTestFrameworkWithUrlAndCronetEngineBuilder(n ull, builder);
27 assertTrue(NativeTestServer.startNativeTestServer(getContext())); 39 assertTrue(NativeTestServer.startNativeTestServer(getContext()));
28 // Add url interceptors after native application context is initialized. 40 // Add url interceptors after native application context is initialized.
29 MockUrlRequestJobFactory.setUp(); 41 MockUrlRequestJobFactory.setUp();
30 } 42 }
31 43
32 @Override 44 @Override
33 protected void tearDown() throws Exception { 45 protected void tearDown() throws Exception {
34 NativeTestServer.shutdownNativeTestServer(); 46 NativeTestServer.shutdownNativeTestServer();
35 mTestFramework.mCronetEngine.shutdown(); 47 mTestFramework.mCronetEngine.shutdown();
36 super.tearDown(); 48 super.tearDown();
37 } 49 }
38 50
39 private class TestBidirectionalStreamCallback extends BidirectionalStream.Ca llback { 51 static class TestHttp2Server {
40 // Executor Service for Cronet callbacks. 52 static String getBaseUrl() {
41 private final ExecutorService mExecutorService = 53 return "https://localhost:8443/";
42 Executors.newSingleThreadExecutor(new ExecutorThreadFactory());
43 private Thread mExecutorThread;
44
45 private class ExecutorThreadFactory implements ThreadFactory {
46 public Thread newThread(Runnable r) {
47 mExecutorThread = new Thread(r);
48 return mExecutorThread;
49 }
50 } 54 }
51 55
52 @Override 56 static String getEchoAllHeadersUrl() {
53 public void onRequestHeadersSent(BidirectionalStream stream) {} 57 return getBaseUrl() + "echoallheaders";
58 }
54 59
55 @Override 60 static String getEchoHeaderUrl(String headerName) {
56 public void onResponseHeadersReceived(BidirectionalStream stream, UrlRes ponseInfo info) {} 61 return getBaseUrl() + "echoheader?" + headerName;
62 }
57 63
58 @Override 64 static String getEchoMethodUrl() {
59 public void onReadCompleted( 65 return getBaseUrl() + "echomethod";
60 BidirectionalStream stream, UrlResponseInfo info, ByteBuffer buf fer) {} 66 }
61 67
62 @Override 68 static String getEchoStreamUrl() {
63 public void onWriteCompleted( 69 return getBaseUrl() + "echostream";
64 BidirectionalStream stream, UrlResponseInfo info, ByteBuffer buf fer) {} 70 }
65 71
66 @Override 72 static String getEchoTrailersUrl() {
67 public void onResponseTrailersReceived(BidirectionalStream stream, UrlRe sponseInfo info, 73 return getBaseUrl() + "echotrailers";
68 UrlResponseInfo.HeaderBlock trailers) {}
69
70 @Override
71 public void onSucceeded(BidirectionalStream stream, UrlResponseInfo info ) {}
72
73 @Override
74 public void onFailed(
75 BidirectionalStream stream, UrlResponseInfo info, CronetExceptio n error) {}
76
77 @Override
78 public void onCanceled(BidirectionalStream stream, UrlResponseInfo info) {}
79
80 Executor getExecutor() {
81 return mExecutorService;
82 } 74 }
83 } 75 }
84 76
77 private TestBidirectionalStreamCallback startAndWaitForComplete(String url) throws Exception {
78 TestBidirectionalStreamCallback callback = new TestBidirectionalStreamCa llback();
79
80 // Create stream.
81 BidirectionalStream stream =
82 new BidirectionalStream.Builder(url, callback, callback.getExecu tor(),
83 mTestFramework.mCronetEngine)
84 .setHttpMethod("GET")
85 .build();
86 stream.start();
87 callback.blockForDone();
88 assertTrue(stream.isDone());
89 return callback;
90 }
91
92 private void checkResponseInfo(UrlResponseInfo responseInfo, String expected Url,
93 int expectedHttpStatusCode, String expectedHttpStatusText) {
94 assertEquals(expectedUrl, responseInfo.getUrl());
95 assertEquals(
96 expectedUrl, responseInfo.getUrlChain().get(responseInfo.getUrlC hain().size() - 1));
97 assertEquals(expectedHttpStatusCode, responseInfo.getHttpStatusCode());
98 assertEquals(expectedHttpStatusText, responseInfo.getHttpStatusText());
99 assertFalse(responseInfo.wasCached());
100 assertTrue(responseInfo.toString().length() > 0);
101 }
102
103 private static String makeLongString(String base, int repetition) {
104 StringBuilder builder = new StringBuilder(base.length() * repetition);
105 for (int i = 0; i < repetition; ++i) {
106 builder.append(i);
107 builder.append(base);
108 }
109 return builder.toString();
110 }
111
85 @SmallTest 112 @SmallTest
86 @Feature({"Cronet"}) 113 @Feature({"Cronet"})
87 public void testBuilderChecks() throws Exception { 114 public void testBuilderChecks() throws Exception {
88 TestBidirectionalStreamCallback callback = new TestBidirectionalStreamCa llback(); 115 TestBidirectionalStreamCallback callback = new TestBidirectionalStreamCa llback();
89 try { 116 try {
90 new BidirectionalStream.Builder( 117 new BidirectionalStream.Builder(
91 null, callback, callback.getExecutor(), mTestFramework.mCron etEngine); 118 null, callback, callback.getExecutor(), mTestFramework.mCron etEngine);
92 fail("URL not null-checked"); 119 fail("URL not null-checked");
93 } catch (NullPointerException e) { 120 } catch (NullPointerException e) {
94 assertEquals("URL is required.", e.getMessage()); 121 assertEquals("URL is required.", e.getMessage());
(...skipping 16 matching lines...) Expand all
111 new BidirectionalStream.Builder( 138 new BidirectionalStream.Builder(
112 NativeTestServer.getRedirectURL(), callback, callback.getExe cutor(), null); 139 NativeTestServer.getRedirectURL(), callback, callback.getExe cutor(), null);
113 fail("CronetEngine not null-checked"); 140 fail("CronetEngine not null-checked");
114 } catch (NullPointerException e) { 141 } catch (NullPointerException e) {
115 assertEquals("CronetEngine is required.", e.getMessage()); 142 assertEquals("CronetEngine is required.", e.getMessage());
116 } 143 }
117 // Verify successful creation doesn't throw. 144 // Verify successful creation doesn't throw.
118 new BidirectionalStream.Builder(NativeTestServer.getRedirectURL(), callb ack, 145 new BidirectionalStream.Builder(NativeTestServer.getRedirectURL(), callb ack,
119 callback.getExecutor(), mTestFramework.mCronetEngine); 146 callback.getExecutor(), mTestFramework.mCronetEngine);
120 } 147 }
148
149 @SmallTest
150 @Feature({"Cronet"})
151 public void testFailPlainHttp() throws Exception {
152 String url = NativeTestServer.getEchoMethodURL();
153 TestBidirectionalStreamCallback callback = startAndWaitForComplete(url);
154 assertEquals("Exception in BidirectionalStream: net::ERR_DISALLOWED_URL_ SCHEME",
155 callback.mError.getMessage());
156 }
157
158 @SmallTest
159 @Feature({"Cronet"})
160 public void testSimpleGet() throws Exception {
161 String url = TestHttp2Server.getEchoMethodUrl();
162 TestBidirectionalStreamCallback callback = startAndWaitForComplete(url);
163 assertEquals(200, callback.mResponseInfo.getHttpStatusCode());
164 // Default method is 'GET'.
165 assertEquals("GET", callback.mResponseAsString);
166 assertEquals(String.format("UrlResponseInfo[%s]: urlChain = [%s], httpSt atus = 200 , "
167 + "headers = [:status=200], wasCached = fal se, "
168 + "negotiatedProtocol = h2, proxyServer= nu ll, "
169 + "receivedBytesCount = 0",
170 url, url),
171 callback.mResponseInfo.toString());
172 checkResponseInfo(callback.mResponseInfo, TestHttp2Server.getEchoMethodU rl(), 200, "");
173 }
174
175 @SmallTest
176 @Feature({"Cronet"})
177 public void testSimplePost() throws Exception {
178 String url = TestHttp2Server.getBaseUrl();
179 mTestFramework.startNetLog();
180
181 TestBidirectionalStreamCallback callback = new TestBidirectionalStreamCa llback();
182 callback.addWriteData("Test String".getBytes());
183 callback.addWriteData("1234567890".getBytes());
184 callback.addWriteData("woot!".getBytes());
185
186 // Create stream.
187 BidirectionalStream stream =
188 new BidirectionalStream.Builder(url, callback, callback.getExecu tor(),
189 mTestFramework.mCronetEngine)
190 .addHeader("foo", "bar")
191 .addHeader("Content-Type", "zebra")
192 .build();
193 stream.start();
194 callback.blockForDone();
195 assertTrue(stream.isDone());
196
197 mTestFramework.stopNetLog();
198
199 assertEquals(200, callback.mResponseInfo.getHttpStatusCode());
200 assertEquals("woot!", callback.mResponseAsString);
201 }
202
203 @SmallTest
204 @Feature({"Cronet"})
205 public void testSetHttpMethod() throws Exception {
206 TestBidirectionalStreamCallback callback = new TestBidirectionalStreamCa llback();
207 callback.addWriteData("Put This Data!".getBytes());
208
209 String methodName = "PUT";
210 BidirectionalStream.Builder builder = new BidirectionalStream.Builder(
211 TEST_URL, callback, callback.getExecutor(), mTestFramework.mCron etEngine);
212 // Try to set 'null' method.
213 try {
214 builder.setHttpMethod(null);
215 fail("Exception not thrown");
216 } catch (NullPointerException e) {
217 assertEquals("Method is required.", e.getMessage());
218 }
219
220 builder.setHttpMethod(methodName);
221 builder.build().start();
222 callback.blockForDone();
223 assertEquals(200, callback.mResponseInfo.getHttpStatusCode());
224 assertEquals("Put This Data!", callback.mResponseAsString);
225 }
226
227 @SmallTest
228 @Feature({"Cronet"})
229 public void testBadMethod() throws Exception {
230 TestBidirectionalStreamCallback callback = new TestBidirectionalStreamCa llback();
231 BidirectionalStream.Builder builder = new BidirectionalStream.Builder(
232 TEST_URL, callback, callback.getExecutor(), mTestFramework.mCron etEngine);
233 try {
234 builder.setHttpMethod("bad:method!");
235 builder.build().start();
236 fail("IllegalArgumentException not thrown.");
237 } catch (IllegalArgumentException e) {
238 assertEquals("Invalid http method bad:method!", e.getMessage());
239 }
240 }
241
242 @SmallTest
243 @Feature({"Cronet"})
244 public void testBadHeaderName() throws Exception {
245 TestBidirectionalStreamCallback callback = new TestBidirectionalStreamCa llback();
246 BidirectionalStream.Builder builder = new BidirectionalStream.Builder(
247 TEST_URL, callback, callback.getExecutor(), mTestFramework.mCron etEngine);
248 try {
249 builder.addHeader("header:name", "headervalue");
250 builder.build().start();
251 fail("IllegalArgumentException not thrown.");
252 } catch (IllegalArgumentException e) {
253 assertEquals("Invalid header header:name=headervalue", e.getMessage( ));
254 }
255 }
256
257 @SmallTest
258 @Feature({"Cronet"})
259 public void testBadHeaderValue() throws Exception {
260 TestBidirectionalStreamCallback callback = new TestBidirectionalStreamCa llback();
261 BidirectionalStream.Builder builder = new BidirectionalStream.Builder(
262 TEST_URL, callback, callback.getExecutor(), mTestFramework.mCron etEngine);
263 try {
264 builder.addHeader("headername", "bad header\r\nvalue");
265 builder.build().start();
266 fail("IllegalArgumentException not thrown.");
267 } catch (IllegalArgumentException e) {
268 assertEquals("Invalid header headername=bad header\r\nvalue", e.getM essage());
269 }
270 }
271
272 @SmallTest
273 @Feature({"Cronet"})
274 public void testAddHeader() throws Exception {
275 TestBidirectionalStreamCallback callback = new TestBidirectionalStreamCa llback();
276 String headerName = "header-name";
277 String headerValue = "header-value";
278 BidirectionalStream.Builder builder =
279 new BidirectionalStream.Builder(TestHttp2Server.getEchoHeaderUrl (headerName),
280 callback, callback.getExecutor(), mTestFramework.mCronet Engine);
281
282 builder.addHeader(headerName, headerValue);
283 builder.setHttpMethod("GET");
284 builder.build().start();
285 callback.blockForDone();
286 assertEquals(200, callback.mResponseInfo.getHttpStatusCode());
287 assertEquals(headerValue, callback.mResponseAsString);
288 }
289
290 @SmallTest
291 @Feature({"Cronet"})
292 public void testMultiRequestHeaders() throws Exception {
293 TestBidirectionalStreamCallback callback = new TestBidirectionalStreamCa llback();
294 String headerName = "header-name";
295 String headerValue1 = "header-value1";
296 String headerValue2 = "header-value2";
297 BidirectionalStream.Builder builder =
298 new BidirectionalStream.Builder(TestHttp2Server.getEchoAllHeader sUrl(), callback,
299 callback.getExecutor(), mTestFramework.mCronetEngine);
300 builder.addHeader(headerName, headerValue1);
301 builder.addHeader(headerName, headerValue2);
302 builder.setHttpMethod("GET");
303 builder.build().start();
304 callback.blockForDone();
305 assertEquals(200, callback.mResponseInfo.getHttpStatusCode());
306 String headers = callback.mResponseAsString;
307 Pattern pattern = Pattern.compile(headerName + ":\\s(.*)\\r\\n");
308 Matcher matcher = pattern.matcher(headers);
309 List<String> actualValues = new ArrayList<String>();
310 while (matcher.find()) {
311 actualValues.add(matcher.group(1));
312 }
313 assertEquals(1, actualValues.size());
314 assertEquals("header-value2", actualValues.get(0));
315 }
316
317 @SmallTest
318 @Feature({"Cronet"})
319 public void testEchoTrailers() throws Exception {
320 mTestFramework.startNetLog();
321
322 TestBidirectionalStreamCallback callback = new TestBidirectionalStreamCa llback();
323 String headerName = "header-name";
324 String headerValue = "header-value";
325 BidirectionalStream.Builder builder =
326 new BidirectionalStream.Builder(TestHttp2Server.getEchoTrailersU rl(), callback,
327 callback.getExecutor(), mTestFramework.mCronetEngine);
328 builder.addHeader(headerName, headerValue);
329 builder.setHttpMethod("GET");
330 builder.build().start();
331 callback.blockForDone();
332 mTestFramework.stopNetLog();
333
334 assertEquals(200, callback.mResponseInfo.getHttpStatusCode());
335 assertNotNull(callback.mTrailers);
336 assertEquals(headerValue, callback.mTrailers.getAsMap().get(headerName). get(0));
337 }
338
339 @SmallTest
340 @Feature({"Cronet"})
341 public void testCustomUserAgent() throws Exception {
342 TestBidirectionalStreamCallback callback = new TestBidirectionalStreamCa llback();
343 String userAgentName = "User-Agent";
344 String userAgentValue = "User-Agent-Value";
345 BidirectionalStream.Builder builder =
346 new BidirectionalStream.Builder(TestHttp2Server.getEchoHeaderUrl (userAgentName),
347 callback, callback.getExecutor(), mTestFramework.mCronet Engine);
348 builder.setHttpMethod("GET");
349 builder.addHeader(userAgentName, userAgentValue);
350 builder.build().start();
351 callback.blockForDone();
352 assertEquals(200, callback.mResponseInfo.getHttpStatusCode());
353 assertEquals(userAgentValue, callback.mResponseAsString);
354 }
355
356 @SmallTest
357 @Feature({"Cronet"})
358 public void testEchoStream() throws Exception {
359 String url = TestHttp2Server.getEchoStreamUrl();
360 mTestFramework.startNetLog();
361
362 TestBidirectionalStreamCallback callback = new TestBidirectionalStreamCa llback();
363 String[] testData = {"Test String", makeLongString("1234567890", 50000), "woot!"};
364 StringBuilder stringData = new StringBuilder();
365 for (String writeData : testData) {
366 callback.addWriteData(writeData.getBytes());
367 stringData.append(writeData);
368 }
369
370 // Create stream.
371 BidirectionalStream stream =
372 new BidirectionalStream.Builder(url, callback, callback.getExecu tor(),
373 mTestFramework.mCronetEngine)
374 .addHeader("foo", "Value with Spaces")
375 .addHeader("Content-Type", "zebra")
376 .build();
377 stream.start();
378 callback.blockForDone();
379 assertTrue(stream.isDone());
380
381 mTestFramework.stopNetLog();
382
383 assertEquals(200, callback.mResponseInfo.getHttpStatusCode());
384 assertEquals(stringData.toString(), callback.mResponseAsString);
385 assertEquals("Value with Spaces", callback.mResponseInfo.getAllHeaders() .get("foo").get(0));
386 assertEquals("zebra", callback.mResponseInfo.getAllHeaders().get("Conten t-Type").get(0));
387 }
388
389 /**
390 * Checks that the buffer is updated correctly, when starting at an offset.
391 */
392 @SmallTest
393 @Feature({"Cronet"})
394 public void testSimpleGetBufferUpdates() throws Exception {
395 TestBidirectionalStreamCallback callback = new TestBidirectionalStreamCa llback();
396 callback.setAutoAdvance(false);
397 // Since themethod is "GET", the expected response body is also "GET".
398 BidirectionalStream.Builder builder =
399 new BidirectionalStream.Builder(TestHttp2Server.getEchoMethodUrl (), callback,
400 callback.getExecutor(), mTestFramework.mCronetEngine);
401 BidirectionalStream stream = builder.setHttpMethod("GET").build();
402 stream.start();
403 callback.waitForNextReadStep();
404
405 assertEquals(null, callback.mError);
406 assertFalse(callback.isDone());
407 assertEquals(TestBidirectionalStreamCallback.ResponseStep.ON_RESPONSE_ST ARTED,
408 callback.mResponseStep);
409
410 ByteBuffer readBuffer = ByteBuffer.allocateDirect(5);
411 readBuffer.put("FOR".getBytes());
412 assertEquals(3, readBuffer.position());
413
414 // Read first two characters of the response ("GE"). It's theoretically
415 // possible to need one read per character, though in practice,
416 // shouldn't happen.
417 while (callback.mResponseAsString.length() < 2) {
418 assertFalse(callback.isDone());
419 callback.startNextRead(stream, readBuffer);
420 callback.waitForNextReadStep();
421 }
422
423 // Make sure the two characters were read.
424 assertEquals("GE", callback.mResponseAsString);
425
426 // Check the contents of the entire buffer. The first 3 characters
427 // should not have been changed, and the last two should be the first
428 // two characters from the response.
429 assertEquals("FORGE", bufferContentsToString(readBuffer, 0, 5));
430 // The limit and position should be 5.
431 assertEquals(5, readBuffer.limit());
432 assertEquals(5, readBuffer.position());
433
434 assertEquals(ResponseStep.ON_READ_COMPLETED, callback.mResponseStep);
435
436 // Start reading from position 3. Since the only remaining character
437 // from the response is a "T", when the read completes, the buffer
438 // should contain "FORTE", with a position() of 4 and a limit() of 5.
439 readBuffer.position(3);
440 callback.startNextRead(stream, readBuffer);
441 callback.waitForNextReadStep();
442
443 // Make sure all three characters of the response have now been read.
444 assertEquals("GET", callback.mResponseAsString);
445
446 // Check the entire contents of the buffer. Only the third character
447 // should have been modified.
448 assertEquals("FORTE", bufferContentsToString(readBuffer, 0, 5));
449
450 // Make sure position and limit were updated correctly.
451 assertEquals(4, readBuffer.position());
452 assertEquals(5, readBuffer.limit());
453
454 assertEquals(ResponseStep.ON_READ_COMPLETED, callback.mResponseStep);
455
456 // One more read attempt. The request should complete.
457 readBuffer.position(1);
458 readBuffer.limit(5);
459 callback.startNextRead(stream, readBuffer);
460 callback.waitForNextReadStep();
461
462 assertEquals(200, callback.mResponseInfo.getHttpStatusCode());
463 assertEquals("GET", callback.mResponseAsString);
464 checkResponseInfo(callback.mResponseInfo, TestHttp2Server.getEchoMethodU rl(), 200, "");
465
466 // Check that buffer contents were not modified.
467 assertEquals("FORTE", bufferContentsToString(readBuffer, 0, 5));
468
469 // Position should not have been modified, since nothing was read.
470 assertEquals(1, readBuffer.position());
471 // Limit should be unchanged as always.
472 assertEquals(5, readBuffer.limit());
473
474 assertEquals(ResponseStep.ON_SUCCEEDED, callback.mResponseStep);
475
476 // Make sure there are no other pending messages, which would trigger
477 // asserts in TestBidirectionalCallback.
478 testSimpleGet();
479 }
480
481 @SmallTest
482 @Feature({"Cronet"})
483 public void testBadBuffers() throws Exception {
484 TestBidirectionalStreamCallback callback = new TestBidirectionalStreamCa llback();
485 callback.setAutoAdvance(false);
486 BidirectionalStream.Builder builder =
487 new BidirectionalStream.Builder(TestHttp2Server.getEchoMethodUrl (), callback,
488 callback.getExecutor(), mTestFramework.mCronetEngine);
489 BidirectionalStream stream = builder.setHttpMethod("GET").build();
490 stream.start();
491 callback.waitForNextReadStep();
492
493 assertEquals(null, callback.mError);
494 assertFalse(callback.isDone());
495 assertEquals(TestBidirectionalStreamCallback.ResponseStep.ON_RESPONSE_ST ARTED,
496 callback.mResponseStep);
497
498 // Try to read using a full buffer.
499 try {
500 ByteBuffer readBuffer = ByteBuffer.allocateDirect(4);
501 readBuffer.put("full".getBytes());
502 stream.read(readBuffer);
503 fail("Exception not thrown");
504 } catch (IllegalArgumentException e) {
505 assertEquals("ByteBuffer is already full.", e.getMessage());
506 }
507
508 // Try to read using a non-direct buffer.
509 try {
510 ByteBuffer readBuffer = ByteBuffer.allocate(5);
511 stream.read(readBuffer);
512 fail("Exception not thrown");
513 } catch (Exception e) {
514 assertEquals("byteBuffer must be a direct ByteBuffer.", e.getMessage ());
515 }
516
517 // Finish the stream with a direct ByteBuffer.
518 callback.setAutoAdvance(true);
519 ByteBuffer readBuffer = ByteBuffer.allocateDirect(5);
520 stream.read(readBuffer);
521 callback.blockForDone();
522 assertEquals(200, callback.mResponseInfo.getHttpStatusCode());
523 assertEquals("GET", callback.mResponseAsString);
524 }
525
526 private void throwOrCancel(FailureType failureType, ResponseStep failureStep ,
527 boolean expectResponseInfo, boolean expectError) {
528 TestBidirectionalStreamCallback callback = new TestBidirectionalStreamCa llback();
529 callback.setFailure(failureType, failureStep);
530 BidirectionalStream.Builder builder =
531 new BidirectionalStream.Builder(TestHttp2Server.getEchoMethodUrl (), callback,
532 callback.getExecutor(), mTestFramework.mCronetEngine);
533 BidirectionalStream stream = builder.setHttpMethod("GET").build();
534 stream.start();
535 callback.blockForDone();
536 assertEquals(callback.mResponseStep, failureStep);
537 assertTrue(stream.isDone());
538 assertEquals(expectResponseInfo, callback.mResponseInfo != null);
539 assertEquals(expectError, callback.mError != null);
540 assertEquals(expectError, callback.mOnErrorCalled);
541 assertEquals(failureType == FailureType.CANCEL_SYNC
542 || failureType == FailureType.CANCEL_ASYNC
543 || failureType == FailureType.CANCEL_ASYNC_WITHOUT_PAUSE ,
544 callback.mOnCanceledCalled);
545 }
546
547 @SmallTest
548 @Feature({"Cronet"})
549 public void testFailures() throws Exception {
550 throwOrCancel(FailureType.CANCEL_SYNC, ResponseStep.ON_REQUEST_HEADERS_S ENT, false, false);
551 throwOrCancel(FailureType.CANCEL_ASYNC, ResponseStep.ON_REQUEST_HEADERS_ SENT, false, false);
552 throwOrCancel(FailureType.CANCEL_ASYNC_WITHOUT_PAUSE, ResponseStep.ON_RE QUEST_HEADERS_SENT,
553 false, false);
554 throwOrCancel(FailureType.THROW_SYNC, ResponseStep.ON_REQUEST_HEADERS_SE NT, false, true);
555
556 throwOrCancel(FailureType.CANCEL_SYNC, ResponseStep.ON_RESPONSE_STARTED, true, false);
557 throwOrCancel(FailureType.CANCEL_ASYNC, ResponseStep.ON_RESPONSE_STARTED , true, false);
558 throwOrCancel(FailureType.CANCEL_ASYNC_WITHOUT_PAUSE, ResponseStep.ON_RE SPONSE_STARTED,
559 true, false);
560 throwOrCancel(FailureType.THROW_SYNC, ResponseStep.ON_RESPONSE_STARTED, true, true);
561
562 throwOrCancel(FailureType.CANCEL_SYNC, ResponseStep.ON_READ_COMPLETED, t rue, false);
563 throwOrCancel(FailureType.CANCEL_ASYNC, ResponseStep.ON_READ_COMPLETED, true, false);
564 throwOrCancel(FailureType.CANCEL_ASYNC_WITHOUT_PAUSE, ResponseStep.ON_RE AD_COMPLETED, true,
565 false);
566 throwOrCancel(FailureType.THROW_SYNC, ResponseStep.ON_READ_COMPLETED, tr ue, true);
567 }
568
569 @SmallTest
570 @Feature({"Cronet"})
571 public void testThrowOnSucceeded() {
572 TestBidirectionalStreamCallback callback = new TestBidirectionalStreamCa llback();
573 callback.setFailure(FailureType.THROW_SYNC, ResponseStep.ON_SUCCEEDED);
574 BidirectionalStream.Builder builder =
575 new BidirectionalStream.Builder(TestHttp2Server.getEchoMethodUrl (), callback,
576 callback.getExecutor(), mTestFramework.mCronetEngine);
577 BidirectionalStream stream = builder.setHttpMethod("GET").build();
578 stream.start();
579 callback.blockForDone();
580 assertEquals(callback.mResponseStep, ResponseStep.ON_SUCCEEDED);
581 assertTrue(stream.isDone());
582 assertNotNull(callback.mResponseInfo);
583 assertNull(callback.mError);
584 assertFalse(callback.mOnErrorCalled);
585 }
586
587 @SmallTest
588 @Feature({"Cronet"})
589 public void testExecutorShutdown() {
590 TestBidirectionalStreamCallback callback = new TestBidirectionalStreamCa llback();
591
592 callback.setAutoAdvance(false);
593 BidirectionalStream.Builder builder =
594 new BidirectionalStream.Builder(TestHttp2Server.getEchoMethodUrl (), callback,
595 callback.getExecutor(), mTestFramework.mCronetEngine);
596 CronetBidirectionalStream stream =
597 (CronetBidirectionalStream) builder.setHttpMethod("GET").build() ;
598 stream.start();
599 callback.waitForNextReadStep();
600 assertFalse(callback.isDone());
601 assertFalse(stream.isDone());
602
603 final ConditionVariable requestDestroyed = new ConditionVariable(false);
604 stream.setOnDestroyedCallbackForTests(new Runnable() {
605 @Override
606 public void run() {
607 requestDestroyed.open();
608 }
609 });
610
611 // Shutdown the executor, so posting the task will throw an exception.
612 callback.shutdownExecutor();
613 ByteBuffer readBuffer = ByteBuffer.allocateDirect(5);
614 stream.read(readBuffer);
615 // Callback will never be called again because executor is shutdown,
616 // but stream will be destroyed from network thread.
617 requestDestroyed.block();
618
619 assertFalse(callback.isDone());
620 assertTrue(stream.isDone());
621 }
622
623 // Returns the contents of byteBuffer, from its position() to its limit(),
624 // as a String. Does not modify byteBuffer's position().
625 private String bufferContentsToString(ByteBuffer byteBuffer, int start, int end) {
626 // Use a duplicate to avoid modifying byteBuffer.
627 ByteBuffer duplicate = byteBuffer.duplicate();
628 duplicate.position(start);
629 duplicate.limit(end);
630 byte[] contents = new byte[duplicate.remaining()];
631 duplicate.get(contents);
632 return new String(contents);
633 }
121 } 634 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698