diff options
Diffstat (limited to 'net/base/network_quality_estimator_unittest.cc')
-rw-r--r-- | net/base/network_quality_estimator_unittest.cc | 382 |
1 files changed, 335 insertions, 47 deletions
diff --git a/net/base/network_quality_estimator_unittest.cc b/net/base/network_quality_estimator_unittest.cc index b1ffdeb..38a22eb 100644 --- a/net/base/network_quality_estimator_unittest.cc +++ b/net/base/network_quality_estimator_unittest.cc @@ -10,6 +10,7 @@ #include <map> #include "base/basictypes.h" +#include "base/files/file_path.h" #include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "base/metrics/histogram_samples.h" @@ -21,22 +22,47 @@ #include "net/base/external_estimate_provider.h" #include "net/base/load_flags.h" #include "net/base/network_change_notifier.h" -#include "net/test/embedded_test_server/embedded_test_server.h" +#include "net/http/http_status_code.h" +#include "net/test/spawned_test_server/spawned_test_server.h" #include "net/url_request/url_request_test_util.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" namespace { +#if !defined(OS_IOS) +// SpawnedTestServer is not supported on iOS. +// Less verbose way of running a simple testserver for the tests below. +class LocalHttpTestServer : public net::SpawnedTestServer { + public: + LocalHttpTestServer() + : net::SpawnedTestServer(net::SpawnedTestServer::TYPE_HTTP, + net::SpawnedTestServer::kLocalhost, + base::FilePath()) {} +}; +#endif // !defined(OS_IOS) + // Helps in setting the current network type and id. class TestNetworkQualityEstimator : public net::NetworkQualityEstimator { public: TestNetworkQualityEstimator( - const std::map<std::string, std::string>& variation_params) - : NetworkQualityEstimator(scoped_ptr<net::ExternalEstimateProvider>(), + const std::map<std::string, std::string>& variation_params, + scoped_ptr<net::ExternalEstimateProvider> external_estimate_provider) + : NetworkQualityEstimator(external_estimate_provider.Pass(), variation_params, true, - true) {} + true) { +#if !defined(OS_IOS) + // Set up test server. + DCHECK(test_server_.Start()); +#endif // !defined(OS_IOS) + } + + explicit TestNetworkQualityEstimator( + const std::map<std::string, std::string>& variation_params) + : TestNetworkQualityEstimator( + variation_params, + scoped_ptr<net::ExternalEstimateProvider>()) {} ~TestNetworkQualityEstimator() override {} @@ -49,6 +75,11 @@ class TestNetworkQualityEstimator : public net::NetworkQualityEstimator { OnConnectionTypeChanged(type); } +#if !defined(OS_IOS) + // Returns a GURL hosted at embedded test server. + const GURL GetEchoURL() const { return test_server_.GetURL("/echo.html"); } +#endif // !defined(OS_IOS) + using NetworkQualityEstimator::ReadCachedNetworkQualityEstimate; using NetworkQualityEstimator::OnConnectionTypeChanged; @@ -62,18 +93,22 @@ class TestNetworkQualityEstimator : public net::NetworkQualityEstimator { net::NetworkChangeNotifier::ConnectionType current_network_type_; std::string current_network_id_; + +#if !defined(OS_IOS) + // Test server used for testing. + LocalHttpTestServer test_server_; +#endif // !defined(OS_IOS) + + DISALLOW_COPY_AND_ASSIGN(TestNetworkQualityEstimator); }; } // namespace namespace net { +#if !defined(OS_IOS) +// SpawnedTestServer is not supported on iOS. TEST(NetworkQualityEstimatorTest, TestKbpsRTTUpdates) { - net::test_server::EmbeddedTestServer embedded_test_server; - embedded_test_server.ServeFilesFromDirectory( - base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); - ASSERT_TRUE(embedded_test_server.InitializeAndWaitUntilReady()); - base::HistogramTester histogram_tester; // Enable requests to local host to be used for network quality estimation. std::map<std::string, std::string> variation_params; @@ -86,19 +121,17 @@ TEST(NetworkQualityEstimatorTest, TestKbpsRTTUpdates) { base::TimeTicks(), 100)); TestDelegate test_delegate; - TestURLRequestContext context(false); + TestURLRequestContext context(true); + context.set_network_quality_estimator(&estimator); + context.Init(); - scoped_ptr<URLRequest> request( - context.CreateRequest(embedded_test_server.GetURL("/echo.html"), - DEFAULT_PRIORITY, &test_delegate)); + scoped_ptr<URLRequest> request(context.CreateRequest( + estimator.GetEchoURL(), DEFAULT_PRIORITY, &test_delegate)); request->SetLoadFlags(request->load_flags() | LOAD_MAIN_FRAME); request->Start(); - base::RunLoop().Run(); // Both RTT and downstream throughput should be updated. - estimator.NotifyHeadersReceived(*request); - estimator.NotifyRequestCompleted(*request); EXPECT_NE(NetworkQualityEstimator::InvalidRTT(), estimator.GetRTTEstimateInternal(base::TimeTicks(), 100)); EXPECT_NE(NetworkQualityEstimator::kInvalidThroughput, @@ -123,8 +156,12 @@ TEST(NetworkQualityEstimatorTest, TestKbpsRTTUpdates) { histogram_tester.ExpectTotalCount("NQE.RatioEstimatedToActualRTT.Unknown", 0); - estimator.NotifyHeadersReceived(*request); - estimator.NotifyRequestCompleted(*request); + scoped_ptr<URLRequest> request2(context.CreateRequest( + estimator.GetEchoURL(), DEFAULT_PRIORITY, &test_delegate)); + request2->SetLoadFlags(request2->load_flags() | LOAD_MAIN_FRAME); + request2->Start(); + base::RunLoop().Run(); + histogram_tester.ExpectTotalCount("NQE.RTTObservations.Unknown", 1); estimator.SimulateNetworkChangeTo( NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI, "test-1"); @@ -166,26 +203,20 @@ TEST(NetworkQualityEstimatorTest, TestKbpsRTTUpdates) { } TEST(NetworkQualityEstimatorTest, StoreObservations) { - net::test_server::EmbeddedTestServer embedded_test_server; - embedded_test_server.ServeFilesFromDirectory( - base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); - ASSERT_TRUE(embedded_test_server.InitializeAndWaitUntilReady()); - std::map<std::string, std::string> variation_params; TestNetworkQualityEstimator estimator(variation_params); + TestDelegate test_delegate; - TestURLRequestContext context(false); + TestURLRequestContext context(true); + context.set_network_quality_estimator(&estimator); + context.Init(); // Push 10 more observations than the maximum buffer size. for (size_t i = 0; i < estimator.kMaximumObservationsBufferSize + 10U; ++i) { - scoped_ptr<URLRequest> request( - context.CreateRequest(embedded_test_server.GetURL("/echo.html"), - DEFAULT_PRIORITY, &test_delegate)); + scoped_ptr<URLRequest> request(context.CreateRequest( + estimator.GetEchoURL(), DEFAULT_PRIORITY, &test_delegate)); request->Start(); base::RunLoop().Run(); - - estimator.NotifyHeadersReceived(*request); - estimator.NotifyRequestCompleted(*request); } EXPECT_EQ(static_cast<size_t>( @@ -200,11 +231,8 @@ TEST(NetworkQualityEstimatorTest, StoreObservations) { NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI, "test-2"); EXPECT_EQ(0U, estimator.downstream_throughput_kbps_observations_.Size()); EXPECT_EQ(0U, estimator.rtt_msec_observations_.Size()); - - scoped_ptr<URLRequest> request( - context.CreateRequest(embedded_test_server.GetURL("/echo.html"), - DEFAULT_PRIORITY, &test_delegate)); } +#endif // !defined(OS_IOS) // Verifies that the percentiles are correctly computed. All observations have // the same timestamp. Kbps percentiles must be in decreasing order. RTT @@ -315,12 +343,9 @@ TEST(NetworkQualityEstimatorTest, PercentileDifferentTimestamps) { // This test notifies NetworkQualityEstimator of received data. Next, // throughput and RTT percentiles are checked for correctness by doing simple // verifications. +#if !defined(OS_IOS) +// SpawnedTestServer is not supported on iOS. TEST(NetworkQualityEstimatorTest, ComputedPercentiles) { - net::test_server::EmbeddedTestServer embedded_test_server; - embedded_test_server.ServeFilesFromDirectory( - base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); - ASSERT_TRUE(embedded_test_server.InitializeAndWaitUntilReady()); - std::map<std::string, std::string> variation_params; TestNetworkQualityEstimator estimator(variation_params); @@ -331,19 +356,16 @@ TEST(NetworkQualityEstimatorTest, ComputedPercentiles) { base::TimeTicks(), 100)); TestDelegate test_delegate; - TestURLRequestContext context(false); + TestURLRequestContext context(true); + context.set_network_quality_estimator(&estimator); + context.Init(); // Number of observations are more than the maximum buffer size. for (size_t i = 0; i < estimator.kMaximumObservationsBufferSize + 100U; ++i) { - scoped_ptr<URLRequest> request( - context.CreateRequest(embedded_test_server.GetURL("/echo.html"), - DEFAULT_PRIORITY, &test_delegate)); + scoped_ptr<URLRequest> request(context.CreateRequest( + estimator.GetEchoURL(), DEFAULT_PRIORITY, &test_delegate)); request->Start(); base::RunLoop().Run(); - - // Use different number of bytes to create variation. - estimator.NotifyHeadersReceived(*request); - estimator.NotifyRequestCompleted(*request); } // Verify the percentiles through simple tests. @@ -367,6 +389,7 @@ TEST(NetworkQualityEstimatorTest, ComputedPercentiles) { } } } +#endif // !defined(OS_IOS) TEST(NetworkQualityEstimatorTest, ObtainOperatingParams) { std::map<std::string, std::string> variation_params; @@ -654,4 +677,269 @@ TEST(NetworkQualityEstimatorTest, TestGetMedianRTTSince) { EXPECT_EQ(100, downstream_throughput_kbps); } +// An external estimate provider that does not have a valid RTT or throughput +// estimate. +class InvalidExternalEstimateProvider : public ExternalEstimateProvider { + public: + InvalidExternalEstimateProvider() : get_rtt_count_(0) {} + ~InvalidExternalEstimateProvider() override {} + + // ExternalEstimateProvider implementation: + bool GetRTT(base::TimeDelta* rtt) const override { + DCHECK(rtt); + get_rtt_count_++; + return false; + } + + // ExternalEstimateProvider implementation: + bool GetDownstreamThroughputKbps( + int32_t* downstream_throughput_kbps) const override { + DCHECK(downstream_throughput_kbps); + return false; + } + + // ExternalEstimateProvider implementation: + bool GetUpstreamThroughputKbps( + int32_t* upstream_throughput_kbps) const override { + // NetworkQualityEstimator does not support upstream throughput. + ADD_FAILURE(); + return false; + } + + // ExternalEstimateProvider implementation: + bool GetTimeSinceLastUpdate( + base::TimeDelta* time_since_last_update) const override { + *time_since_last_update = base::TimeDelta::FromMilliseconds(1); + return true; + } + + // ExternalEstimateProvider implementation: + void SetUpdatedEstimateDelegate(UpdatedEstimateDelegate* delegate) override {} + + // ExternalEstimateProvider implementation: + void Update() const override {} + + size_t get_rtt_count() const { return get_rtt_count_; } + + private: + // Keeps track of number of times different functions were called. + mutable size_t get_rtt_count_; + + DISALLOW_COPY_AND_ASSIGN(InvalidExternalEstimateProvider); +}; + +// Tests if the RTT value from external estimate provider is discarded if the +// external estimate provider is invalid. +TEST(NetworkQualityEstimatorTest, InvalidExternalEstimateProvider) { + InvalidExternalEstimateProvider* invalid_external_estimate_provider = + new InvalidExternalEstimateProvider(); + scoped_ptr<ExternalEstimateProvider> external_estimate_provider( + invalid_external_estimate_provider); + + TestNetworkQualityEstimator estimator(std::map<std::string, std::string>(), + external_estimate_provider.Pass()); + + base::TimeDelta rtt; + int32_t kbps; + EXPECT_EQ(1U, invalid_external_estimate_provider->get_rtt_count()); + EXPECT_FALSE(estimator.GetRTTEstimate(&rtt)); + EXPECT_FALSE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps)); +} + +class TestExternalEstimateProvider : public ExternalEstimateProvider { + public: + TestExternalEstimateProvider(base::TimeDelta rtt, + int32_t downstream_throughput_kbps) + : rtt_(rtt), + downstream_throughput_kbps_(downstream_throughput_kbps), + time_since_last_update_(base::TimeDelta::FromSeconds(1)), + get_time_since_last_update_count_(0), + get_rtt_count_(0), + get_downstream_throughput_kbps_count_(0), + update_count_(0) {} + ~TestExternalEstimateProvider() override {} + + // ExternalEstimateProvider implementation: + bool GetRTT(base::TimeDelta* rtt) const override { + *rtt = rtt_; + get_rtt_count_++; + return true; + } + + // ExternalEstimateProvider implementation: + bool GetDownstreamThroughputKbps( + int32_t* downstream_throughput_kbps) const override { + *downstream_throughput_kbps = downstream_throughput_kbps_; + get_downstream_throughput_kbps_count_++; + return true; + } + + // ExternalEstimateProvider implementation: + bool GetUpstreamThroughputKbps( + int32_t* upstream_throughput_kbps) const override { + // NetworkQualityEstimator does not support upstream throughput. + ADD_FAILURE(); + return false; + } + + // ExternalEstimateProvider implementation: + bool GetTimeSinceLastUpdate( + base::TimeDelta* time_since_last_update) const override { + *time_since_last_update = time_since_last_update_; + get_time_since_last_update_count_++; + return true; + } + + // ExternalEstimateProvider implementation: + void SetUpdatedEstimateDelegate(UpdatedEstimateDelegate* delegate) override {} + + // ExternalEstimateProvider implementation: + void Update() const override { update_count_++; } + + void set_time_since_last_update(base::TimeDelta time_since_last_update) { + time_since_last_update_ = time_since_last_update; + } + + size_t get_time_since_last_update_count() const { + return get_time_since_last_update_count_; + } + size_t get_rtt_count() const { return get_rtt_count_; } + size_t get_downstream_throughput_kbps_count() const { + return get_downstream_throughput_kbps_count_; + } + size_t update_count() const { return update_count_; } + + private: + // RTT and downstream throughput estimates. + const base::TimeDelta rtt_; + const int32_t downstream_throughput_kbps_; + + base::TimeDelta time_since_last_update_; + + // Keeps track of number of times different functions were called. + mutable size_t get_time_since_last_update_count_; + mutable size_t get_rtt_count_; + mutable size_t get_downstream_throughput_kbps_count_; + mutable size_t update_count_; + + DISALLOW_COPY_AND_ASSIGN(TestExternalEstimateProvider); +}; + +// Tests if the external estimate provider is called in the constructor and +// on network change notification. +TEST(NetworkQualityEstimatorTest, TestExternalEstimateProvider) { + TestExternalEstimateProvider* test_external_estimate_provider = + new TestExternalEstimateProvider(base::TimeDelta::FromMilliseconds(1), + 100); + scoped_ptr<ExternalEstimateProvider> external_estimate_provider( + test_external_estimate_provider); + std::map<std::string, std::string> variation_params; + TestNetworkQualityEstimator estimator(variation_params, + external_estimate_provider.Pass()); + + base::TimeDelta rtt; + int32_t kbps; + EXPECT_TRUE(estimator.GetRTTEstimate(&rtt)); + EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps)); + + EXPECT_EQ( + 1U, test_external_estimate_provider->get_time_since_last_update_count()); + EXPECT_EQ(1U, test_external_estimate_provider->get_rtt_count()); + EXPECT_EQ( + 1U, + test_external_estimate_provider->get_downstream_throughput_kbps_count()); + + // Change network type to WiFi. Number of queries to External estimate + // provider must increment. + estimator.SimulateNetworkChangeTo( + NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI, "test-1"); + EXPECT_TRUE(estimator.GetRTTEstimate(&rtt)); + EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps)); + EXPECT_EQ( + 2U, test_external_estimate_provider->get_time_since_last_update_count()); + EXPECT_EQ(2U, test_external_estimate_provider->get_rtt_count()); + EXPECT_EQ( + 2U, + test_external_estimate_provider->get_downstream_throughput_kbps_count()); + + // Change network type to 2G. Number of queries to External estimate provider + // must increment. + estimator.SimulateNetworkChangeTo( + NetworkChangeNotifier::ConnectionType::CONNECTION_2G, "test-1"); + EXPECT_EQ( + 3U, test_external_estimate_provider->get_time_since_last_update_count()); + EXPECT_EQ(3U, test_external_estimate_provider->get_rtt_count()); + EXPECT_EQ( + 3U, + test_external_estimate_provider->get_downstream_throughput_kbps_count()); + + // Set the external estimate as old. Network Quality estimator should request + // an update on connection type change. + EXPECT_EQ(0U, test_external_estimate_provider->update_count()); + test_external_estimate_provider->set_time_since_last_update( + base::TimeDelta::Max()); + + estimator.SimulateNetworkChangeTo( + NetworkChangeNotifier::ConnectionType::CONNECTION_2G, "test-2"); + EXPECT_EQ( + 4U, test_external_estimate_provider->get_time_since_last_update_count()); + EXPECT_EQ(3U, test_external_estimate_provider->get_rtt_count()); + EXPECT_EQ( + 3U, + test_external_estimate_provider->get_downstream_throughput_kbps_count()); + EXPECT_EQ(1U, test_external_estimate_provider->update_count()); + + // Estimates are unavailable because external estimate provider never + // notifies network quality estimator of the updated estimates. + EXPECT_FALSE(estimator.GetRTTEstimate(&rtt)); + EXPECT_FALSE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps)); +} + +// Tests if the estimate from the external estimate provider is merged with the +// observations collected from the HTTP requests. +#if !defined(OS_IOS) +// SpawnedTestServer is not supported on iOS. +TEST(NetworkQualityEstimatorTest, TestExternalEstimateProviderMergeEstimates) { + const base::TimeDelta external_estimate_provider_rtt = + base::TimeDelta::FromMilliseconds(1); + const int32_t external_estimate_provider_downstream_throughput = 100; + TestExternalEstimateProvider* test_external_estimate_provider = + new TestExternalEstimateProvider( + external_estimate_provider_rtt, + external_estimate_provider_downstream_throughput); + scoped_ptr<ExternalEstimateProvider> external_estimate_provider( + test_external_estimate_provider); + + std::map<std::string, std::string> variation_params; + TestNetworkQualityEstimator estimator(variation_params, + external_estimate_provider.Pass()); + + base::TimeDelta rtt; + // Estimate provided by network quality estimator should match the estimate + // provided by external estimate provider. + EXPECT_TRUE(estimator.GetRTTEstimate(&rtt)); + EXPECT_EQ(external_estimate_provider_rtt, rtt); + + int32_t kbps; + EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps)); + EXPECT_EQ(external_estimate_provider_downstream_throughput, kbps); + + EXPECT_EQ(1U, estimator.rtt_msec_observations_.Size()); + EXPECT_EQ(1U, estimator.downstream_throughput_kbps_observations_.Size()); + + TestDelegate test_delegate; + TestURLRequestContext context(true); + context.set_network_quality_estimator(&estimator); + context.Init(); + + scoped_ptr<URLRequest> request(context.CreateRequest( + estimator.GetEchoURL(), DEFAULT_PRIORITY, &test_delegate)); + request->Start(); + base::RunLoop().Run(); + + EXPECT_EQ(2U, estimator.rtt_msec_observations_.Size()); + EXPECT_EQ(2U, estimator.downstream_throughput_kbps_observations_.Size()); +} +#endif // !defined(OS_IOS) + } // namespace net |