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

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

Issue 2416473004: Add functionality for embedders to configure NQE (Closed)
Patch Set: rebased, mgersh comments Created 3 years, 5 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
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 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.StrictMode; 7 import android.os.StrictMode;
8 import android.support.test.filters.SmallTest; 8 import android.support.test.filters.SmallTest;
9 9
10 import org.json.JSONObject;
11
10 import org.chromium.base.Log; 12 import org.chromium.base.Log;
11 import org.chromium.base.annotations.JNINamespace; 13 import org.chromium.base.annotations.JNINamespace;
12 import org.chromium.base.annotations.SuppressFBWarnings; 14 import org.chromium.base.annotations.SuppressFBWarnings;
13 import org.chromium.base.test.util.DisabledTest;
14 import org.chromium.base.test.util.Feature; 15 import org.chromium.base.test.util.Feature;
15 import org.chromium.base.test.util.MetricsUtils.HistogramDelta; 16 import org.chromium.base.test.util.MetricsUtils.HistogramDelta;
16 import org.chromium.net.MetricsTestUtil.TestExecutor; 17 import org.chromium.net.MetricsTestUtil.TestExecutor;
17 import org.chromium.net.test.EmbeddedTestServer; 18 import org.chromium.net.test.EmbeddedTestServer;
18 19
19 import java.io.File; 20 import java.io.File;
20 import java.io.FileInputStream; 21 import java.io.FileInputStream;
21 import java.io.FileNotFoundException; 22 import java.io.FileNotFoundException;
22 import java.io.IOException; 23 import java.io.IOException;
23 import java.util.concurrent.Executor; 24 import java.util.concurrent.Executor;
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 UrlRequest urlRequest = builder.build(); 120 UrlRequest urlRequest = builder.build();
120 urlRequest.start(); 121 urlRequest.start();
121 callback.blockForDone(); 122 callback.blockForDone();
122 networkQualityExecutor.runAllTasks(); 123 networkQualityExecutor.runAllTasks();
123 assertEquals(0, rttListener.rttObservationCount()); 124 assertEquals(0, rttListener.rttObservationCount());
124 cronetEngine.shutdown(); 125 cronetEngine.shutdown();
125 } 126 }
126 127
127 // Returns whether a file contains a particular string. 128 // Returns whether a file contains a particular string.
128 @SuppressFBWarnings("OBL_UNSATISFIED_OBLIGATION_EXCEPTION_EDGE") 129 @SuppressFBWarnings("OBL_UNSATISFIED_OBLIGATION_EXCEPTION_EDGE")
129 private boolean fileContainsString(String filename, String content) throws I OException { 130 private boolean prefsFileContainsString(String content) throws IOException {
130 File file = new File(getTestStorage(getContext()) + "/prefs/" + filename ); 131 File file = new File(getTestStorage(getContext()) + "/prefs/local_prefs. json");
131 FileInputStream fileInputStream = new FileInputStream(file); 132 FileInputStream fileInputStream = new FileInputStream(file);
132 byte[] data = new byte[(int) file.length()]; 133 byte[] data = new byte[(int) file.length()];
133 fileInputStream.read(data); 134 fileInputStream.read(data);
134 fileInputStream.close(); 135 fileInputStream.close();
135 return new String(data, "UTF-8").contains(content); 136 return new String(data, "UTF-8").contains(content);
136 } 137 }
137 138
139 @SuppressFBWarnings("OBL_UNSATISFIED_OBLIGATION_EXCEPTION_EDGE")
140 private boolean deletePrefsFile() throws Exception {
141 File file = new File(getTestStorage(getContext()) + "/prefs/local_prefs. json");
142 if (file.exists()) {
143 return file.delete();
144 }
145 return true;
146 }
147
138 @SmallTest 148 @SmallTest
139 @Feature({"Cronet"}) 149 @Feature({"Cronet"})
140 @DisabledTest(message = "Disabled due to flaky assert. See crbug.com/710626" )
141 public void testQuicDisabled() throws Exception { 150 public void testQuicDisabled() throws Exception {
142 ExperimentalCronetEngine.Builder cronetEngineBuilder = 151 ExperimentalCronetEngine.Builder cronetEngineBuilder =
143 new ExperimentalCronetEngine.Builder(getContext()); 152 new ExperimentalCronetEngine.Builder(getContext());
144 assert RttThroughputValues.INVALID_RTT_THROUGHPUT < 0; 153 assert RttThroughputValues.INVALID_RTT_THROUGHPUT < 0;
145 Executor listenersExecutor = Executors.newSingleThreadExecutor(new Execu torThreadFactory()); 154 Executor listenersExecutor = Executors.newSingleThreadExecutor(new Execu torThreadFactory());
146 TestNetworkQualityRttListener rttListener = 155 TestNetworkQualityRttListener rttListener =
147 new TestNetworkQualityRttListener(listenersExecutor); 156 new TestNetworkQualityRttListener(listenersExecutor);
148 TestNetworkQualityThroughputListener throughputListener = 157 TestNetworkQualityThroughputListener throughputListener =
149 new TestNetworkQualityThroughputListener(listenersExecutor); 158 new TestNetworkQualityThroughputListener(listenersExecutor);
150 cronetEngineBuilder.enableNetworkQualityEstimator(true).enableHttp2(true ).enableQuic(false); 159 cronetEngineBuilder.enableNetworkQualityEstimator(true).enableHttp2(true ).enableQuic(false);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 // estimates are available. 216 // estimates are available.
208 assertTrue(cronetEngine.getHttpRttMs() >= 0); 217 assertTrue(cronetEngine.getHttpRttMs() >= 0);
209 assertTrue(cronetEngine.getTransportRttMs() >= 0); 218 assertTrue(cronetEngine.getTransportRttMs() >= 0);
210 assertTrue(cronetEngine.getDownstreamThroughputKbps() >= 0); 219 assertTrue(cronetEngine.getDownstreamThroughputKbps() >= 0);
211 220
212 // Verify that the cached estimates were written to the prefs. 221 // Verify that the cached estimates were written to the prefs.
213 while (true) { 222 while (true) {
214 Log.i(TAG, "Still waiting for pref file update....."); 223 Log.i(TAG, "Still waiting for pref file update.....");
215 Thread.sleep(12000); 224 Thread.sleep(12000);
216 try { 225 try {
217 if (fileContainsString("local_prefs.json", "network_qualities")) { 226 if (prefsFileContainsString("network_qualities")) {
218 break; 227 break;
219 } 228 }
220 } catch (FileNotFoundException e) { 229 } catch (FileNotFoundException e) {
221 // Ignored this exception since the file will only be created wh en updates are 230 // Ignored this exception since the file will only be created wh en updates are
222 // flushed to the disk. 231 // flushed to the disk.
223 } 232 }
224 } 233 }
225 assertTrue(fileContainsString("local_prefs.json", "network_qualities")); 234 assertTrue(prefsFileContainsString("network_qualities"));
226 235
227 cronetEngine.shutdown(); 236 cronetEngine.shutdown();
228 assertTrue(writeCountHistogram.getDelta() > 0); 237 assertTrue(writeCountHistogram.getDelta() > 0);
229 } 238 }
239
240 @SmallTest
241 @Feature({"Cronet"})
242 public void testPrefsWriteRead() throws Exception {
243 // Clear the prefs file when the test is ran again. See
244 // https://bugs.chromium.org/p/chromium/issues/detail?id=569589 for deta ils.
245 deletePrefsFile();
246
247 // When the loop is run for the first time, network quality is written t o the disk. The
248 // test verifies that in the next loop, the network quality is read back .
249 for (int i = 0; i <= 1; ++i) {
250 ExperimentalCronetEngine.Builder cronetEngineBuilder =
251 new ExperimentalCronetEngine.Builder(getContext());
252 assert RttThroughputValues.INVALID_RTT_THROUGHPUT < 0;
253 Executor listenersExecutor =
254 Executors.newSingleThreadExecutor(new ExecutorThreadFactory( ));
255 TestNetworkQualityRttListener rttListener =
256 new TestNetworkQualityRttListener(listenersExecutor);
257 cronetEngineBuilder.enableNetworkQualityEstimator(true).enableHttp2( true).enableQuic(
258 false);
259 cronetEngineBuilder.setStoragePath(getTestStorage(getContext()));
260
261 JSONObject nqeOptions = new JSONObject().put("persistent_cache_readi ng_enabled", true);
262 JSONObject experimentalOptions =
263 new JSONObject().put("NetworkQualityEstimator", nqeOptions);
264
265 cronetEngineBuilder.setExperimentalOptions(experimentalOptions.toStr ing());
266 final ExperimentalCronetEngine cronetEngine = cronetEngineBuilder.bu ild();
267 cronetEngine.configureNetworkQualityEstimatorForTesting(true, true, true);
268 cronetEngine.addRttListener(rttListener);
269
270 HistogramDelta writeCountHistogram = new HistogramDelta("NQE.Prefs.W riteCount", 1);
271 assertEquals(0, writeCountHistogram.getDelta()); // Sanity check.
272
273 HistogramDelta readCountHistogram = new HistogramDelta("NQE.Prefs.Re adCount", 1);
274 assertEquals(0, readCountHistogram.getDelta()); // Sanity check.
275
276 HistogramDelta readPrefsSizeHistogram = new HistogramDelta("NQE.Pref s.ReadSize", 1);
277 assertEquals(0, readPrefsSizeHistogram.getDelta()); // Sanity check.
278
279 // NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP_CACHED_ESTIMATE: 3
280 HistogramDelta cachedRttHistogram = new HistogramDelta("NQE.RTT.Obse rvationSource", 3);
281 assertEquals(0, cachedRttHistogram.getDelta()); // Sanity check.
282
283 TestUrlRequestCallback callback = new TestUrlRequestCallback();
284 UrlRequest.Builder builder =
285 cronetEngine.newUrlRequestBuilder(mUrl, callback, callback.g etExecutor());
286 UrlRequest urlRequest = builder.build();
287 urlRequest.start();
288 callback.blockForDone();
289
290 // Wait for RTT observation (at the URL request layer) to be posted.
291 rttListener.waitUntilFirstUrlRequestRTTReceived();
292
293 // Prefs must be read at startup.
294 assertTrue(readCountHistogram.getDelta() > 0);
295
296 // Check RTT observation count after throughput observation has been received. This
297 // ensures
298 // that executor has finished posting the RTT observation to the RTT listeners.
299 assertTrue(rttListener.rttObservationCount() > 0);
300
301 // Verify that effective connection type callback is received and
302 // effective connection type is correctly set.
303 assertTrue(cronetEngine.getEffectiveConnectionType()
304 != EffectiveConnectionType.TYPE_UNKNOWN);
305
306 cronetEngine.shutdown();
307
308 if (i == 0) {
309 // Verify that the cached estimates were written to the prefs.
310 while (true) {
mgersh 2017/06/29 19:02:32 What shutdown() does is destroy the native CronetU
tbansal1 2017/06/29 22:45:05 Done.
311 Log.i(TAG, "Still waiting for pref file update.....");
312 try {
313 if (prefsFileContainsString("network_qualities")) {
314 break;
315 }
316 } catch (FileNotFoundException e) {
mgersh 2017/06/29 19:02:32 This try/catch can be removed if you wait for a pr
tbansal1 2017/06/29 22:45:05 Done.
317 // Ignored this exception since the file will only be cr eated when updates
318 // are flushed to the disk.
319 }
320 Thread.sleep(2000);
mgersh 2017/06/29 19:02:32 In order to be useful, this sleep should happen be
tbansal1 2017/06/29 22:45:05 Done.
321 }
322 assertTrue(prefsFileContainsString("network_qualities"));
323 }
324
325 // Stored network quality in the pref should be read in the second i teration.
326 assertEquals(readPrefsSizeHistogram.getDelta() > 0, i > 0);
327 assertEquals(cachedRttHistogram.getDelta() > 0, i > 0);
328 }
329 }
330
331 @SmallTest
332 @Feature({"Cronet"})
333 public void testQuicDisabledWithParams() throws Exception {
334 ExperimentalCronetEngine.Builder cronetEngineBuilder =
335 new ExperimentalCronetEngine.Builder(getContext());
336 Executor listenersExecutor = Executors.newSingleThreadExecutor(new Execu torThreadFactory());
337 TestNetworkQualityRttListener rttListener =
338 new TestNetworkQualityRttListener(listenersExecutor);
339 TestNetworkQualityThroughputListener throughputListener =
340 new TestNetworkQualityThroughputListener(listenersExecutor);
341
342 // Force the effective connection type to "2G".
343 JSONObject nqeOptions = new JSONObject().put("force_effective_connection _type", "Slow-2G");
344 // Add one more extra param two times to ensure robustness.
345 nqeOptions.put("some_other_param_1", "value1");
346 nqeOptions.put("some_other_param_2", "value2");
347 JSONObject experimentalOptions =
348 new JSONObject().put("NetworkQualityEstimator", nqeOptions);
349 experimentalOptions.put("SomeOtherFieldTrialName", new JSONObject());
350
351 cronetEngineBuilder.enableNetworkQualityEstimator(true).enableHttp2(true ).enableQuic(false);
352 cronetEngineBuilder.setExperimentalOptions(experimentalOptions.toString( ));
353 final ExperimentalCronetEngine cronetEngine = cronetEngineBuilder.build( );
354 cronetEngine.configureNetworkQualityEstimatorForTesting(true, true, fals e);
355
356 cronetEngine.addRttListener(rttListener);
357 cronetEngine.addThroughputListener(throughputListener);
358
359 TestUrlRequestCallback callback = new TestUrlRequestCallback();
360 UrlRequest.Builder builder =
361 cronetEngine.newUrlRequestBuilder(mUrl, callback, callback.getEx ecutor());
362 UrlRequest urlRequest = builder.build();
363 urlRequest.start();
364 callback.blockForDone();
365
366 // Throughput observation is posted to the network quality estimator on the network thread
367 // after the UrlRequest is completed. The observations are then eventual ly posted to
368 // throughput listeners on the executor provided to network quality.
369 throughputListener.waitUntilFirstThroughputObservationReceived();
370
371 // Wait for RTT observation (at the URL request layer) to be posted.
372 rttListener.waitUntilFirstUrlRequestRTTReceived();
373
374 assertTrue(throughputListener.throughputObservationCount() > 0);
375
376 // Check RTT observation count after throughput observation has been rec eived. This ensures
377 // that executor has finished posting the RTT observation to the RTT lis teners.
378 assertTrue(rttListener.rttObservationCount() > 0);
379
380 // NETWORK_QUALITY_OBSERVATION_SOURCE_URL_REQUEST
381 assertTrue(rttListener.rttObservationCount(0) > 0);
382
383 // NETWORK_QUALITY_OBSERVATION_SOURCE_TCP
384 assertTrue(rttListener.rttObservationCount(1) > 0);
385
386 // NETWORK_QUALITY_OBSERVATION_SOURCE_QUIC
387 assertEquals(0, rttListener.rttObservationCount(2));
388
389 // Verify that the listeners were notified on the expected thread.
390 assertEquals(mNetworkQualityThread, rttListener.getThread());
391 assertEquals(mNetworkQualityThread, throughputListener.getThread());
392
393 // Verify that effective connection type callback is received and effect ive connection type
394 // is correctly set to the forced value. This also verifies that the con figuration params
395 // from Cronet embedders were correctly read by NetworkQualityEstimator.
396 assertEquals(
397 EffectiveConnectionType.TYPE_SLOW_2G, cronetEngine.getEffectiveC onnectionType());
398
399 cronetEngine.shutdown();
400 }
230 } 401 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698