/*
 *  Copyright 2015 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include <map>
#include <memory>

#include "p2p/base/dtlstransport.h"
#include "p2p/base/fakeportallocator.h"
#include "p2p/base/p2ptransportchannel.h"
#include "p2p/base/portallocator.h"
#include "pc/test/faketransportcontroller.h"
#include "pc/transportcontroller.h"
#include "rtc_base/fakesslidentity.h"
#include "rtc_base/gunit.h"
#include "rtc_base/helpers.h"
#include "rtc_base/sslidentity.h"
#include "rtc_base/thread.h"
#include "test/gtest.h"

using webrtc::SdpType;

static const int kTimeout = 100;
static const char kIceUfrag1[] = "TESTICEUFRAG0001";
static const char kIcePwd1[] = "TESTICEPWD00000000000001";
static const char kIceUfrag2[] = "TESTICEUFRAG0002";
static const char kIcePwd2[] = "TESTICEPWD00000000000002";
static const char kIceUfrag3[] = "TESTICEUFRAG0003";
static const char kIcePwd3[] = "TESTICEPWD00000000000003";
static const bool kRtcpMuxEnabled = true;

namespace cricket {

// Only subclassing from FakeTransportController because currently that's the
// only way to have a TransportController with fake ICE/DTLS transports.
//
// TODO(deadbeef): Pass a "TransportFactory" or something similar into
// TransportController, instead of using inheritance in this way for testing.
typedef FakeTransportController TransportControllerForTest;

class TransportControllerTest : public testing::Test,
                                public sigslot::has_slots<> {
 public:
  TransportControllerTest()
      : transport_controller_(new TransportControllerForTest()),
        signaling_thread_(rtc::Thread::Current()) {
    ConnectTransportControllerSignals();
  }

  void CreateTransportControllerWithNetworkThread() {
    if (!network_thread_) {
      network_thread_ = rtc::Thread::CreateWithSocketServer();
      network_thread_->Start();
    }
    transport_controller_.reset(
        new TransportControllerForTest(network_thread_.get()));
    ConnectTransportControllerSignals();
  }

  void ConnectTransportControllerSignals() {
    transport_controller_->SignalConnectionState.connect(
        this, &TransportControllerTest::OnConnectionState);
    transport_controller_->SignalReceiving.connect(
        this, &TransportControllerTest::OnReceiving);
    transport_controller_->SignalGatheringState.connect(
        this, &TransportControllerTest::OnGatheringState);
    transport_controller_->SignalCandidatesGathered.connect(
        this, &TransportControllerTest::OnCandidatesGathered);
  }

  FakeDtlsTransport* CreateFakeDtlsTransport(const std::string& content,
                                             int component) {
    DtlsTransportInternal* transport =
        transport_controller_->CreateDtlsTransport_n(content, component);
    return static_cast<FakeDtlsTransport*>(transport);
  }

  void DestroyFakeDtlsTransport(const std::string& content, int component) {
    transport_controller_->DestroyDtlsTransport_n(content, component);
  }

  Candidate CreateCandidate(int component) {
    Candidate c;
    c.set_address(rtc::SocketAddress("192.168.1.1", 8000));
    c.set_component(1);
    c.set_protocol(UDP_PROTOCOL_NAME);
    c.set_priority(1);
    return c;
  }

  // Used for thread hopping test.
  void CreateFakeDtlsTransportsAndCompleteConnectionOnNetworkThread() {
    network_thread_->Invoke<void>(
        RTC_FROM_HERE,
        rtc::Bind(&TransportControllerTest::
                      CreateFakeDtlsTransportsAndCompleteConnection_w,
                  this));
  }

  void CreateFakeDtlsTransportsAndCompleteConnection_w() {
    transport_controller_->SetIceRole(ICEROLE_CONTROLLING);
    FakeDtlsTransport* transport1 = CreateFakeDtlsTransport("audio", 1);
    ASSERT_NE(nullptr, transport1);
    FakeDtlsTransport* transport2 = CreateFakeDtlsTransport("video", 1);
    ASSERT_NE(nullptr, transport2);

    TransportDescription local_desc(std::vector<std::string>(), kIceUfrag1,
                                    kIcePwd1, ICEMODE_FULL,
                                    CONNECTIONROLE_ACTPASS, nullptr);
    std::string err;
    transport_controller_->SetLocalTransportDescription("audio", local_desc,
                                                        SdpType::kOffer, &err);
    transport_controller_->SetLocalTransportDescription("video", local_desc,
                                                        SdpType::kOffer, &err);
    transport_controller_->MaybeStartGathering();
    transport1->fake_ice_transport()->SignalCandidateGathered(
        transport1->fake_ice_transport(), CreateCandidate(1));
    transport2->fake_ice_transport()->SignalCandidateGathered(
        transport2->fake_ice_transport(), CreateCandidate(1));
    transport1->fake_ice_transport()->SetCandidatesGatheringComplete();
    transport2->fake_ice_transport()->SetCandidatesGatheringComplete();
    transport1->fake_ice_transport()->SetConnectionCount(2);
    transport2->fake_ice_transport()->SetConnectionCount(2);
    transport1->SetReceiving(true);
    transport2->SetReceiving(true);
    transport1->SetWritable(true);
    transport2->SetWritable(true);
    transport1->fake_ice_transport()->SetConnectionCount(1);
    transport2->fake_ice_transport()->SetConnectionCount(1);
  }

  IceConfig CreateIceConfig(
      int receiving_timeout,
      ContinualGatheringPolicy continual_gathering_policy) {
    IceConfig config;
    config.receiving_timeout = receiving_timeout;
    config.continual_gathering_policy = continual_gathering_policy;
    return config;
  }

 protected:
  void OnConnectionState(IceConnectionState state) {
    if (!signaling_thread_->IsCurrent()) {
      signaled_on_non_signaling_thread_ = true;
    }
    connection_state_ = state;
    ++connection_state_signal_count_;
  }

  void OnReceiving(bool receiving) {
    if (!signaling_thread_->IsCurrent()) {
      signaled_on_non_signaling_thread_ = true;
    }
    receiving_ = receiving;
    ++receiving_signal_count_;
  }

  void OnGatheringState(IceGatheringState state) {
    if (!signaling_thread_->IsCurrent()) {
      signaled_on_non_signaling_thread_ = true;
    }
    gathering_state_ = state;
    ++gathering_state_signal_count_;
  }

  void OnCandidatesGathered(const std::string& transport_name,
                            const Candidates& candidates) {
    if (!signaling_thread_->IsCurrent()) {
      signaled_on_non_signaling_thread_ = true;
    }
    candidates_[transport_name].insert(candidates_[transport_name].end(),
                                       candidates.begin(), candidates.end());
    ++candidates_signal_count_;
  }

  std::unique_ptr<rtc::Thread> network_thread_;  // Not used for most tests.
  std::unique_ptr<TransportControllerForTest> transport_controller_;

  // Information received from signals from transport controller.
  IceConnectionState connection_state_ = kIceConnectionConnecting;
  bool receiving_ = false;
  IceGatheringState gathering_state_ = kIceGatheringNew;
  // transport_name => candidates
  std::map<std::string, Candidates> candidates_;
  // Counts of each signal emitted.
  int connection_state_signal_count_ = 0;
  int receiving_signal_count_ = 0;
  int gathering_state_signal_count_ = 0;
  int candidates_signal_count_ = 0;

  // Used to make sure signals only come on signaling thread.
  rtc::Thread* const signaling_thread_ = nullptr;
  bool signaled_on_non_signaling_thread_ = false;
};

TEST_F(TransportControllerTest, TestSetIceConfig) {
  FakeDtlsTransport* transport1 = CreateFakeDtlsTransport("audio", 1);
  ASSERT_NE(nullptr, transport1);

  transport_controller_->SetIceConfig(
      CreateIceConfig(1000, GATHER_CONTINUALLY));
  EXPECT_EQ(1000, transport1->fake_ice_transport()->receiving_timeout());
  EXPECT_TRUE(transport1->fake_ice_transport()->gather_continually());

  transport_controller_->SetIceConfig(
      CreateIceConfig(1000, GATHER_CONTINUALLY_AND_RECOVER));
  // Test that value stored in controller is applied to new transports.
  FakeDtlsTransport* transport2 = CreateFakeDtlsTransport("video", 1);
  ASSERT_NE(nullptr, transport2);
  EXPECT_EQ(1000, transport2->fake_ice_transport()->receiving_timeout());
  EXPECT_TRUE(transport2->fake_ice_transport()->gather_continually());
}

TEST_F(TransportControllerTest, TestSetSslMaxProtocolVersion) {
  EXPECT_TRUE(transport_controller_->SetSslMaxProtocolVersion(
      rtc::SSL_PROTOCOL_DTLS_12));
  FakeDtlsTransport* transport = CreateFakeDtlsTransport("audio", 1);

  ASSERT_NE(nullptr, transport);
  EXPECT_EQ(rtc::SSL_PROTOCOL_DTLS_12, transport->ssl_max_protocol_version());

  // Setting max version after transport is created should fail.
  EXPECT_FALSE(transport_controller_->SetSslMaxProtocolVersion(
      rtc::SSL_PROTOCOL_DTLS_10));
}

TEST_F(TransportControllerTest, TestSetIceRole) {
  FakeDtlsTransport* transport1 = CreateFakeDtlsTransport("audio", 1);
  ASSERT_NE(nullptr, transport1);

  transport_controller_->SetIceRole(ICEROLE_CONTROLLING);
  EXPECT_EQ(ICEROLE_CONTROLLING,
            transport1->fake_ice_transport()->GetIceRole());
  transport_controller_->SetIceRole(ICEROLE_CONTROLLED);
  EXPECT_EQ(ICEROLE_CONTROLLED, transport1->fake_ice_transport()->GetIceRole());

  // Test that value stored in controller is applied to new transports.
  FakeDtlsTransport* transport2 = CreateFakeDtlsTransport("video", 1);
  ASSERT_NE(nullptr, transport2);
  EXPECT_EQ(ICEROLE_CONTROLLED, transport2->fake_ice_transport()->GetIceRole());
}

// Test that when one transport encounters a role conflict, the ICE role is
// swapped on every transport.
TEST_F(TransportControllerTest, TestIceRoleConflict) {
  FakeDtlsTransport* transport1 = CreateFakeDtlsTransport("audio", 1);
  ASSERT_NE(nullptr, transport1);
  FakeDtlsTransport* transport2 = CreateFakeDtlsTransport("video", 1);
  ASSERT_NE(nullptr, transport2);

  transport_controller_->SetIceRole(ICEROLE_CONTROLLING);
  EXPECT_EQ(ICEROLE_CONTROLLING,
            transport1->fake_ice_transport()->GetIceRole());
  EXPECT_EQ(ICEROLE_CONTROLLING,
            transport2->fake_ice_transport()->GetIceRole());

  transport1->fake_ice_transport()->SignalRoleConflict(
      transport1->fake_ice_transport());
  EXPECT_EQ(ICEROLE_CONTROLLED, transport1->fake_ice_transport()->GetIceRole());
  EXPECT_EQ(ICEROLE_CONTROLLED, transport2->fake_ice_transport()->GetIceRole());

  // Should be able to handle a second role conflict. The remote endpoint can
  // change its role/tie-breaker when it does an ICE restart.
  transport2->fake_ice_transport()->SignalRoleConflict(
      transport2->fake_ice_transport());
  EXPECT_EQ(ICEROLE_CONTROLLING,
            transport1->fake_ice_transport()->GetIceRole());
  EXPECT_EQ(ICEROLE_CONTROLLING,
            transport2->fake_ice_transport()->GetIceRole());
}

TEST_F(TransportControllerTest, TestGetSslRole) {
  rtc::SSLRole role;
  CreateFakeDtlsTransport("audio", 1);

  // Should return false before role has been negotiated.
  EXPECT_FALSE(transport_controller_->GetSslRole("audio", &role));

  // To negotiate an SSL role, need to set a local certificate, and
  // local/remote transport descriptions with DTLS info.
  rtc::scoped_refptr<rtc::RTCCertificate> certificate =
      rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
          rtc::SSLIdentity::Generate("testing", rtc::KT_ECDSA)));
  std::unique_ptr<rtc::SSLFingerprint> fingerprint(
      rtc::SSLFingerprint::CreateFromCertificate(certificate));
  transport_controller_->SetLocalCertificate(certificate);

  // Set the same fingerprint on both sides since the remote fingerprint
  // doesn't really matter for this test.
  TransportDescription local_desc(std::vector<std::string>(), kIceUfrag1,
                                  kIcePwd1, ICEMODE_FULL,
                                  CONNECTIONROLE_ACTPASS, fingerprint.get());
  TransportDescription remote_desc(std::vector<std::string>(), kIceUfrag2,
                                   kIcePwd2, ICEMODE_FULL,
                                   CONNECTIONROLE_ACTIVE, fingerprint.get());
  std::string err;
  EXPECT_TRUE(transport_controller_->SetLocalTransportDescription(
      "audio", local_desc, SdpType::kOffer, &err));
  EXPECT_TRUE(transport_controller_->SetRemoteTransportDescription(
      "audio", remote_desc, SdpType::kAnswer, &err));

  // Finally we can get the role. Should be "server" since the remote
  // endpoint's role was "active".
  EXPECT_TRUE(transport_controller_->GetSslRole("audio", &role));
  EXPECT_EQ(rtc::SSL_SERVER, role);

  // Lastly, test that GetSslRole returns false for a nonexistent transport.
  EXPECT_FALSE(transport_controller_->GetSslRole("video", &role));
}

TEST_F(TransportControllerTest, TestSetAndGetLocalCertificate) {
  rtc::scoped_refptr<rtc::RTCCertificate> certificate1 =
      rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
          rtc::SSLIdentity::Generate("session1", rtc::KT_DEFAULT)));
  rtc::scoped_refptr<rtc::RTCCertificate> certificate2 =
      rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
          rtc::SSLIdentity::Generate("session2", rtc::KT_DEFAULT)));
  rtc::scoped_refptr<rtc::RTCCertificate> returned_certificate;

  FakeDtlsTransport* transport1 = CreateFakeDtlsTransport("audio", 1);
  ASSERT_NE(nullptr, transport1);

  EXPECT_TRUE(transport_controller_->SetLocalCertificate(certificate1));
  EXPECT_TRUE(transport_controller_->GetLocalCertificate(
      "audio", &returned_certificate));
  EXPECT_EQ(certificate1->identity()->certificate().ToPEMString(),
            returned_certificate->identity()->certificate().ToPEMString());

  // Should fail if called for a nonexistant transport.
  EXPECT_FALSE(transport_controller_->GetLocalCertificate(
      "video", &returned_certificate));

  // Test that identity stored in controller is applied to new transports.
  FakeDtlsTransport* transport2 = CreateFakeDtlsTransport("video", 1);
  ASSERT_NE(nullptr, transport2);
  EXPECT_TRUE(transport_controller_->GetLocalCertificate(
      "video", &returned_certificate));
  EXPECT_EQ(certificate1->identity()->certificate().ToPEMString(),
            returned_certificate->identity()->certificate().ToPEMString());

  // Shouldn't be able to change the identity once set.
  EXPECT_FALSE(transport_controller_->SetLocalCertificate(certificate2));
}

TEST_F(TransportControllerTest, TestGetRemoteSSLCertChain) {
  rtc::FakeSSLCertificate fake_certificate("fake_data");

  FakeDtlsTransport* transport = CreateFakeDtlsTransport("audio", 1);
  ASSERT_NE(nullptr, transport);

  transport->SetRemoteSSLCertificate(&fake_certificate);
  std::unique_ptr<rtc::SSLCertChain> returned_cert_chain =
      transport_controller_->GetRemoteSSLCertChain("audio");
  EXPECT_TRUE(returned_cert_chain);
  EXPECT_EQ(fake_certificate.ToPEMString(),
            returned_cert_chain->Get(0).ToPEMString());

  // Should fail if called for a nonexistant transport.
  EXPECT_FALSE(transport_controller_->GetRemoteSSLCertChain("video"));
}

TEST_F(TransportControllerTest, TestSetLocalTransportDescription) {
  FakeDtlsTransport* transport = CreateFakeDtlsTransport("audio", 1);
  ASSERT_NE(nullptr, transport);
  TransportDescription local_desc(std::vector<std::string>(), kIceUfrag1,
                                  kIcePwd1, ICEMODE_FULL,
                                  CONNECTIONROLE_ACTPASS, nullptr);
  std::string err;
  EXPECT_TRUE(transport_controller_->SetLocalTransportDescription(
      "audio", local_desc, SdpType::kOffer, &err));
  // Check that ICE ufrag and pwd were propagated to transport.
  EXPECT_EQ(kIceUfrag1, transport->fake_ice_transport()->ice_ufrag());
  EXPECT_EQ(kIcePwd1, transport->fake_ice_transport()->ice_pwd());
  // After setting local description, we should be able to start gathering
  // candidates.
  transport_controller_->MaybeStartGathering();
  EXPECT_EQ_WAIT(kIceGatheringGathering, gathering_state_, kTimeout);
  EXPECT_EQ(1, gathering_state_signal_count_);
}

TEST_F(TransportControllerTest, TestSetRemoteTransportDescription) {
  FakeDtlsTransport* transport = CreateFakeDtlsTransport("audio", 1);
  ASSERT_NE(nullptr, transport);
  TransportDescription remote_desc(std::vector<std::string>(), kIceUfrag1,
                                   kIcePwd1, ICEMODE_FULL,
                                   CONNECTIONROLE_ACTPASS, nullptr);
  std::string err;
  EXPECT_TRUE(transport_controller_->SetRemoteTransportDescription(
      "audio", remote_desc, SdpType::kOffer, &err));
  // Check that ICE ufrag and pwd were propagated to transport.
  EXPECT_EQ(kIceUfrag1, transport->fake_ice_transport()->remote_ice_ufrag());
  EXPECT_EQ(kIcePwd1, transport->fake_ice_transport()->remote_ice_pwd());
}

TEST_F(TransportControllerTest, TestAddRemoteCandidates) {
  FakeDtlsTransport* transport = CreateFakeDtlsTransport("audio", 1);
  ASSERT_NE(nullptr, transport);
  Candidates candidates;
  candidates.push_back(CreateCandidate(1));
  std::string err;
  EXPECT_TRUE(
      transport_controller_->AddRemoteCandidates("audio", candidates, &err));
  EXPECT_EQ(1U, transport->fake_ice_transport()->remote_candidates().size());
}

TEST_F(TransportControllerTest, TestReadyForRemoteCandidates) {
  FakeDtlsTransport* transport = CreateFakeDtlsTransport("audio", 1);
  ASSERT_NE(nullptr, transport);
  // We expect to be ready for remote candidates only after local and remote
  // descriptions are set.
  EXPECT_FALSE(transport_controller_->ReadyForRemoteCandidates("audio"));

  std::string err;
  TransportDescription remote_desc(std::vector<std::string>(), kIceUfrag1,
                                   kIcePwd1, ICEMODE_FULL,
                                   CONNECTIONROLE_ACTPASS, nullptr);
  EXPECT_TRUE(transport_controller_->SetRemoteTransportDescription(
      "audio", remote_desc, SdpType::kOffer, &err));
  EXPECT_FALSE(transport_controller_->ReadyForRemoteCandidates("audio"));

  TransportDescription local_desc(std::vector<std::string>(), kIceUfrag2,
                                  kIcePwd2, ICEMODE_FULL,
                                  CONNECTIONROLE_ACTPASS, nullptr);
  EXPECT_TRUE(transport_controller_->SetLocalTransportDescription(
      "audio", local_desc, SdpType::kAnswer, &err));
  EXPECT_TRUE(transport_controller_->ReadyForRemoteCandidates("audio"));
}

TEST_F(TransportControllerTest, TestGetStats) {
  FakeDtlsTransport* transport1 = CreateFakeDtlsTransport("audio", 1);
  ASSERT_NE(nullptr, transport1);
  FakeDtlsTransport* transport2 = CreateFakeDtlsTransport("audio", 2);
  ASSERT_NE(nullptr, transport2);
  FakeDtlsTransport* transport3 = CreateFakeDtlsTransport("video", 1);
  ASSERT_NE(nullptr, transport3);

  TransportStats stats;
  EXPECT_TRUE(transport_controller_->GetStats("audio", &stats));
  EXPECT_EQ("audio", stats.transport_name);
  EXPECT_EQ(2U, stats.channel_stats.size());
}

// Test that a "transport" from a stats perspective (combination of RTP/RTCP
// transports) goes away when all references to its transports are gone.
TEST_F(TransportControllerTest, TestCreateAndDestroyFakeDtlsTransport) {
  FakeDtlsTransport* transport1 = CreateFakeDtlsTransport("audio", 1);
  ASSERT_NE(nullptr, transport1);
  FakeDtlsTransport* transport2 = CreateFakeDtlsTransport("audio", 1);
  ASSERT_NE(nullptr, transport2);
  ASSERT_EQ(transport1, transport2);
  FakeDtlsTransport* transport3 = CreateFakeDtlsTransport("audio", 2);
  ASSERT_NE(nullptr, transport3);

  // Using GetStats to check if transport is destroyed from an outside class's
  // perspective.
  TransportStats stats;
  EXPECT_TRUE(transport_controller_->GetStats("audio", &stats));
  DestroyFakeDtlsTransport("audio", 2);
  DestroyFakeDtlsTransport("audio", 1);
  EXPECT_TRUE(transport_controller_->GetStats("audio", &stats));
  DestroyFakeDtlsTransport("audio", 1);
  EXPECT_FALSE(transport_controller_->GetStats("audio", &stats));
}

TEST_F(TransportControllerTest, TestSignalConnectionStateFailed) {
  // Need controlling ICE role to get in failed state.
  transport_controller_->SetIceRole(ICEROLE_CONTROLLING);
  FakeDtlsTransport* transport1 = CreateFakeDtlsTransport("audio", 1);
  ASSERT_NE(nullptr, transport1);
  FakeDtlsTransport* transport2 = CreateFakeDtlsTransport("video", 1);
  ASSERT_NE(nullptr, transport2);

  // Should signal "failed" if any transport failed; transport is considered
  // failed
  // if it previously had a connection but now has none, and gathering is
  // complete.
  transport1->fake_ice_transport()->SetCandidatesGatheringComplete();
  transport1->fake_ice_transport()->SetConnectionCount(1);
  transport1->fake_ice_transport()->SetConnectionCount(0);
  EXPECT_EQ_WAIT(kIceConnectionFailed, connection_state_, kTimeout);
  EXPECT_EQ(1, connection_state_signal_count_);
}

TEST_F(TransportControllerTest, TestSignalConnectionStateConnected) {
  transport_controller_->SetIceRole(ICEROLE_CONTROLLING);
  FakeDtlsTransport* transport1 = CreateFakeDtlsTransport("audio", 1);
  ASSERT_NE(nullptr, transport1);
  FakeDtlsTransport* transport2 = CreateFakeDtlsTransport("video", 1);
  ASSERT_NE(nullptr, transport2);
  FakeDtlsTransport* transport3 = CreateFakeDtlsTransport("video", 2);
  ASSERT_NE(nullptr, transport3);

  // First, have one transport connect, and another fail, to ensure that
  // the first transport connecting didn't trigger a "connected" state signal.
  // We should only get a signal when all are connected.
  transport1->fake_ice_transport()->SetConnectionCount(2);
  transport1->SetWritable(true);
  transport3->fake_ice_transport()->SetCandidatesGatheringComplete();
  transport3->fake_ice_transport()->SetConnectionCount(1);
  transport3->fake_ice_transport()->SetConnectionCount(0);
  EXPECT_EQ_WAIT(kIceConnectionFailed, connection_state_, kTimeout);
  // Signal count of 1 means that the only signal emitted was "failed".
  EXPECT_EQ(1, connection_state_signal_count_);

  // Destroy the failed transport to return to "connecting" state.
  DestroyFakeDtlsTransport("video", 2);
  EXPECT_EQ_WAIT(kIceConnectionConnecting, connection_state_, kTimeout);
  EXPECT_EQ(2, connection_state_signal_count_);

  // Make the remaining transport reach a connected state.
  transport2->fake_ice_transport()->SetConnectionCount(2);
  transport2->SetWritable(true);
  EXPECT_EQ_WAIT(kIceConnectionConnected, connection_state_, kTimeout);
  EXPECT_EQ(3, connection_state_signal_count_);
}

TEST_F(TransportControllerTest, TestSignalConnectionStateComplete) {
  transport_controller_->SetIceRole(ICEROLE_CONTROLLING);
  FakeDtlsTransport* transport1 = CreateFakeDtlsTransport("audio", 1);
  ASSERT_NE(nullptr, transport1);
  FakeDtlsTransport* transport2 = CreateFakeDtlsTransport("video", 1);
  ASSERT_NE(nullptr, transport2);
  FakeDtlsTransport* transport3 = CreateFakeDtlsTransport("video", 2);
  ASSERT_NE(nullptr, transport3);

  // Similar to above test, but we're now reaching the completed state, which
  // means only one connection per FakeDtlsTransport.
  transport1->fake_ice_transport()->SetCandidatesGatheringComplete();
  transport1->fake_ice_transport()->SetConnectionCount(1);
  transport1->SetWritable(true);
  transport3->fake_ice_transport()->SetCandidatesGatheringComplete();
  transport3->fake_ice_transport()->SetConnectionCount(1);
  transport3->fake_ice_transport()->SetConnectionCount(0);
  EXPECT_EQ_WAIT(kIceConnectionFailed, connection_state_, kTimeout);
  // Signal count of 1 means that the only signal emitted was "failed".
  EXPECT_EQ(1, connection_state_signal_count_);

  // Destroy the failed transport to return to "connecting" state.
  DestroyFakeDtlsTransport("video", 2);
  EXPECT_EQ_WAIT(kIceConnectionConnecting, connection_state_, kTimeout);
  EXPECT_EQ(2, connection_state_signal_count_);

  // Make the remaining transport reach a connected state.
  transport2->fake_ice_transport()->SetCandidatesGatheringComplete();
  transport2->fake_ice_transport()->SetConnectionCount(2);
  transport2->SetWritable(true);
  EXPECT_EQ_WAIT(kIceConnectionConnected, connection_state_, kTimeout);
  EXPECT_EQ(3, connection_state_signal_count_);

  // Finally, transition to completed state.
  transport2->fake_ice_transport()->SetConnectionCount(1);
  EXPECT_EQ_WAIT(kIceConnectionCompleted, connection_state_, kTimeout);
  EXPECT_EQ(4, connection_state_signal_count_);
}

// Make sure that if we're "connected" and remove a transport, we stay in the
// "connected" state.
TEST_F(TransportControllerTest, TestDestroyTransportAndStayConnected) {
  FakeDtlsTransport* transport1 = CreateFakeDtlsTransport("audio", 1);
  ASSERT_NE(nullptr, transport1);
  FakeDtlsTransport* transport2 = CreateFakeDtlsTransport("video", 1);
  ASSERT_NE(nullptr, transport2);

  transport1->fake_ice_transport()->SetCandidatesGatheringComplete();
  transport1->fake_ice_transport()->SetConnectionCount(2);
  transport1->SetWritable(true);
  transport2->fake_ice_transport()->SetCandidatesGatheringComplete();
  transport2->fake_ice_transport()->SetConnectionCount(2);
  transport2->SetWritable(true);
  EXPECT_EQ_WAIT(kIceConnectionConnected, connection_state_, kTimeout);
  EXPECT_EQ(1, connection_state_signal_count_);

  // Destroy one transport, then "complete" the other one, so we reach
  // a known state.
  DestroyFakeDtlsTransport("video", 1);
  transport1->fake_ice_transport()->SetConnectionCount(1);
  EXPECT_EQ_WAIT(kIceConnectionCompleted, connection_state_, kTimeout);
  // Signal count of 2 means the deletion didn't cause any unexpected signals
  EXPECT_EQ(2, connection_state_signal_count_);
}

// If we destroy the last/only transport, we should simply transition to
// "connecting".
TEST_F(TransportControllerTest, TestDestroyLastTransportWhileConnected) {
  FakeDtlsTransport* transport = CreateFakeDtlsTransport("audio", 1);
  ASSERT_NE(nullptr, transport);

  transport->fake_ice_transport()->SetCandidatesGatheringComplete();
  transport->fake_ice_transport()->SetConnectionCount(2);
  transport->SetWritable(true);
  EXPECT_EQ_WAIT(kIceConnectionConnected, connection_state_, kTimeout);
  EXPECT_EQ(1, connection_state_signal_count_);

  DestroyFakeDtlsTransport("audio", 1);
  EXPECT_EQ_WAIT(kIceConnectionConnecting, connection_state_, kTimeout);
  // Signal count of 2 means the deletion didn't cause any unexpected signals
  EXPECT_EQ(2, connection_state_signal_count_);
}

TEST_F(TransportControllerTest, TestSignalReceiving) {
  FakeDtlsTransport* transport1 = CreateFakeDtlsTransport("audio", 1);
  ASSERT_NE(nullptr, transport1);
  FakeDtlsTransport* transport2 = CreateFakeDtlsTransport("video", 1);
  ASSERT_NE(nullptr, transport2);

  // Should signal receiving as soon as any transport is receiving.
  transport1->SetReceiving(true);
  EXPECT_TRUE_WAIT(receiving_, kTimeout);
  EXPECT_EQ(1, receiving_signal_count_);

  transport2->SetReceiving(true);
  transport1->SetReceiving(false);
  transport2->SetReceiving(false);
  EXPECT_TRUE_WAIT(!receiving_, kTimeout);
  EXPECT_EQ(2, receiving_signal_count_);
}

TEST_F(TransportControllerTest, TestSignalGatheringStateGathering) {
  FakeDtlsTransport* transport = CreateFakeDtlsTransport("audio", 1);
  ASSERT_NE(nullptr, transport);
  transport->fake_ice_transport()->MaybeStartGathering();
  // Should be in the gathering state as soon as any transport starts gathering.
  EXPECT_EQ_WAIT(kIceGatheringGathering, gathering_state_, kTimeout);
  EXPECT_EQ(1, gathering_state_signal_count_);
}

TEST_F(TransportControllerTest, TestSignalGatheringStateComplete) {
  FakeDtlsTransport* transport1 = CreateFakeDtlsTransport("audio", 1);
  ASSERT_NE(nullptr, transport1);
  FakeDtlsTransport* transport2 = CreateFakeDtlsTransport("video", 1);
  ASSERT_NE(nullptr, transport2);
  FakeDtlsTransport* transport3 = CreateFakeDtlsTransport("data", 1);
  ASSERT_NE(nullptr, transport3);

  transport3->fake_ice_transport()->MaybeStartGathering();
  EXPECT_EQ_WAIT(kIceGatheringGathering, gathering_state_, kTimeout);
  EXPECT_EQ(1, gathering_state_signal_count_);

  // Have one transport finish gathering, then destroy it, to make sure
  // gathering
  // completion wasn't signalled if only one transport finished gathering.
  transport3->fake_ice_transport()->SetCandidatesGatheringComplete();
  DestroyFakeDtlsTransport("data", 1);
  EXPECT_EQ_WAIT(kIceGatheringNew, gathering_state_, kTimeout);
  EXPECT_EQ(2, gathering_state_signal_count_);

  // Make remaining transports start and then finish gathering.
  transport1->fake_ice_transport()->MaybeStartGathering();
  transport2->fake_ice_transport()->MaybeStartGathering();
  EXPECT_EQ_WAIT(kIceGatheringGathering, gathering_state_, kTimeout);
  EXPECT_EQ(3, gathering_state_signal_count_);

  transport1->fake_ice_transport()->SetCandidatesGatheringComplete();
  transport2->fake_ice_transport()->SetCandidatesGatheringComplete();
  EXPECT_EQ_WAIT(kIceGatheringComplete, gathering_state_, kTimeout);
  EXPECT_EQ(4, gathering_state_signal_count_);
}

// Test that when the last transport that hasn't finished connecting and/or
// gathering is destroyed, the aggregate state jumps to "completed". This can
// happen if, for example, we have an audio and video transport, the audio
// transport completes, then we start bundling video on the audio transport.
TEST_F(TransportControllerTest,
       TestSignalingWhenLastIncompleteTransportDestroyed) {
  transport_controller_->SetIceRole(ICEROLE_CONTROLLING);
  FakeDtlsTransport* transport1 = CreateFakeDtlsTransport("audio", 1);
  ASSERT_NE(nullptr, transport1);
  FakeDtlsTransport* transport2 = CreateFakeDtlsTransport("video", 1);
  ASSERT_NE(nullptr, transport2);

  transport1->fake_ice_transport()->SetCandidatesGatheringComplete();
  EXPECT_EQ_WAIT(kIceGatheringGathering, gathering_state_, kTimeout);
  EXPECT_EQ(1, gathering_state_signal_count_);

  transport1->fake_ice_transport()->SetConnectionCount(1);
  transport1->SetWritable(true);
  DestroyFakeDtlsTransport("video", 1);
  EXPECT_EQ_WAIT(kIceConnectionCompleted, connection_state_, kTimeout);
  EXPECT_EQ(1, connection_state_signal_count_);
  EXPECT_EQ_WAIT(kIceGatheringComplete, gathering_state_, kTimeout);
  EXPECT_EQ(2, gathering_state_signal_count_);
}

TEST_F(TransportControllerTest, TestSignalCandidatesGathered) {
  FakeDtlsTransport* transport = CreateFakeDtlsTransport("audio", 1);
  ASSERT_NE(nullptr, transport);

  // Transport won't signal candidates until it has a local description.
  TransportDescription local_desc(std::vector<std::string>(), kIceUfrag1,
                                  kIcePwd1, ICEMODE_FULL,
                                  CONNECTIONROLE_ACTPASS, nullptr);
  std::string err;
  EXPECT_TRUE(transport_controller_->SetLocalTransportDescription(
      "audio", local_desc, SdpType::kOffer, &err));
  transport_controller_->MaybeStartGathering();

  transport->fake_ice_transport()->SignalCandidateGathered(
      transport->fake_ice_transport(), CreateCandidate(1));
  EXPECT_EQ_WAIT(1, candidates_signal_count_, kTimeout);
  EXPECT_EQ(1U, candidates_["audio"].size());
}

TEST_F(TransportControllerTest, TestSignalingOccursOnSignalingThread) {
  CreateTransportControllerWithNetworkThread();
  CreateFakeDtlsTransportsAndCompleteConnectionOnNetworkThread();

  // connecting --> connected --> completed
  EXPECT_EQ_WAIT(kIceConnectionCompleted, connection_state_, kTimeout);
  EXPECT_EQ(2, connection_state_signal_count_);

  EXPECT_TRUE_WAIT(receiving_, kTimeout);
  EXPECT_EQ(1, receiving_signal_count_);

  // new --> gathering --> complete
  EXPECT_EQ_WAIT(kIceGatheringComplete, gathering_state_, kTimeout);
  EXPECT_EQ(2, gathering_state_signal_count_);

  EXPECT_EQ_WAIT(1U, candidates_["audio"].size(), kTimeout);
  EXPECT_EQ_WAIT(1U, candidates_["video"].size(), kTimeout);
  EXPECT_EQ(2, candidates_signal_count_);

  EXPECT_TRUE(!signaled_on_non_signaling_thread_);
}

// Older versions of Chrome expect the ICE role to be re-determined when an
// ICE restart occurs, and also don't perform conflict resolution correctly,
// so for now we can't safely stop doing this.
// See: https://bugs.chromium.org/p/chromium/issues/detail?id=628676
// TODO(deadbeef): Remove this when these old versions of Chrome reach a low
// enough population.
TEST_F(TransportControllerTest, IceRoleRedeterminedOnIceRestartByDefault) {
  FakeDtlsTransport* transport = CreateFakeDtlsTransport("audio", 1);
  ASSERT_NE(nullptr, transport);
  std::string err;
  // Do an initial offer answer, so that the next offer is an ICE restart.
  transport_controller_->SetIceRole(ICEROLE_CONTROLLED);
  TransportDescription remote_desc(std::vector<std::string>(), kIceUfrag1,
                                   kIcePwd1, ICEMODE_FULL,
                                   CONNECTIONROLE_ACTPASS, nullptr);
  EXPECT_TRUE(transport_controller_->SetRemoteTransportDescription(
      "audio", remote_desc, SdpType::kOffer, &err));
  TransportDescription local_desc(std::vector<std::string>(), kIceUfrag2,
                                  kIcePwd2, ICEMODE_FULL,
                                  CONNECTIONROLE_ACTPASS, nullptr);
  EXPECT_TRUE(transport_controller_->SetLocalTransportDescription(
      "audio", local_desc, SdpType::kAnswer, &err));
  EXPECT_EQ(ICEROLE_CONTROLLED, transport->fake_ice_transport()->GetIceRole());

  // The endpoint that initiated an ICE restart should take the controlling
  // role.
  TransportDescription ice_restart_desc(std::vector<std::string>(), kIceUfrag3,
                                        kIcePwd3, ICEMODE_FULL,
                                        CONNECTIONROLE_ACTPASS, nullptr);
  EXPECT_TRUE(transport_controller_->SetLocalTransportDescription(
      "audio", ice_restart_desc, SdpType::kOffer, &err));
  EXPECT_EQ(ICEROLE_CONTROLLING, transport->fake_ice_transport()->GetIceRole());
}

// Test that if the TransportController was created with the
// |redetermine_role_on_ice_restart| parameter set to false, the role is *not*
// redetermined on an ICE restart.
TEST_F(TransportControllerTest, IceRoleNotRedetermined) {
  bool redetermine_role = false;
  transport_controller_.reset(new TransportControllerForTest(redetermine_role));
  FakeDtlsTransport* transport = CreateFakeDtlsTransport("audio", 1);
  ASSERT_NE(nullptr, transport);
  std::string err;
  // Do an initial offer answer, so that the next offer is an ICE restart.
  transport_controller_->SetIceRole(ICEROLE_CONTROLLED);
  TransportDescription remote_desc(std::vector<std::string>(), kIceUfrag1,
                                   kIcePwd1, ICEMODE_FULL,
                                   CONNECTIONROLE_ACTPASS, nullptr);
  EXPECT_TRUE(transport_controller_->SetRemoteTransportDescription(
      "audio", remote_desc, SdpType::kOffer, &err));
  TransportDescription local_desc(std::vector<std::string>(), kIceUfrag2,
                                  kIcePwd2, ICEMODE_FULL,
                                  CONNECTIONROLE_ACTPASS, nullptr);
  EXPECT_TRUE(transport_controller_->SetLocalTransportDescription(
      "audio", local_desc, SdpType::kAnswer, &err));
  EXPECT_EQ(ICEROLE_CONTROLLED, transport->fake_ice_transport()->GetIceRole());

  // The endpoint that initiated an ICE restart should keep the existing role.
  TransportDescription ice_restart_desc(std::vector<std::string>(), kIceUfrag3,
                                        kIcePwd3, ICEMODE_FULL,
                                        CONNECTIONROLE_ACTPASS, nullptr);
  EXPECT_TRUE(transport_controller_->SetLocalTransportDescription(
      "audio", ice_restart_desc, SdpType::kOffer, &err));
  EXPECT_EQ(ICEROLE_CONTROLLED, transport->fake_ice_transport()->GetIceRole());
}

// Tests ICE role is reversed after receiving ice-lite from remote.
TEST_F(TransportControllerTest, TestSetRemoteIceLiteInOffer) {
  FakeDtlsTransport* transport = CreateFakeDtlsTransport("audio", 1);
  ASSERT_NE(nullptr, transport);
  std::string err;

  transport_controller_->SetIceRole(ICEROLE_CONTROLLED);
  TransportDescription remote_desc(std::vector<std::string>(), kIceUfrag1,
                                   kIcePwd1, ICEMODE_LITE,
                                   CONNECTIONROLE_ACTPASS, nullptr);
  EXPECT_TRUE(transport_controller_->SetRemoteTransportDescription(
      "audio", remote_desc, SdpType::kOffer, &err));
  TransportDescription local_desc(kIceUfrag1, kIcePwd1);
  ASSERT_TRUE(transport_controller_->SetLocalTransportDescription(
      "audio", local_desc, SdpType::kAnswer, nullptr));

  EXPECT_EQ(ICEROLE_CONTROLLING, transport->fake_ice_transport()->GetIceRole());
  EXPECT_EQ(ICEMODE_LITE, transport->fake_ice_transport()->remote_ice_mode());
}

// Tests ice-lite in remote answer.
TEST_F(TransportControllerTest, TestSetRemoteIceLiteInAnswer) {
  FakeDtlsTransport* transport = CreateFakeDtlsTransport("audio", 1);
  ASSERT_NE(nullptr, transport);
  std::string err;

  transport_controller_->SetIceRole(ICEROLE_CONTROLLING);
  TransportDescription local_desc(kIceUfrag1, kIcePwd1);
  ASSERT_TRUE(transport_controller_->SetLocalTransportDescription(
      "audio", local_desc, SdpType::kOffer, nullptr));
  EXPECT_EQ(ICEROLE_CONTROLLING, transport->fake_ice_transport()->GetIceRole());
  // Transports will be created in ICEFULL_MODE.
  EXPECT_EQ(ICEMODE_FULL, transport->fake_ice_transport()->remote_ice_mode());
  TransportDescription remote_desc(std::vector<std::string>(), kIceUfrag1,
                                   kIcePwd1, ICEMODE_LITE, CONNECTIONROLE_NONE,
                                   nullptr);
  ASSERT_TRUE(transport_controller_->SetRemoteTransportDescription(
      "audio", remote_desc, SdpType::kAnswer, nullptr));
  EXPECT_EQ(ICEROLE_CONTROLLING, transport->fake_ice_transport()->GetIceRole());
  // After receiving remote description with ICEMODE_LITE, transport should
  // have mode set to ICEMODE_LITE.
  EXPECT_EQ(ICEMODE_LITE, transport->fake_ice_transport()->remote_ice_mode());
}

// Tests that the ICE role remains "controlling" if a subsequent offer that
// does an ICE restart is received from an ICE lite endpoint. Regression test
// for: https://crbug.com/710760
TEST_F(TransportControllerTest,
       IceRoleIsControllingAfterIceRestartFromIceLiteEndpoint) {
  FakeDtlsTransport* transport = CreateFakeDtlsTransport("audio", 1);
  ASSERT_NE(nullptr, transport);
  std::string err;

  // Initial offer/answer.
  TransportDescription remote_desc(std::vector<std::string>(), kIceUfrag1,
                                   kIcePwd1, ICEMODE_LITE,
                                   CONNECTIONROLE_ACTPASS, nullptr);
  TransportDescription local_desc(kIceUfrag1, kIcePwd1);
  ASSERT_TRUE(transport_controller_->SetRemoteTransportDescription(
      "audio", remote_desc, SdpType::kOffer, &err));
  ASSERT_TRUE(transport_controller_->SetLocalTransportDescription(
      "audio", local_desc, SdpType::kAnswer, nullptr));
  // Subsequent ICE restart offer/answer.
  remote_desc.ice_ufrag = kIceUfrag2;
  remote_desc.ice_pwd = kIcePwd2;
  local_desc.ice_ufrag = kIceUfrag2;
  local_desc.ice_pwd = kIcePwd2;
  ASSERT_TRUE(transport_controller_->SetRemoteTransportDescription(
      "audio", remote_desc, SdpType::kOffer, &err));
  ASSERT_TRUE(transport_controller_->SetLocalTransportDescription(
      "audio", local_desc, SdpType::kAnswer, nullptr));

  EXPECT_EQ(ICEROLE_CONTROLLING, transport->fake_ice_transport()->GetIceRole());
}

// Tests SetNeedsIceRestartFlag and NeedsIceRestart, setting the flag and then
// initiating an ICE restart for one of the transports.
TEST_F(TransportControllerTest, NeedsIceRestart) {
  CreateFakeDtlsTransport("audio", 1);
  CreateFakeDtlsTransport("video", 1);

  // Do initial offer/answer so there's something to restart.
  TransportDescription local_desc(kIceUfrag1, kIcePwd1);
  TransportDescription remote_desc(kIceUfrag1, kIcePwd1);
  ASSERT_TRUE(transport_controller_->SetLocalTransportDescription(
      "audio", local_desc, SdpType::kOffer, nullptr));
  ASSERT_TRUE(transport_controller_->SetLocalTransportDescription(
      "video", local_desc, SdpType::kOffer, nullptr));
  ASSERT_TRUE(transport_controller_->SetRemoteTransportDescription(
      "audio", remote_desc, SdpType::kAnswer, nullptr));
  ASSERT_TRUE(transport_controller_->SetRemoteTransportDescription(
      "video", remote_desc, SdpType::kAnswer, nullptr));

  // Initially NeedsIceRestart should return false.
  EXPECT_FALSE(transport_controller_->NeedsIceRestart("audio"));
  EXPECT_FALSE(transport_controller_->NeedsIceRestart("video"));

  // Set the needs-ice-restart flag and verify NeedsIceRestart starts returning
  // true.
  transport_controller_->SetNeedsIceRestartFlag();
  EXPECT_TRUE(transport_controller_->NeedsIceRestart("audio"));
  EXPECT_TRUE(transport_controller_->NeedsIceRestart("video"));
  // For a nonexistent transport, false should be returned.
  EXPECT_FALSE(transport_controller_->NeedsIceRestart("deadbeef"));

  // Do ICE restart but only for audio.
  TransportDescription ice_restart_local_desc(kIceUfrag2, kIcePwd2);
  ASSERT_TRUE(transport_controller_->SetLocalTransportDescription(
      "audio", ice_restart_local_desc, SdpType::kOffer, nullptr));
  ASSERT_TRUE(transport_controller_->SetLocalTransportDescription(
      "video", local_desc, SdpType::kOffer, nullptr));
  // NeedsIceRestart should still be true for video.
  EXPECT_FALSE(transport_controller_->NeedsIceRestart("audio"));
  EXPECT_TRUE(transport_controller_->NeedsIceRestart("video"));
}

enum class RTPTransportType { kSdes, kDtlsSrtp };
std::ostream& operator<<(std::ostream& out, RTPTransportType value) {
  switch (value) {
    case RTPTransportType::kSdes:
      return out << "SDES";
    case RTPTransportType::kDtlsSrtp:
      return out << "DTLS-SRTP";
  }
  return out;
}

// Tests the TransportController can correctly create and destroy the RTP
// transports.
class TransportControllerRTPTransportTest
    : public TransportControllerTest,
      public ::testing::WithParamInterface<RTPTransportType> {
 protected:
  // Helper function used to create an RTP layer transport.
  webrtc::RtpTransportInternal* CreateRtpTransport(
      const std::string& transport_name) {
    RTPTransportType type = GetParam();
    switch (type) {
      case RTPTransportType::kSdes:
        return transport_controller_->CreateSdesTransport(transport_name,
                                                          kRtcpMuxEnabled);
      case RTPTransportType::kDtlsSrtp:
        return transport_controller_->CreateDtlsSrtpTransport(transport_name,
                                                              kRtcpMuxEnabled);
    }
    return nullptr;
  }
};

// Tests that creating transports with the same name will cause the
// second call to re-use the transport created in the first call.
TEST_P(TransportControllerRTPTransportTest, CreateTransportsWithReference) {
  const std::string transport_name = "transport";
  webrtc::RtpTransportInternal* transport1 = CreateRtpTransport(transport_name);
  webrtc::RtpTransportInternal* transport2 = CreateRtpTransport(transport_name);
  EXPECT_NE(nullptr, transport1);
  EXPECT_NE(nullptr, transport2);
  // The TransportController is expected to return the existing one when using
  // the same transport name.
  EXPECT_EQ(transport1, transport2);
  transport_controller_->DestroyTransport(transport_name);
  transport_controller_->DestroyTransport(transport_name);
}

// Tests that creating different type of RTP transports with same name is not
// allowed.
TEST_P(TransportControllerRTPTransportTest,
       CreateDifferentTypeOfTransportsWithSameName) {
  const std::string transport_name = "transport";
  webrtc::RtpTransportInternal* transport1 = CreateRtpTransport(transport_name);
  EXPECT_NE(nullptr, transport1);
  RTPTransportType type = GetParam();
  switch (type) {
    case RTPTransportType::kSdes:
      EXPECT_EQ(nullptr, transport_controller_->CreateDtlsSrtpTransport(
                             transport_name, kRtcpMuxEnabled));
      break;
    case RTPTransportType::kDtlsSrtp:
      EXPECT_EQ(nullptr, transport_controller_->CreateSdesTransport(
                             transport_name, kRtcpMuxEnabled));
      break;
    default:
      ASSERT_TRUE(false);
  }
  transport_controller_->DestroyTransport(transport_name);
}

// Tests the RTP transport is not actually destroyed if references still exist.
TEST_P(TransportControllerRTPTransportTest, DestroyTransportWithReference) {
  const std::string transport_name = "transport";
  webrtc::RtpTransportInternal* transport1 = CreateRtpTransport(transport_name);
  webrtc::RtpTransportInternal* transport2 = CreateRtpTransport(transport_name);
  EXPECT_NE(nullptr, transport1);
  EXPECT_NE(nullptr, transport2);
  transport_controller_->DestroyTransport(transport_name);
  EXPECT_NE(nullptr, transport1->rtp_packet_transport());
  EXPECT_EQ(nullptr, transport1->rtcp_packet_transport());
  transport_controller_->DestroyTransport(transport_name);
}

// Tests the RTP is actually destroyed if there is no reference to it.
// Disabled because of sometimes not working on Windows.
// https://bugs.webrtc.org/34942
TEST_P(TransportControllerRTPTransportTest,
       DISABLED_DestroyTransportWithNoReference) {
  const std::string transport_name = "transport";
  webrtc::RtpTransportInternal* transport1 = CreateRtpTransport(transport_name);
  webrtc::RtpTransportInternal* transport2 = CreateRtpTransport(transport_name);
  EXPECT_NE(nullptr, transport1);
  EXPECT_NE(nullptr, transport2);
  transport_controller_->DestroyTransport(transport_name);
  transport_controller_->DestroyTransport(transport_name);
#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
  EXPECT_DEATH(transport1->IsWritable(false), /*error_message=*/"");
#endif
}

INSTANTIATE_TEST_CASE_P(TransportControllerTest,
                        TransportControllerRTPTransportTest,
                        ::testing::Values(RTPTransportType::kSdes,
                                          RTPTransportType::kDtlsSrtp));

}  // namespace cricket
