Commit fd2e773f authored by Tarun Bansal's avatar Tarun Bansal Committed by Commit Bot

Add mechanism to add RTT/throughput estimates observer to NQT

Add mechanism to add HTTP RTT, transport RTT, downlink throughout
estimate change observer to NetworkQualityTracker.

In the next CL, an IO object owned by UINetworkQualityEstimatorService
would subscribe to these changes, and then pass them on to the UI
thread.

Bug: 819244
Cq-Include-Trybots: luci.chromium.try:linux_mojo
Change-Id: Ieeb786c9376af7afe9f2e8bff85468067c4c4ecf
Reviewed-on: https://chromium-review.googlesource.com/1144470Reviewed-by: default avatarNick Carter <nick@chromium.org>
Reviewed-by: default avatarMatt Menke <mmenke@chromium.org>
Commit-Queue: Tarun Bansal <tbansal@chromium.org>
Cr-Commit-Position: refs/heads/master@{#580367}
parent 6a9a4587
...@@ -24,7 +24,8 @@ class TestNetworkConnectionObserver ...@@ -24,7 +24,8 @@ class TestNetworkConnectionObserver
explicit TestNetworkConnectionObserver(NetworkConnectionTracker* tracker) explicit TestNetworkConnectionObserver(NetworkConnectionTracker* tracker)
: num_notifications_(0), : num_notifications_(0),
tracker_(tracker), tracker_(tracker),
run_loop_(std::make_unique<base::RunLoop>()), expected_connection_type_(
network::mojom::ConnectionType::CONNECTION_UNKNOWN),
connection_type_(network::mojom::ConnectionType::CONNECTION_UNKNOWN) { connection_type_(network::mojom::ConnectionType::CONNECTION_UNKNOWN) {
tracker_->AddNetworkConnectionObserver(this); tracker_->AddNetworkConnectionObserver(this);
} }
...@@ -52,13 +53,22 @@ class TestNetworkConnectionObserver ...@@ -52,13 +53,22 @@ class TestNetworkConnectionObserver
num_notifications_++; num_notifications_++;
connection_type_ = type; connection_type_ = type;
run_loop_->Quit(); if (run_loop_ && expected_connection_type_ == type)
run_loop_->Quit();
} }
size_t num_notifications() const { return num_notifications_; } size_t num_notifications() const { return num_notifications_; }
void WaitForNotification() { void WaitForNotification(
network::mojom::ConnectionType expected_connection_type) {
expected_connection_type_ = expected_connection_type;
if (connection_type_ == expected_connection_type)
return;
// WaitForNotification() should not be called twice.
EXPECT_EQ(nullptr, run_loop_);
run_loop_ = std::make_unique<base::RunLoop>();
run_loop_->Run(); run_loop_->Run();
run_loop_.reset(new base::RunLoop()); run_loop_.reset();
} }
network::mojom::ConnectionType connection_type() const { network::mojom::ConnectionType connection_type() const {
...@@ -75,7 +85,9 @@ class TestNetworkConnectionObserver ...@@ -75,7 +85,9 @@ class TestNetworkConnectionObserver
size_t num_notifications_; size_t num_notifications_;
NetworkConnectionTracker* tracker_; NetworkConnectionTracker* tracker_;
// May be null.
std::unique_ptr<base::RunLoop> run_loop_; std::unique_ptr<base::RunLoop> run_loop_;
network::mojom::ConnectionType expected_connection_type_;
network::mojom::ConnectionType connection_type_; network::mojom::ConnectionType connection_type_;
DISALLOW_COPY_AND_ASSIGN(TestNetworkConnectionObserver); DISALLOW_COPY_AND_ASSIGN(TestNetworkConnectionObserver);
...@@ -217,7 +229,8 @@ TEST_F(NetworkConnectionTrackerTest, ObserverNotified) { ...@@ -217,7 +229,8 @@ TEST_F(NetworkConnectionTrackerTest, ObserverNotified) {
SimulateConnectionTypeChange( SimulateConnectionTypeChange(
net::NetworkChangeNotifier::ConnectionType::CONNECTION_3G); net::NetworkChangeNotifier::ConnectionType::CONNECTION_3G);
network_connection_observer()->WaitForNotification(); network_connection_observer()->WaitForNotification(
network::mojom::ConnectionType::CONNECTION_3G);
EXPECT_EQ(network::mojom::ConnectionType::CONNECTION_3G, EXPECT_EQ(network::mojom::ConnectionType::CONNECTION_3G,
network_connection_observer()->connection_type()); network_connection_observer()->connection_type());
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
...@@ -234,10 +247,12 @@ TEST_F(NetworkConnectionTrackerTest, UnregisteredObserverNotNotified) { ...@@ -234,10 +247,12 @@ TEST_F(NetworkConnectionTrackerTest, UnregisteredObserverNotNotified) {
SimulateConnectionTypeChange( SimulateConnectionTypeChange(
net::NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI); net::NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI);
network_connection_observer2->WaitForNotification(); network_connection_observer2->WaitForNotification(
network::mojom::ConnectionType::CONNECTION_WIFI);
EXPECT_EQ(network::mojom::ConnectionType::CONNECTION_WIFI, EXPECT_EQ(network::mojom::ConnectionType::CONNECTION_WIFI,
network_connection_observer2->connection_type()); network_connection_observer2->connection_type());
network_connection_observer()->WaitForNotification(); network_connection_observer()->WaitForNotification(
network::mojom::ConnectionType::CONNECTION_WIFI);
EXPECT_EQ(network::mojom::ConnectionType::CONNECTION_WIFI, EXPECT_EQ(network::mojom::ConnectionType::CONNECTION_WIFI,
network_connection_observer()->connection_type()); network_connection_observer()->connection_type());
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
...@@ -247,7 +262,8 @@ TEST_F(NetworkConnectionTrackerTest, UnregisteredObserverNotNotified) { ...@@ -247,7 +262,8 @@ TEST_F(NetworkConnectionTrackerTest, UnregisteredObserverNotNotified) {
// Simulate an another network change. // Simulate an another network change.
SimulateConnectionTypeChange( SimulateConnectionTypeChange(
net::NetworkChangeNotifier::ConnectionType::CONNECTION_2G); net::NetworkChangeNotifier::ConnectionType::CONNECTION_2G);
network_connection_observer()->WaitForNotification(); network_connection_observer()->WaitForNotification(
network::mojom::ConnectionType::CONNECTION_2G);
EXPECT_EQ(network::mojom::ConnectionType::CONNECTION_2G, EXPECT_EQ(network::mojom::ConnectionType::CONNECTION_2G,
network_connection_observer()->connection_type()); network_connection_observer()->connection_type());
EXPECT_EQ(2u, network_connection_observer()->num_notifications()); EXPECT_EQ(2u, network_connection_observer()->num_notifications());
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "services/network/public/cpp/network_quality_tracker.h" #include "services/network/public/cpp/network_quality_tracker.h"
#include <limits>
#include <utility> #include <utility>
#include "base/logging.h" #include "base/logging.h"
...@@ -14,7 +15,7 @@ NetworkQualityTracker::NetworkQualityTracker( ...@@ -14,7 +15,7 @@ NetworkQualityTracker::NetworkQualityTracker(
base::RepeatingCallback<network::mojom::NetworkService*()> callback) base::RepeatingCallback<network::mojom::NetworkService*()> callback)
: get_network_service_callback_(callback), : get_network_service_callback_(callback),
effective_connection_type_(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN), effective_connection_type_(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN),
downlink_bandwidth_kbps_(INT32_MAX), downlink_bandwidth_kbps_(std::numeric_limits<int32_t>::max()),
binding_(this) { binding_(this) {
InitializeMojoChannel(); InitializeMojoChannel();
DCHECK(binding_.is_bound()); DCHECK(binding_.is_bound());
...@@ -57,6 +58,20 @@ void NetworkQualityTracker::RemoveEffectiveConnectionTypeObserver( ...@@ -57,6 +58,20 @@ void NetworkQualityTracker::RemoveEffectiveConnectionTypeObserver(
effective_connection_type_observer_list_.RemoveObserver(observer); effective_connection_type_observer_list_.RemoveObserver(observer);
} }
void NetworkQualityTracker::AddRTTAndThroughputEstimatesObserver(
RTTAndThroughputEstimatesObserver* observer) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
rtt_and_throughput_observer_list_.AddObserver(observer);
observer->OnRTTOrThroughputEstimatesComputed(http_rtt_, transport_rtt_,
downlink_bandwidth_kbps_);
}
void NetworkQualityTracker::RemoveRTTAndThroughputEstimatesObserver(
RTTAndThroughputEstimatesObserver* observer) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
rtt_and_throughput_observer_list_.RemoveObserver(observer);
}
void NetworkQualityTracker::OnNetworkQualityChanged( void NetworkQualityTracker::OnNetworkQualityChanged(
net::EffectiveConnectionType effective_connection_type, net::EffectiveConnectionType effective_connection_type,
base::TimeDelta http_rtt, base::TimeDelta http_rtt,
...@@ -64,15 +79,23 @@ void NetworkQualityTracker::OnNetworkQualityChanged( ...@@ -64,15 +79,23 @@ void NetworkQualityTracker::OnNetworkQualityChanged(
int32_t bandwidth_kbps) { int32_t bandwidth_kbps) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
http_rtt_ = http_rtt; if (http_rtt_ != http_rtt || transport_rtt_ != transport_rtt ||
transport_rtt_ = transport_rtt; downlink_bandwidth_kbps_ != bandwidth_kbps) {
downlink_bandwidth_kbps_ = bandwidth_kbps; http_rtt_ = http_rtt;
transport_rtt_ = transport_rtt;
if (effective_connection_type == effective_connection_type_) downlink_bandwidth_kbps_ = bandwidth_kbps;
return;
effective_connection_type_ = effective_connection_type; for (auto& observer : rtt_and_throughput_observer_list_) {
for (auto& observer : effective_connection_type_observer_list_) observer.OnRTTOrThroughputEstimatesComputed(http_rtt_, transport_rtt_,
observer.OnEffectiveConnectionTypeChanged(effective_connection_type_); downlink_bandwidth_kbps_);
}
}
if (effective_connection_type != effective_connection_type_) {
effective_connection_type_ = effective_connection_type;
for (auto& observer : effective_connection_type_observer_list_)
observer.OnEffectiveConnectionTypeChanged(effective_connection_type_);
}
} }
void NetworkQualityTracker::InitializeMojoChannel() { void NetworkQualityTracker::InitializeMojoChannel() {
......
...@@ -41,6 +41,28 @@ class COMPONENT_EXPORT(NETWORK_CPP) NetworkQualityTracker ...@@ -41,6 +41,28 @@ class COMPONENT_EXPORT(NETWORK_CPP) NetworkQualityTracker
DISALLOW_COPY_AND_ASSIGN(EffectiveConnectionTypeObserver); DISALLOW_COPY_AND_ASSIGN(EffectiveConnectionTypeObserver);
}; };
// Observes changes in the HTTP RTT, transport RTT or downstream throughput
// estimates.
class COMPONENT_EXPORT(NETWORK_CPP) RTTAndThroughputEstimatesObserver {
public:
// Called when there is a substantial change in either HTTP RTT, transport
// RTT or downstream estimate. If either of the RTT estimates are
// unavailable, then the value of that estimate is set to base::TimeDelta().
// If downstream estimate is unavailable, its value is set to INT32_MAX.
virtual void OnRTTOrThroughputEstimatesComputed(
base::TimeDelta http_rtt,
base::TimeDelta transport_rtt,
int32_t downstream_throughput_kbps) = 0;
virtual ~RTTAndThroughputEstimatesObserver() {}
protected:
RTTAndThroughputEstimatesObserver() {}
private:
DISALLOW_COPY_AND_ASSIGN(RTTAndThroughputEstimatesObserver);
};
// Running the |callback| returns the network service in use. // Running the |callback| returns the network service in use.
// NetworkQualityTracker does not need to be destroyed before the network // NetworkQualityTracker does not need to be destroyed before the network
// service. // service.
...@@ -76,12 +98,30 @@ class COMPONENT_EXPORT(NETWORK_CPP) NetworkQualityTracker ...@@ -76,12 +98,30 @@ class COMPONENT_EXPORT(NETWORK_CPP) NetworkQualityTracker
void AddEffectiveConnectionTypeObserver( void AddEffectiveConnectionTypeObserver(
EffectiveConnectionTypeObserver* observer); EffectiveConnectionTypeObserver* observer);
// Unregisters |observer| from receiving notifications. This must be called // Unregisters |observer| from receiving notifications. This must be called
// on the same thread on which AddObserver() was called. // on the same thread on which AddObserver() was called.
// All observers must be unregistered before |this| is destroyed. // All observers must be unregistered before |this| is destroyed.
void RemoveEffectiveConnectionTypeObserver( void RemoveEffectiveConnectionTypeObserver(
EffectiveConnectionTypeObserver* observer); EffectiveConnectionTypeObserver* observer);
// Registers |observer| to receive notifications of RTT or throughput changes.
// This should be called on the same thread as the thread on which |this| is
// created. The |observer| would be called back with notifications on that
// same thread. The |observer| is notified of the current HTTP RTT, transport
// RTT and downstrean bandwidth estimates on the same thread. If either of the
// RTT estimate are unavailable, then the value of that estimate is set to
// base::TimeDelta(). If downstream estimate is unavailable, its value is set
// to INT32_MAX. The |observer| is notified of the current RTT and
// throughput estimates synchronously when this method is invoked.
void AddRTTAndThroughputEstimatesObserver(
RTTAndThroughputEstimatesObserver* observer);
// Unregisters |observer| from receiving notifications. This must be called
// on the same thread on which AddObserver() was called.
// All observers must be unregistered before |this| is destroyed.
void RemoveRTTAndThroughputEstimatesObserver(
RTTAndThroughputEstimatesObserver* observer);
protected: protected:
// NetworkQualityEstimatorManagerClient implementation. Protected for testing. // NetworkQualityEstimatorManagerClient implementation. Protected for testing.
void OnNetworkQualityChanged( void OnNetworkQualityChanged(
...@@ -112,6 +152,9 @@ class COMPONENT_EXPORT(NETWORK_CPP) NetworkQualityTracker ...@@ -112,6 +152,9 @@ class COMPONENT_EXPORT(NETWORK_CPP) NetworkQualityTracker
base::ObserverList<EffectiveConnectionTypeObserver> base::ObserverList<EffectiveConnectionTypeObserver>
effective_connection_type_observer_list_; effective_connection_type_observer_list_;
base::ObserverList<RTTAndThroughputEstimatesObserver>
rtt_and_throughput_observer_list_;
mojo::Binding<network::mojom::NetworkQualityEstimatorManagerClient> binding_; mojo::Binding<network::mojom::NetworkQualityEstimatorManagerClient> binding_;
SEQUENCE_CHECKER(sequence_checker_); SEQUENCE_CHECKER(sequence_checker_);
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "services/network/public/cpp/network_quality_tracker.h" #include "services/network/public/cpp/network_quality_tracker.h"
#include <limits>
#include "base/macros.h" #include "base/macros.h"
#include "base/run_loop.h" #include "base/run_loop.h"
#include "base/test/scoped_task_environment.h" #include "base/test/scoped_task_environment.h"
...@@ -25,7 +27,8 @@ class TestEffectiveConnectionTypeObserver ...@@ -25,7 +27,8 @@ class TestEffectiveConnectionTypeObserver
explicit TestEffectiveConnectionTypeObserver(NetworkQualityTracker* tracker) explicit TestEffectiveConnectionTypeObserver(NetworkQualityTracker* tracker)
: num_notifications_(0), : num_notifications_(0),
tracker_(tracker), tracker_(tracker),
run_loop_(std::make_unique<base::RunLoop>()), expected_effective_connection_type_(
net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN),
effective_connection_type_(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN) { effective_connection_type_(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN) {
tracker_->AddEffectiveConnectionTypeObserver(this); tracker_->AddEffectiveConnectionTypeObserver(this);
} }
...@@ -46,14 +49,23 @@ class TestEffectiveConnectionTypeObserver ...@@ -46,14 +49,23 @@ class TestEffectiveConnectionTypeObserver
EXPECT_EQ(type, GetEffectiveConnectionTypeSync()); EXPECT_EQ(type, GetEffectiveConnectionTypeSync());
num_notifications_++; num_notifications_++;
effective_connection_type_ = type; effective_connection_type_ = type;
run_loop_->Quit(); if (run_loop_ && type == expected_effective_connection_type_)
run_loop_->Quit();
} }
size_t num_notifications() const { return num_notifications_; } size_t num_notifications() const { return num_notifications_; }
void WaitForNotification() { void WaitForNotification(
net::EffectiveConnectionType expected_effective_connection_type) {
if (expected_effective_connection_type == effective_connection_type_)
return;
expected_effective_connection_type_ = expected_effective_connection_type;
// WaitForNotification should not be called twice.
EXPECT_EQ(nullptr, run_loop_);
run_loop_ = std::make_unique<base::RunLoop>();
run_loop_->Run(); run_loop_->Run();
run_loop_.reset(new base::RunLoop()); run_loop_.reset();
} }
net::EffectiveConnectionType effective_connection_type() const { net::EffectiveConnectionType effective_connection_type() const {
...@@ -61,22 +73,94 @@ class TestEffectiveConnectionTypeObserver ...@@ -61,22 +73,94 @@ class TestEffectiveConnectionTypeObserver
} }
private: private:
static void GetEffectiveConnectionTypeCallback(
base::RunLoop* run_loop,
net::EffectiveConnectionType* out,
net::EffectiveConnectionType type) {
*out = type;
run_loop->Quit();
}
size_t num_notifications_; size_t num_notifications_;
NetworkQualityTracker* tracker_; NetworkQualityTracker* tracker_;
// May be null.
std::unique_ptr<base::RunLoop> run_loop_; std::unique_ptr<base::RunLoop> run_loop_;
net::EffectiveConnectionType expected_effective_connection_type_;
net::EffectiveConnectionType effective_connection_type_; net::EffectiveConnectionType effective_connection_type_;
DISALLOW_COPY_AND_ASSIGN(TestEffectiveConnectionTypeObserver); DISALLOW_COPY_AND_ASSIGN(TestEffectiveConnectionTypeObserver);
}; };
class TestRTTAndThroughputEstimatesObserver
: public NetworkQualityTracker::RTTAndThroughputEstimatesObserver {
public:
explicit TestRTTAndThroughputEstimatesObserver(NetworkQualityTracker* tracker)
: num_notifications_(0),
tracker_(tracker),
downstream_throughput_kbps_(std::numeric_limits<int32_t>::max()) {
tracker_->AddRTTAndThroughputEstimatesObserver(this);
}
~TestRTTAndThroughputEstimatesObserver() override {
tracker_->RemoveRTTAndThroughputEstimatesObserver(this);
}
// RTTAndThroughputEstimatesObserver implementation:
void OnRTTOrThroughputEstimatesComputed(
base::TimeDelta http_rtt,
base::TimeDelta transport_rtt,
int32_t downstream_throughput_kbps) override {
EXPECT_EQ(http_rtt, tracker_->GetHttpRTT());
EXPECT_EQ(transport_rtt, tracker_->GetTransportRTT());
EXPECT_EQ(downstream_throughput_kbps,
tracker_->GetDownstreamThroughputKbps());
num_notifications_++;
http_rtt_ = http_rtt;
transport_rtt_ = transport_rtt;
downstream_throughput_kbps_ = downstream_throughput_kbps;
if (run_loop_ && http_rtt == http_rtt_notification_wait_)
run_loop_->Quit();
}
size_t num_notifications() const { return num_notifications_; }
void WaitForNotification(base::TimeDelta expected_http_rtt) {
// It's not meaningful to wait for notification with RTT set to
// base::TimeDelta() since that value implies that the network quality
// estimate was unavailable.
EXPECT_NE(base::TimeDelta(), expected_http_rtt);
http_rtt_notification_wait_ = expected_http_rtt;
if (http_rtt_notification_wait_ == http_rtt_)
return;
// WaitForNotification should not be called twice.
EXPECT_EQ(nullptr, run_loop_);
run_loop_ = std::make_unique<base::RunLoop>();
run_loop_->Run();
EXPECT_EQ(expected_http_rtt, http_rtt_);
run_loop_.reset();
}
void VerifyNetworkQualityMatchesWithTracker() const {
EXPECT_EQ(tracker_->GetHttpRTT(), http_rtt_);
EXPECT_EQ(tracker_->GetTransportRTT(), transport_rtt_);
EXPECT_EQ(tracker_->GetDownstreamThroughputKbps(),
downstream_throughput_kbps_);
}
base::TimeDelta http_rtt() const { return http_rtt_; }
base::TimeDelta transport_rtt() const { return transport_rtt_; }
int32_t downstream_throughput_kbps() const {
return downstream_throughput_kbps_;
}
private:
size_t num_notifications_;
NetworkQualityTracker* tracker_;
// May be null.
std::unique_ptr<base::RunLoop> run_loop_;
base::TimeDelta http_rtt_;
base::TimeDelta transport_rtt_;
int32_t downstream_throughput_kbps_;
base::TimeDelta http_rtt_notification_wait_;
DISALLOW_COPY_AND_ASSIGN(TestRTTAndThroughputEstimatesObserver);
};
} // namespace } // namespace
class NetworkQualityTrackerTest : public testing::Test { class NetworkQualityTrackerTest : public testing::Test {
...@@ -91,8 +175,10 @@ class NetworkQualityTrackerTest : public testing::Test { ...@@ -91,8 +175,10 @@ class NetworkQualityTrackerTest : public testing::Test {
tracker_ = std::make_unique<NetworkQualityTracker>( tracker_ = std::make_unique<NetworkQualityTracker>(
base::BindRepeating(&NetworkQualityTrackerTest::mojom_network_service, base::BindRepeating(&NetworkQualityTrackerTest::mojom_network_service,
base::Unretained(this))); base::Unretained(this)));
observer_ = ect_observer_ =
std::make_unique<TestEffectiveConnectionTypeObserver>(tracker_.get()); std::make_unique<TestEffectiveConnectionTypeObserver>(tracker_.get());
rtt_throughput_observer_ =
std::make_unique<TestRTTAndThroughputEstimatesObserver>(tracker_.get());
} }
~NetworkQualityTrackerTest() override {} ~NetworkQualityTrackerTest() override {}
...@@ -102,7 +188,11 @@ class NetworkQualityTrackerTest : public testing::Test { ...@@ -102,7 +188,11 @@ class NetworkQualityTrackerTest : public testing::Test {
NetworkQualityTracker* network_quality_tracker() { return tracker_.get(); } NetworkQualityTracker* network_quality_tracker() { return tracker_.get(); }
TestEffectiveConnectionTypeObserver* effective_connection_type_observer() { TestEffectiveConnectionTypeObserver* effective_connection_type_observer() {
return observer_.get(); return ect_observer_.get();
}
TestRTTAndThroughputEstimatesObserver* rtt_throughput_observer() {
return rtt_throughput_observer_.get();
} }
// Simulates a connection type change and broadcast it to observers. // Simulates a connection type change and broadcast it to observers.
...@@ -121,18 +211,20 @@ class NetworkQualityTrackerTest : public testing::Test { ...@@ -121,18 +211,20 @@ class NetworkQualityTrackerTest : public testing::Test {
base::test::ScopedTaskEnvironment scoped_task_environment_; base::test::ScopedTaskEnvironment scoped_task_environment_;
std::unique_ptr<network::NetworkService> network_service_; std::unique_ptr<network::NetworkService> network_service_;
std::unique_ptr<NetworkQualityTracker> tracker_; std::unique_ptr<NetworkQualityTracker> tracker_;
std::unique_ptr<TestEffectiveConnectionTypeObserver> observer_; std::unique_ptr<TestEffectiveConnectionTypeObserver> ect_observer_;
std::unique_ptr<TestRTTAndThroughputEstimatesObserver>
rtt_throughput_observer_;
DISALLOW_COPY_AND_ASSIGN(NetworkQualityTrackerTest); DISALLOW_COPY_AND_ASSIGN(NetworkQualityTrackerTest);
}; };
TEST_F(NetworkQualityTrackerTest, ObserverNotified) { TEST_F(NetworkQualityTrackerTest, ECTObserverNotified) {
EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN, EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN,
effective_connection_type_observer()->effective_connection_type()); effective_connection_type_observer()->effective_connection_type());
SimulateEffectiveConnectionTypeChange(net::EFFECTIVE_CONNECTION_TYPE_3G); SimulateEffectiveConnectionTypeChange(net::EFFECTIVE_CONNECTION_TYPE_3G);
effective_connection_type_observer()->WaitForNotification(
effective_connection_type_observer()->WaitForNotification(); net::EFFECTIVE_CONNECTION_TYPE_3G);
EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_3G, EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_3G,
effective_connection_type_observer()->effective_connection_type()); effective_connection_type_observer()->effective_connection_type());
// Typical RTT and downlink values when effective connection type is 3G. Taken // Typical RTT and downlink values when effective connection type is 3G. Taken
...@@ -144,20 +236,131 @@ TEST_F(NetworkQualityTrackerTest, ObserverNotified) { ...@@ -144,20 +236,131 @@ TEST_F(NetworkQualityTrackerTest, ObserverNotified) {
EXPECT_EQ(400, network_quality_tracker()->GetDownstreamThroughputKbps()); EXPECT_EQ(400, network_quality_tracker()->GetDownstreamThroughputKbps());
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
EXPECT_EQ(1u, effective_connection_type_observer()->num_notifications()); EXPECT_EQ(1u, effective_connection_type_observer()->num_notifications());
SimulateEffectiveConnectionTypeChange(net::EFFECTIVE_CONNECTION_TYPE_2G);
effective_connection_type_observer()->WaitForNotification(
net::EFFECTIVE_CONNECTION_TYPE_2G);
EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_2G,
effective_connection_type_observer()->effective_connection_type());
// Typical RTT and downlink values when effective connection type is 3G. Taken
// from net::NetworkQualityEstimatorParams.
EXPECT_EQ(base::TimeDelta::FromMilliseconds(1800),
network_quality_tracker()->GetHttpRTT());
EXPECT_EQ(base::TimeDelta::FromMilliseconds(1500),
network_quality_tracker()->GetTransportRTT());
EXPECT_EQ(75, network_quality_tracker()->GetDownstreamThroughputKbps());
base::RunLoop().RunUntilIdle();
EXPECT_EQ(2u, effective_connection_type_observer()->num_notifications());
} }
TEST_F(NetworkQualityTrackerTest, UnregisteredObserverNotNotified) { TEST_F(NetworkQualityTrackerTest, RttThroughputObserverNotified) {
auto network_quality_observer2 = // One notification must be received by rtt_throughput_observer() as soon as
std::make_unique<TestEffectiveConnectionTypeObserver>( // it is registered as an observer.
EXPECT_EQ(1u, rtt_throughput_observer()->num_notifications());
SimulateEffectiveConnectionTypeChange(net::EFFECTIVE_CONNECTION_TYPE_3G);
rtt_throughput_observer()->WaitForNotification(
base::TimeDelta::FromMilliseconds(450));
// Typical RTT and downlink values when effective connection type is 3G. Taken
// from net::NetworkQualityEstimatorParams.
EXPECT_EQ(base::TimeDelta::FromMilliseconds(450),
network_quality_tracker()->GetHttpRTT());
EXPECT_EQ(base::TimeDelta::FromMilliseconds(400),
network_quality_tracker()->GetTransportRTT());
EXPECT_EQ(400, network_quality_tracker()->GetDownstreamThroughputKbps());
rtt_throughput_observer()->VerifyNetworkQualityMatchesWithTracker();
EXPECT_EQ(2u, rtt_throughput_observer()->num_notifications());
SimulateEffectiveConnectionTypeChange(net::EFFECTIVE_CONNECTION_TYPE_2G);
rtt_throughput_observer()->VerifyNetworkQualityMatchesWithTracker();
rtt_throughput_observer()->WaitForNotification(
base::TimeDelta::FromMilliseconds(1800));
// Typical RTT and downlink values when effective connection type is 3G. Taken
// from net::NetworkQualityEstimatorParams.
EXPECT_EQ(base::TimeDelta::FromMilliseconds(1800),
network_quality_tracker()->GetHttpRTT());
EXPECT_EQ(base::TimeDelta::FromMilliseconds(1500),
network_quality_tracker()->GetTransportRTT());
EXPECT_EQ(75, network_quality_tracker()->GetDownstreamThroughputKbps());
EXPECT_EQ(3u, rtt_throughput_observer()->num_notifications());
}
TEST_F(NetworkQualityTrackerTest, ECTObserverNotifiedOnAddition) {
EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN,
effective_connection_type_observer()->effective_connection_type());
SimulateEffectiveConnectionTypeChange(net::EFFECTIVE_CONNECTION_TYPE_3G);
effective_connection_type_observer()->WaitForNotification(
net::EFFECTIVE_CONNECTION_TYPE_3G);
EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_3G,
effective_connection_type_observer()->effective_connection_type());
// Typical RTT and downlink values when effective connection type is 3G. Taken
// from net::NetworkQualityEstimatorParams.
EXPECT_EQ(base::TimeDelta::FromMilliseconds(450),
network_quality_tracker()->GetHttpRTT());
EXPECT_EQ(base::TimeDelta::FromMilliseconds(400),
network_quality_tracker()->GetTransportRTT());
EXPECT_EQ(400, network_quality_tracker()->GetDownstreamThroughputKbps());
EXPECT_EQ(1u, effective_connection_type_observer()->num_notifications());
auto ect_observer_2 = std::make_unique<TestEffectiveConnectionTypeObserver>(
network_quality_tracker());
ect_observer_2->WaitForNotification(net::EFFECTIVE_CONNECTION_TYPE_3G);
EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_3G,
ect_observer_2->effective_connection_type());
}
TEST_F(NetworkQualityTrackerTest, RttThroughputObserverNotifiedOnAddition) {
SimulateEffectiveConnectionTypeChange(net::EFFECTIVE_CONNECTION_TYPE_3G);
rtt_throughput_observer()->WaitForNotification(
base::TimeDelta::FromMilliseconds(450));
// Typical RTT and downlink values when effective connection type is 3G. Taken
// from net::NetworkQualityEstimatorParams.
EXPECT_EQ(base::TimeDelta::FromMilliseconds(450),
network_quality_tracker()->GetHttpRTT());
EXPECT_EQ(base::TimeDelta::FromMilliseconds(400),
network_quality_tracker()->GetTransportRTT());
EXPECT_EQ(400, network_quality_tracker()->GetDownstreamThroughputKbps());
rtt_throughput_observer()->VerifyNetworkQualityMatchesWithTracker();
EXPECT_EQ(2u, rtt_throughput_observer()->num_notifications());
auto rtt_throughput_observer_2 =
std::make_unique<TestRTTAndThroughputEstimatesObserver>(
network_quality_tracker()); network_quality_tracker());
rtt_throughput_observer_2->VerifyNetworkQualityMatchesWithTracker();
EXPECT_EQ(1u, rtt_throughput_observer_2->num_notifications());
// Simulate a network quality change.
SimulateEffectiveConnectionTypeChange(net::EFFECTIVE_CONNECTION_TYPE_2G);
rtt_throughput_observer()->WaitForNotification(
base::TimeDelta::FromMilliseconds(1800));
// Typical RTT and downlink values when effective connection type is 2G. Taken
// from net::NetworkQualityEstimatorParams.
EXPECT_EQ(base::TimeDelta::FromMilliseconds(1800),
network_quality_tracker()->GetHttpRTT());
EXPECT_EQ(base::TimeDelta::FromMilliseconds(1500),
network_quality_tracker()->GetTransportRTT());
EXPECT_EQ(75, network_quality_tracker()->GetDownstreamThroughputKbps());
rtt_throughput_observer()->VerifyNetworkQualityMatchesWithTracker();
EXPECT_EQ(3u, rtt_throughput_observer()->num_notifications());
rtt_throughput_observer_2->VerifyNetworkQualityMatchesWithTracker();
EXPECT_EQ(2u, rtt_throughput_observer_2->num_notifications());
}
TEST_F(NetworkQualityTrackerTest, UnregisteredECTObserverNotNotified) {
auto ect_observer_2 = std::make_unique<TestEffectiveConnectionTypeObserver>(
network_quality_tracker());
// Simulate a network quality change. // Simulate a network quality change.
SimulateEffectiveConnectionTypeChange(net::EFFECTIVE_CONNECTION_TYPE_3G); SimulateEffectiveConnectionTypeChange(net::EFFECTIVE_CONNECTION_TYPE_3G);
network_quality_observer2->WaitForNotification(); ect_observer_2->WaitForNotification(net::EFFECTIVE_CONNECTION_TYPE_3G);
EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_3G, EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_3G,
network_quality_observer2->effective_connection_type()); ect_observer_2->effective_connection_type());
effective_connection_type_observer()->WaitForNotification(); effective_connection_type_observer()->WaitForNotification(
net::EFFECTIVE_CONNECTION_TYPE_3G);
EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_3G, EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_3G,
effective_connection_type_observer()->effective_connection_type()); effective_connection_type_observer()->effective_connection_type());
// Typical RTT and downlink values when effective connection type is 3G. Taken // Typical RTT and downlink values when effective connection type is 3G. Taken
...@@ -167,13 +370,13 @@ TEST_F(NetworkQualityTrackerTest, UnregisteredObserverNotNotified) { ...@@ -167,13 +370,13 @@ TEST_F(NetworkQualityTrackerTest, UnregisteredObserverNotNotified) {
EXPECT_EQ(base::TimeDelta::FromMilliseconds(400), EXPECT_EQ(base::TimeDelta::FromMilliseconds(400),
network_quality_tracker()->GetTransportRTT()); network_quality_tracker()->GetTransportRTT());
EXPECT_EQ(400, network_quality_tracker()->GetDownstreamThroughputKbps()); EXPECT_EQ(400, network_quality_tracker()->GetDownstreamThroughputKbps());
base::RunLoop().RunUntilIdle();
network_quality_observer2.reset(); ect_observer_2.reset();
// Simulate an another network quality change. // Simulate an another network quality change.
SimulateEffectiveConnectionTypeChange(net::EFFECTIVE_CONNECTION_TYPE_2G); SimulateEffectiveConnectionTypeChange(net::EFFECTIVE_CONNECTION_TYPE_2G);
effective_connection_type_observer()->WaitForNotification(); effective_connection_type_observer()->WaitForNotification(
net::EFFECTIVE_CONNECTION_TYPE_2G);
EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_2G, EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_2G,
effective_connection_type_observer()->effective_connection_type()); effective_connection_type_observer()->effective_connection_type());
EXPECT_EQ(base::TimeDelta::FromMilliseconds(1800), EXPECT_EQ(base::TimeDelta::FromMilliseconds(1800),
...@@ -184,4 +387,42 @@ TEST_F(NetworkQualityTrackerTest, UnregisteredObserverNotNotified) { ...@@ -184,4 +387,42 @@ TEST_F(NetworkQualityTrackerTest, UnregisteredObserverNotNotified) {
EXPECT_EQ(2u, effective_connection_type_observer()->num_notifications()); EXPECT_EQ(2u, effective_connection_type_observer()->num_notifications());
} }
TEST_F(NetworkQualityTrackerTest, UnregisteredRttThroughputbserverNotNotified) {
auto rtt_throughput_observer_2 =
std::make_unique<TestRTTAndThroughputEstimatesObserver>(
network_quality_tracker());
// Simulate a network quality change.
SimulateEffectiveConnectionTypeChange(net::EFFECTIVE_CONNECTION_TYPE_3G);
rtt_throughput_observer()->WaitForNotification(
base::TimeDelta::FromMilliseconds(450));
// Typical RTT and downlink values when effective connection type is 3G. Taken
// from net::NetworkQualityEstimatorParams.
EXPECT_EQ(base::TimeDelta::FromMilliseconds(450),
network_quality_tracker()->GetHttpRTT());
EXPECT_EQ(base::TimeDelta::FromMilliseconds(400),
network_quality_tracker()->GetTransportRTT());
EXPECT_EQ(400, network_quality_tracker()->GetDownstreamThroughputKbps());
rtt_throughput_observer()->VerifyNetworkQualityMatchesWithTracker();
rtt_throughput_observer_2->VerifyNetworkQualityMatchesWithTracker();
// Destroying |rtt_throughput_observer_2| should unregister it as an observer.
// Verify that doing this causes network quality tracker to remove it as an
// observer from the list of registered observers.
rtt_throughput_observer_2.reset();
// Simulate an another network quality change.
SimulateEffectiveConnectionTypeChange(net::EFFECTIVE_CONNECTION_TYPE_2G);
rtt_throughput_observer()->WaitForNotification(
base::TimeDelta::FromMilliseconds(1800));
EXPECT_EQ(base::TimeDelta::FromMilliseconds(1800),
network_quality_tracker()->GetHttpRTT());
EXPECT_EQ(base::TimeDelta::FromMilliseconds(1500),
network_quality_tracker()->GetTransportRTT());
EXPECT_EQ(75, network_quality_tracker()->GetDownstreamThroughputKbps());
rtt_throughput_observer()->VerifyNetworkQualityMatchesWithTracker();
EXPECT_EQ(3u, rtt_throughput_observer()->num_notifications());
}
} // namespace network } // namespace network
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment