• 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 #ifndef NET_NQE_NETWORK_QUALITY_ESTIMATOR_TEST_UTIL_H_
6 #define NET_NQE_NETWORK_QUALITY_ESTIMATOR_TEST_UTIL_H_
7 
8 #include <stdint.h>
9 
10 #include <map>
11 #include <memory>
12 #include <string>
13 #include <utility>
14 #include <vector>
15 
16 #include "base/files/file_path.h"
17 #include "base/time/time.h"
18 #include "net/base/network_change_notifier.h"
19 #include "net/log/net_log.h"
20 #include "net/log/test_net_log.h"
21 #include "net/nqe/effective_connection_type.h"
22 #include "net/nqe/network_quality_estimator.h"
23 #include "net/test/embedded_test_server/embedded_test_server.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25 #include "third_party/abseil-cpp/absl/types/optional.h"
26 #include "url/gurl.h"
27 
28 namespace net {
29 
30 // Helps in setting the current network type and id.
31 class TestNetworkQualityEstimator : public NetworkQualityEstimator {
32  public:
33   TestNetworkQualityEstimator();
34 
35   explicit TestNetworkQualityEstimator(
36       const std::map<std::string, std::string>& variation_params);
37 
38   TestNetworkQualityEstimator(
39       const std::map<std::string, std::string>& variation_params,
40       bool allow_local_host_requests_for_tests,
41       bool allow_smaller_responses_for_tests);
42 
43   TestNetworkQualityEstimator(
44       const std::map<std::string, std::string>& variation_params,
45       bool allow_local_host_requests_for_tests,
46       bool allow_smaller_responses_for_tests,
47       bool suppress_notifications_for_testing);
48 
49   explicit TestNetworkQualityEstimator(
50       std::unique_ptr<NetworkQualityEstimatorParams> params);
51 
52   TestNetworkQualityEstimator(const TestNetworkQualityEstimator&) = delete;
53   TestNetworkQualityEstimator& operator=(const TestNetworkQualityEstimator&) =
54       delete;
55 
56   ~TestNetworkQualityEstimator() override;
57 
58   // Runs one URL request to completion.
59   void RunOneRequest();
60 
61   // Overrides the current network type and id.
62   // Notifies network quality estimator of a change in connection.
63   void SimulateNetworkChange(
64       NetworkChangeNotifier::ConnectionType new_connection_type,
65       const std::string& network_id);
66 
67   // Returns a GURL hosted at the embedded test server.
68   const GURL GetEchoURL();
69 
70   // Returns a GURL hosted at the embedded test server which contains redirect
71   // to another HTTPS URL.
72   const GURL GetRedirectURL();
73 
set_effective_connection_type(EffectiveConnectionType type)74   void set_effective_connection_type(EffectiveConnectionType type) {
75     effective_connection_type_ = type;
76   }
77 
78   // Returns the effective connection type that was set using
79   // |set_effective_connection_type|. If the connection type has not been set,
80   // then the base implementation is called.
81   EffectiveConnectionType GetEffectiveConnectionType() const override;
82 
set_recent_effective_connection_type(EffectiveConnectionType type)83   void set_recent_effective_connection_type(EffectiveConnectionType type) {
84     // Callers should not set effective connection type along with the
85     // lower-layer metrics.
86     DCHECK(!start_time_null_http_rtt_ && !recent_http_rtt_ &&
87            !start_time_null_transport_rtt_ && !recent_transport_rtt_ &&
88            !start_time_null_downlink_throughput_kbps_ &&
89            !recent_downlink_throughput_kbps_);
90     recent_effective_connection_type_ = type;
91   }
92 
93   // Returns the effective connection type that was set using
94   // |set_effective_connection_type|. If the connection type has not been set,
95   // then the base implementation is called. |http_rtt|, |transport_rtt| and
96   // |downstream_throughput_kbps| are set to the values that were previously
97   // set by calling set_recent_http_rtt(), set_recent_transport_rtt()
98   // and set_recent_transport_rtt() methods, respectively.
99   EffectiveConnectionType GetRecentEffectiveConnectionTypeUsingMetrics(
100       base::TimeDelta* http_rtt,
101       base::TimeDelta* transport_rtt,
102       base::TimeDelta* end_to_end_rtt,
103       int32_t* downstream_throughput_kbps,
104       size_t* observations_count,
105       size_t* end_to_end_rtt_observation_count) const override;
106 
107   void NotifyObserversOfRTTOrThroughputComputed() const override;
108 
109   void NotifyRTTAndThroughputEstimatesObserverIfPresent(
110       RTTAndThroughputEstimatesObserver* observer) const override;
111 
112   // Force set the HTTP RTT estimate.
113   void SetStartTimeNullHttpRtt(const base::TimeDelta http_rtt);
114 
set_recent_http_rtt(const base::TimeDelta & recent_http_rtt)115   void set_recent_http_rtt(const base::TimeDelta& recent_http_rtt) {
116     // Callers should not set effective connection type along with the
117     // lower-layer metrics.
118     DCHECK(!effective_connection_type_ && !recent_effective_connection_type_);
119     recent_http_rtt_ = recent_http_rtt;
120   }
121 
122   // Returns the recent RTT that was set using set_recent_http_rtt() or
123   // set_recent_transport_rtt(). If the recent RTT has not been set, then the
124   // base implementation is called.
125   bool GetRecentRTT(nqe::internal::ObservationCategory observation_category,
126                     const base::TimeTicks& start_time,
127                     base::TimeDelta* rtt,
128                     size_t* observations_count) const override;
129 
130   // Force set the transport RTT estimate.
131   void SetStartTimeNullTransportRtt(const base::TimeDelta transport_rtt);
132 
set_recent_transport_rtt(const base::TimeDelta & recent_transport_rtt)133   void set_recent_transport_rtt(const base::TimeDelta& recent_transport_rtt) {
134     // Callers should not set effective connection type along with the
135     // lower-layer metrics.
136     DCHECK(!effective_connection_type_ && !recent_effective_connection_type_);
137     recent_transport_rtt_ = recent_transport_rtt;
138   }
139 
140   absl::optional<base::TimeDelta> GetTransportRTT() const override;
141 
set_start_time_null_downlink_throughput_kbps(int32_t downlink_throughput_kbps)142   void set_start_time_null_downlink_throughput_kbps(
143       int32_t downlink_throughput_kbps) {
144     start_time_null_downlink_throughput_kbps_ = downlink_throughput_kbps;
145   }
146 
set_recent_downlink_throughput_kbps(int32_t recent_downlink_throughput_kbps)147   void set_recent_downlink_throughput_kbps(
148       int32_t recent_downlink_throughput_kbps) {
149     // Callers should not set effective connection type along with the
150     // lower-layer metrics.
151     DCHECK(!effective_connection_type_ && !recent_effective_connection_type_);
152     recent_downlink_throughput_kbps_ = recent_downlink_throughput_kbps;
153   }
154   // Returns the downlink throughput that was set using
155   // |set_recent_downlink_throughput_kbps|. If the downlink throughput has not
156   // been set, then the base implementation is called.
157   bool GetRecentDownlinkThroughputKbps(const base::TimeTicks& start_time,
158                                        int32_t* kbps) const override;
159 
160   // Returns the recent HTTP RTT value that was set using
161   // |set_rtt_estimate_internal|. If it has not been set, then the base
162   // implementation is called.
163   base::TimeDelta GetRTTEstimateInternal(
164       base::TimeTicks start_time,
165       nqe::internal::ObservationCategory observation_category,
166       int percentile,
167       size_t* observations_count) const override;
168 
set_rtt_estimate_internal(base::TimeDelta value)169   void set_rtt_estimate_internal(base::TimeDelta value) {
170     rtt_estimate_internal_ = value;
171   }
172 
set_start_time_null_end_to_end_rtt(const base::TimeDelta rtt)173   void set_start_time_null_end_to_end_rtt(const base::TimeDelta rtt) {
174     // Callers should not set effective connection type along with the
175     // lower-layer metrics.
176     DCHECK(!effective_connection_type_ && !recent_effective_connection_type_);
177     start_time_null_end_to_end_rtt_ = rtt;
178   }
179 
set_start_time_null_end_to_end_rtt_observation_count(size_t count)180   void set_start_time_null_end_to_end_rtt_observation_count(size_t count) {
181     end_to_end_rtt_observation_count_at_last_ect_computation_ = count;
182   }
183 
184   // Returns the number of entries in |net_log_| that have type set to |type|.
185   int GetEntriesCount(NetLogEventType type) const;
186 
187   // Returns the value of the parameter with name |key| from the last net log
188   // entry that has type set to |type|. Different methods are provided for
189   // values of different types.
190   std::string GetNetLogLastStringValue(NetLogEventType type,
191                                        const std::string& key) const;
192   int GetNetLogLastIntegerValue(NetLogEventType type,
193                                 const std::string& key) const;
194 
195   // Notifies the registered observers that the network quality estimate has
196   // changed to |network_quality|.
197   void NotifyObserversOfRTTOrThroughputEstimatesComputed(
198       const net::nqe::internal::NetworkQuality& network_quality);
199 
200   // Updates the computed effective connection type to |type| and notifies the
201   // registered observers that the effective connection type has changed to
202   // |type|.
203   void SetAndNotifyObserversOfEffectiveConnectionType(
204       EffectiveConnectionType type);
205 
206   // Updates the count of active P2P connections to |count| and notifies the
207   // registered observers that the active P2P connection counts has changed to
208   // |count|.
209   void SetAndNotifyObserversOfP2PActiveConnectionsCountChange(uint32_t count);
210 
SetTransportRTTAtastECTSampleCount(size_t count)211   void SetTransportRTTAtastECTSampleCount(size_t count) {
212     transport_rtt_observation_count_last_ect_computation_ = count;
213   }
214 
215   // Returns count of ping RTTs received from H2/spdy connections.
ping_rtt_received_count()216   size_t ping_rtt_received_count() const { return ping_rtt_received_count_; }
217 
218   const NetworkQualityEstimatorParams* params() const;
219 
220   void RecordSpdyPingLatency(const HostPortPair& host_port_pair,
221                              base::TimeDelta rtt) override;
222 
223   using NetworkQualityEstimator::SetTickClockForTesting;
224   using NetworkQualityEstimator::OnConnectionTypeChanged;
225   using NetworkQualityEstimator::OnUpdatedTransportRTTAvailable;
226   using NetworkQualityEstimator::AddAndNotifyObserversOfRTT;
227   using NetworkQualityEstimator::AddAndNotifyObserversOfThroughput;
228   using NetworkQualityEstimator::IsHangingRequest;
229 
230  private:
231   class LocalHttpTestServer : public EmbeddedTestServer {
232    public:
233     explicit LocalHttpTestServer(const base::FilePath& document_root);
234   };
235 
236   // NetworkQualityEstimator implementation that returns the overridden
237   // network id and signal strength (instead of invoking platform APIs).
238   nqe::internal::NetworkID GetCurrentNetworkID() const override;
239 
240   absl::optional<net::EffectiveConnectionType> GetOverrideECT() const override;
241 
242   // Net log observer used to test correctness of NetLog entries.
243   net::RecordingNetLogObserver net_log_observer_;
244 
245   // If set, GetEffectiveConnectionType() and GetRecentEffectiveConnectionType()
246   // would return the set values, respectively.
247   absl::optional<EffectiveConnectionType> effective_connection_type_;
248   absl::optional<EffectiveConnectionType> recent_effective_connection_type_;
249 
250   NetworkChangeNotifier::ConnectionType current_network_type_ =
251       NetworkChangeNotifier::CONNECTION_UNKNOWN;
252   std::string current_network_id_;
253 
254   // If set, GetRecentHttpRTT() would return one of the set values.
255   // |start_time_null_http_rtt_| is returned if the |start_time| is null.
256   // Otherwise, |recent_http_rtt_| is returned.
257   absl::optional<base::TimeDelta> start_time_null_http_rtt_;
258   absl::optional<base::TimeDelta> recent_http_rtt_;
259 
260   // If set, GetRecentTransportRTT() would return one of the set values.
261   // |start_time_null_transport_rtt_| is returned if the |start_time| is null.
262   // Otherwise, |recent_transport_rtt_| is returned.
263   absl::optional<base::TimeDelta> start_time_null_transport_rtt_;
264   absl::optional<base::TimeDelta> recent_transport_rtt_;
265 
266   // If set, GetRecentDownlinkThroughputKbps() would return one of the set
267   // values. |start_time_null_downlink_throughput_kbps_| is returned if the
268   // |start_time| is null. Otherwise, |recent_downlink_throughput_kbps_| is
269   // returned.
270   absl::optional<int32_t> start_time_null_downlink_throughput_kbps_;
271   absl::optional<int32_t> recent_downlink_throughput_kbps_;
272 
273   // If set, GetRTTEstimateInternal() would return the set value.
274   absl::optional<base::TimeDelta> rtt_estimate_internal_;
275 
276   // If set, GetRTTEstimateInternal() would return the set value.
277   absl::optional<base::TimeDelta> start_time_null_end_to_end_rtt_;
278 
279   LocalHttpTestServer embedded_test_server_;
280 
281   // If true, notifications are not sent to any of the observers.
282   const bool suppress_notifications_for_testing_;
283 
284   size_t ping_rtt_received_count_ = 0;
285 
286   absl::optional<size_t> transport_rtt_observation_count_last_ect_computation_;
287 };
288 
289 }  // namespace net
290 
291 #endif  // NET_NQE_NETWORK_QUALITY_ESTIMATOR_TEST_UTIL_H_
292