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 #include "net/nqe/network_quality_estimator.h" | 5 #include "net/nqe/network_quality_estimator.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <limits> | 10 #include <limits> |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 effective_connection_type_(EFFECTIVE_CONNECTION_TYPE_UNKNOWN), | 70 effective_connection_type_(EFFECTIVE_CONNECTION_TYPE_UNKNOWN), |
71 recent_effective_connection_type_set_(false), | 71 recent_effective_connection_type_set_(false), |
72 recent_effective_connection_type_(EFFECTIVE_CONNECTION_TYPE_UNKNOWN), | 72 recent_effective_connection_type_(EFFECTIVE_CONNECTION_TYPE_UNKNOWN), |
73 current_network_type_(NetworkChangeNotifier::CONNECTION_UNKNOWN), | 73 current_network_type_(NetworkChangeNotifier::CONNECTION_UNKNOWN), |
74 accuracy_recording_intervals_set_(false), | 74 accuracy_recording_intervals_set_(false), |
75 http_rtt_set_(false), | 75 http_rtt_set_(false), |
76 recent_http_rtt_set_(false), | 76 recent_http_rtt_set_(false), |
77 transport_rtt_set_(false), | 77 transport_rtt_set_(false), |
78 recent_transport_rtt_set_(false), | 78 recent_transport_rtt_set_(false), |
79 downlink_throughput_kbps_set_(false), | 79 downlink_throughput_kbps_set_(false), |
80 recent_downlink_throughput_kbps_set_(false) { | 80 recent_downlink_throughput_kbps_set_(false), |
| 81 rand_double_(0.0) { |
81 // Set up embedded test server. | 82 // Set up embedded test server. |
82 embedded_test_server_.ServeFilesFromDirectory( | 83 embedded_test_server_.ServeFilesFromDirectory( |
83 base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); | 84 base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); |
84 EXPECT_TRUE(embedded_test_server_.Start()); | 85 EXPECT_TRUE(embedded_test_server_.Start()); |
85 embedded_test_server_.RegisterRequestHandler(base::Bind( | 86 embedded_test_server_.RegisterRequestHandler(base::Bind( |
86 &TestNetworkQualityEstimator::HandleRequest, base::Unretained(this))); | 87 &TestNetworkQualityEstimator::HandleRequest, base::Unretained(this))); |
87 } | 88 } |
88 | 89 |
89 explicit TestNetworkQualityEstimator( | 90 explicit TestNetworkQualityEstimator( |
90 const std::map<std::string, std::string>& variation_params) | 91 const std::map<std::string, std::string>& variation_params) |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
256 } | 257 } |
257 | 258 |
258 const std::vector<base::TimeDelta>& GetAccuracyRecordingIntervals() | 259 const std::vector<base::TimeDelta>& GetAccuracyRecordingIntervals() |
259 const override { | 260 const override { |
260 if (accuracy_recording_intervals_set_) | 261 if (accuracy_recording_intervals_set_) |
261 return accuracy_recording_intervals_; | 262 return accuracy_recording_intervals_; |
262 | 263 |
263 return NetworkQualityEstimator::GetAccuracyRecordingIntervals(); | 264 return NetworkQualityEstimator::GetAccuracyRecordingIntervals(); |
264 } | 265 } |
265 | 266 |
| 267 void set_rand_double(double rand_double) { rand_double_ = rand_double; } |
| 268 |
| 269 double RandDouble() const override { return rand_double_; } |
| 270 |
266 using NetworkQualityEstimator::SetTickClockForTesting; | 271 using NetworkQualityEstimator::SetTickClockForTesting; |
267 using NetworkQualityEstimator::ReadCachedNetworkQualityEstimate; | 272 using NetworkQualityEstimator::ReadCachedNetworkQualityEstimate; |
268 using NetworkQualityEstimator::OnConnectionTypeChanged; | 273 using NetworkQualityEstimator::OnConnectionTypeChanged; |
269 | 274 |
270 private: | 275 private: |
271 // NetworkQualityEstimator implementation that returns the overridden | 276 // NetworkQualityEstimator implementation that returns the overridden |
272 // network | 277 // network |
273 // id (instead of invoking platform APIs). | 278 // id (instead of invoking platform APIs). |
274 NetworkQualityEstimator::NetworkID GetCurrentNetworkID() const override { | 279 NetworkQualityEstimator::NetworkID GetCurrentNetworkID() const override { |
275 return NetworkQualityEstimator::NetworkID(current_network_type_, | 280 return NetworkQualityEstimator::NetworkID(current_network_type_, |
(...skipping 23 matching lines...) Expand all Loading... |
299 | 304 |
300 bool recent_transport_rtt_set_; | 305 bool recent_transport_rtt_set_; |
301 base::TimeDelta recent_transport_rtt_; | 306 base::TimeDelta recent_transport_rtt_; |
302 | 307 |
303 bool downlink_throughput_kbps_set_; | 308 bool downlink_throughput_kbps_set_; |
304 int32_t downlink_throughput_kbps_; | 309 int32_t downlink_throughput_kbps_; |
305 | 310 |
306 bool recent_downlink_throughput_kbps_set_; | 311 bool recent_downlink_throughput_kbps_set_; |
307 int32_t recent_downlink_throughput_kbps_; | 312 int32_t recent_downlink_throughput_kbps_; |
308 | 313 |
| 314 double rand_double_; |
| 315 |
309 // Embedded server used for testing. | 316 // Embedded server used for testing. |
310 EmbeddedTestServer embedded_test_server_; | 317 EmbeddedTestServer embedded_test_server_; |
311 | 318 |
312 DISALLOW_COPY_AND_ASSIGN(TestNetworkQualityEstimator); | 319 DISALLOW_COPY_AND_ASSIGN(TestNetworkQualityEstimator); |
313 }; | 320 }; |
314 | 321 |
315 class TestEffectiveConnectionTypeObserver | 322 class TestEffectiveConnectionTypeObserver |
316 : public NetworkQualityEstimator::EffectiveConnectionTypeObserver { | 323 : public NetworkQualityEstimator::EffectiveConnectionTypeObserver { |
317 public: | 324 public: |
318 std::vector<NetworkQualityEstimator::EffectiveConnectionType>& | 325 std::vector<NetworkQualityEstimator::EffectiveConnectionType>& |
(...skipping 1658 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1977 histogram_tester.ExpectBucketCount("NQE.NetworkIdAvailable", 1, 2); | 1984 histogram_tester.ExpectBucketCount("NQE.NetworkIdAvailable", 1, 2); |
1978 histogram_tester.ExpectTotalCount("NQE.NetworkIdAvailable", 3); | 1985 histogram_tester.ExpectTotalCount("NQE.NetworkIdAvailable", 3); |
1979 | 1986 |
1980 // The NetworkID is recorded as being available on a cellular connection. | 1987 // The NetworkID is recorded as being available on a cellular connection. |
1981 estimator.SimulateNetworkChangeTo( | 1988 estimator.SimulateNetworkChangeTo( |
1982 NetworkChangeNotifier::ConnectionType::CONNECTION_2G, "test-1"); | 1989 NetworkChangeNotifier::ConnectionType::CONNECTION_2G, "test-1"); |
1983 histogram_tester.ExpectBucketCount("NQE.NetworkIdAvailable", 1, 3); | 1990 histogram_tester.ExpectBucketCount("NQE.NetworkIdAvailable", 1, 3); |
1984 histogram_tester.ExpectTotalCount("NQE.NetworkIdAvailable", 4); | 1991 histogram_tester.ExpectTotalCount("NQE.NetworkIdAvailable", 4); |
1985 } | 1992 } |
1986 | 1993 |
| 1994 // Tests that the correlation histogram is recorded correctly based on |
| 1995 // correlation logging probability set in the variation params. |
| 1996 TEST(NetworkQualityEstimatorTest, CorrelationHistogram) { |
| 1997 // Match the values set in network_quality_estimator.cc. |
| 1998 static const int32_t kTrimBits = 5; |
| 1999 static const int32_t kBitsPerMetric = 7; |
| 2000 |
| 2001 const struct { |
| 2002 bool use_transport_rtt; |
| 2003 double rand_double; |
| 2004 double correlation_logging_probability; |
| 2005 base::TimeDelta transport_rtt; |
| 2006 int32_t expected_transport_rtt_milliseconds; |
| 2007 base::TimeDelta http_rtt; |
| 2008 int32_t expected_http_rtt_milliseconds; |
| 2009 int32_t downstream_throughput_kbps; |
| 2010 int32_t expected_downstream_throughput_kbps; |
| 2011 |
| 2012 } tests[] = { |
| 2013 { |
| 2014 // Verify that the metric is not recorded if the logging probability |
| 2015 // is set to 0.0. |
| 2016 false, 0.5, 0.0, base::TimeDelta::FromSeconds(1), 1000 >> kTrimBits, |
| 2017 base::TimeDelta::FromSeconds(2), 2000 >> kTrimBits, 3000, |
| 2018 3000 >> kTrimBits, |
| 2019 }, |
| 2020 { |
| 2021 // Verify that the metric is not recorded if the logging probability |
| 2022 // is lower than the value returned by the random number generator. |
| 2023 false, 0.3, 0.1, base::TimeDelta::FromSeconds(1), 1000 >> kTrimBits, |
| 2024 base::TimeDelta::FromSeconds(2), 2000 >> kTrimBits, 3000, |
| 2025 3000 >> kTrimBits, |
| 2026 }, |
| 2027 { |
| 2028 // Verify that the metric is recorded if the logging probability is |
| 2029 // higher than the value returned by the random number generator. |
| 2030 false, 0.3, 0.4, base::TimeDelta::FromSeconds(1), 1000 >> kTrimBits, |
| 2031 base::TimeDelta::FromSeconds(2), 2000 >> kTrimBits, 3000, |
| 2032 3000 >> kTrimBits, |
| 2033 }, |
| 2034 { |
| 2035 // Verify that the metric is recorded if the logging probability is |
| 2036 // set to 1.0. |
| 2037 false, 0.5, 1.0, base::TimeDelta::FromSeconds(1), 1000 >> kTrimBits, |
| 2038 base::TimeDelta::FromSeconds(2), 2000 >> kTrimBits, 3000, |
| 2039 3000 >> kTrimBits, |
| 2040 }, |
| 2041 { |
| 2042 // Verify that the metric is recorded if the logging probability is |
| 2043 // set to 1.0. |
| 2044 true, 0.5, 1.0, base::TimeDelta::FromSeconds(1), 1000 >> kTrimBits, |
| 2045 base::TimeDelta::FromSeconds(2), 2000 >> kTrimBits, 3000, |
| 2046 3000 >> kTrimBits, |
| 2047 }, |
| 2048 { |
| 2049 // Verify that if the metric is larger than |
| 2050 // 2^(kBitsPerMetric + kTrimBits), it is rounded down to |
| 2051 // (2^(kBitsPerMetric + kTrimBits) - 1) >> kTrimBits. |
| 2052 false, 0.5, 1.0, base::TimeDelta::FromSeconds(10), 4095 >> kTrimBits, |
| 2053 base::TimeDelta::FromSeconds(20), 4095 >> kTrimBits, 30000, |
| 2054 4095 >> kTrimBits, |
| 2055 }, |
| 2056 }; |
| 2057 |
| 2058 for (const auto& test : tests) { |
| 2059 base::HistogramTester histogram_tester; |
| 2060 |
| 2061 std::map<std::string, std::string> variation_params; |
| 2062 variation_params["correlation_logging_probability"] = |
| 2063 base::DoubleToString(test.correlation_logging_probability); |
| 2064 if (test.use_transport_rtt) { |
| 2065 variation_params["effective_connection_type_algorithm"] = |
| 2066 "TransportRTTOrDownstreamThroughput"; |
| 2067 } |
| 2068 TestNetworkQualityEstimator estimator(variation_params); |
| 2069 |
| 2070 estimator.set_transport_rtt(test.transport_rtt); |
| 2071 estimator.set_recent_transport_rtt(test.transport_rtt); |
| 2072 estimator.set_http_rtt(test.http_rtt); |
| 2073 estimator.set_recent_http_rtt(test.http_rtt); |
| 2074 estimator.set_downlink_throughput_kbps(test.downstream_throughput_kbps); |
| 2075 estimator.set_rand_double(test.rand_double); |
| 2076 |
| 2077 TestDelegate test_delegate; |
| 2078 TestURLRequestContext context(true); |
| 2079 context.set_network_quality_estimator(&estimator); |
| 2080 context.Init(); |
| 2081 |
| 2082 // Start a main-frame request that should cause network quality estimator to |
| 2083 // record the network quality at the last main frame request. |
| 2084 std::unique_ptr<URLRequest> request_1(context.CreateRequest( |
| 2085 estimator.GetEchoURL(), DEFAULT_PRIORITY, &test_delegate)); |
| 2086 request_1->SetLoadFlags(request_1->load_flags() | LOAD_MAIN_FRAME); |
| 2087 request_1->Start(); |
| 2088 base::RunLoop().Run(); |
| 2089 histogram_tester.ExpectTotalCount( |
| 2090 "NQE.Correlation.ResourceLoadTime.0Kb_128Kb", 0); |
| 2091 |
| 2092 // Start another main-frame request which should cause network quality |
| 2093 // estimator to record the correlation UMA. |
| 2094 std::unique_ptr<URLRequest> request_2(context.CreateRequest( |
| 2095 estimator.GetEchoURL(), DEFAULT_PRIORITY, &test_delegate)); |
| 2096 request_2->Start(); |
| 2097 base::RunLoop().Run(); |
| 2098 |
| 2099 if (test.rand_double >= test.correlation_logging_probability) { |
| 2100 histogram_tester.ExpectTotalCount( |
| 2101 "NQE.Correlation.ResourceLoadTime.0Kb_128Kb", 0); |
| 2102 continue; |
| 2103 } |
| 2104 histogram_tester.ExpectTotalCount( |
| 2105 "NQE.Correlation.ResourceLoadTime.0Kb_128Kb", 1); |
| 2106 std::vector<base::Bucket> buckets = histogram_tester.GetAllSamples( |
| 2107 "NQE.Correlation.ResourceLoadTime.0Kb_128Kb"); |
| 2108 // Get the bits at index 0-10 which contain the RTT. |
| 2109 // 128 is 2^kBitsPerMetric. |
| 2110 if (test.use_transport_rtt) { |
| 2111 EXPECT_EQ(test.expected_transport_rtt_milliseconds, |
| 2112 buckets.at(0).min >> kBitsPerMetric >> kBitsPerMetric >> |
| 2113 kBitsPerMetric); |
| 2114 } else { |
| 2115 EXPECT_EQ(test.expected_http_rtt_milliseconds, |
| 2116 buckets.at(0).min >> kBitsPerMetric >> kBitsPerMetric >> |
| 2117 kBitsPerMetric); |
| 2118 } |
| 2119 |
| 2120 // Get the bits at index 11-17 which contain the downstream throughput. |
| 2121 EXPECT_EQ(test.expected_downstream_throughput_kbps, |
| 2122 (buckets.at(0).min >> kBitsPerMetric >> kBitsPerMetric) % 128); |
| 2123 |
| 2124 // Get the bits at index 18-24 which contain the resource fetch time. |
| 2125 EXPECT_LE(0, (buckets.at(0).min >> kBitsPerMetric) % 128); |
| 2126 |
| 2127 // Get the bits at index 25-31 which contain the resource load size. |
| 2128 EXPECT_LE(0, (buckets.at(0).min) % 128); |
| 2129 } |
| 2130 } |
| 2131 |
1987 } // namespace net | 2132 } // namespace net |
OLD | NEW |