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