// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/test/mock_callback.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/test_mock_time_task_runner.h"
#include "base/timer/mock_timer.h"
#include "chrome/browser/media/router/media_router_feature.h"
#include "chrome/browser/media/router/test_helper.h"
#include "components/cast_channel/cast_socket.h"
#include "components/cast_channel/cast_socket_service.h"
#include "components/cast_channel/cast_test_util.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/public/test/test_utils.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using ::testing::Invoke;
using ::testing::Return;
using ::testing::SaveArg;
using ::testing::WithArgs;
using ::testing::_;
using cast_channel::ChannelError;

namespace {

net::IPEndPoint CreateIPEndPoint(int num) {
  net::IPAddress ip_address;
  CHECK(ip_address.AssignFromIPLiteral(
      base::StringPrintf("192.168.0.10%d", num)));
  return net::IPEndPoint(ip_address, 8009 + num);
}

media_router::MediaSinkInternal CreateCastSink(int num) {
  std::string friendly_name = base::StringPrintf("friendly name %d", num);
  std::string unique_id = base::StringPrintf("id %d", num);
  net::IPEndPoint ip_endpoint = CreateIPEndPoint(num);

  media_router::MediaSink sink(unique_id, friendly_name,
                               media_router::SinkIconType::CAST);
  media_router::CastSinkExtraData extra_data;
  extra_data.ip_endpoint = ip_endpoint;
  extra_data.port = ip_endpoint.port();
  extra_data.model_name = base::StringPrintf("model name %d", num);
  extra_data.cast_channel_id = num;
  extra_data.capabilities = cast_channel::CastDeviceCapability::AUDIO_OUT |
                            cast_channel::CastDeviceCapability::VIDEO_OUT;
  return media_router::MediaSinkInternal(sink, extra_data);
}

media_router::MediaSinkInternal CreateDialSink(int num) {
  std::string friendly_name = base::StringPrintf("friendly name %d", num);
  std::string unique_id = base::StringPrintf("id %d", num);
  net::IPEndPoint ip_endpoint = CreateIPEndPoint(num);

  media_router::MediaSink sink(unique_id, friendly_name,
                               media_router::SinkIconType::GENERIC);
  media_router::DialSinkExtraData extra_data;
  extra_data.ip_address = ip_endpoint.address();
  extra_data.model_name = base::StringPrintf("model name %d", num);
  return media_router::MediaSinkInternal(sink, extra_data);
}

}  // namespace

namespace media_router {

class CastMediaSinkServiceImplTest : public ::testing::Test {
 public:
  CastMediaSinkServiceImplTest()
      : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
        mock_cast_socket_service_(new cast_channel::MockCastSocketService()),
        mock_time_task_runner_(new base::TestMockTimeTaskRunner()),
        media_sink_service_impl_(mock_sink_discovered_cb_.Get(),
                                 mock_cast_socket_service_.get(),
                                 discovery_network_monitor_.get(),
                                 mock_time_task_runner_.get()) {}

  void SetUp() override {
    fake_network_info_.clear();
    auto mock_timer = base::MakeUnique<base::MockTimer>(
        true /*retain_user_task*/, false /*is_repeating*/);
    mock_timer_ = mock_timer.get();
    media_sink_service_impl_.SetTimerForTest(std::move(mock_timer));
  }

 protected:
  void ExpectOpenSocketInternal(cast_channel::CastSocket* socket) {
    EXPECT_CALL(*mock_cast_socket_service_,
                OpenSocketInternal(socket->ip_endpoint(), _, _, _))
        .WillOnce(Invoke([socket](const auto& ip_endpoint, auto* net_log,
                                  auto open_cb, auto* observer) {
          std::move(open_cb).Run(socket);
          return socket->id();
        }));
  }

  cast_channel::CastSocket::Observer& observer() {
    return static_cast<cast_channel::CastSocket::Observer&>(
        media_sink_service_impl_);
  }

