Commit 4935983c authored by btolsch's avatar btolsch Committed by Commit Bot

Fix cache bugs in CastMediaSinkServiceImpl

This change fixes two bugs with caching of media sinks and a potential
initialization race that could also affect the cache's performance.

The first fix is to allow network ID changes of network1->network2 to
cache sinks for network1 rather than only caching for
network1->disconnected/unknown.  The cache originally used the latter
logic because net::NetworkChangeNotifier broadcasts a disconnect between
any two network changes.  However, DiscoveryNetworkMonitor doesn't
necessarily forward this behavior to its observers because it actually
calculates the current network ID on every net::NetworkChangeNotifier
notification.  Not caching in the former case could account for some of
the cache's low utilization currently seen in metrics.

The second fix is to add CastMediaSinkServiceImpl as a
DiscoveryNetworkMonitor::Observer from the correct sequence so it
receives notifications on the correct sequence.  This in turn
exacerbates a race between the first network ID update and
CastMediaSinkServiceImpl's AddObserver call.  The race was therefore
also addressed in this change.

Bug: 782788, 782859
Change-Id: I064bd184508e66f1806e55dc5afe1eea907836ea
Reviewed-on: https://chromium-review.googlesource.com/760667
Commit-Queue: Brandon Tolsch <btolsch@chromium.org>
Reviewed-by: default avatarDerek Cheng <imcheng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#517134}
parent b3716d7f
...@@ -181,7 +181,6 @@ CastMediaSinkServiceImpl::CastMediaSinkServiceImpl( ...@@ -181,7 +181,6 @@ CastMediaSinkServiceImpl::CastMediaSinkServiceImpl(
DETACH_FROM_SEQUENCE(sequence_checker_); DETACH_FROM_SEQUENCE(sequence_checker_);
DCHECK(cast_socket_service_); DCHECK(cast_socket_service_);
DCHECK(network_monitor_); DCHECK(network_monitor_);
network_monitor_->AddObserver(this);
cast_socket_service_->AddObserver(this); cast_socket_service_->AddObserver(this);
retry_params_ = RetryParams::GetFromFieldTrialParam(); retry_params_ = RetryParams::GetFromFieldTrialParam();
...@@ -224,7 +223,6 @@ CastMediaSinkServiceImpl::CastMediaSinkServiceImpl( ...@@ -224,7 +223,6 @@ CastMediaSinkServiceImpl::CastMediaSinkServiceImpl(
CastMediaSinkServiceImpl::~CastMediaSinkServiceImpl() { CastMediaSinkServiceImpl::~CastMediaSinkServiceImpl() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
cast_channel::CastSocketService::GetInstance()->RemoveObserver(this); cast_channel::CastSocketService::GetInstance()->RemoveObserver(this);
network_monitor_->RemoveObserver(this);
} }
void CastMediaSinkServiceImpl::SetTaskRunnerForTest( void CastMediaSinkServiceImpl::SetTaskRunnerForTest(
...@@ -241,11 +239,18 @@ void CastMediaSinkServiceImpl::SetClockForTest( ...@@ -241,11 +239,18 @@ void CastMediaSinkServiceImpl::SetClockForTest(
void CastMediaSinkServiceImpl::Start() { void CastMediaSinkServiceImpl::Start() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
MediaSinkServiceBase::StartTimer(); MediaSinkServiceBase::StartTimer();
// This call to |GetNetworkId| ensures that we get the current network ID at
// least once during startup in case |AddObserver| occurs after the first
// round of notifications has already been dispatched.
network_monitor_->GetNetworkId(base::BindOnce(
&CastMediaSinkServiceImpl::OnNetworksChanged, AsWeakPtr()));
network_monitor_->AddObserver(this);
} }
void CastMediaSinkServiceImpl::Stop() { void CastMediaSinkServiceImpl::Stop() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
MediaSinkServiceBase::StopTimer(); MediaSinkServiceBase::StopTimer();
network_monitor_->RemoveObserver(this);
} }
void CastMediaSinkServiceImpl::OnFetchCompleted() { void CastMediaSinkServiceImpl::OnFetchCompleted() {
...@@ -338,21 +343,28 @@ void CastMediaSinkServiceImpl::OnMessage( ...@@ -338,21 +343,28 @@ void CastMediaSinkServiceImpl::OnMessage(
void CastMediaSinkServiceImpl::OnNetworksChanged( void CastMediaSinkServiceImpl::OnNetworksChanged(
const std::string& network_id) { const std::string& network_id) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// Although DiscoveryNetworkMonitor guarantees this condition won't be true
// from its Observer interface, the callback from |AddNetworkChangeObserver|
// could cause this to happen.
if (network_id == current_network_id_) {
return;
}
std::string last_network_id = current_network_id_; std::string last_network_id = current_network_id_;
current_network_id_ = network_id; current_network_id_ = network_id;
dial_sink_failure_count_.clear(); dial_sink_failure_count_.clear();
if (IsNetworkIdUnknownOrDisconnected(network_id)) { if (!IsNetworkIdUnknownOrDisconnected(last_network_id)) {
if (!IsNetworkIdUnknownOrDisconnected(last_network_id)) { // Collect current sinks even if OnFetchCompleted hasn't collected the
// Collect current sinks even if OnFetchCompleted hasn't collected the // latest sinks.
// latest sinks. std::vector<MediaSinkInternal> current_sinks;
std::vector<MediaSinkInternal> current_sinks; for (const auto& sink_it : current_sinks_map_) {
for (const auto& sink_it : current_sinks_map_) { current_sinks.push_back(sink_it.second);
current_sinks.push_back(sink_it.second);
}
sink_cache_[last_network_id] = std::move(current_sinks);
} }
return; sink_cache_[last_network_id] = std::move(current_sinks);
} }
if (IsNetworkIdUnknownOrDisconnected(network_id))
return;
auto cache_entry = sink_cache_.find(network_id); auto cache_entry = sink_cache_.find(network_id);
// Check if we have any cached sinks for this network ID. // Check if we have any cached sinks for this network ID.
if (cache_entry == sink_cache_.end()) if (cache_entry == sink_cache_.end())
......
...@@ -113,6 +113,8 @@ class CastMediaSinkServiceImpl ...@@ -113,6 +113,8 @@ class CastMediaSinkServiceImpl
CacheDialDiscoveredSinks); CacheDialDiscoveredSinks);
FRIEND_TEST_ALL_PREFIXES(CastMediaSinkServiceImplTest, FRIEND_TEST_ALL_PREFIXES(CastMediaSinkServiceImplTest,
DualDiscoveryDoesntDuplicateCacheItems); DualDiscoveryDoesntDuplicateCacheItems);
FRIEND_TEST_ALL_PREFIXES(CastMediaSinkServiceImplTest,
CacheSinksForDirectNetworkChange);
FRIEND_TEST_ALL_PREFIXES(CastMediaSinkServiceImplTest, TestAttemptConnection); FRIEND_TEST_ALL_PREFIXES(CastMediaSinkServiceImplTest, TestAttemptConnection);
FRIEND_TEST_ALL_PREFIXES(CastMediaSinkServiceImplTest, FRIEND_TEST_ALL_PREFIXES(CastMediaSinkServiceImplTest,
TestInitRetryParametersWithFeatureDisabled); TestInitRetryParametersWithFeatureDisabled);
......
...@@ -21,14 +21,14 @@ ...@@ -21,14 +21,14 @@
#include "testing/gmock/include/gmock/gmock.h" #include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
using base::Bucket;
using cast_channel::ChannelError;
using ::testing::_;
using testing::ElementsAre;
using ::testing::Invoke; using ::testing::Invoke;
using ::testing::Return; using ::testing::Return;
using ::testing::SaveArg; using ::testing::SaveArg;
using ::testing::WithArgs; using ::testing::WithArgs;
using ::testing::_;
using base::Bucket;
using cast_channel::ChannelError;
using testing::ElementsAre;
namespace { namespace {
...@@ -103,15 +103,17 @@ class CastMediaSinkServiceImplTest : public ::testing::Test { ...@@ -103,15 +103,17 @@ class CastMediaSinkServiceImplTest : public ::testing::Test {
mock_time_task_runner_.get()) {} mock_time_task_runner_.get()) {}
void SetUp() override { void SetUp() override {
content::RunAllTasksUntilIdle();
fake_network_info_.clear();
auto mock_timer = base::MakeUnique<base::MockTimer>( auto mock_timer = base::MakeUnique<base::MockTimer>(
true /*retain_user_task*/, false /*is_repeating*/); true /*retain_user_task*/, false /*is_repeating*/);
mock_timer_ = mock_timer.get(); mock_timer_ = mock_timer.get();
media_sink_service_impl_.SetTimerForTest(std::move(mock_timer)); media_sink_service_impl_.SetTimerForTest(std::move(mock_timer));
} }
void TearDown() override {
content::RunAllTasksUntilIdle();
fake_network_info_ = fake_ethernet_info_;
}
protected: protected:
void ExpectOpenSocketInternal(cast_channel::CastSocket* socket) { void ExpectOpenSocketInternal(cast_channel::CastSocket* socket) {
EXPECT_CALL(*mock_cast_socket_service_, EXPECT_CALL(*mock_cast_socket_service_,
...@@ -128,20 +130,16 @@ class CastMediaSinkServiceImplTest : public ::testing::Test { ...@@ -128,20 +130,16 @@ class CastMediaSinkServiceImplTest : public ::testing::Test {
media_sink_service_impl_); media_sink_service_impl_);
} }
static const std::vector<DiscoveryNetworkInfo> fake_ethernet_info_;
static const std::vector<DiscoveryNetworkInfo> fake_wifi_info_;
static const std::vector<DiscoveryNetworkInfo> fake_unknown_info_;
static std::vector<DiscoveryNetworkInfo> FakeGetNetworkInfo() { static std::vector<DiscoveryNetworkInfo> FakeGetNetworkInfo() {
return fake_network_info_; return fake_network_info_;
} }
static std::vector<DiscoveryNetworkInfo> fake_network_info_; static std::vector<DiscoveryNetworkInfo> fake_network_info_;
std::vector<DiscoveryNetworkInfo> fake_ethernet_info_ = {
DiscoveryNetworkInfo{std::string("enp0s2"), std::string("ethernet1")}};
std::vector<DiscoveryNetworkInfo> fake_wifi_info_ = {
DiscoveryNetworkInfo{std::string("wlp3s0"), std::string("wifi1")},
DiscoveryNetworkInfo{std::string("wlp3s1"), std::string("wifi2")}};
std::vector<DiscoveryNetworkInfo> fake_unknown_info_ = {
DiscoveryNetworkInfo{std::string("enp0s2"), std::string()}};
std::unique_ptr<net::NetworkChangeNotifier> network_change_notifier_ = std::unique_ptr<net::NetworkChangeNotifier> network_change_notifier_ =
base::WrapUnique(net::NetworkChangeNotifier::CreateMock()); base::WrapUnique(net::NetworkChangeNotifier::CreateMock());
...@@ -161,9 +159,24 @@ class CastMediaSinkServiceImplTest : public ::testing::Test { ...@@ -161,9 +159,24 @@ class CastMediaSinkServiceImplTest : public ::testing::Test {
DISALLOW_COPY_AND_ASSIGN(CastMediaSinkServiceImplTest); DISALLOW_COPY_AND_ASSIGN(CastMediaSinkServiceImplTest);
}; };
// static
const std::vector<DiscoveryNetworkInfo>
CastMediaSinkServiceImplTest::fake_ethernet_info_ = {
DiscoveryNetworkInfo{std::string("enp0s2"), std::string("ethernet1")}};
// static
const std::vector<DiscoveryNetworkInfo>
CastMediaSinkServiceImplTest::fake_wifi_info_ = {
DiscoveryNetworkInfo{std::string("wlp3s0"), std::string("wifi1")},
DiscoveryNetworkInfo{std::string("wlp3s1"), std::string("wifi2")}};
// static
const std::vector<DiscoveryNetworkInfo>
CastMediaSinkServiceImplTest::fake_unknown_info_ = {
DiscoveryNetworkInfo{std::string("enp0s2"), std::string()}};
// static // static
std::vector<DiscoveryNetworkInfo> std::vector<DiscoveryNetworkInfo>
CastMediaSinkServiceImplTest::fake_network_info_; CastMediaSinkServiceImplTest::fake_network_info_ =
CastMediaSinkServiceImplTest::fake_ethernet_info_;
TEST_F(CastMediaSinkServiceImplTest, TestOnChannelOpenSucceeded) { TEST_F(CastMediaSinkServiceImplTest, TestOnChannelOpenSucceeded) {
auto cast_sink = CreateCastSink(1); auto cast_sink = CreateCastSink(1);
...@@ -668,10 +681,12 @@ TEST_F(CastMediaSinkServiceImplTest, TestAttemptConnection) { ...@@ -668,10 +681,12 @@ TEST_F(CastMediaSinkServiceImplTest, TestAttemptConnection) {
} }
TEST_F(CastMediaSinkServiceImplTest, CacheSinksForKnownNetwork) { TEST_F(CastMediaSinkServiceImplTest, CacheSinksForKnownNetwork) {
fake_network_info_ = fake_ethernet_info_; media_sink_service_impl_.Start();
net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
net::NetworkChangeNotifier::CONNECTION_ETHERNET);
content::RunAllTasksUntilIdle(); content::RunAllTasksUntilIdle();
// We need to run the mock task runner for the network change callback, but
// the socket retries interfere with our normal expectations. Instead we
// disable retries with this line.
media_sink_service_impl_.retry_params_.max_retry_attempts = 0;
MediaSinkInternal sink1 = CreateCastSink(1); MediaSinkInternal sink1 = CreateCastSink(1);
MediaSinkInternal sink2 = CreateCastSink(2); MediaSinkInternal sink2 = CreateCastSink(2);
...@@ -696,11 +711,13 @@ TEST_F(CastMediaSinkServiceImplTest, CacheSinksForKnownNetwork) { ...@@ -696,11 +711,13 @@ TEST_F(CastMediaSinkServiceImplTest, CacheSinksForKnownNetwork) {
net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests( net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
net::NetworkChangeNotifier::CONNECTION_NONE); net::NetworkChangeNotifier::CONNECTION_NONE);
content::RunAllTasksUntilIdle(); content::RunAllTasksUntilIdle();
mock_time_task_runner_->RunUntilIdle();
fake_network_info_ = fake_wifi_info_; fake_network_info_ = fake_wifi_info_;
net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests( net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
net::NetworkChangeNotifier::CONNECTION_WIFI); net::NetworkChangeNotifier::CONNECTION_WIFI);
content::RunAllTasksUntilIdle(); content::RunAllTasksUntilIdle();
mock_time_task_runner_->RunUntilIdle();
media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1); media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1);
media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint2); media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint2);
...@@ -721,6 +738,7 @@ TEST_F(CastMediaSinkServiceImplTest, CacheSinksForKnownNetwork) { ...@@ -721,6 +738,7 @@ TEST_F(CastMediaSinkServiceImplTest, CacheSinksForKnownNetwork) {
net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests( net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
net::NetworkChangeNotifier::CONNECTION_NONE); net::NetworkChangeNotifier::CONNECTION_NONE);
content::RunAllTasksUntilIdle(); content::RunAllTasksUntilIdle();
mock_time_task_runner_->RunUntilIdle();
EXPECT_CALL(*mock_cast_socket_service_, EXPECT_CALL(*mock_cast_socket_service_,
OpenSocketInternal(ip_endpoint1, _, _)); OpenSocketInternal(ip_endpoint1, _, _));
...@@ -730,13 +748,16 @@ TEST_F(CastMediaSinkServiceImplTest, CacheSinksForKnownNetwork) { ...@@ -730,13 +748,16 @@ TEST_F(CastMediaSinkServiceImplTest, CacheSinksForKnownNetwork) {
net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests( net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
net::NetworkChangeNotifier::CONNECTION_ETHERNET); net::NetworkChangeNotifier::CONNECTION_ETHERNET);
content::RunAllTasksUntilIdle(); content::RunAllTasksUntilIdle();
mock_time_task_runner_->RunUntilIdle();
} }
TEST_F(CastMediaSinkServiceImplTest, CacheContainsOnlyResolvedSinks) { TEST_F(CastMediaSinkServiceImplTest, CacheContainsOnlyResolvedSinks) {
fake_network_info_ = fake_ethernet_info_; media_sink_service_impl_.Start();
net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
net::NetworkChangeNotifier::CONNECTION_ETHERNET);
content::RunAllTasksUntilIdle(); content::RunAllTasksUntilIdle();
// We need to run the mock task runner for the network change callback, but
// the socket retries interfere with our normal expectations. Instead we
// disable retries with this line.
media_sink_service_impl_.retry_params_.max_retry_attempts = 0;
MediaSinkInternal sink1 = CreateCastSink(1); MediaSinkInternal sink1 = CreateCastSink(1);
MediaSinkInternal sink2 = CreateCastSink(2); MediaSinkInternal sink2 = CreateCastSink(2);
...@@ -762,11 +783,13 @@ TEST_F(CastMediaSinkServiceImplTest, CacheContainsOnlyResolvedSinks) { ...@@ -762,11 +783,13 @@ TEST_F(CastMediaSinkServiceImplTest, CacheContainsOnlyResolvedSinks) {
net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests( net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
net::NetworkChangeNotifier::CONNECTION_NONE); net::NetworkChangeNotifier::CONNECTION_NONE);
content::RunAllTasksUntilIdle(); content::RunAllTasksUntilIdle();
mock_time_task_runner_->RunUntilIdle();
fake_network_info_ = fake_wifi_info_; fake_network_info_ = fake_wifi_info_;
net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests( net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
net::NetworkChangeNotifier::CONNECTION_WIFI); net::NetworkChangeNotifier::CONNECTION_WIFI);
content::RunAllTasksUntilIdle(); content::RunAllTasksUntilIdle();
mock_time_task_runner_->RunUntilIdle();
media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1); media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1);
MediaSinkInternal sink3 = CreateCastSink(3); MediaSinkInternal sink3 = CreateCastSink(3);
...@@ -786,6 +809,7 @@ TEST_F(CastMediaSinkServiceImplTest, CacheContainsOnlyResolvedSinks) { ...@@ -786,6 +809,7 @@ TEST_F(CastMediaSinkServiceImplTest, CacheContainsOnlyResolvedSinks) {
net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests( net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
net::NetworkChangeNotifier::CONNECTION_NONE); net::NetworkChangeNotifier::CONNECTION_NONE);
content::RunAllTasksUntilIdle(); content::RunAllTasksUntilIdle();
mock_time_task_runner_->RunUntilIdle();
EXPECT_CALL(*mock_cast_socket_service_, EXPECT_CALL(*mock_cast_socket_service_,
OpenSocketInternal(ip_endpoint1, _, _)); OpenSocketInternal(ip_endpoint1, _, _));
...@@ -796,13 +820,16 @@ TEST_F(CastMediaSinkServiceImplTest, CacheContainsOnlyResolvedSinks) { ...@@ -796,13 +820,16 @@ TEST_F(CastMediaSinkServiceImplTest, CacheContainsOnlyResolvedSinks) {
net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests( net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
net::NetworkChangeNotifier::CONNECTION_ETHERNET); net::NetworkChangeNotifier::CONNECTION_ETHERNET);
content::RunAllTasksUntilIdle(); content::RunAllTasksUntilIdle();
mock_time_task_runner_->RunUntilIdle();
} }
TEST_F(CastMediaSinkServiceImplTest, CacheUpdatedOnChannelOpenFailed) { TEST_F(CastMediaSinkServiceImplTest, CacheUpdatedOnChannelOpenFailed) {
fake_network_info_ = fake_ethernet_info_; media_sink_service_impl_.Start();
net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
net::NetworkChangeNotifier::CONNECTION_ETHERNET);
content::RunAllTasksUntilIdle(); content::RunAllTasksUntilIdle();
// We need to run the mock task runner for the network change callback, but
// the socket retries interfere with our normal expectations. Instead we
// disable retries with this line.
media_sink_service_impl_.retry_params_.max_retry_attempts = 0;
MediaSinkInternal sink1 = CreateCastSink(1); MediaSinkInternal sink1 = CreateCastSink(1);
net::IPEndPoint ip_endpoint1 = CreateIPEndPoint(1); net::IPEndPoint ip_endpoint1 = CreateIPEndPoint(1);
...@@ -823,11 +850,13 @@ TEST_F(CastMediaSinkServiceImplTest, CacheUpdatedOnChannelOpenFailed) { ...@@ -823,11 +850,13 @@ TEST_F(CastMediaSinkServiceImplTest, CacheUpdatedOnChannelOpenFailed) {
net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests( net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
net::NetworkChangeNotifier::CONNECTION_NONE); net::NetworkChangeNotifier::CONNECTION_NONE);
content::RunAllTasksUntilIdle(); content::RunAllTasksUntilIdle();
mock_time_task_runner_->RunUntilIdle();
fake_network_info_ = fake_wifi_info_; fake_network_info_ = fake_wifi_info_;
net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests( net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
net::NetworkChangeNotifier::CONNECTION_WIFI); net::NetworkChangeNotifier::CONNECTION_WIFI);
content::RunAllTasksUntilIdle(); content::RunAllTasksUntilIdle();
mock_time_task_runner_->RunUntilIdle();
MediaSinkInternal sink2 = CreateCastSink(2); MediaSinkInternal sink2 = CreateCastSink(2);
net::IPEndPoint ip_endpoint2 = CreateIPEndPoint(2); net::IPEndPoint ip_endpoint2 = CreateIPEndPoint(2);
...@@ -847,17 +876,30 @@ TEST_F(CastMediaSinkServiceImplTest, CacheUpdatedOnChannelOpenFailed) { ...@@ -847,17 +876,30 @@ TEST_F(CastMediaSinkServiceImplTest, CacheUpdatedOnChannelOpenFailed) {
net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests( net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
net::NetworkChangeNotifier::CONNECTION_NONE); net::NetworkChangeNotifier::CONNECTION_NONE);
content::RunAllTasksUntilIdle(); content::RunAllTasksUntilIdle();
mock_time_task_runner_->RunUntilIdle();
EXPECT_CALL(*mock_cast_socket_service_, OpenSocketInternal(_, _, _)).Times(0); EXPECT_CALL(*mock_cast_socket_service_, OpenSocketInternal(_, _, _)).Times(0);
fake_network_info_ = fake_ethernet_info_; fake_network_info_ = fake_ethernet_info_;
net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests( net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
net::NetworkChangeNotifier::CONNECTION_ETHERNET); net::NetworkChangeNotifier::CONNECTION_ETHERNET);
content::RunAllTasksUntilIdle(); content::RunAllTasksUntilIdle();
mock_time_task_runner_->RunUntilIdle();
} }
TEST_F(CastMediaSinkServiceImplTest, UnknownNetworkNoCache) { TEST_F(CastMediaSinkServiceImplTest, UnknownNetworkNoCache) {
// Without any network notification here, network ID will remain __unknown__ media_sink_service_impl_.Start();
// and the cache shouldn't save any of these sinks. content::RunAllTasksUntilIdle();
// We need to run the mock task runner for the network change callback, but
// the socket retries interfere with our normal expectations. Instead we
// disable retries with this line.
media_sink_service_impl_.retry_params_.max_retry_attempts = 0;
fake_network_info_ = fake_unknown_info_;
net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
net::NetworkChangeNotifier::CONNECTION_UNKNOWN);
content::RunAllTasksUntilIdle();
mock_time_task_runner_->RunUntilIdle();
MediaSinkInternal sink1 = CreateCastSink(1); MediaSinkInternal sink1 = CreateCastSink(1);
MediaSinkInternal sink2 = CreateCastSink(2); MediaSinkInternal sink2 = CreateCastSink(2);
net::IPEndPoint ip_endpoint1 = CreateIPEndPoint(1); net::IPEndPoint ip_endpoint1 = CreateIPEndPoint(1);
...@@ -881,6 +923,7 @@ TEST_F(CastMediaSinkServiceImplTest, UnknownNetworkNoCache) { ...@@ -881,6 +923,7 @@ TEST_F(CastMediaSinkServiceImplTest, UnknownNetworkNoCache) {
net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests( net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
net::NetworkChangeNotifier::CONNECTION_NONE); net::NetworkChangeNotifier::CONNECTION_NONE);
content::RunAllTasksUntilIdle(); content::RunAllTasksUntilIdle();
mock_time_task_runner_->RunUntilIdle();
media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1); media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1);
media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint2); media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint2);
...@@ -902,19 +945,23 @@ TEST_F(CastMediaSinkServiceImplTest, UnknownNetworkNoCache) { ...@@ -902,19 +945,23 @@ TEST_F(CastMediaSinkServiceImplTest, UnknownNetworkNoCache) {
net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests( net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
net::NetworkChangeNotifier::CONNECTION_WIFI); net::NetworkChangeNotifier::CONNECTION_WIFI);
content::RunAllTasksUntilIdle(); content::RunAllTasksUntilIdle();
mock_time_task_runner_->RunUntilIdle();
// Similarly, disconnecting from the network shouldn't pull any cache items. // Similarly, disconnecting from the network shouldn't pull any cache items.
fake_network_info_.clear(); fake_network_info_.clear();
net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests( net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
net::NetworkChangeNotifier::CONNECTION_NONE); net::NetworkChangeNotifier::CONNECTION_NONE);
content::RunAllTasksUntilIdle(); content::RunAllTasksUntilIdle();
mock_time_task_runner_->RunUntilIdle();
} }
TEST_F(CastMediaSinkServiceImplTest, CacheUpdatedForKnownNetwork) { TEST_F(CastMediaSinkServiceImplTest, CacheUpdatedForKnownNetwork) {
fake_network_info_ = fake_ethernet_info_; media_sink_service_impl_.Start();
net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
net::NetworkChangeNotifier::CONNECTION_ETHERNET);
content::RunAllTasksUntilIdle(); content::RunAllTasksUntilIdle();
// We need to run the mock task runner for the network change callback, but
// the socket retries interfere with our normal expectations. Instead we
// disable retries with this line.
media_sink_service_impl_.retry_params_.max_retry_attempts = 0;
MediaSinkInternal sink1 = CreateCastSink(1); MediaSinkInternal sink1 = CreateCastSink(1);
MediaSinkInternal sink2 = CreateCastSink(2); MediaSinkInternal sink2 = CreateCastSink(2);
...@@ -939,11 +986,13 @@ TEST_F(CastMediaSinkServiceImplTest, CacheUpdatedForKnownNetwork) { ...@@ -939,11 +986,13 @@ TEST_F(CastMediaSinkServiceImplTest, CacheUpdatedForKnownNetwork) {
net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests( net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
net::NetworkChangeNotifier::CONNECTION_NONE); net::NetworkChangeNotifier::CONNECTION_NONE);
content::RunAllTasksUntilIdle(); content::RunAllTasksUntilIdle();
mock_time_task_runner_->RunUntilIdle();
fake_network_info_ = fake_wifi_info_; fake_network_info_ = fake_wifi_info_;
net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests( net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
net::NetworkChangeNotifier::CONNECTION_WIFI); net::NetworkChangeNotifier::CONNECTION_WIFI);
content::RunAllTasksUntilIdle(); content::RunAllTasksUntilIdle();
mock_time_task_runner_->RunUntilIdle();
media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1); media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1);
media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint2); media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint2);
...@@ -964,6 +1013,7 @@ TEST_F(CastMediaSinkServiceImplTest, CacheUpdatedForKnownNetwork) { ...@@ -964,6 +1013,7 @@ TEST_F(CastMediaSinkServiceImplTest, CacheUpdatedForKnownNetwork) {
net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests( net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
net::NetworkChangeNotifier::CONNECTION_NONE); net::NetworkChangeNotifier::CONNECTION_NONE);
content::RunAllTasksUntilIdle(); content::RunAllTasksUntilIdle();
mock_time_task_runner_->RunUntilIdle();
media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint3); media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint3);
...@@ -976,6 +1026,7 @@ TEST_F(CastMediaSinkServiceImplTest, CacheUpdatedForKnownNetwork) { ...@@ -976,6 +1026,7 @@ TEST_F(CastMediaSinkServiceImplTest, CacheUpdatedForKnownNetwork) {
net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests( net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
net::NetworkChangeNotifier::CONNECTION_ETHERNET); net::NetworkChangeNotifier::CONNECTION_ETHERNET);
content::RunAllTasksUntilIdle(); content::RunAllTasksUntilIdle();
mock_time_task_runner_->RunUntilIdle();
// A new sink is found on the ethernet network. // A new sink is found on the ethernet network.
MediaSinkInternal sink4 = CreateCastSink(4); MediaSinkInternal sink4 = CreateCastSink(4);
...@@ -994,6 +1045,7 @@ TEST_F(CastMediaSinkServiceImplTest, CacheUpdatedForKnownNetwork) { ...@@ -994,6 +1045,7 @@ TEST_F(CastMediaSinkServiceImplTest, CacheUpdatedForKnownNetwork) {
net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests( net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
net::NetworkChangeNotifier::CONNECTION_NONE); net::NetworkChangeNotifier::CONNECTION_NONE);
content::RunAllTasksUntilIdle(); content::RunAllTasksUntilIdle();
mock_time_task_runner_->RunUntilIdle();
media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint4); media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint4);
// Reconnect and expect only |sink4| to be cached. // Reconnect and expect only |sink4| to be cached.
...@@ -1003,13 +1055,16 @@ TEST_F(CastMediaSinkServiceImplTest, CacheUpdatedForKnownNetwork) { ...@@ -1003,13 +1055,16 @@ TEST_F(CastMediaSinkServiceImplTest, CacheUpdatedForKnownNetwork) {
net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests( net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
net::NetworkChangeNotifier::CONNECTION_ETHERNET); net::NetworkChangeNotifier::CONNECTION_ETHERNET);
content::RunAllTasksUntilIdle(); content::RunAllTasksUntilIdle();
mock_time_task_runner_->RunUntilIdle();
} }
TEST_F(CastMediaSinkServiceImplTest, CacheDialDiscoveredSinks) { TEST_F(CastMediaSinkServiceImplTest, CacheDialDiscoveredSinks) {
fake_network_info_ = fake_ethernet_info_; media_sink_service_impl_.Start();
net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
net::NetworkChangeNotifier::CONNECTION_ETHERNET);
content::RunAllTasksUntilIdle(); content::RunAllTasksUntilIdle();
// We need to run the mock task runner for the network change callback, but
// the socket retries interfere with our normal expectations. Instead we
// disable retries with this line.
media_sink_service_impl_.retry_params_.max_retry_attempts = 0;
MediaSinkInternal sink1_cast = CreateCastSink(1); MediaSinkInternal sink1_cast = CreateCastSink(1);
MediaSinkInternal sink2_dial = CreateDialSink(2); MediaSinkInternal sink2_dial = CreateDialSink(2);
...@@ -1036,11 +1091,13 @@ TEST_F(CastMediaSinkServiceImplTest, CacheDialDiscoveredSinks) { ...@@ -1036,11 +1091,13 @@ TEST_F(CastMediaSinkServiceImplTest, CacheDialDiscoveredSinks) {
net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests( net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
net::NetworkChangeNotifier::CONNECTION_NONE); net::NetworkChangeNotifier::CONNECTION_NONE);
content::RunAllTasksUntilIdle(); content::RunAllTasksUntilIdle();
mock_time_task_runner_->RunUntilIdle();
fake_network_info_ = fake_wifi_info_; fake_network_info_ = fake_wifi_info_;
net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests( net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
net::NetworkChangeNotifier::CONNECTION_WIFI); net::NetworkChangeNotifier::CONNECTION_WIFI);
content::RunAllTasksUntilIdle(); content::RunAllTasksUntilIdle();
mock_time_task_runner_->RunUntilIdle();
media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1); media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1);
media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint2); media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint2);
...@@ -1069,6 +1126,7 @@ TEST_F(CastMediaSinkServiceImplTest, CacheDialDiscoveredSinks) { ...@@ -1069,6 +1126,7 @@ TEST_F(CastMediaSinkServiceImplTest, CacheDialDiscoveredSinks) {
net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests( net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
net::NetworkChangeNotifier::CONNECTION_NONE); net::NetworkChangeNotifier::CONNECTION_NONE);
content::RunAllTasksUntilIdle(); content::RunAllTasksUntilIdle();
mock_time_task_runner_->RunUntilIdle();
EXPECT_CALL(*mock_cast_socket_service_, EXPECT_CALL(*mock_cast_socket_service_,
OpenSocketInternal(ip_endpoint1, _, _)); OpenSocketInternal(ip_endpoint1, _, _));
...@@ -1078,13 +1136,16 @@ TEST_F(CastMediaSinkServiceImplTest, CacheDialDiscoveredSinks) { ...@@ -1078,13 +1136,16 @@ TEST_F(CastMediaSinkServiceImplTest, CacheDialDiscoveredSinks) {
net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests( net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
net::NetworkChangeNotifier::CONNECTION_ETHERNET); net::NetworkChangeNotifier::CONNECTION_ETHERNET);
content::RunAllTasksUntilIdle(); content::RunAllTasksUntilIdle();
mock_time_task_runner_->RunUntilIdle();
} }
TEST_F(CastMediaSinkServiceImplTest, DualDiscoveryDoesntDuplicateCacheItems) { TEST_F(CastMediaSinkServiceImplTest, DualDiscoveryDoesntDuplicateCacheItems) {
fake_network_info_ = fake_ethernet_info_; media_sink_service_impl_.Start();
net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
net::NetworkChangeNotifier::CONNECTION_ETHERNET);
content::RunAllTasksUntilIdle(); content::RunAllTasksUntilIdle();
// We need to run the mock task runner for the network change callback, but
// the socket retries interfere with our normal expectations. Instead we
// disable retries with this line.
media_sink_service_impl_.retry_params_.max_retry_attempts = 0;
// The same sink will be discovered via dial and mdns. // The same sink will be discovered via dial and mdns.
MediaSinkInternal sink1_cast = CreateCastSink(0); MediaSinkInternal sink1_cast = CreateCastSink(0);
...@@ -1114,11 +1175,13 @@ TEST_F(CastMediaSinkServiceImplTest, DualDiscoveryDoesntDuplicateCacheItems) { ...@@ -1114,11 +1175,13 @@ TEST_F(CastMediaSinkServiceImplTest, DualDiscoveryDoesntDuplicateCacheItems) {
net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests( net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
net::NetworkChangeNotifier::CONNECTION_NONE); net::NetworkChangeNotifier::CONNECTION_NONE);
content::RunAllTasksUntilIdle(); content::RunAllTasksUntilIdle();
mock_time_task_runner_->RunUntilIdle();
fake_network_info_ = fake_wifi_info_; fake_network_info_ = fake_wifi_info_;
net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests( net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
net::NetworkChangeNotifier::CONNECTION_WIFI); net::NetworkChangeNotifier::CONNECTION_WIFI);
content::RunAllTasksUntilIdle(); content::RunAllTasksUntilIdle();
mock_time_task_runner_->RunUntilIdle();
media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1_cast); media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1_cast);
media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1_dial); media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1_dial);
...@@ -1139,6 +1202,7 @@ TEST_F(CastMediaSinkServiceImplTest, DualDiscoveryDoesntDuplicateCacheItems) { ...@@ -1139,6 +1202,7 @@ TEST_F(CastMediaSinkServiceImplTest, DualDiscoveryDoesntDuplicateCacheItems) {
net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests( net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
net::NetworkChangeNotifier::CONNECTION_NONE); net::NetworkChangeNotifier::CONNECTION_NONE);
content::RunAllTasksUntilIdle(); content::RunAllTasksUntilIdle();
mock_time_task_runner_->RunUntilIdle();
EXPECT_CALL(*mock_cast_socket_service_, EXPECT_CALL(*mock_cast_socket_service_,
OpenSocketInternal(ip_endpoint1_cast, _, _)); OpenSocketInternal(ip_endpoint1_cast, _, _));
...@@ -1146,6 +1210,66 @@ TEST_F(CastMediaSinkServiceImplTest, DualDiscoveryDoesntDuplicateCacheItems) { ...@@ -1146,6 +1210,66 @@ TEST_F(CastMediaSinkServiceImplTest, DualDiscoveryDoesntDuplicateCacheItems) {
net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests( net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
net::NetworkChangeNotifier::CONNECTION_ETHERNET); net::NetworkChangeNotifier::CONNECTION_ETHERNET);
content::RunAllTasksUntilIdle(); content::RunAllTasksUntilIdle();
mock_time_task_runner_->RunUntilIdle();
}
TEST_F(CastMediaSinkServiceImplTest, CacheSinksForDirectNetworkChange) {
media_sink_service_impl_.Start();
content::RunAllTasksUntilIdle();
// We need to run the mock task runner for the network change callback, but
// the socket retries interfere with our normal expectations. Instead we
// disable retries with this line.
media_sink_service_impl_.retry_params_.max_retry_attempts = 0;
MediaSinkInternal sink1 = CreateCastSink(1);
MediaSinkInternal sink2 = CreateCastSink(2);
net::IPEndPoint ip_endpoint1 = CreateIPEndPoint(1);
net::IPEndPoint ip_endpoint2 = CreateIPEndPoint(2);
std::vector<MediaSinkInternal> sink_list1{sink1, sink2};
// Resolution will succeed for both sinks.
cast_channel::MockCastSocket socket1;
cast_channel::MockCastSocket socket2;
socket1.SetIPEndpoint(ip_endpoint1);
socket1.set_id(1);
socket2.SetIPEndpoint(ip_endpoint2);
socket2.set_id(2);
ExpectOpenSocketInternal(&socket1);
ExpectOpenSocketInternal(&socket2);
media_sink_service_impl_.OpenChannels(
sink_list1, CastMediaSinkServiceImpl::SinkSource::kMdns);
// Connect to a new network with different sinks.
fake_network_info_ = fake_wifi_info_;
net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
net::NetworkChangeNotifier::CONNECTION_WIFI);
content::RunAllTasksUntilIdle();
mock_time_task_runner_->RunUntilIdle();
media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1);
media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint2);
MediaSinkInternal sink3 = CreateCastSink(3);
net::IPEndPoint ip_endpoint3 = CreateIPEndPoint(3);
std::vector<MediaSinkInternal> sink_list2{sink3};
cast_channel::MockCastSocket socket3;
socket3.SetIPEndpoint(ip_endpoint3);
socket3.set_id(3);
ExpectOpenSocketInternal(&socket3);
media_sink_service_impl_.OpenChannels(
sink_list2, CastMediaSinkServiceImpl::SinkSource::kMdns);
// Reconnecting to the previous ethernet network should restore the same sinks
// from the cache and attempt to resolve them.
EXPECT_CALL(*mock_cast_socket_service_,
OpenSocketInternal(ip_endpoint1, _, _));
EXPECT_CALL(*mock_cast_socket_service_,
OpenSocketInternal(ip_endpoint2, _, _));
fake_network_info_ = fake_ethernet_info_;
net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
net::NetworkChangeNotifier::CONNECTION_ETHERNET);
content::RunAllTasksUntilIdle();
mock_time_task_runner_->RunUntilIdle();
} }
TEST_F(CastMediaSinkServiceImplTest, TestCreateCastSocketOpenParams) { TEST_F(CastMediaSinkServiceImplTest, TestCreateCastSocketOpenParams) {
......
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