1 // Copyright 2016 The Chromium Authors 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 static com.google.common.truth.Truth.assertThat; 8 9 import androidx.test.ext.junit.runners.AndroidJUnit4; 10 import androidx.test.filters.SmallTest; 11 12 import org.json.JSONObject; 13 import org.junit.After; 14 import org.junit.Before; 15 import org.junit.Rule; 16 import org.junit.Test; 17 import org.junit.runner.RunWith; 18 19 import org.chromium.base.test.util.Batch; 20 import org.chromium.net.CronetEngine; 21 import org.chromium.net.CronetTestRule; 22 import org.chromium.net.CronetTestRule.CronetImplementation; 23 import org.chromium.net.CronetTestRule.IgnoreFor; 24 import org.chromium.net.CronetTestUtil; 25 import org.chromium.net.QuicTestServer; 26 27 import java.io.OutputStream; 28 import java.net.HttpURLConnection; 29 import java.net.URL; 30 import java.util.Arrays; 31 32 /** Tests HttpURLConnection upload using QUIC. */ 33 @Batch(Batch.UNIT_TESTS) 34 @RunWith(AndroidJUnit4.class) 35 @IgnoreFor( 36 implementations = {CronetImplementation.FALLBACK, CronetImplementation.AOSP_PLATFORM}, 37 reason = 38 "The fallback implementation doesn't support QUIC. " 39 + "crbug.com/1494870: Enable for AOSP_PLATFORM once fixed") 40 public class QuicUploadTest { 41 @Rule public final CronetTestRule mTestRule = CronetTestRule.withManualEngineStartup(); 42 43 private CronetEngine mCronetEngine; 44 45 @Before setUp()46 public void setUp() throws Exception { 47 QuicTestServer.startQuicTestServer(mTestRule.getTestFramework().getContext()); 48 49 mTestRule 50 .getTestFramework() 51 .applyEngineBuilderPatch( 52 (builder) -> { 53 builder.enableQuic(true); 54 JSONObject hostResolverParams = 55 CronetTestUtil.generateHostResolverRules(); 56 JSONObject experimentalOptions = 57 new JSONObject().put("HostResolverRules", hostResolverParams); 58 builder.setExperimentalOptions(experimentalOptions.toString()); 59 60 builder.addQuicHint( 61 QuicTestServer.getServerHost(), 62 QuicTestServer.getServerPort(), 63 QuicTestServer.getServerPort()); 64 65 CronetTestUtil.setMockCertVerifierForTesting( 66 builder, QuicTestServer.createMockCertVerifier()); 67 }); 68 69 mCronetEngine = mTestRule.getTestFramework().startEngine(); 70 } 71 72 @After tearDown()73 public void tearDown() throws Exception { 74 QuicTestServer.shutdownQuicTestServer(); 75 } 76 77 @Test 78 @SmallTest 79 // Regression testing for crbug.com/618872. testOneMassiveWrite()80 public void testOneMassiveWrite() throws Exception { 81 String path = "/simple.txt"; 82 URL url = new URL(QuicTestServer.getServerURL() + path); 83 HttpURLConnection connection = (HttpURLConnection) mCronetEngine.openConnection(url); 84 connection.setDoOutput(true); 85 connection.setRequestMethod("POST"); 86 // Size is chosen so the last time mBuffer will be written 14831 bytes, 87 // which is larger than the internal QUIC read buffer size of 14520. 88 byte[] largeData = new byte[195055]; 89 Arrays.fill(largeData, "a".getBytes("UTF-8")[0]); 90 connection.setFixedLengthStreamingMode(largeData.length); 91 OutputStream out = connection.getOutputStream(); 92 // Write everything at one go, so the data is larger than the buffer 93 // used in CronetFixedModeOutputStream. 94 out.write(largeData); 95 assertThat(connection.getResponseCode()).isEqualTo(200); 96 connection.disconnect(); 97 } 98 } 99