  static std::vector<DiscoveryNetworkInfo> FakeGetNetworkInfo() {
    return 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_ =
      base::WrapUnique(net::NetworkChangeNotifier::CreateMock());

  const content::TestBrowserThreadBundle thread_bundle_;

  std::unique_ptr<DiscoveryNetworkMonitor> discovery_network_monitor_ =
      DiscoveryNetworkMonitor::CreateInstanceForTest(&FakeGetNetworkInfo);

  base::MockCallback<MediaSinkService::OnSinksDiscoveredCallback>
      mock_sink_discovered_cb_;
  std::unique_ptr<cast_channel::MockCastSocketService>
      mock_cast_socket_service_;
  base::MockTimer* mock_timer_;
  scoped_refptr<base::TestMockTimeTaskRunner> mock_time_task_runner_;
  CastMediaSinkServiceImpl media_sink_service_impl_;

  DISALLOW_COPY_AND_ASSIGN(CastMediaSinkServiceImplTest);
};

// static
std::vector<DiscoveryNetworkInfo>
    CastMediaSinkServiceImplTest::fake_network_info_;

TEST_F(CastMediaSinkServiceImplTest, TestOnChannelOpenSucceeded) {
  auto cast_sink = CreateCastSink(1);
  net::IPEndPoint ip_endpoint1 = CreateIPEndPoint(1);
  cast_channel::MockCastSocket socket;
  socket.set_id(1);

  media_sink_service_impl_.OnChannelOpenSucceeded(
      cast_sink, &socket, CastMediaSinkServiceImpl::SinkSource::kMdns);

  // Verify sink content
  EXPECT_CALL(mock_sink_discovered_cb_,
              Run(std::vector<MediaSinkInternal>({cast_sink})));
  media_sink_service_impl_.OnFetchCompleted();
}

TEST_F(CastMediaSinkServiceImplTest, TestMultipleOnChannelOpenSucceeded) {
  auto cast_sink1 = CreateCastSink(1);
  auto cast_sink2 = CreateCastSink(2);
  auto cast_sink3 = CreateCastSink(3);
  auto ip_endpoint1 = CreateIPEndPoint(1);
  auto ip_endpoint2 = CreateIPEndPoint(2);
  auto ip_endpoint3 = CreateIPEndPoint(3);

  cast_channel::MockCastSocket socket2;
  socket2.set_id(2);
  cast_channel::MockCastSocket socket3;
  socket3.set_id(3);

  // Current round of Dns discovery finds service1 and service 2.
  // Fail to open channel 1.
  media_sink_service_impl_.OnChannelOpenSucceeded(
      cast_sink2, &socket2, CastMediaSinkServiceImpl::SinkSource::kMdns);
  media_sink_service_impl_.OnChannelOpenSucceeded(
      cast_sink3, &socket3, CastMediaSinkServiceImpl::SinkSource::kMdns);

  // Verify sink content
  EXPECT_CALL(mock_sink_discovered_cb_,
              Run(std::vector<MediaSinkInternal>({cast_sink2, cast_sink3})));
  media_sink_service_impl_.OnFetchCompleted();
}

TEST_F(CastMediaSinkServiceImplTest, TestTimer) {
  auto cast_sink1 = CreateCastSink(1);
  auto cast_sink2 = CreateCastSink(2);
  net::IPEndPoint ip_endpoint1 = CreateIPEndPoint(1);
  net::IPEndPoint ip_endpoint2 = CreateIPEndPoint(2);

  EXPECT_FALSE(mock_timer_->IsRunning());
  media_sink_service_impl_.Start();
  EXPECT_TRUE(mock_timer_->IsRunning());

  // Channel 2 is opened.
  cast_channel::MockCastSocket socket2;
  socket2.set_id(2);

  media_sink_service_impl_.OnChannelOpenSucceeded(
      cast_sink2, &socket2, CastMediaSinkServiceImpl::SinkSource::kMdns);

  std::vector<MediaSinkInternal> sinks;
  EXPECT_CALL(mock_sink_discovered_cb_, Run(_)).WillOnce(SaveArg<0>(&sinks));

  // Fire timer.
  mock_timer_->Fire();
  EXPECT_EQ(sinks, std::vector<MediaSinkInternal>({cast_sink2}));

  EXPECT_FALSE(mock_timer_->IsRunning());
  // Channel 1 is opened and timer is restarted.
  cast_channel::MockCastSocket socket1;
  socket1.set_id(1);

  media_sink_service_impl_.OnChannelOpenSucceeded(
      cast_sink1, &socket1, CastMediaSinkServiceImpl::SinkSource::kMdns);
  EXPECT_TRUE(mock_timer_->IsRunning());
}

TEST_F(CastMediaSinkServiceImplTest, TestOpenChannelNoRetry) {
  MediaSinkInternal cast_sink = CreateCastSink(1);
  net::IPEndPoint ip_endpoint = CreateIPEndPoint(1);
  cast_channel::MockCastSocket socket;
  socket.set_id(1);
  socket.SetIPEndpoint(ip_endpoint);
  socket.SetErrorState(cast_channel::ChannelError::NONE);

  // No pending sink
  EXPECT_CALL(*mock_cast_socket_service_,
              OpenSocketInternal(ip_endpoint, _, _, _))
      .Times(1);
  media_sink_service_impl_.OpenChannel(
      ip_endpoint, cast_sink, nullptr,
      CastMediaSinkServiceImpl::SinkSource::kMdns);

  // One pending sink, the same as |cast_sink|
  EXPECT_CALL(*mock_cast_socket_service_,
              OpenSocketInternal(ip_endpoint, _, _, _))
      .Times(0);
  media_sink_service_impl_.OpenChannel(
      ip_endpoint, cast_sink, nullptr,
      CastMediaSinkServiceImpl::SinkSource::kMdns);
}

TEST_F(CastMediaSinkServiceImplTest, TestOpenChannelRetryOnce) {
  MediaSinkInternal cast_sink = CreateCastSink(1);
  net::IPEndPoint ip_endpoint = CreateIPEndPoint(1);
  cast_channel::MockCastSocket socket;
  socket.set_id(1);
  socket.SetIPEndpoint(ip_endpoint);
  socket.SetErrorState(cast_channel::ChannelError::NONE);
  socket.SetErrorState(cast_channel::ChannelError::CAST_SOCKET_ERROR);

  media_sink_service_impl_.SetTaskRunnerForTest(mock_time_task_runner_);
  std::unique_ptr<net::BackoffEntry> backoff_entry(
      new net::BackoffEntry(&CastMediaSinkServiceImpl::kDefaultBackoffPolicy));
  ExpectOpenSocketInternal(&socket);
  media_sink_service_impl_.max_retry_attempts_ = 3;
  media_sink_service_impl_.OpenChannel(
      ip_endpoint, cast_sink, std::move(backoff_entry),
      CastMediaSinkServiceImpl::SinkSource::kMdns);

  socket.SetErrorState(cast_channel::ChannelError::NONE);
  ExpectOpenSocketInternal(&socket);
  // Wait for 16 seconds.
  mock_time_task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(16));
}

TEST_F(CastMediaSinkServiceImplTest, TestOpenChannelFails) {
  MediaSinkInternal cast_sink = CreateCastSink(1);
  net::IPEndPoint ip_endpoint = CreateIPEndPoint(1);
  cast_channel::MockCastSocket socket;
  socket.set_id(1);
  socket.SetIPEndpoint(ip_endpoint);
  socket.SetErrorState(cast_channel::ChannelError::CAST_SOCKET_ERROR);

  media_sink_service_impl_.SetTaskRunnerForTest(mock_time_task_runner_);

  ExpectOpenSocketInternal(&socket);
  net::BackoffEntry::Policy policy =
      CastMediaSinkServiceImpl::kDefaultBackoffPolicy;
  std::unique_ptr<net::BackoffEntry> backoff_entry(
      new net::BackoffEntry(&policy));
  auto* backoff_entry_ptr = backoff_entry.get();
  media_sink_service_impl_.max_retry_attempts_ = 3;
  media_sink_service_impl_.OpenChannel(
      ip_endpoint, cast_sink, std::move(backoff_entry),
      CastMediaSinkServiceImpl::SinkSource::kMdns);

  // 1st retry attempt
  ExpectOpenSocketInternal(&socket);
  base::TimeDelta delay = backoff_entry_ptr->GetTimeUntilRelease() +
                          base::TimeDelta::FromSeconds(1);
  mock_time_task_runner_->FastForwardBy(delay);
  // 2nd retry attempt
  ExpectOpenSocketInternal(&socket);
  delay = backoff_entry_ptr->GetTimeUntilRelease() +
          base::TimeDelta::FromSeconds(1);
  mock_time_task_runner_->FastForwardBy(delay);
  // 3rd retry attempt
  ExpectOpenSocketInternal(&socket);
  delay = backoff_entry_ptr->GetTimeUntilRelease() +
          base::TimeDelta::FromSeconds(1);
  mock_time_task_runner_->FastForwardBy(delay);
  // No more retry.
  EXPECT_CALL(*mock_cast_socket_service_,
              OpenSocketInternal(ip_endpoint, _, _, _))
      .Times(0);
  mock_time_task_runner_->FastForwardBy(delay);
}

TEST_F(CastMediaSinkServiceImplTest, TestMultipleOpenChannels) {
  auto cast_sink1 = CreateCastSink(1);
  auto cast_sink2 = CreateCastSink(2);
  auto cast_sink3 = CreateCastSink(3);
  net::IPEndPoint ip_endpoint1 = CreateIPEndPoint(1);
  net::IPEndPoint ip_endpoint2 = CreateIPEndPoint(2);
  net::IPEndPoint ip_endpoint3 = CreateIPEndPoint(3);

  EXPECT_CALL(*mock_cast_socket_service_,
              OpenSocketInternal(ip_endpoint1, _, _, _));
  EXPECT_CALL(*mock_cast_socket_service_,
              OpenSocketInternal(ip_endpoint2, _, _, _));

  // 1st round finds service 1 & 2.
  std::vector<MediaSinkInternal> sinks1{cast_sink1, cast_sink2};
  media_sink_service_impl_.OpenChannels(
      sinks1, CastMediaSinkServiceImpl::SinkSource::kMdns);

  // Channel 2 opened.
  cast_channel::MockCastSocket socket2;
  socket2.set_id(2);
  socket2.SetErrorState(cast_channel::ChannelError::NONE);
  media_sink_service_impl_.OnChannelOpened(
      cast_sink2, nullptr, CastMediaSinkServiceImpl::SinkSource::kMdns,
      &socket2);

  EXPECT_CALL(*mock_cast_socket_service_,
              OpenSocketInternal(ip_endpoint2, _, _, _));
  EXPECT_CALL(*mock_cast_socket_service_,
              OpenSocketInternal(ip_endpoint3, _, _, _));

  // 2nd round finds service 2 & 3.
  std::vector<MediaSinkInternal> sinks2{cast_sink2, cast_sink3};
  media_sink_service_impl_.OpenChannels(
      sinks2, CastMediaSinkServiceImpl::SinkSource::kMdns);

  // Channel 1 and 3 opened.
  cast_channel::MockCastSocket socket1;
  cast_channel::MockCastSocket socket3;
  socket1.set_id(1);
  socket3.set_id(3);
  socket1.SetErrorState(cast_channel::ChannelError::NONE);
  socket3.SetErrorState(cast_channel::ChannelError::NONE);
  media_sink_service_impl_.OnChannelOpened(
      cast_sink1, nullptr, CastMediaSinkServiceImpl::SinkSource::kMdns,
      &socket1);
  media_sink_service_impl_.OnChannelOpened(
      cast_sink3, nullptr, CastMediaSinkServiceImpl::SinkSource::kMdns,
      &socket3);

  EXPECT_CALL(mock_sink_discovered_cb_,
              Run(std::vector<MediaSinkInternal>(
                  {cast_sink1, cast_sink2, cast_sink3})));
  media_sink_service_impl_.OnFetchCompleted();
}

TEST_F(CastMediaSinkServiceImplTest, TestOnChannelOpenFailed) {
  auto cast_sink = CreateCastSink(1);
  net::IPEndPoint ip_endpoint1 = CreateIPEndPoint(1);
  cast_channel::MockCastSocket socket;
  socket.set_id(1);

  media_sink_service_impl_.OnChannelOpenSucceeded(
      cast_sink, &socket, CastMediaSinkServiceImpl::SinkSource::kMdns);

  EXPECT_EQ(1u, media_sink_service_impl_.current_sinks_map_.size());

  socket.SetIPEndpoint(ip_endpoint1);
  media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1);
  EXPECT_TRUE(media_sink_service_impl_.current_sinks_map_.empty());
}

