• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "net/nqe/network_quality_estimator_test_util.h"
6 
7 #include "base/files/file_path.h"
8 #include "base/run_loop.h"
9 #include "net/base/load_flags.h"
10 #include "net/log/net_log.h"
11 #include "net/log/net_log_with_source.h"
12 #include "net/log/test_net_log_util.h"
13 #include "net/nqe/network_quality_estimator_params.h"
14 #include "net/test/embedded_test_server/http_response.h"
15 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
16 #include "net/url_request/url_request.h"
17 #include "net/url_request/url_request_context.h"
18 #include "net/url_request/url_request_context_builder.h"
19 #include "net/url_request/url_request_test_util.h"
20 
21 namespace {
22 
23 const base::FilePath::CharType kTestFilePath[] =
24     FILE_PATH_LITERAL("net/data/url_request_unittest");
25 
26 }  // namespace
27 
28 namespace net {
29 
TestNetworkQualityEstimator()30 TestNetworkQualityEstimator::TestNetworkQualityEstimator()
31     : TestNetworkQualityEstimator(std::map<std::string, std::string>()) {}
32 
TestNetworkQualityEstimator(const std::map<std::string,std::string> & variation_params)33 TestNetworkQualityEstimator::TestNetworkQualityEstimator(
34     const std::map<std::string, std::string>& variation_params)
35     : TestNetworkQualityEstimator(variation_params, true, true) {}
36 
TestNetworkQualityEstimator(const std::map<std::string,std::string> & variation_params,bool allow_local_host_requests_for_tests,bool allow_smaller_responses_for_tests)37 TestNetworkQualityEstimator::TestNetworkQualityEstimator(
38     const std::map<std::string, std::string>& variation_params,
39     bool allow_local_host_requests_for_tests,
40     bool allow_smaller_responses_for_tests)
41     : TestNetworkQualityEstimator(variation_params,
42                                   allow_local_host_requests_for_tests,
43                                   allow_smaller_responses_for_tests,
44                                   false) {}
45 
TestNetworkQualityEstimator(const std::map<std::string,std::string> & variation_params,bool allow_local_host_requests_for_tests,bool allow_smaller_responses_for_tests,bool suppress_notifications_for_testing)46 TestNetworkQualityEstimator::TestNetworkQualityEstimator(
47     const std::map<std::string, std::string>& variation_params,
48     bool allow_local_host_requests_for_tests,
49     bool allow_smaller_responses_for_tests,
50     bool suppress_notifications_for_testing)
51     : NetworkQualityEstimator(
52           std::make_unique<NetworkQualityEstimatorParams>(variation_params),
53           NetLog::Get()),
54       embedded_test_server_(base::FilePath(kTestFilePath)),
55       suppress_notifications_for_testing_(suppress_notifications_for_testing) {
56   SetUseLocalHostRequestsForTesting(allow_local_host_requests_for_tests);
57   SetUseSmallResponsesForTesting(allow_smaller_responses_for_tests);
58 }
59 
TestNetworkQualityEstimator(std::unique_ptr<NetworkQualityEstimatorParams> params)60 TestNetworkQualityEstimator::TestNetworkQualityEstimator(
61     std::unique_ptr<NetworkQualityEstimatorParams> params)
62     : NetworkQualityEstimator(std::move(params), NetLog::Get()),
63       embedded_test_server_(base::FilePath(kTestFilePath)),
64       suppress_notifications_for_testing_(false) {}
65 
66 TestNetworkQualityEstimator::~TestNetworkQualityEstimator() = default;
67 
RunOneRequest()68 void TestNetworkQualityEstimator::RunOneRequest() {
69   // Set up the embedded test server.
70   if (!embedded_test_server_.Started()) {
71     EXPECT_TRUE(embedded_test_server_.Start());
72   }
73 
74   TestDelegate test_delegate;
75   auto builder = CreateTestURLRequestContextBuilder();
76   builder->set_network_quality_estimator(this);
77   auto context = builder->Build();
78   std::unique_ptr<URLRequest> request(
79       context->CreateRequest(GetEchoURL(), DEFAULT_PRIORITY, &test_delegate,
80                              TRAFFIC_ANNOTATION_FOR_TESTS));
81   request->SetLoadFlags(request->load_flags() | LOAD_MAIN_FRAME_DEPRECATED);
82   request->Start();
83   base::RunLoop().Run();
84 }
85 
SimulateNetworkChange(NetworkChangeNotifier::ConnectionType new_connection_type,const std::string & network_id)86 void TestNetworkQualityEstimator::SimulateNetworkChange(
87     NetworkChangeNotifier::ConnectionType new_connection_type,
88     const std::string& network_id) {
89   current_network_type_ = new_connection_type;
90   current_network_id_ = network_id;
91   OnConnectionTypeChanged(new_connection_type);
92 }
93 
GetEchoURL()94 const GURL TestNetworkQualityEstimator::GetEchoURL() {
95   // Set up the embedded test server.
96   if (!embedded_test_server_.Started()) {
97     EXPECT_TRUE(embedded_test_server_.Start());
98   }
99   return embedded_test_server_.GetURL("/simple.html");
100 }
101 
GetRedirectURL()102 const GURL TestNetworkQualityEstimator::GetRedirectURL() {
103   // Set up the embedded test server.
104   if (!embedded_test_server_.Started()) {
105     EXPECT_TRUE(embedded_test_server_.Start());
106   }
107   return embedded_test_server_.GetURL("/redirect302-to-https");
108 }
109 
110 EffectiveConnectionType
GetEffectiveConnectionType() const111 TestNetworkQualityEstimator::GetEffectiveConnectionType() const {
112   if (effective_connection_type_)
113     return effective_connection_type_.value();
114   return NetworkQualityEstimator::GetEffectiveConnectionType();
115 }
116 
117 EffectiveConnectionType
GetRecentEffectiveConnectionTypeUsingMetrics(base::TimeDelta * http_rtt,base::TimeDelta * transport_rtt,base::TimeDelta * end_to_end_rtt,int32_t * downstream_throughput_kbps,size_t * observations_count,size_t * end_to_end_rtt_observation_count) const118 TestNetworkQualityEstimator::GetRecentEffectiveConnectionTypeUsingMetrics(
119     base::TimeDelta* http_rtt,
120     base::TimeDelta* transport_rtt,
121     base::TimeDelta* end_to_end_rtt,
122     int32_t* downstream_throughput_kbps,
123     size_t* observations_count,
124     size_t* end_to_end_rtt_observation_count) const {
125   if (recent_effective_connection_type_) {
126     GetRecentRTT(nqe::internal::OBSERVATION_CATEGORY_HTTP, base::TimeTicks(),
127                  http_rtt, nullptr);
128     GetRecentRTT(nqe::internal::OBSERVATION_CATEGORY_TRANSPORT,
129                  base::TimeTicks(), transport_rtt, observations_count);
130     GetRecentDownlinkThroughputKbps(base::TimeTicks(),
131                                     downstream_throughput_kbps);
132     return recent_effective_connection_type_.value();
133   }
134   return NetworkQualityEstimator::GetRecentEffectiveConnectionTypeUsingMetrics(
135       http_rtt, transport_rtt, end_to_end_rtt, downstream_throughput_kbps,
136       observations_count, end_to_end_rtt_observation_count);
137 }
138 
GetRecentRTT(nqe::internal::ObservationCategory observation_category,const base::TimeTicks & start_time,base::TimeDelta * rtt,size_t * observations_count) const139 bool TestNetworkQualityEstimator::GetRecentRTT(
140     nqe::internal::ObservationCategory observation_category,
141     const base::TimeTicks& start_time,
142     base::TimeDelta* rtt,
143     size_t* observations_count) const {
144   switch (observation_category) {
145     case nqe::internal::OBSERVATION_CATEGORY_HTTP:
146 
147       if (start_time.is_null()) {
148         if (start_time_null_http_rtt_) {
149           *rtt = start_time_null_http_rtt_.value();
150           return true;
151         }
152         return NetworkQualityEstimator::GetRecentRTT(
153             observation_category, start_time, rtt, observations_count);
154       }
155       if (recent_http_rtt_) {
156         *rtt = recent_http_rtt_.value();
157         return true;
158       }
159       break;
160 
161     case nqe::internal::OBSERVATION_CATEGORY_TRANSPORT:
162       if (start_time.is_null()) {
163         if (start_time_null_transport_rtt_) {
164           *rtt = start_time_null_transport_rtt_.value();
165           if (transport_rtt_observation_count_last_ect_computation_) {
166             *observations_count =
167                 transport_rtt_observation_count_last_ect_computation_.value();
168           }
169           return true;
170         }
171         return NetworkQualityEstimator::GetRecentRTT(
172             observation_category, start_time, rtt, observations_count);
173       }
174 
175       if (recent_transport_rtt_) {
176         *rtt = recent_transport_rtt_.value();
177         return true;
178       }
179       break;
180     case nqe::internal::OBSERVATION_CATEGORY_END_TO_END:
181       if (start_time_null_end_to_end_rtt_) {
182         *rtt = start_time_null_end_to_end_rtt_.value();
183         return true;
184       }
185       break;
186     case nqe::internal::OBSERVATION_CATEGORY_COUNT:
187       NOTREACHED();
188   }
189 
190   return NetworkQualityEstimator::GetRecentRTT(observation_category, start_time,
191                                                rtt, observations_count);
192 }
193 
GetTransportRTT() const194 absl::optional<base::TimeDelta> TestNetworkQualityEstimator::GetTransportRTT()
195     const {
196   if (start_time_null_transport_rtt_)
197     return start_time_null_transport_rtt_;
198   return NetworkQualityEstimator::GetTransportRTT();
199 }
200 
GetRecentDownlinkThroughputKbps(const base::TimeTicks & start_time,int32_t * kbps) const201 bool TestNetworkQualityEstimator::GetRecentDownlinkThroughputKbps(
202     const base::TimeTicks& start_time,
203     int32_t* kbps) const {
204   if (start_time.is_null()) {
205     if (start_time_null_downlink_throughput_kbps_) {
206       *kbps = start_time_null_downlink_throughput_kbps_.value();
207       return true;
208     }
209     return NetworkQualityEstimator::GetRecentDownlinkThroughputKbps(start_time,
210                                                                     kbps);
211   }
212 
213   if (recent_downlink_throughput_kbps_) {
214     *kbps = recent_downlink_throughput_kbps_.value();
215     return true;
216   }
217   return NetworkQualityEstimator::GetRecentDownlinkThroughputKbps(start_time,
218                                                                   kbps);
219 }
220 
GetRTTEstimateInternal(base::TimeTicks start_time,nqe::internal::ObservationCategory observation_category,int percentile,size_t * observations_count) const221 base::TimeDelta TestNetworkQualityEstimator::GetRTTEstimateInternal(
222     base::TimeTicks start_time,
223     nqe::internal::ObservationCategory observation_category,
224     int percentile,
225     size_t* observations_count) const {
226   if (rtt_estimate_internal_)
227     return rtt_estimate_internal_.value();
228 
229   return NetworkQualityEstimator::GetRTTEstimateInternal(
230       start_time, observation_category, percentile, observations_count);
231 }
232 
GetEntriesCount(NetLogEventType type) const233 int TestNetworkQualityEstimator::GetEntriesCount(NetLogEventType type) const {
234   return net_log_observer_.GetEntriesWithType(type).size();
235 }
236 
GetNetLogLastStringValue(NetLogEventType type,const std::string & key) const237 std::string TestNetworkQualityEstimator::GetNetLogLastStringValue(
238     NetLogEventType type,
239     const std::string& key) const {
240   auto entries = net_log_observer_.GetEntries();
241 
242   for (int i = entries.size() - 1; i >= 0; --i) {
243     if (entries[i].type == type) {
244       auto value = GetOptionalStringValueFromParams(entries[i], key);
245       if (value)
246         return *value;
247     }
248   }
249   return std::string();
250 }
251 
GetNetLogLastIntegerValue(NetLogEventType type,const std::string & key) const252 int TestNetworkQualityEstimator::GetNetLogLastIntegerValue(
253     NetLogEventType type,
254     const std::string& key) const {
255   auto entries = net_log_observer_.GetEntries();
256 
257   for (int i = entries.size() - 1; i >= 0; --i) {
258     if (entries[i].type == type) {
259       auto value = GetOptionalIntegerValueFromParams(entries[i], key);
260       if (value)
261         return *value;
262     }
263   }
264   return 0;
265 }
266 
267 void TestNetworkQualityEstimator::
NotifyObserversOfRTTOrThroughputEstimatesComputed(const net::nqe::internal::NetworkQuality & network_quality)268     NotifyObserversOfRTTOrThroughputEstimatesComputed(
269         const net::nqe::internal::NetworkQuality& network_quality) {
270   for (auto& observer : rtt_and_throughput_estimates_observer_list_) {
271     observer.OnRTTOrThroughputEstimatesComputed(
272         network_quality.http_rtt(), network_quality.transport_rtt(),
273         network_quality.downstream_throughput_kbps());
274   }
275 }
276 
277 void TestNetworkQualityEstimator::
SetAndNotifyObserversOfEffectiveConnectionType(EffectiveConnectionType type)278     SetAndNotifyObserversOfEffectiveConnectionType(
279         EffectiveConnectionType type) {
280   set_effective_connection_type(type);
281   for (auto& observer : effective_connection_type_observer_list_)
282     observer.OnEffectiveConnectionTypeChanged(type);
283 }
284 
285 absl::optional<net::EffectiveConnectionType>
GetOverrideECT() const286 TestNetworkQualityEstimator::GetOverrideECT() const {
287   return effective_connection_type_;
288 }
289 
290 void TestNetworkQualityEstimator::
SetAndNotifyObserversOfP2PActiveConnectionsCountChange(uint32_t count)291     SetAndNotifyObserversOfP2PActiveConnectionsCountChange(uint32_t count) {
292   p2p_connections_count_ = count;
293   for (auto& observer : peer_to_peer_type_observer_list_)
294     observer.OnPeerToPeerConnectionsCountChange(count);
295 }
296 
RecordSpdyPingLatency(const HostPortPair & host_port_pair,base::TimeDelta rtt)297 void TestNetworkQualityEstimator::RecordSpdyPingLatency(
298     const HostPortPair& host_port_pair,
299     base::TimeDelta rtt) {
300   ++ping_rtt_received_count_;
301   NetworkQualityEstimator::RecordSpdyPingLatency(host_port_pair, rtt);
302 }
303 
params() const304 const NetworkQualityEstimatorParams* TestNetworkQualityEstimator::params()
305     const {
306   return params_.get();
307 }
308 
GetCurrentNetworkID() const309 nqe::internal::NetworkID TestNetworkQualityEstimator::GetCurrentNetworkID()
310     const {
311   return nqe::internal::NetworkID(current_network_type_, current_network_id_,
312                                   INT32_MIN);
313 }
314 
LocalHttpTestServer(const base::FilePath & document_root)315 TestNetworkQualityEstimator::LocalHttpTestServer::LocalHttpTestServer(
316     const base::FilePath& document_root) {
317   AddDefaultHandlers(document_root);
318 }
319 
NotifyObserversOfRTTOrThroughputComputed() const320 void TestNetworkQualityEstimator::NotifyObserversOfRTTOrThroughputComputed()
321     const {
322   if (suppress_notifications_for_testing_)
323     return;
324 
325   NetworkQualityEstimator::NotifyObserversOfRTTOrThroughputComputed();
326 }
327 
328 void TestNetworkQualityEstimator::
NotifyRTTAndThroughputEstimatesObserverIfPresent(RTTAndThroughputEstimatesObserver * observer) const329     NotifyRTTAndThroughputEstimatesObserverIfPresent(
330         RTTAndThroughputEstimatesObserver* observer) const {
331   if (suppress_notifications_for_testing_)
332     return;
333 
334   NetworkQualityEstimator::NotifyRTTAndThroughputEstimatesObserverIfPresent(
335       observer);
336 }
337 
SetStartTimeNullHttpRtt(const base::TimeDelta http_rtt)338 void TestNetworkQualityEstimator::SetStartTimeNullHttpRtt(
339     const base::TimeDelta http_rtt) {
340   start_time_null_http_rtt_ = http_rtt;
341   // Force compute effective connection type so that the new RTT value is
342   // immediately picked up. This ensures that the next call to
343   // GetEffectiveConnectionType() returns the effective connnection type
344   // that was computed based on |http_rtt|.
345   ComputeEffectiveConnectionType();
346 }
347 
SetStartTimeNullTransportRtt(const base::TimeDelta transport_rtt)348 void TestNetworkQualityEstimator::SetStartTimeNullTransportRtt(
349     const base::TimeDelta transport_rtt) {
350   start_time_null_transport_rtt_ = transport_rtt;
351   // Force compute effective connection type so that the new RTT value is
352   // immediately picked up. This ensures that the next call to
353   // GetEffectiveConnectionType() returns the effective connnection type
354   // that was computed based on |transport_rtt|.
355   ComputeEffectiveConnectionType();
356 }
357 
358 }  // namespace net
359