OLD | NEW |
---|---|
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.LargeTest; | 8 import android.test.suitebuilder.annotation.LargeTest; |
8 import android.test.suitebuilder.annotation.SmallTest; | 9 import android.test.suitebuilder.annotation.SmallTest; |
10 import android.util.SparseIntArray; | |
9 | 11 |
10 import org.chromium.base.Log; | 12 import org.chromium.base.Log; |
11 import org.chromium.base.annotations.SuppressFBWarnings; | 13 import org.chromium.base.annotations.SuppressFBWarnings; |
12 import org.chromium.base.test.util.Feature; | 14 import org.chromium.base.test.util.Feature; |
13 import org.chromium.net.CronetTestBase.OnlyRunNativeCronet; | 15 import org.chromium.net.CronetTestBase.OnlyRunNativeCronet; |
14 import org.json.JSONObject; | 16 import org.json.JSONObject; |
15 | 17 |
16 import java.io.File; | 18 import java.io.File; |
17 import java.io.FileInputStream; | 19 import java.io.FileInputStream; |
18 import java.io.FileNotFoundException; | 20 import java.io.FileNotFoundException; |
19 import java.io.IOException; | 21 import java.io.IOException; |
20 import java.util.HashMap; | 22 import java.util.HashMap; |
23 import java.util.concurrent.Executors; | |
21 | 24 |
22 /** | 25 /** |
23 * Tests making requests using QUIC. | 26 * Tests making requests using QUIC. |
24 */ | 27 */ |
25 public class QuicTest extends CronetTestBase { | 28 public class QuicTest extends CronetTestBase { |
26 private static final String TAG = "cr.QuicTest"; | 29 private static final String TAG = "cr.QuicTest"; |
27 private CronetTestFramework mTestFramework; | 30 private CronetTestFramework mTestFramework; |
28 private CronetEngine.Builder mBuilder; | 31 private CronetEngine.Builder mBuilder; |
29 | 32 |
30 @Override | 33 @Override |
31 protected void setUp() throws Exception { | 34 protected void setUp() throws Exception { |
32 super.setUp(); | 35 super.setUp(); |
33 // Load library first, since we need the Quic test server's URL. | 36 // Load library first, since we need the Quic test server's URL. |
34 System.loadLibrary("cronet_tests"); | 37 System.loadLibrary("cronet_tests"); |
35 QuicTestServer.startQuicTestServer(getContext()); | 38 QuicTestServer.startQuicTestServer(getContext()); |
36 | 39 |
37 mBuilder = new CronetEngine.Builder(getContext()); | 40 mBuilder = new CronetEngine.Builder(getContext()); |
38 mBuilder.enableQUIC(true); | 41 mBuilder.enableQUIC(true).enableNetworkQualityEstimator( |
42 true, Executors.newSingleThreadExecutor()); | |
39 mBuilder.addQuicHint(QuicTestServer.getServerHost(), QuicTestServer.getS erverPort(), | 43 mBuilder.addQuicHint(QuicTestServer.getServerHost(), QuicTestServer.getS erverPort(), |
40 QuicTestServer.getServerPort()); | 44 QuicTestServer.getServerPort()); |
41 | 45 |
42 JSONObject quicParams = new JSONObject() | 46 JSONObject quicParams = new JSONObject() |
43 .put("connection_options", "PACE,IW10,FO O,DEADBEEF") | 47 .put("connection_options", "PACE,IW10,FO O,DEADBEEF") |
44 .put("host_whitelist", "test.example.com ") | 48 .put("host_whitelist", "test.example.com ") |
45 .put("max_server_configs_stored_in_prope rties", 2) | 49 .put("max_server_configs_stored_in_prope rties", 2) |
46 .put("delay_tcp_race", true) | 50 .put("delay_tcp_race", true) |
47 .put("max_number_of_lossy_connections", 10) | 51 .put("max_number_of_lossy_connections", 10) |
48 .put("packet_loss_threshold", 0.5) | 52 .put("packet_loss_threshold", 0.5) |
49 .put("idle_connection_timeout_seconds", 300) | 53 .put("idle_connection_timeout_seconds", 300) |
50 .put("close_sessions_on_ip_change", fals e) | 54 .put("close_sessions_on_ip_change", fals e) |
51 .put("migrate_sessions_on_network_change ", true) | 55 .put("migrate_sessions_on_network_change ", true) |
52 .put("migrate_sessions_early", true); | 56 .put("migrate_sessions_early", true); |
53 JSONObject experimentalOptions = new JSONObject().put("QUIC", quicParams ); | 57 JSONObject experimentalOptions = new JSONObject().put("QUIC", quicParams ); |
54 mBuilder.setExperimentalOptions(experimentalOptions.toString()); | 58 mBuilder.setExperimentalOptions(experimentalOptions.toString()); |
55 | 59 |
56 mBuilder.setMockCertVerifierForTesting(QuicTestServer.createMockCertVeri fier()); | 60 mBuilder.setMockCertVerifierForTesting(QuicTestServer.createMockCertVeri fier()); |
57 mBuilder.setStoragePath(CronetTestFramework.getTestStorage(getContext()) ); | 61 mBuilder.setStoragePath(CronetTestFramework.getTestStorage(getContext()) ); |
58 mBuilder.enableHttpCache(CronetEngine.Builder.HTTP_CACHE_DISK_NO_HTTP, 1 000 * 1024); | 62 mBuilder.enableHttpCache(CronetEngine.Builder.HTTP_CACHE_DISK_NO_HTTP, 1 000 * 1024); |
59 } | 63 } |
60 | 64 |
61 @Override | 65 @Override |
62 protected void tearDown() throws Exception { | 66 protected void tearDown() throws Exception { |
63 QuicTestServer.shutdownQuicTestServer(); | 67 QuicTestServer.shutdownQuicTestServer(); |
64 super.tearDown(); | 68 super.tearDown(); |
65 } | 69 } |
66 | 70 |
71 static class TestNetworkQualityListener | |
72 implements NetworkQualityRttListener, NetworkQualityThroughputListen er { | |
73 // Lock to ensure that observation counts can be updated and read by dif ferent threads. | |
74 private final Object mLock = new Object(); | |
bengr
2016/06/07 20:53:16
Consider renaming as mObservationLock
tbansal1
2016/06/07 21:37:17
Done.
| |
75 private final ConditionVariable mWaitForThroughput; | |
76 private int mThroughputObservationCount; | |
77 private SparseIntArray mRttObservationCountBySource = new SparseIntArray (); | |
78 | |
79 TestNetworkQualityListener(ConditionVariable waitForThroughput) { | |
80 mWaitForThroughput = waitForThroughput; | |
81 } | |
82 | |
83 @Override | |
84 public void onRttObservation(int rttMs, long when, int source) { | |
85 synchronized (mLock) { | |
86 mRttObservationCountBySource.put( | |
87 source, mRttObservationCountBySource.get(source) + 1); | |
88 } | |
89 } | |
90 | |
91 @Override | |
92 public void onThroughputObservation(int throughputKbps, long when, int s ource) { | |
93 synchronized (mLock) { | |
94 if (mWaitForThroughput != null) { | |
95 mWaitForThroughput.open(); | |
96 } | |
97 mThroughputObservationCount++; | |
98 } | |
99 } | |
100 | |
101 public int rttObservationCount(int source) { | |
102 synchronized (mLock) { | |
103 return mRttObservationCountBySource.get(source); | |
104 } | |
105 } | |
106 | |
107 public int throughputObservationCount() { | |
108 synchronized (mLock) { | |
109 return mThroughputObservationCount; | |
110 } | |
111 } | |
112 } | |
113 | |
67 @SmallTest | 114 @SmallTest |
68 @Feature({"Cronet"}) | 115 @Feature({"Cronet"}) |
69 @SuppressWarnings("deprecation") | 116 @SuppressWarnings("deprecation") |
70 @OnlyRunNativeCronet | 117 @OnlyRunNativeCronet |
71 public void testQuicLoadUrl_LegacyAPI() throws Exception { | 118 public void testQuicLoadUrl_LegacyAPI() throws Exception { |
72 String[] commandLineArgs = { | 119 String[] commandLineArgs = { |
73 CronetTestFramework.LIBRARY_INIT_KEY, CronetTestFramework.Librar yInitType.LEGACY}; | 120 CronetTestFramework.LIBRARY_INIT_KEY, CronetTestFramework.Librar yInitType.LEGACY}; |
74 mTestFramework = new CronetTestFramework(null, commandLineArgs, getConte xt(), mBuilder); | 121 mTestFramework = new CronetTestFramework(null, commandLineArgs, getConte xt(), mBuilder); |
75 registerHostResolver(mTestFramework, true); | 122 registerHostResolver(mTestFramework, true); |
76 String quicURL = QuicTestServer.getServerURL() + "/simple.txt"; | 123 String quicURL = QuicTestServer.getServerURL() + "/simple.txt"; |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
163 @SuppressFBWarnings("OBL_UNSATISFIED_OBLIGATION_EXCEPTION_EDGE") | 210 @SuppressFBWarnings("OBL_UNSATISFIED_OBLIGATION_EXCEPTION_EDGE") |
164 private boolean fileContainsString(String filename, String content) throws I OException { | 211 private boolean fileContainsString(String filename, String content) throws I OException { |
165 File file = | 212 File file = |
166 new File(CronetTestFramework.getTestStorage(getContext()) + "/pr efs/" + filename); | 213 new File(CronetTestFramework.getTestStorage(getContext()) + "/pr efs/" + filename); |
167 FileInputStream fileInputStream = new FileInputStream(file); | 214 FileInputStream fileInputStream = new FileInputStream(file); |
168 byte[] data = new byte[(int) file.length()]; | 215 byte[] data = new byte[(int) file.length()]; |
169 fileInputStream.read(data); | 216 fileInputStream.read(data); |
170 fileInputStream.close(); | 217 fileInputStream.close(); |
171 return new String(data, "UTF-8").contains(content); | 218 return new String(data, "UTF-8").contains(content); |
172 } | 219 } |
220 | |
221 @LargeTest | |
222 @Feature({"Cronet"}) | |
223 @OnlyRunNativeCronet | |
224 @SuppressWarnings("deprecation") | |
225 public void testRealTimeNetworkQualityObservationsWithQuic() throws Exceptio n { | |
226 mTestFramework = startCronetTestFrameworkWithUrlAndCronetEngineBuilder(n ull, mBuilder); | |
227 registerHostResolver(mTestFramework); | |
228 String quicURL = QuicTestServer.getServerURL() + "/simple.txt"; | |
bengr
2016/06/07 20:53:16
quicUrl? Shouldn't getServerURL be getServerUrl? I
tbansal1
2016/06/07 21:37:17
May be, may be not :) I am not sure about Java sty
| |
229 | |
230 ConditionVariable waitForThroughput = new ConditionVariable(); | |
231 TestNetworkQualityListener networkQualityListener = | |
232 new TestNetworkQualityListener(waitForThroughput); | |
233 mTestFramework.mCronetEngine.configureNetworkQualityEstimatorForTesting( true, true); | |
234 mTestFramework.mCronetEngine.addRttListener(networkQualityListener); | |
235 mTestFramework.mCronetEngine.addThroughputListener(networkQualityListene r); | |
236 TestUrlRequestCallback callback = new TestUrlRequestCallback(); | |
237 | |
238 // Although the native stack races QUIC and SPDY for the first request, | |
239 // since there is no http server running on the corresponding TCP port, | |
240 // QUIC will always succeed with a 200 (see | |
241 // net::HttpStreamFactoryImpl::Request::OnStreamFailed). | |
242 UrlRequest.Builder requestBuilder = new UrlRequest.Builder( | |
243 quicURL, callback, callback.getExecutor(), mTestFramework.mCrone tEngine); | |
244 requestBuilder.build().start(); | |
245 callback.blockForDone(); | |
246 | |
247 assertEquals(200, callback.mResponseInfo.getHttpStatusCode()); | |
248 String expectedContent = "This is a simple text file served by QUIC.\n"; | |
249 assertEquals(expectedContent, callback.mResponseAsString); | |
250 assertEquals("quic/1+spdy/3", callback.mResponseInfo.getNegotiatedProtoc ol()); | |
251 | |
252 // Throughput observation is posted to the network quality estimator on the network thread | |
253 // after the UrlRequest is completed. The observations are then eventual ly posted to | |
254 // throughput listeners on the executor provided to network quality. | |
255 waitForThroughput.block(); | |
256 assertTrue(networkQualityListener.throughputObservationCount() > 0); | |
257 | |
258 // Check RTT observation count after throughput observation has been rec eived. This ensures | |
259 // that executor has finished posting the RTT observation to the RTT lis teners. | |
260 // NETWORK_QUALITY_OBSERVATION_SOURCE_URL_REQUEST | |
261 assertTrue(networkQualityListener.rttObservationCount(0) > 0); | |
262 | |
263 // NETWORK_QUALITY_OBSERVATION_SOURCE_QUIC | |
264 assertTrue(networkQualityListener.rttObservationCount(2) > 0); | |
265 | |
266 mTestFramework.mCronetEngine.shutdown(); | |
267 } | |
173 } | 268 } |
OLD | NEW |