TEST_F(CastMediaSinkServiceImplTest,
       TestOnChannelErrorMayRetryForConnectingChannel) {
  net::IPEndPoint ip_endpoint1 = CreateIPEndPoint(1);
  cast_channel::MockCastSocket socket;
  socket.set_id(1);
  socket.SetIPEndpoint(ip_endpoint1);

  media_sink_service_impl_.SetTaskRunnerForTest(mock_time_task_runner_);

  // No op for CONNECTING cast channel.
  EXPECT_CALL(socket, ready_state())
      .WillOnce(Return(cast_channel::ReadyState::CONNECTING));
  EXPECT_CALL(*mock_cast_socket_service_, OpenSocketInternal(_, _, _, _))
      .Times(0);

  media_sink_service_impl_.OnError(
      socket, cast_channel::ChannelError::CHANNEL_NOT_OPEN);
  mock_time_task_runner_->RunUntilIdle();
}

TEST_F(CastMediaSinkServiceImplTest, TestOnChannelErrorMayRetryForCastSink) {
  auto cast_sink = CreateCastSink(1);
  net::IPEndPoint ip_endpoint1 = CreateIPEndPoint(1);
  cast_channel::MockCastSocket socket;
  socket.set_id(1);
  socket.SetIPEndpoint(ip_endpoint1);

  media_sink_service_impl_.SetTaskRunnerForTest(mock_time_task_runner_);

  // There is an existing cast sink in |current_sinks_map_|.
  media_sink_service_impl_.current_sinks_map_[ip_endpoint1.address()] =
      cast_sink;
  EXPECT_CALL(socket, ready_state())
      .WillRepeatedly(Return(cast_channel::ReadyState::CLOSED));
  media_sink_service_impl_.OnError(
      socket, cast_channel::ChannelError::CHANNEL_NOT_OPEN);

  EXPECT_CALL(*mock_cast_socket_service_,
              OpenSocketInternal(ip_endpoint1, _, _, _));
  mock_time_task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(16));
  EXPECT_TRUE(media_sink_service_impl_.current_sinks_map_.empty());

  base::RunLoop().RunUntilIdle();
}

TEST_F(CastMediaSinkServiceImplTest, TestOnChannelErrorNoRetryForMissingSink) {
  net::IPEndPoint ip_endpoint1 = CreateIPEndPoint(1);
  cast_channel::MockCastSocket socket;
  socket.set_id(1);
  socket.SetIPEndpoint(ip_endpoint1);
  EXPECT_CALL(socket, ready_state())
      .WillOnce(Return(cast_channel::ReadyState::CLOSED));

  media_sink_service_impl_.SetTaskRunnerForTest(mock_time_task_runner_);

  // There is no existing cast sink.
  media_sink_service_impl_.pending_for_open_ip_endpoints_.clear();
  media_sink_service_impl_.current_sinks_map_.clear();

  media_sink_service_impl_.OnError(
      socket, cast_channel::ChannelError::CHANNEL_NOT_OPEN);

  EXPECT_CALL(*mock_cast_socket_service_,
              OpenSocketInternal(ip_endpoint1, _, _, _))
      .Times(0);
  mock_time_task_runner_->RunUntilIdle();
}

TEST_F(CastMediaSinkServiceImplTest, TestOnDialSinkAdded) {
  MediaSinkInternal dial_sink1 = CreateDialSink(1);
  MediaSinkInternal dial_sink2 = CreateDialSink(2);
  net::IPEndPoint ip_endpoint1(dial_sink1.dial_data().ip_address,
                               CastMediaSinkServiceImpl::kCastControlPort);
  net::IPEndPoint ip_endpoint2(dial_sink2.dial_data().ip_address,
                               CastMediaSinkServiceImpl::kCastControlPort);

  cast_channel::MockCastSocket socket1;
  cast_channel::MockCastSocket socket2;
  socket1.set_id(1);
  socket2.set_id(2);

  // Channel 1, 2 opened.
  EXPECT_CALL(*mock_cast_socket_service_,
              OpenSocketInternal(ip_endpoint1, _, _, _))
      .WillOnce(DoAll(
          WithArgs<2>(Invoke(
              [&](const base::Callback<void(cast_channel::CastSocket * socket)>&
                      callback) { std::move(callback).Run(&socket1); })),
          Return(1)));
  EXPECT_CALL(*mock_cast_socket_service_,
              OpenSocketInternal(ip_endpoint2, _, _, _))
      .WillOnce(DoAll(
          WithArgs<2>(Invoke(
              [&](const base::Callback<void(cast_channel::CastSocket * socket)>&
                      callback) { std::move(callback).Run(&socket2); })),
          Return(2)));

  // Invoke CastSocketService::OpenSocket on the IO thread.
  media_sink_service_impl_.OnDialSinkAdded(dial_sink1);
  base::RunLoop().RunUntilIdle();

  // Invoke CastSocketService::OpenSocket on the IO thread.
  media_sink_service_impl_.OnDialSinkAdded(dial_sink2);
  base::RunLoop().RunUntilIdle();
  // Verify sink content.
  EXPECT_EQ(2u, media_sink_service_impl_.current_sinks_map_.size());
}

TEST_F(CastMediaSinkServiceImplTest, TestOnFetchCompleted) {
  std::vector<MediaSinkInternal> sinks;
  EXPECT_CALL(mock_sink_discovered_cb_, Run(_)).WillOnce(SaveArg<0>(&sinks));

  auto cast_sink1 = CreateCastSink(1);
  auto cast_sink2 = CreateCastSink(2);
  auto cast_sink3 = CreateCastSink(3);
  net::IPEndPoint ip_endpoint1 = CreateIPEndPoint(1);
  net::IPEndPoint ip_endpoint2 = CreateIPEndPoint(2);
  net::IPEndPoint ip_endpoint3 = CreateIPEndPoint(3);

  // Find Cast sink 1, 2, 3
  media_sink_service_impl_.current_sinks_map_[ip_endpoint1.address()] =
      cast_sink1;
  media_sink_service_impl_.current_sinks_map_[ip_endpoint2.address()] =
      cast_sink2;
  media_sink_service_impl_.current_sinks_map_[ip_endpoint3.address()] =
      cast_sink3;

  // Callback returns Cast sink 1, 2, 3
  media_sink_service_impl_.OnFetchCompleted();
  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(base::ContainsValue(sinks, cast_sink1));
  EXPECT_TRUE(base::ContainsValue(sinks, cast_sink2));
  EXPECT_TRUE(base::ContainsValue(sinks, cast_sink3));
}

TEST_F(CastMediaSinkServiceImplTest, TestAttemptConnection) {
  auto cast_sink1 = CreateCastSink(1);
  auto cast_sink2 = CreateCastSink(2);
  net::IPEndPoint ip_endpoint1 = CreateIPEndPoint(1);
  net::IPEndPoint ip_endpoint2 = CreateIPEndPoint(2);

  // Find Cast sink 1
  media_sink_service_impl_.current_sinks_map_[ip_endpoint1.address()] =
      cast_sink1;

  EXPECT_CALL(*mock_cast_socket_service_,
              OpenSocketInternal(ip_endpoint1, _, _, _))
      .Times(0);
  EXPECT_CALL(*mock_cast_socket_service_,
              OpenSocketInternal(ip_endpoint2, _, _, _));

  // Attempt to connect to Cast sink 1, 2
  std::vector<MediaSinkInternal> sinks{cast_sink1, cast_sink2};
  media_sink_service_impl_.AttemptConnection(sinks);
}

TEST_F(CastMediaSinkServiceImplTest, CacheSinksForKnownNetwork) {
  fake_network_info_ = fake_ethernet_info_;
  net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
      net::NetworkChangeNotifier::CONNECTION_ETHERNET);
  content::RunAllTasksUntilIdle();

  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_.clear();
  net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
      net::NetworkChangeNotifier::CONNECTION_NONE);
  content::RunAllTasksUntilIdle();

  fake_network_info_ = fake_wifi_info_;
  net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
      net::NetworkChangeNotifier::CONNECTION_WIFI);
  content::RunAllTasksUntilIdle();
  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.
  fake_network_info_.clear();
  net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
      net::NetworkChangeNotifier::CONNECTION_NONE);
  content::RunAllTasksUntilIdle();

  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();
}

TEST_F(CastMediaSinkServiceImplTest, CacheContainsOnlyResolvedSinks) {
  fake_network_info_ = fake_ethernet_info_;
  net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
      net::NetworkChangeNotifier::CONNECTION_ETHERNET);
  content::RunAllTasksUntilIdle();

  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 fail for |sink2|.
  cast_channel::MockCastSocket socket1;
  cast_channel::MockCastSocket socket2;
  socket1.SetIPEndpoint(ip_endpoint1);
  socket1.set_id(1);
  socket2.SetErrorState(cast_channel::ChannelError::CONNECT_ERROR);
  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_.clear();
  net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
      net::NetworkChangeNotifier::CONNECTION_NONE);
  content::RunAllTasksUntilIdle();

  fake_network_info_ = fake_wifi_info_;
  net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
      net::NetworkChangeNotifier::CONNECTION_WIFI);
  content::RunAllTasksUntilIdle();
  media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1);

  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 only |sink1|,
  // since |sink2| failed to resolve.
  fake_network_info_.clear();
  net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
      net::NetworkChangeNotifier::CONNECTION_NONE);
  content::RunAllTasksUntilIdle();

  EXPECT_CALL(*mock_cast_socket_service_,
              OpenSocketInternal(ip_endpoint1, _, _, _));
  EXPECT_CALL(*mock_cast_socket_service_,
              OpenSocketInternal(ip_endpoint2, _, _, _))
      .Times(0);
  fake_network_info_ = fake_ethernet_info_;
  net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
      net::NetworkChangeNotifier::CONNECTION_ETHERNET);
  content::RunAllTasksUntilIdle();
}

TEST_F(CastMediaSinkServiceImplTest, CacheUpdatedOnChannelOpenFailed) {
  fake_network_info_ = fake_ethernet_info_;
  net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
      net::NetworkChangeNotifier::CONNECTION_ETHERNET);
  content::RunAllTasksUntilIdle();

  MediaSinkInternal sink1 = CreateCastSink(1);
  net::IPEndPoint ip_endpoint1 = CreateIPEndPoint(1);
  std::vector<MediaSinkInternal> sink_list1{sink1};

  // Resolve |sink1| but then raise a channel error.  This should remove it from
  // the cached sinks for the ethernet network.
  cast_channel::MockCastSocket socket1;
  socket1.SetIPEndpoint(ip_endpoint1);
  socket1.set_id(1);
  ExpectOpenSocketInternal(&socket1);
  media_sink_service_impl_.OpenChannels(
      sink_list1, CastMediaSinkServiceImpl::SinkSource::kMdns);
  media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1);

  // Connect to a new network with different sinks.
  fake_network_info_.clear();
  net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
      net::NetworkChangeNotifier::CONNECTION_NONE);
  content::RunAllTasksUntilIdle();

  fake_network_info_ = fake_wifi_info_;
  net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
      net::NetworkChangeNotifier::CONNECTION_WIFI);
  content::RunAllTasksUntilIdle();

  MediaSinkInternal sink2 = CreateCastSink(2);
  net::IPEndPoint ip_endpoint2 = CreateIPEndPoint(2);
  std::vector<MediaSinkInternal> sink_list2{sink2};

  cast_channel::MockCastSocket socket2;
  socket2.SetIPEndpoint(ip_endpoint2);
  socket2.set_id(2);
  ExpectOpenSocketInternal(&socket2);
  media_sink_service_impl_.OpenChannels(
      sink_list2, CastMediaSinkServiceImpl::SinkSource::kMdns);

  // Reconnecting to the previous ethernet network should not restore any sinks
  // since the only sink to resolve successfully, |sink1|, later had a channel
  // error.
  fake_network_info_.clear();
  net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
      net::NetworkChangeNotifier::CONNECTION_NONE);
  content::RunAllTasksUntilIdle();

  EXPECT_CALL(*mock_cast_socket_service_, OpenSocketInternal(_, _, _, _))
      .Times(0);
  fake_network_info_ = fake_ethernet_info_;
  net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
      net::NetworkChangeNotifier::CONNECTION_ETHERNET);
  content::RunAllTasksUntilIdle();
}

TEST_F(CastMediaSinkServiceImplTest, UnknownNetworkNoCache) {
  // Without any network notification here, network ID will remain __unknown__
  // and the cache shouldn't save any of these sinks.
  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);

  // Network is reported as disconnected but discover a new device.
  fake_network_info_.clear();
  net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
      net::NetworkChangeNotifier::CONNECTION_NONE);
  content::RunAllTasksUntilIdle();
  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);

  // Connecting to a network whose ID resolves to __unknown__ shouldn't pull any
  // cache items from another unknown network.
  EXPECT_CALL(*mock_cast_socket_service_, OpenSocketInternal(_, _, _, _))
      .Times(0);
  fake_network_info_ = fake_unknown_info_;
  net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
      net::NetworkChangeNotifier::CONNECTION_WIFI);
  content::RunAllTasksUntilIdle();

  // Similarly, disconnecting from the network shouldn't pull any cache items.
  fake_network_info_.clear();
  net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
      net::NetworkChangeNotifier::CONNECTION_NONE);
  content::RunAllTasksUntilIdle();
}

