/*
 *  Copyright 2016 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 "webrtc/p2p/quic/quictransportchannel.h"

#include <memory>
#include <set>
#include <string>
#include <vector>

#include "webrtc/base/common.h"
#include "webrtc/base/gunit.h"
#include "webrtc/base/sslidentity.h"
#include "webrtc/p2p/base/faketransportcontroller.h"

using cricket::ConnectionRole;
using cricket::IceRole;
using cricket::QuicTransportChannel;
using cricket::ReliableQuicStream;
using cricket::TransportChannel;
using cricket::TransportDescription;

// Timeout in milliseconds for asynchronous operations in unit tests.
static const int kTimeoutMs = 1000;

// Export keying material parameters.
static const char kExporterLabel[] = "label";
static const uint8_t kExporterContext[] = "context";
static const size_t kExporterContextLength = sizeof(kExporterContext);
static const size_t kOutputKeyLength = 20;

// Packet size for SRTP.
static const size_t kPacketSize = 100;

// Indicates ICE channel has no write error.
static const int kNoWriteError = 0;

// ICE parameters.
static const char kIceUfrag[] = "TESTICEUFRAG0001";
static const char kIcePwd[] = "TESTICEPWD00000000000001";

// QUIC packet parameters.
static const net::IPAddress kIpAddress(0, 0, 0, 0);
static const net::IPEndPoint kIpEndpoint(kIpAddress, 0);

// Detects incoming RTP packets.
static bool IsRtpLeadByte(uint8_t b) {
  return (b & 0xC0) == 0x80;
}

// Maps SSL role to ICE connection role. The peer with a client role is assumed
// to be the one who initiates the connection.
static ConnectionRole SslRoleToConnectionRole(rtc::SSLRole ssl_role) {
  return (ssl_role == rtc::SSL_CLIENT) ? cricket::CONNECTIONROLE_ACTIVE
                                       : cricket::CONNECTIONROLE_PASSIVE;
}

// Allows cricket::FakeTransportChannel to simulate write blocked
// and write error states.
// TODO(mikescarlett): Add this functionality to cricket::FakeTransportChannel.
class FailableTransportChannel : public cricket::FakeTransportChannel {
 public:
  FailableTransportChannel(const std::string& name, int component)
      : cricket::FakeTransportChannel(name, component), error_(kNoWriteError) {}
  int GetError() override { return error_; }
  void SetError(int error) { error_ = error; }
  int SendPacket(const char* data,
                 size_t len,
                 const rtc::PacketOptions& options,
                 int flags) override {
    if (error_ == kNoWriteError) {
      return cricket::FakeTransportChannel::SendPacket(data, len, options,
                                                       flags);
    }
    return -1;
  }

 private:
  int error_;
};

// Peer who establishes a handshake using a QuicTransportChannel, which wraps
// a FailableTransportChannel to simulate network connectivity and ICE
// negotiation.
class QuicTestPeer : public sigslot::has_slots<> {
 public:
  explicit QuicTestPeer(const std::string& name)
      : name_(name),
        bytes_sent_(0),
        ice_channel_(new FailableTransportChannel(name_, 0)),
        quic_channel_(ice_channel_),
        incoming_stream_count_(0) {
    quic_channel_.SignalReadPacket.connect(
        this, &QuicTestPeer::OnTransportChannelReadPacket);
    quic_channel_.SignalIncomingStream.connect(this,
                                               &QuicTestPeer::OnIncomingStream);
    quic_channel_.SignalClosed.connect(this, &QuicTestPeer::OnClosed);
    ice_channel_->SetAsync(true);
    rtc::scoped_refptr<rtc::RTCCertificate> local_cert =
        rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
            rtc::SSLIdentity::Generate(name_, rtc::KT_DEFAULT)));
    quic_channel_.SetLocalCertificate(local_cert);
    local_fingerprint_.reset(CreateFingerprint(local_cert.get()));
  }

  // Connects |ice_channel_| to that of the other peer.
  void Connect(QuicTestPeer* other_peer) {
    ice_channel_->Connect();
    other_peer->ice_channel_->Connect();
    ice_channel_->SetDestination(other_peer->ice_channel_);
  }

  // Disconnects |ice_channel_|.
  void Disconnect() { ice_channel_->SetDestination(nullptr); }

  // Generates ICE credentials and passes them to |quic_channel_|.
  void SetIceParameters(IceRole local_ice_role,
                        ConnectionRole local_connection_role,
                        ConnectionRole remote_connection_role,
                        rtc::SSLFingerprint* remote_fingerprint) {
    quic_channel_.SetIceRole(local_ice_role);
    quic_channel_.SetIceTiebreaker(
        (local_ice_role == cricket::ICEROLE_CONTROLLING) ? 1 : 2);

    TransportDescription local_desc(
        std::vector<std::string>(), kIceUfrag, kIcePwd, cricket::ICEMODE_FULL,
        local_connection_role, local_fingerprint_.get());
    TransportDescription remote_desc(
        std::vector<std::string>(), kIceUfrag, kIcePwd, cricket::ICEMODE_FULL,
        remote_connection_role, remote_fingerprint);

    quic_channel_.SetIceCredentials(local_desc.ice_ufrag, local_desc.ice_pwd);
    quic_channel_.SetRemoteIceCredentials(remote_desc.ice_ufrag,
                                          remote_desc.ice_pwd);
  }

  // Creates fingerprint from certificate.
  rtc::SSLFingerprint* CreateFingerprint(rtc::RTCCertificate* cert) {
    std::string digest_algorithm;
    bool get_digest_algorithm =
        cert->ssl_certificate().GetSignatureDigestAlgorithm(&digest_algorithm);
    if (!get_digest_algorithm || digest_algorithm.empty()) {
      return nullptr;
    }
    std::unique_ptr<rtc::SSLFingerprint> fingerprint(
        rtc::SSLFingerprint::Create(digest_algorithm, cert->identity()));
    if (digest_algorithm != rtc::DIGEST_SHA_256) {
      return nullptr;
    }
    return fingerprint.release();
  }

  // Sends SRTP packet to the other peer via |quic_channel_|.
  int SendSrtpPacket() {
    char packet[kPacketSize];
    packet[0] = 0x80;  // Make the packet header look like RTP.
    int rv = quic_channel_.SendPacket(
        &packet[0], kPacketSize, rtc::PacketOptions(), cricket::PF_SRTP_BYPASS);
    bytes_sent_ += rv;
    return rv;
  }

  // Sends a non-SRTP packet with the PF_SRTP_BYPASS flag via |quic_channel_|.
  int SendInvalidSrtpPacket() {
    char packet[kPacketSize];
    // Fill the packet with 0 to form an invalid SRTP packet.
    memset(packet, 0, kPacketSize);
    return quic_channel_.SendPacket(
        &packet[0], kPacketSize, rtc::PacketOptions(), cricket::PF_SRTP_BYPASS);
  }

  // Sends an RTP packet to the other peer via |quic_channel_|, without the SRTP
  // bypass flag.
  int SendRtpPacket() {
    char packet[kPacketSize];
    packet[0] = 0x80;  // Make the packet header look like RTP.
    return quic_channel_.SendPacket(&packet[0], kPacketSize,
                                    rtc::PacketOptions(), 0);
  }

  void ClearBytesSent() { bytes_sent_ = 0; }

  void ClearBytesReceived() { bytes_received_ = 0; }

  void SetWriteError(int error) { ice_channel_->SetError(error); }

  size_t bytes_received() const { return bytes_received_; }

  size_t bytes_sent() const { return bytes_sent_; }

  FailableTransportChannel* ice_channel() { return ice_channel_; }

  QuicTransportChannel* quic_channel() { return &quic_channel_; }

  std::unique_ptr<rtc::SSLFingerprint>& local_fingerprint() {
    return local_fingerprint_;
  }

  ReliableQuicStream* incoming_quic_stream() { return incoming_quic_stream_; }

  size_t incoming_stream_count() const { return incoming_stream_count_; }

  bool signal_closed_emitted() const { return signal_closed_emitted_; }

 private:
  // QuicTransportChannel callbacks.
  void OnTransportChannelReadPacket(TransportChannel* channel,
                                    const char* data,
                                    size_t size,
                                    const rtc::PacketTime& packet_time,
                                    int flags) {
    bytes_received_ += size;
    // Only SRTP packets should have the bypass flag set.
    int expected_flags = IsRtpLeadByte(data[0]) ? cricket::PF_SRTP_BYPASS : 0;
    ASSERT_EQ(expected_flags, flags);
  }
  void OnIncomingStream(ReliableQuicStream* stream) {
    incoming_quic_stream_ = stream;
    ++incoming_stream_count_;
  }
  void OnClosed() { signal_closed_emitted_ = true; }

  std::string name_;                      // Channel name.
  size_t bytes_sent_;                     // Bytes sent by QUIC channel.
  size_t bytes_received_;                 // Bytes received by QUIC channel.
  FailableTransportChannel* ice_channel_;  // Simulates an ICE channel.
  QuicTransportChannel quic_channel_;     // QUIC channel to test.
  std::unique_ptr<rtc::SSLFingerprint> local_fingerprint_;
  ReliableQuicStream* incoming_quic_stream_ = nullptr;
  size_t incoming_stream_count_;
  bool signal_closed_emitted_ = false;
};

class QuicTransportChannelTest : public testing::Test {
 public:
  QuicTransportChannelTest() : peer1_("P1"), peer2_("P2") {}

  // Performs negotiation before QUIC handshake, then connects the fake
  // transport channels of each peer. As a side effect, the QUIC channels
  // start sending handshake messages. |peer1_| has a client role and |peer2_|
  // has server role in the QUIC handshake.
  void Connect() {
    SetIceAndCryptoParameters(rtc::SSL_CLIENT, rtc::SSL_SERVER);
    peer1_.Connect(&peer2_);
  }

  // Disconnects the fake transport channels.
  void Disconnect() {
    peer1_.Disconnect();
    peer2_.Disconnect();
  }

  // Sets up ICE parameters and exchanges fingerprints before QUIC handshake.
  void SetIceAndCryptoParameters(rtc::SSLRole peer1_ssl_role,
                                 rtc::SSLRole peer2_ssl_role) {
    peer1_.quic_channel()->SetSslRole(peer1_ssl_role);
    peer2_.quic_channel()->SetSslRole(peer2_ssl_role);

    std::unique_ptr<rtc::SSLFingerprint>& peer1_fingerprint =
        peer1_.local_fingerprint();
    std::unique_ptr<rtc::SSLFingerprint>& peer2_fingerprint =
        peer2_.local_fingerprint();

    peer1_.quic_channel()->SetRemoteFingerprint(
        peer2_fingerprint->algorithm,
        reinterpret_cast<const uint8_t*>(peer2_fingerprint->digest.data()),
        peer2_fingerprint->digest.size());
    peer2_.quic_channel()->SetRemoteFingerprint(
        peer1_fingerprint->algorithm,
        reinterpret_cast<const uint8_t*>(peer1_fingerprint->digest.data()),
        peer1_fingerprint->digest.size());

    ConnectionRole peer1_connection_role =
        SslRoleToConnectionRole(peer1_ssl_role);
    ConnectionRole peer2_connection_role =
        SslRoleToConnectionRole(peer2_ssl_role);

    peer1_.SetIceParameters(cricket::ICEROLE_CONTROLLED, peer1_connection_role,
                            peer2_connection_role, peer2_fingerprint.get());
    peer2_.SetIceParameters(cricket::ICEROLE_CONTROLLING, peer2_connection_role,
                            peer1_connection_role, peer1_fingerprint.get());
  }

  // Checks if QUIC handshake is done.
  bool quic_connected() {
    return peer1_.quic_channel()->quic_state() ==
               cricket::QUIC_TRANSPORT_CONNECTED &&
           peer2_.quic_channel()->quic_state() ==
               cricket::QUIC_TRANSPORT_CONNECTED;
  }

  // Checks if QUIC channels are writable.
  bool quic_writable() {
    return peer1_.quic_channel()->writable() &&
           peer2_.quic_channel()->writable();
  }

 protected:
  // QUIC peer with a client role, who initiates the QUIC handshake.
  QuicTestPeer peer1_;
  // QUIC peer with a server role, who responds to the client peer.
  QuicTestPeer peer2_;
};

// Test that the QUIC channel passes ICE parameters to the underlying ICE
// channel.
TEST_F(QuicTransportChannelTest, ChannelSetupIce) {
  SetIceAndCryptoParameters(rtc::SSL_CLIENT, rtc::SSL_SERVER);
  FailableTransportChannel* channel1 = peer1_.ice_channel();
  FailableTransportChannel* channel2 = peer2_.ice_channel();
  EXPECT_EQ(cricket::ICEROLE_CONTROLLED, channel1->GetIceRole());
  EXPECT_EQ(2u, channel1->IceTiebreaker());
  EXPECT_EQ(kIceUfrag, channel1->ice_ufrag());
  EXPECT_EQ(kIcePwd, channel1->ice_pwd());
  EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel2->GetIceRole());
  EXPECT_EQ(1u, channel2->IceTiebreaker());
}

// Test that export keying material generates identical keys for both peers
// after the QUIC handshake.
TEST_F(QuicTransportChannelTest, ExportKeyingMaterial) {
  Connect();
  ASSERT_TRUE_WAIT(quic_connected(), kTimeoutMs);
  uint8_t key1[kOutputKeyLength];
  uint8_t key2[kOutputKeyLength];

  bool from_success = peer1_.quic_channel()->ExportKeyingMaterial(
      kExporterLabel, kExporterContext, kExporterContextLength, true, key1,
      kOutputKeyLength);
  ASSERT_TRUE(from_success);
  bool to_success = peer2_.quic_channel()->ExportKeyingMaterial(
      kExporterLabel, kExporterContext, kExporterContextLength, true, key2,
      kOutputKeyLength);
  ASSERT_TRUE(to_success);

  EXPECT_EQ(0, memcmp(key1, key2, sizeof(key1)));
}

// Test that the QUIC channel is not writable before the QUIC handshake.
TEST_F(QuicTransportChannelTest, NotWritableBeforeHandshake) {
  Connect();
  EXPECT_FALSE(quic_writable());
  Disconnect();
  EXPECT_FALSE(quic_writable());
  Connect();
  EXPECT_FALSE(quic_writable());
}

// Test that once handshake begins, QUIC is not writable until its completion.
TEST_F(QuicTransportChannelTest, QuicHandshake) {
  Connect();
  EXPECT_FALSE(quic_writable());
  ASSERT_TRUE_WAIT(quic_connected(), kTimeoutMs);
  EXPECT_TRUE(quic_writable());
}

// Test that Non-SRTP data is not sent using SendPacket(), regardless of QUIC
// channel state.
TEST_F(QuicTransportChannelTest, TransferNonSrtp) {
  // Send data before ICE channel is connected.
  peer1_.ClearBytesSent();
  peer2_.ClearBytesReceived();
  ASSERT_EQ(-1, peer1_.SendRtpPacket());
  EXPECT_EQ(0u, peer1_.bytes_sent());
  // Send data after ICE channel is connected, before QUIC handshake.
  Connect();
  peer1_.ClearBytesSent();
  peer2_.ClearBytesReceived();
  ASSERT_EQ(-1, peer1_.SendRtpPacket());
  EXPECT_EQ(0u, peer1_.bytes_sent());
  // Send data after QUIC handshake.
  ASSERT_TRUE_WAIT(quic_connected(), kTimeoutMs);
  peer1_.ClearBytesSent();
  peer2_.ClearBytesReceived();
  ASSERT_EQ(-1, peer1_.SendRtpPacket());
  EXPECT_EQ(0u, peer1_.bytes_sent());
}

// Test that SRTP data is always be sent, regardless of QUIC channel state, when
// the ICE channel is connected.
TEST_F(QuicTransportChannelTest, TransferSrtp) {
  // Send data after ICE channel is connected, before QUIC handshake.
  Connect();
  peer1_.ClearBytesSent();
  peer2_.ClearBytesReceived();
  ASSERT_EQ(kPacketSize, static_cast<size_t>(peer1_.SendSrtpPacket()));
  EXPECT_EQ_WAIT(kPacketSize, peer2_.bytes_received(), kTimeoutMs);
  EXPECT_EQ(kPacketSize, peer1_.bytes_sent());
  ASSERT_TRUE_WAIT(quic_connected(), kTimeoutMs);
  // Send data after QUIC handshake.
  peer1_.ClearBytesSent();
  peer2_.ClearBytesReceived();
  ASSERT_EQ(kPacketSize, static_cast<size_t>(peer1_.SendSrtpPacket()));
  EXPECT_EQ_WAIT(kPacketSize, peer2_.bytes_received(), kTimeoutMs);
  EXPECT_EQ(kPacketSize, peer1_.bytes_sent());
}

// Test that invalid SRTP (non-SRTP data with
// PF_SRTP_BYPASS flag) fails to send with return value -1.
TEST_F(QuicTransportChannelTest, TransferInvalidSrtp) {
  peer1_.ClearBytesSent();
  peer2_.ClearBytesReceived();
  EXPECT_EQ(-1, peer1_.SendInvalidSrtpPacket());
  EXPECT_EQ(0u, peer2_.bytes_received());
  Connect();
  peer1_.ClearBytesSent();
  peer2_.ClearBytesReceived();
  EXPECT_EQ(-1, peer1_.SendInvalidSrtpPacket());
  EXPECT_EQ(0u, peer2_.bytes_received());
}

// Test that QuicTransportChannel::WritePacket blocks when the ICE
// channel is not writable, and otherwise succeeds.
TEST_F(QuicTransportChannelTest, QuicWritePacket) {
  peer1_.ice_channel()->Connect();
  peer2_.ice_channel()->Connect();
  peer1_.ice_channel()->SetDestination(peer2_.ice_channel());
  std::string packet = "FAKEQUICPACKET";

  // QUIC should be write blocked when the ICE channel is not writable.
  peer1_.ice_channel()->SetWritable(false);
  EXPECT_TRUE(peer1_.quic_channel()->IsWriteBlocked());
  net::WriteResult write_blocked_result = peer1_.quic_channel()->WritePacket(
      packet.data(), packet.size(), kIpAddress, kIpEndpoint, nullptr);
  EXPECT_EQ(net::WRITE_STATUS_BLOCKED, write_blocked_result.status);
  EXPECT_EQ(EWOULDBLOCK, write_blocked_result.error_code);

  // QUIC should ignore errors when the ICE channel is writable.
  peer1_.ice_channel()->SetWritable(true);
  EXPECT_FALSE(peer1_.quic_channel()->IsWriteBlocked());
  peer1_.SetWriteError(EWOULDBLOCK);
  net::WriteResult ignore_error_result = peer1_.quic_channel()->WritePacket(
      packet.data(), packet.size(), kIpAddress, kIpEndpoint, nullptr);
  EXPECT_EQ(net::WRITE_STATUS_OK, ignore_error_result.status);
  EXPECT_EQ(0, ignore_error_result.bytes_written);

  peer1_.SetWriteError(kNoWriteError);
  net::WriteResult no_error_result = peer1_.quic_channel()->WritePacket(
      packet.data(), packet.size(), kIpAddress, kIpEndpoint, nullptr);
  EXPECT_EQ(net::WRITE_STATUS_OK, no_error_result.status);
  EXPECT_EQ(static_cast<int>(packet.size()), no_error_result.bytes_written);
}

// Test that SSL roles can be reversed before QUIC handshake.
TEST_F(QuicTransportChannelTest, QuicRoleReversalBeforeQuic) {
  EXPECT_TRUE(peer1_.quic_channel()->SetSslRole(rtc::SSL_SERVER));
  EXPECT_TRUE(peer1_.quic_channel()->SetSslRole(rtc::SSL_CLIENT));
  EXPECT_TRUE(peer1_.quic_channel()->SetSslRole(rtc::SSL_SERVER));
}

// Test that SSL roles cannot be reversed after the QUIC handshake. SetSslRole
// returns true if the current SSL role equals the proposed SSL role.
TEST_F(QuicTransportChannelTest, QuicRoleReversalAfterQuic) {
  Connect();
  ASSERT_TRUE_WAIT(quic_connected(), kTimeoutMs);
  EXPECT_FALSE(peer1_.quic_channel()->SetSslRole(rtc::SSL_SERVER));
  EXPECT_TRUE(peer1_.quic_channel()->SetSslRole(rtc::SSL_CLIENT));
  EXPECT_FALSE(peer2_.quic_channel()->SetSslRole(rtc::SSL_CLIENT));
  EXPECT_TRUE(peer2_.quic_channel()->SetSslRole(rtc::SSL_SERVER));
}

// Set the SSL role, then test that GetSslRole returns the same value.
TEST_F(QuicTransportChannelTest, SetGetSslRole) {
  ASSERT_TRUE(peer1_.quic_channel()->SetSslRole(rtc::SSL_SERVER));
  std::unique_ptr<rtc::SSLRole> role(new rtc::SSLRole());
  ASSERT_TRUE(peer1_.quic_channel()->GetSslRole(role.get()));
  EXPECT_EQ(rtc::SSL_SERVER, *role);
}

// Test that after the QUIC handshake is complete, the QUIC handshake remains
// confirmed even if the ICE channel reconnects.
TEST_F(QuicTransportChannelTest, HandshakeConfirmedAfterReconnect) {
  Connect();
  ASSERT_TRUE_WAIT(quic_connected(), kTimeoutMs);
  Disconnect();
  EXPECT_TRUE(quic_connected());
  Connect();
  EXPECT_TRUE(quic_connected());
}

// Test that if the ICE channel becomes receiving after the QUIC channel is
// connected, then the QUIC channel becomes receiving.
TEST_F(QuicTransportChannelTest, IceReceivingAfterConnected) {
  Connect();
  ASSERT_TRUE_WAIT(quic_connected(), kTimeoutMs);
  ASSERT_FALSE(peer1_.ice_channel()->receiving());
  EXPECT_FALSE(peer1_.quic_channel()->receiving());
  peer1_.ice_channel()->SetReceiving(true);
  EXPECT_TRUE(peer1_.quic_channel()->receiving());
}

// Test that if the ICE channel becomes receiving before the QUIC channel is
// connected, then the QUIC channel becomes receiving.
TEST_F(QuicTransportChannelTest, IceReceivingBeforeConnected) {
  Connect();
  peer1_.ice_channel()->SetReceiving(true);
  ASSERT_TRUE(peer1_.ice_channel()->receiving());
  ASSERT_TRUE_WAIT(quic_connected(), kTimeoutMs);
  EXPECT_TRUE(peer1_.quic_channel()->receiving());
}

// Test that when peer 1 creates an outgoing stream, peer 2 creates an incoming
// QUIC stream with the same ID and fires OnIncomingStream.
TEST_F(QuicTransportChannelTest, CreateOutgoingAndIncomingQuicStream) {
  Connect();
  EXPECT_EQ(nullptr, peer1_.quic_channel()->CreateQuicStream());
  ASSERT_TRUE_WAIT(quic_connected(), kTimeoutMs);
  ReliableQuicStream* stream = peer1_.quic_channel()->CreateQuicStream();
  ASSERT_NE(nullptr, stream);
  stream->Write("Hi", 2);
  EXPECT_TRUE_WAIT(peer2_.incoming_quic_stream() != nullptr, kTimeoutMs);
  EXPECT_EQ(stream->id(), peer2_.incoming_quic_stream()->id());
}

// Test that if the QuicTransportChannel is unwritable, then all outgoing QUIC
// streams can send data once the QuicTransprotChannel becomes writable again.
TEST_F(QuicTransportChannelTest, OutgoingQuicStreamSendsDataAfterReconnect) {
  Connect();
  ASSERT_TRUE_WAIT(quic_connected(), kTimeoutMs);
  ReliableQuicStream* stream1 = peer1_.quic_channel()->CreateQuicStream();
  ASSERT_NE(nullptr, stream1);
  ReliableQuicStream* stream2 = peer1_.quic_channel()->CreateQuicStream();
  ASSERT_NE(nullptr, stream2);

  peer1_.ice_channel()->SetWritable(false);
  stream1->Write("First", 5);
  EXPECT_EQ(5u, stream1->queued_data_bytes());
  stream2->Write("Second", 6);
  EXPECT_EQ(6u, stream2->queued_data_bytes());
  EXPECT_EQ(0u, peer2_.incoming_stream_count());

  peer1_.ice_channel()->SetWritable(true);
  EXPECT_EQ_WAIT(0u, stream1->queued_data_bytes(), kTimeoutMs);
  EXPECT_EQ_WAIT(0u, stream2->queued_data_bytes(), kTimeoutMs);
  EXPECT_EQ_WAIT(2u, peer2_.incoming_stream_count(), kTimeoutMs);
}

// Test that SignalClosed is emitted when the QuicConnection closes.
TEST_F(QuicTransportChannelTest, SignalClosedEmitted) {
  Connect();
  ASSERT_TRUE_WAIT(quic_connected(), kTimeoutMs);
  ASSERT_FALSE(peer1_.signal_closed_emitted());
  ReliableQuicStream* stream = peer1_.quic_channel()->CreateQuicStream();
  ASSERT_NE(nullptr, stream);
  stream->CloseConnectionWithDetails(net::QuicErrorCode::QUIC_NO_ERROR,
                                     "Closing QUIC for testing");
  EXPECT_TRUE(peer1_.signal_closed_emitted());
  EXPECT_TRUE_WAIT(peer2_.signal_closed_emitted(), kTimeoutMs);
}