TEST_F(CastMediaSinkServiceImplTest, CacheUpdatedForKnownNetwork) {
  fake_network_info_ = fake_ethernet_info_;
  net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
      net::NetworkChangeNotifier::CONNECTION_ETHERNET);
  content::RunAllTasksUntilIdle();

  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_.clear();
  net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
      net::NetworkChangeNotifier::CONNECTION_NONE);
  content::RunAllTasksUntilIdle();

  fake_network_info_ = fake_wifi_info_;
  net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
      net::NetworkChangeNotifier::CONNECTION_WIFI);
  content::RunAllTasksUntilIdle();
  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.  |sink3| is also lost.
  fake_network_info_.clear();
  net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
      net::NetworkChangeNotifier::CONNECTION_NONE);
  content::RunAllTasksUntilIdle();

  media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint3);

  // Resolution will fail for cached sinks.
  socket1.SetErrorState(cast_channel::ChannelError::CONNECT_ERROR);
  socket2.SetErrorState(cast_channel::ChannelError::CONNECT_ERROR);
  ExpectOpenSocketInternal(&socket1);
  ExpectOpenSocketInternal(&socket2);
  fake_network_info_ = fake_ethernet_info_;
  net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
      net::NetworkChangeNotifier::CONNECTION_ETHERNET);
  content::RunAllTasksUntilIdle();

  // A new sink is found on the ethernet network.
  MediaSinkInternal sink4 = CreateCastSink(4);
  net::IPEndPoint ip_endpoint4 = CreateIPEndPoint(4);
  std::vector<MediaSinkInternal> sink_list3{sink4};

  cast_channel::MockCastSocket socket4;
  socket4.SetIPEndpoint(ip_endpoint4);
  socket4.set_id(4);
  ExpectOpenSocketInternal(&socket4);
  media_sink_service_impl_.OpenChannels(
      sink_list3, CastMediaSinkServiceImpl::SinkSource::kMdns);

  // Disconnect from the network and lose sinks.
  fake_network_info_.clear();
  net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
      net::NetworkChangeNotifier::CONNECTION_NONE);
  content::RunAllTasksUntilIdle();
  media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint4);

  // Reconnect and expect only |sink4| to be cached.
  EXPECT_CALL(*mock_cast_socket_service_,
              OpenSocketInternal(ip_endpoint4, _, _, _));
  fake_network_info_ = fake_ethernet_info_;
  net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
      net::NetworkChangeNotifier::CONNECTION_ETHERNET);
  content::RunAllTasksUntilIdle();
}

TEST_F(CastMediaSinkServiceImplTest, CacheDialDiscoveredSinks) {
  fake_network_info_ = fake_ethernet_info_;
  net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
      net::NetworkChangeNotifier::CONNECTION_ETHERNET);
  content::RunAllTasksUntilIdle();

  MediaSinkInternal sink1_cast = CreateCastSink(1);
  MediaSinkInternal sink2_dial = CreateDialSink(2);
  net::IPEndPoint ip_endpoint1 = CreateIPEndPoint(1);
  net::IPEndPoint ip_endpoint2(sink2_dial.dial_data().ip_address,
                               CastMediaSinkServiceImpl::kCastControlPort);
  std::vector<MediaSinkInternal> sink_list1{sink1_cast};

  // 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);
  media_sink_service_impl_.OnDialSinkAdded(sink2_dial);

  // Connect to a new network with different sinks.
  fake_network_info_.clear();
  net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
      net::NetworkChangeNotifier::CONNECTION_NONE);
  content::RunAllTasksUntilIdle();

  fake_network_info_ = fake_wifi_info_;
  net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
      net::NetworkChangeNotifier::CONNECTION_WIFI);
  content::RunAllTasksUntilIdle();
  media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1);
  media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint2);

  MediaSinkInternal sink3_cast = CreateCastSink(3);
  MediaSinkInternal sink4_dial = CreateDialSink(4);
  net::IPEndPoint ip_endpoint3 = CreateIPEndPoint(3);
  net::IPEndPoint ip_endpoint4(sink4_dial.dial_data().ip_address,
                               CastMediaSinkServiceImpl::kCastControlPort);
  std::vector<MediaSinkInternal> sink_list2{sink3_cast};

  cast_channel::MockCastSocket socket3;
  cast_channel::MockCastSocket socket4;
  socket3.SetIPEndpoint(ip_endpoint3);
  socket3.set_id(3);
  socket4.SetIPEndpoint(ip_endpoint4);
  socket4.set_id(4);
  ExpectOpenSocketInternal(&socket3);
  ExpectOpenSocketInternal(&socket4);
  media_sink_service_impl_.OpenChannels(
      sink_list2, CastMediaSinkServiceImpl::SinkSource::kMdns);
  media_sink_service_impl_.OnDialSinkAdded(sink4_dial);

  // Reconnecting to the previous ethernet network should restore the same sinks
  // from the cache and attempt to resolve them.
  fake_network_info_.clear();
  net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
      net::NetworkChangeNotifier::CONNECTION_NONE);
  content::RunAllTasksUntilIdle();

  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();
}

TEST_F(CastMediaSinkServiceImplTest, DualDiscoveryDoesntDuplicateCacheItems) {
  fake_network_info_ = fake_ethernet_info_;
  net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
      net::NetworkChangeNotifier::CONNECTION_ETHERNET);
  content::RunAllTasksUntilIdle();

  // The same sink will be discovered via dial and mdns.
  MediaSinkInternal sink1_cast = CreateCastSink(1);
  MediaSinkInternal sink1_dial = CreateDialSink(1);
  net::IPEndPoint ip_endpoint1_cast = CreateIPEndPoint(1);
  net::IPEndPoint ip_endpoint1_dial(sink1_dial.dial_data().ip_address,
                                    CastMediaSinkServiceImpl::kCastControlPort);
  std::vector<MediaSinkInternal> sink_list1{sink1_cast};

  // Dial discovery will succeed first.
  cast_channel::MockCastSocket socket1_dial;
  socket1_dial.SetIPEndpoint(ip_endpoint1_dial);
  socket1_dial.set_id(1);
  ExpectOpenSocketInternal(&socket1_dial);
  media_sink_service_impl_.OnDialSinkAdded(sink1_dial);

  // The same sink is then discovered via mdns.
  cast_channel::MockCastSocket socket1_cast;
  socket1_cast.SetIPEndpoint(ip_endpoint1_cast);
  socket1_cast.set_id(2);
  ExpectOpenSocketInternal(&socket1_cast);
  media_sink_service_impl_.OpenChannels(
      sink_list1, CastMediaSinkServiceImpl::SinkSource::kMdns);

  // Connect to a new network with different sinks.
  fake_network_info_.clear();
  net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
      net::NetworkChangeNotifier::CONNECTION_NONE);
  content::RunAllTasksUntilIdle();

  fake_network_info_ = fake_wifi_info_;
  net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
      net::NetworkChangeNotifier::CONNECTION_WIFI);
  content::RunAllTasksUntilIdle();
  media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1_cast);
  media_sink_service_impl_.OnChannelOpenFailed(ip_endpoint1_dial);

  MediaSinkInternal sink2_cast = CreateCastSink(2);
  net::IPEndPoint ip_endpoint2 = CreateIPEndPoint(2);
  std::vector<MediaSinkInternal> sink_list2{sink2_cast};

  cast_channel::MockCastSocket socket2;
  socket2.SetIPEndpoint(ip_endpoint2);
  socket2.set_id(3);
  ExpectOpenSocketInternal(&socket2);
  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.
  fake_network_info_.clear();
  net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
      net::NetworkChangeNotifier::CONNECTION_NONE);
  content::RunAllTasksUntilIdle();

  EXPECT_CALL(*mock_cast_socket_service_,
              OpenSocketInternal(ip_endpoint1_cast, _, _, _));
  fake_network_info_ = fake_ethernet_info_;
  net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
      net::NetworkChangeNotifier::CONNECTION_ETHERNET);
  content::RunAllTasksUntilIdle();
}

TEST_F(CastMediaSinkServiceImplTest,
       TestInitRetryParametersWithFeatureDisabled) {
  // Feature not enabled.
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndDisableFeature(kEnableCastChannelRetry);

  net::BackoffEntry::Policy backoff_policy;
  int max_retry_attempts;
  CastMediaSinkServiceImpl::InitRetryParameters(&backoff_policy,
                                                &max_retry_attempts);
  EXPECT_EQ(0, max_retry_attempts);
}

TEST_F(CastMediaSinkServiceImplTest, TestInitRetryParameters) {
  base::test::ScopedFeatureList scoped_feature_list;
  std::map<std::string, std::string> params;
  params[CastMediaSinkServiceImpl::kParamNameMaxRetryAttempts] = "20";
  params[CastMediaSinkServiceImpl::kParamNameInitialDelayMS] = "2000";
  params[CastMediaSinkServiceImpl::kParamNameExponential] = "2.0";
  scoped_feature_list.InitAndEnableFeatureWithParameters(
      kEnableCastChannelRetry, params);

  net::BackoffEntry::Policy backoff_policy;
  int max_retry_attempts;
  CastMediaSinkServiceImpl::InitRetryParameters(&backoff_policy,
                                                &max_retry_attempts);
  EXPECT_EQ(20, max_retry_attempts);
  EXPECT_EQ(2000, backoff_policy.initial_delay_ms);
  EXPECT_EQ(2.0, backoff_policy.multiply_factor);
}

TEST_F(CastMediaSinkServiceImplTest, TestInitRetryParametersWithDefaultValue) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndEnableFeature(kEnableCastChannelRetry);

  net::BackoffEntry::Policy backoff_policy;
  int max_retry_attempts;
  CastMediaSinkServiceImpl::InitRetryParameters(&backoff_policy,
                                                &max_retry_attempts);
  EXPECT_EQ(CastMediaSinkServiceImpl::kDefaultMaxRetryAttempts,
            max_retry_attempts);
  EXPECT_EQ(CastMediaSinkServiceImpl::kDefaultBackoffPolicy.initial_delay_ms,
            backoff_policy.initial_delay_ms);
  EXPECT_EQ(CastMediaSinkServiceImpl::kDefaultBackoffPolicy.multiply_factor,
            backoff_policy.multiply_factor);
}

}  // namespace media_router
