/*
 *  Copyright 2006 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 <algorithm>
#include <array>
#include <cmath>
#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <memory>
#include <span>
#include <utility>
#include <vector>

#include "absl/memory/memory.h"
#include "api/environment/environment.h"
#include "api/transport/ecn_marking.h"
#include "api/units/time_delta.h"
#include "api/units/timestamp.h"
#include "rtc_base/async_packet_socket.h"
#include "rtc_base/async_udp_socket.h"
#include "rtc_base/byte_order.h"
#include "rtc_base/ip_address.h"
#include "rtc_base/logging.h"
#include "rtc_base/net_helpers.h"
#include "rtc_base/network/received_packet.h"
#include "rtc_base/socket.h"
#include "rtc_base/socket_address.h"
#include "rtc_base/task_utils/repeating_task.h"
#include "rtc_base/test_client.h"
#include "rtc_base/test_utils.h"
#include "rtc_base/thread.h"
#include "rtc_base/virtual_socket_server.h"
#include "test/create_test_environment.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/time_controller/simulated_time_controller.h"

namespace webrtc {
namespace {

using ::testing::ContainerEq;
using ::testing::Eq;
using ::testing::NotNull;
using ::testing::Pointwise;
using testing::SSE_CLOSE;
using testing::SSE_ERROR;
using testing::SSE_OPEN;
using testing::SSE_READ;
using testing::SSE_WRITE;
using testing::StreamSink;

// Sends at a constant rate but with random packet sizes.
struct Sender {
  Sender(const Environment& env,
         Thread* th,
         std::unique_ptr<Socket> s,
         uint32_t rt)
      : env(env),
        thread(th),
        socket(std::make_unique<AsyncUDPSocket>(env, std::move(s))),
        rate(rt),
        count(0) {
    last_send = this->env.clock().TimeInMilliseconds();

    periodic = RepeatingTaskHandle::DelayedStart(thread, NextDelay(), [this] {
      int64_t cur_time = this->env.clock().TimeInMilliseconds();
      int64_t delay = cur_time - last_send;
      uint32_t size =
          std::clamp<uint32_t>(rate * delay / 1000, sizeof(uint32_t), 4096);
      count += size;

      SetLE64(dummy, static_cast<uint64_t>(cur_time));
      socket->Send(dummy.data(), size, options);

      last_send = cur_time;
      return NextDelay();
    });
  }

  TimeDelta NextDelay() {
    int size = (rand() % 4096) + 1;
    return TimeDelta::Seconds(1) * size / rate;
  }

  const Environment env;
  Thread* thread;
  std::unique_ptr<AsyncUDPSocket> socket;
  AsyncSocketPacketOptions options;
  RepeatingTaskHandle periodic;
  uint32_t rate;  // bytes per second
  uint32_t count;
  int64_t last_send;
  std::array<uint8_t, 4096> dummy;
};

struct Receiver {
  Receiver(const Environment& env,
           Thread* th,
           std::unique_ptr<Socket> s,
           uint32_t bw)
      : env(env),
        thread(th),
        socket(std::make_unique<AsyncUDPSocket>(this->env, std::move(s))),
        bandwidth(bw),
        count(0),
        sec_count(0),
        sum(0),
        sum_sq(0),
        samples(0) {
    socket->RegisterReceivedPacketCallback(
        [&](AsyncPacketSocket* s, const ReceivedIpPacket& packet) {
          OnReadPacket(s, packet);
        });
    periodic = RepeatingTaskHandle::DelayedStart(
        thread, TimeDelta::Seconds(1), [this] {
          // It is always possible for us to receive more than expected because
          // packets can be further delayed in delivery.
          if (bandwidth > 0) {
            EXPECT_LE(sec_count, 5 * bandwidth / 4);
          }
          sec_count = 0;
          return TimeDelta::Seconds(1);
        });
  }

  ~Receiver() { periodic.Stop(); }

  void OnReadPacket(AsyncPacketSocket* s, const ReceivedIpPacket& packet) {
    ASSERT_EQ(socket.get(), s);
    ASSERT_GE(packet.payload().size(), 4U);

    count += packet.payload().size();
    sec_count += packet.payload().size();

    uint32_t send_time = GetLE32(packet.payload());
    uint32_t recv_time =
        static_cast<uint32_t>(env.clock().TimeInMilliseconds());
    uint32_t delay = recv_time - send_time;
    sum += delay;
    sum_sq += delay * delay;
    samples += 1;
  }

  const Environment env;
  Thread* thread;
  std::unique_ptr<AsyncUDPSocket> socket;
  uint32_t bandwidth;
  RepeatingTaskHandle periodic;
  size_t count;
  size_t sec_count;
  double sum;
  double sum_sq;
  uint32_t samples;
};

// Note: This test uses a fake clock in addition to a virtual network.
class VirtualSocketServerTest : public ::testing::Test {
 public:
  VirtualSocketServerTest()
      : time_controller_(Timestamp::Millis(1000), &ss_),
        env_(CreateTestEnvironment(
            CreateTestEnvironmentOptions{.time = &time_controller_})),
        kIPv4AnyAddress(IPAddress(INADDR_ANY), 0),
        kIPv6AnyAddress(IPAddress(in6addr_any), 0) {}

  void CheckPortIncrementalization(const SocketAddress& post,
                                   const SocketAddress& pre) {
    EXPECT_EQ(post.port(), pre.port() + 1);
    IPAddress post_ip = post.ipaddr();
    IPAddress pre_ip = pre.ipaddr();
    EXPECT_EQ(pre_ip.family(), post_ip.family());
    if (post_ip.family() == AF_INET) {
      in_addr pre_ipv4 = pre_ip.ipv4_address();
      in_addr post_ipv4 = post_ip.ipv4_address();
      EXPECT_EQ(post_ipv4.s_addr, pre_ipv4.s_addr);
    } else if (post_ip.family() == AF_INET6) {
      in6_addr post_ip6 = post_ip.ipv6_address();
      in6_addr pre_ip6 = pre_ip.ipv6_address();
      std::span<uint8_t, 16> post_bytes = post_ip6.s6_addr;
      std::span<uint8_t, 16> pre_bytes = pre_ip6.s6_addr;
      EXPECT_THAT(post_bytes.subspan(12, 4),
                  Pointwise(Eq(), pre_bytes.subspan(12, 4)));
    }
  }

  // Test a client can bind to the any address, and all sent packets will have
  // the default source address. Also, it can receive packets sent to the
  // default address.
  void TestDefaultSourceAddress(const IPAddress& default_address) {
    ss_.SetDefaultSourceAddress(default_address);

    // Create client1 bound to the any address.
    std::unique_ptr<Socket> socket =
        ss_.Create(default_address.family(), SOCK_DGRAM);
    socket->Bind(EmptySocketAddressWithFamily(default_address.family()));
    SocketAddress client1_any_addr = socket->GetLocalAddress();
    EXPECT_TRUE(client1_any_addr.IsAnyIP());
    TestClient client1(
        std::make_unique<AsyncUDPSocket>(env_, std::move(socket)),
        &time_controller_);

    // Create client2 bound to the address route.
    std::unique_ptr<Socket> socket2 =
        ss_.Create(default_address.family(), SOCK_DGRAM);
    socket2->Bind(SocketAddress(default_address, 0));
    SocketAddress client2_addr = socket2->GetLocalAddress();
    EXPECT_FALSE(client2_addr.IsAnyIP());
    TestClient client2(
        std::make_unique<AsyncUDPSocket>(env_, std::move(socket2)),
        &time_controller_);

    // Client1 sends to client2, client2 should see the default address as
    // client1's address.
    SocketAddress client1_addr;
    EXPECT_EQ(6, client1.SendTo("bizbaz", 6, client2_addr));
    EXPECT_TRUE(client2.CheckNextPacket("bizbaz", 6, &client1_addr));
    EXPECT_EQ(client1_addr,
              SocketAddress(default_address, client1_any_addr.port()));

    // Client2 can send back to client1's default address.
    EXPECT_EQ(3, client2.SendTo("foo", 3, client1_addr));
    EXPECT_TRUE(client1.CheckNextPacket("foo", 3, &client2_addr));
  }

  void BasicTest(const SocketAddress& initial_addr) {
    std::unique_ptr<Socket> socket =
        ss_.Create(initial_addr.family(), SOCK_DGRAM);
    socket->Bind(initial_addr);
    SocketAddress server_addr = socket->GetLocalAddress();
    // Make sure VSS didn't switch families on us.
    EXPECT_EQ(server_addr.family(), initial_addr.family());

    TestClient client1(
        std::make_unique<AsyncUDPSocket>(env_, std::move(socket)),
        &time_controller_);
    SocketAddress client2_addr;
    {
      std::unique_ptr<Socket> socket2 =
          ss_.Create(initial_addr.family(), SOCK_DGRAM);
      TestClient client2(
          std::make_unique<AsyncUDPSocket>(env_, std::move(socket2)),
          &time_controller_);

      EXPECT_EQ(3, client2.SendTo("foo", 3, server_addr));
      EXPECT_TRUE(client1.CheckNextPacket("foo", 3, &client2_addr));

      SocketAddress client1_addr;
      EXPECT_EQ(6, client1.SendTo("bizbaz", 6, client2_addr));
      EXPECT_TRUE(client2.CheckNextPacket("bizbaz", 6, &client1_addr));
      EXPECT_EQ(client1_addr, server_addr);
    }

    SocketAddress empty = EmptySocketAddressWithFamily(initial_addr.family());
    for (int i = 0; i < 10; i++) {
      TestClient client2(AsyncUDPSocket::Create(env_, empty, ss_),
                         &time_controller_);

      SocketAddress next_client2_addr;
      EXPECT_EQ(3, client2.SendTo("foo", 3, server_addr));
      EXPECT_TRUE(client1.CheckNextPacket("foo", 3, &next_client2_addr));
      CheckPortIncrementalization(next_client2_addr, client2_addr);
      // EXPECT_EQ(next_client2_addr.port(), client2_addr.port() + 1);

      SocketAddress server_addr2;
      EXPECT_EQ(6, client1.SendTo("bizbaz", 6, next_client2_addr));
      EXPECT_TRUE(client2.CheckNextPacket("bizbaz", 6, &server_addr2));
      EXPECT_EQ(server_addr2, server_addr);

      client2_addr = next_client2_addr;
    }
  }

  // initial_addr should be made from either INADDR_ANY or in6addr_any.
  void ConnectTest(const SocketAddress& initial_addr) {
    StreamSink sink;
    SocketAddress accept_addr;
    const SocketAddress kEmptyAddr =
        EmptySocketAddressWithFamily(initial_addr.family());

    // Create client
    std::unique_ptr<Socket> client =
        ss_.Create(initial_addr.family(), SOCK_STREAM);
    sink.Monitor(client.get());
    EXPECT_EQ(client->GetState(), Socket::CS_CLOSED);
    EXPECT_TRUE(client->GetLocalAddress().IsNil());

    // Create server
    std::unique_ptr<Socket> server =
        ss_.Create(initial_addr.family(), SOCK_STREAM);
    sink.Monitor(server.get());
    EXPECT_NE(0, server->Listen(5));  // Bind required
    EXPECT_EQ(0, server->Bind(initial_addr));
    EXPECT_EQ(server->GetLocalAddress().family(), initial_addr.family());
    EXPECT_EQ(0, server->Listen(5));
    EXPECT_EQ(server->GetState(), Socket::CS_CONNECTING);

    // No pending server connections
    EXPECT_FALSE(sink.Check(server.get(), SSE_READ));
    EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
    EXPECT_EQ(AF_UNSPEC, accept_addr.family());

    // Attempt connect to listening socket
    EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
    EXPECT_NE(client->GetLocalAddress(), kEmptyAddr);          // Implicit Bind
    EXPECT_NE(AF_UNSPEC, client->GetLocalAddress().family());  // Implicit Bind
    EXPECT_NE(client->GetLocalAddress(), server->GetLocalAddress());

    // Client is connecting
    EXPECT_EQ(client->GetState(), Socket::CS_CONNECTING);
    EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
    EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));

    time_controller_.AdvanceTime(TimeDelta::Zero());

    // Client still connecting
    EXPECT_EQ(client->GetState(), Socket::CS_CONNECTING);
    EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
    EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));

    // Server has pending connection
    EXPECT_TRUE(sink.Check(server.get(), SSE_READ));
    std::unique_ptr<Socket> accepted =
        absl::WrapUnique(server->Accept(&accept_addr));
    EXPECT_TRUE(nullptr != accepted);
    EXPECT_NE(accept_addr, kEmptyAddr);
    EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);

    EXPECT_EQ(accepted->GetState(), Socket::CS_CONNECTED);
    EXPECT_EQ(accepted->GetLocalAddress(), server->GetLocalAddress());
    EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());

    time_controller_.AdvanceTime(TimeDelta::Zero());

    // Client has connected
    EXPECT_EQ(client->GetState(), Socket::CS_CONNECTED);
    EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
    EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
    EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
    EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
  }

  void ConnectToNonListenerTest(const SocketAddress& initial_addr) {
    StreamSink sink;
    SocketAddress accept_addr;
    const SocketAddress nil_addr;
    const SocketAddress empty_addr =
        EmptySocketAddressWithFamily(initial_addr.family());

    // Create client
    std::unique_ptr<Socket> client =
        ss_.Create(initial_addr.family(), SOCK_STREAM);
    sink.Monitor(client.get());

    // Create server
    std::unique_ptr<Socket> server =
        ss_.Create(initial_addr.family(), SOCK_STREAM);
    sink.Monitor(server.get());
    EXPECT_EQ(0, server->Bind(initial_addr));
    EXPECT_EQ(server->GetLocalAddress().family(), initial_addr.family());
    // Attempt connect to non-listening socket
    EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));

    time_controller_.AdvanceTime(TimeDelta::Zero());

    // No pending server connections
    EXPECT_FALSE(sink.Check(server.get(), SSE_READ));
    EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
    EXPECT_EQ(accept_addr, nil_addr);

    // Connection failed
    EXPECT_EQ(client->GetState(), Socket::CS_CLOSED);
    EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
    EXPECT_TRUE(sink.Check(client.get(), SSE_ERROR));
    EXPECT_EQ(client->GetRemoteAddress(), nil_addr);
  }

  void CloseDuringConnectTest(const SocketAddress& initial_addr) {
    StreamSink sink;
    SocketAddress accept_addr;
    const SocketAddress empty_addr =
        EmptySocketAddressWithFamily(initial_addr.family());

    // Create client and server
    std::unique_ptr<Socket> client =
        ss_.Create(initial_addr.family(), SOCK_STREAM);
    sink.Monitor(client.get());
    std::unique_ptr<Socket> server =
        ss_.Create(initial_addr.family(), SOCK_STREAM);
    sink.Monitor(server.get());

    // Initiate connect
    EXPECT_EQ(0, server->Bind(initial_addr));
    EXPECT_EQ(server->GetLocalAddress().family(), initial_addr.family());

    EXPECT_EQ(0, server->Listen(5));
    EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));

    // Server close before socket enters accept queue
    EXPECT_FALSE(sink.Check(server.get(), SSE_READ));
    server->Close();

    time_controller_.AdvanceTime(TimeDelta::Zero());

    // Result: connection failed
    EXPECT_EQ(client->GetState(), Socket::CS_CLOSED);
    EXPECT_TRUE(sink.Check(client.get(), SSE_ERROR));

    server = ss_.Create(initial_addr.family(), SOCK_STREAM);
    sink.Monitor(server.get());

    // Initiate connect
    EXPECT_EQ(0, server->Bind(initial_addr));
    EXPECT_EQ(server->GetLocalAddress().family(), initial_addr.family());

    EXPECT_EQ(0, server->Listen(5));
    EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));

    time_controller_.AdvanceTime(TimeDelta::Zero());

    // Server close while socket is in accept queue
    EXPECT_TRUE(sink.Check(server.get(), SSE_READ));
    server->Close();

    time_controller_.AdvanceTime(TimeDelta::Zero());

    // Result: connection failed
    EXPECT_EQ(client->GetState(), Socket::CS_CLOSED);
    EXPECT_TRUE(sink.Check(client.get(), SSE_ERROR));

    // New server
    server = ss_.Create(initial_addr.family(), SOCK_STREAM);
    sink.Monitor(server.get());

    // Initiate connect
    EXPECT_EQ(0, server->Bind(initial_addr));
    EXPECT_EQ(server->GetLocalAddress().family(), initial_addr.family());

    EXPECT_EQ(0, server->Listen(5));
    EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));

    time_controller_.AdvanceTime(TimeDelta::Zero());

    // Server accepts connection
    EXPECT_TRUE(sink.Check(server.get(), SSE_READ));
    std::unique_ptr<Socket> accepted(server->Accept(&accept_addr));
    ASSERT_TRUE(nullptr != accepted.get());
    sink.Monitor(accepted.get());

    // Client closes before connection complets
    EXPECT_EQ(accepted->GetState(), Socket::CS_CONNECTED);

    // Connected message has not been processed yet.
    EXPECT_EQ(client->GetState(), Socket::CS_CONNECTING);
    client->Close();

    time_controller_.AdvanceTime(TimeDelta::Zero());

    // Result: accepted socket closes
    EXPECT_EQ(accepted->GetState(), Socket::CS_CLOSED);
    EXPECT_TRUE(sink.Check(accepted.get(), SSE_CLOSE));
    EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
  }

  void CloseTest(const SocketAddress& initial_addr) {
    StreamSink sink;
    const SocketAddress kEmptyAddr;

    // Create clients
    std::unique_ptr<Socket> a = ss_.Create(initial_addr.family(), SOCK_STREAM);
    sink.Monitor(a.get());
    a->Bind(initial_addr);
    EXPECT_EQ(a->GetLocalAddress().family(), initial_addr.family());

    std::unique_ptr<Socket> b = ss_.Create(initial_addr.family(), SOCK_STREAM);
    sink.Monitor(b.get());
    b->Bind(initial_addr);
    EXPECT_EQ(b->GetLocalAddress().family(), initial_addr.family());

    EXPECT_EQ(0, a->Connect(b->GetLocalAddress()));
    EXPECT_EQ(0, b->Connect(a->GetLocalAddress()));

    time_controller_.AdvanceTime(TimeDelta::Zero());

    EXPECT_TRUE(sink.Check(a.get(), SSE_OPEN));
    EXPECT_EQ(a->GetState(), Socket::CS_CONNECTED);
    EXPECT_EQ(a->GetRemoteAddress(), b->GetLocalAddress());

    EXPECT_TRUE(sink.Check(b.get(), SSE_OPEN));
    EXPECT_EQ(b->GetState(), Socket::CS_CONNECTED);
    EXPECT_EQ(b->GetRemoteAddress(), a->GetLocalAddress());

    EXPECT_EQ(1, a->Send("a", 1));
    b->Close();
    EXPECT_EQ(1, a->Send("b", 1));

    time_controller_.AdvanceTime(TimeDelta::Zero());

    char buffer[10];
    EXPECT_FALSE(sink.Check(b.get(), SSE_READ));
    EXPECT_EQ(-1, b->Recv(buffer, 10, nullptr));

    EXPECT_TRUE(sink.Check(a.get(), SSE_CLOSE));
    EXPECT_EQ(a->GetState(), Socket::CS_CLOSED);
    EXPECT_EQ(a->GetRemoteAddress(), kEmptyAddr);

    // No signal for Closer
    EXPECT_FALSE(sink.Check(b.get(), SSE_CLOSE));
    EXPECT_EQ(b->GetState(), Socket::CS_CLOSED);
    EXPECT_EQ(b->GetRemoteAddress(), kEmptyAddr);
  }

  void TcpSendTest(const SocketAddress& initial_addr) {
    StreamSink sink;
    const SocketAddress kEmptyAddr;

    // Connect two sockets
    std::unique_ptr<Socket> a = ss_.Create(initial_addr.family(), SOCK_STREAM);
    sink.Monitor(a.get());
    a->Bind(initial_addr);
    EXPECT_EQ(a->GetLocalAddress().family(), initial_addr.family());

    std::unique_ptr<Socket> b = ss_.Create(initial_addr.family(), SOCK_STREAM);
    sink.Monitor(b.get());
    b->Bind(initial_addr);
    EXPECT_EQ(b->GetLocalAddress().family(), initial_addr.family());

    EXPECT_EQ(0, a->Connect(b->GetLocalAddress()));
    EXPECT_EQ(0, b->Connect(a->GetLocalAddress()));

    time_controller_.AdvanceTime(TimeDelta::Zero());

    const size_t kBufferSize = 2000;
    ss_.set_send_buffer_capacity(kBufferSize);
    ss_.set_recv_buffer_capacity(kBufferSize);

    const size_t kDataSize = 5000;
    std::vector<char> send_buffer(kDataSize);
    std::vector<char> recv_buffer(kDataSize);
    for (size_t i = 0; i < kDataSize; ++i)
      send_buffer[i] = static_cast<char>(i % 256);
    std::fill(recv_buffer.begin(), recv_buffer.end(), 0);
    size_t send_pos = 0, recv_pos = 0;

    // Can't send more than send buffer in one write
    int result = a->Send(&send_buffer[send_pos], kDataSize - send_pos);
    EXPECT_EQ(static_cast<int>(kBufferSize), result);
    send_pos += result;

    time_controller_.AdvanceTime(TimeDelta::Zero());
    EXPECT_FALSE(sink.Check(a.get(), SSE_WRITE));
    EXPECT_TRUE(sink.Check(b.get(), SSE_READ));

    // Receive buffer is already filled, fill send buffer again
    result = a->Send(&send_buffer[send_pos], kDataSize - send_pos);
    EXPECT_EQ(static_cast<int>(kBufferSize), result);
    send_pos += result;

    time_controller_.AdvanceTime(TimeDelta::Zero());
    EXPECT_FALSE(sink.Check(a.get(), SSE_WRITE));
    EXPECT_FALSE(sink.Check(b.get(), SSE_READ));

    // No more room in send or receive buffer
    result = a->Send(&send_buffer[send_pos], kDataSize - send_pos);
    EXPECT_EQ(-1, result);
    EXPECT_TRUE(a->IsBlocking());

    // Read a subset of the data
    result = b->Recv(&recv_buffer[recv_pos], 500, nullptr);
    EXPECT_EQ(500, result);
    recv_pos += result;

    time_controller_.AdvanceTime(TimeDelta::Zero());
    EXPECT_TRUE(sink.Check(a.get(), SSE_WRITE));
    EXPECT_TRUE(sink.Check(b.get(), SSE_READ));

    // Room for more on the sending side
    result = a->Send(&send_buffer[send_pos], kDataSize - send_pos);
    EXPECT_EQ(500, result);
    send_pos += result;

    // Empty the recv buffer
    while (true) {
      if (recv_pos >= kDataSize)
        break;
      result = b->Recv(&recv_buffer[recv_pos], kDataSize - recv_pos, nullptr);
      if (result < 0) {
        EXPECT_EQ(-1, result);
        EXPECT_TRUE(b->IsBlocking());
        break;
      }
      recv_pos += result;
    }

    time_controller_.AdvanceTime(TimeDelta::Zero());
    EXPECT_TRUE(sink.Check(b.get(), SSE_READ));

    // Continue to empty the recv buffer
    while (true) {
      if (recv_pos >= kDataSize)
        break;
      result = b->Recv(&recv_buffer[recv_pos], kDataSize - recv_pos, nullptr);
      if (result < 0) {
        EXPECT_EQ(-1, result);
        EXPECT_TRUE(b->IsBlocking());
        break;
      }
      recv_pos += result;
    }

    // Send last of the data
    result = a->Send(&send_buffer[send_pos], kDataSize - send_pos);
    EXPECT_EQ(500, result);
    send_pos += result;

    time_controller_.AdvanceTime(TimeDelta::Zero());
    EXPECT_TRUE(sink.Check(b.get(), SSE_READ));

    // Receive the last of the data
    while (true) {
      if (recv_pos >= kDataSize)
        break;
      result = b->Recv(&recv_buffer[recv_pos], kDataSize - recv_pos, nullptr);
      if (result < 0) {
        EXPECT_EQ(-1, result);
        EXPECT_TRUE(b->IsBlocking());
        break;
      }
      recv_pos += result;
    }

    time_controller_.AdvanceTime(TimeDelta::Zero());
    EXPECT_FALSE(sink.Check(b.get(), SSE_READ));

    // The received data matches the sent data
    EXPECT_EQ(kDataSize, send_pos);
    EXPECT_EQ(kDataSize, recv_pos);
    EXPECT_EQ(recv_buffer, send_buffer);
  }

  void TcpSendsPacketsInOrderTest(const SocketAddress& initial_addr) {
    const SocketAddress kEmptyAddr;

    // Connect two sockets
    std::unique_ptr<Socket> a = ss_.Create(initial_addr.family(), SOCK_STREAM);
    std::unique_ptr<Socket> b = ss_.Create(initial_addr.family(), SOCK_STREAM);
    a->Bind(initial_addr);
    EXPECT_EQ(a->GetLocalAddress().family(), initial_addr.family());

    b->Bind(initial_addr);
    EXPECT_EQ(b->GetLocalAddress().family(), initial_addr.family());

    EXPECT_EQ(0, a->Connect(b->GetLocalAddress()));
    EXPECT_EQ(0, b->Connect(a->GetLocalAddress()));
    time_controller_.AdvanceTime(TimeDelta::Zero());

    // First, deliver all packets in 0 ms.
    std::array<char, 2> buffer = {0, 0};
    const char cNumPackets = 10;
    for (char i = 0; i < cNumPackets; ++i) {
      buffer[0] = '0' + i;
      EXPECT_EQ(1, a->Send(buffer.data(), 1));
    }

    time_controller_.AdvanceTime(TimeDelta::Zero());

    for (char i = 0; i < cNumPackets; ++i) {
      EXPECT_EQ(1, b->Recv(buffer.data(), buffer.size(), nullptr));
      EXPECT_EQ(static_cast<char>('0' + i), buffer[0]);
    }

    // Next, deliver packets at random intervals
    const uint32_t mean = 50;
    const uint32_t stddev = 50;

    ss_.set_delay_mean(mean);
    ss_.set_delay_stddev(stddev);
    ss_.UpdateDelayDistribution();

    for (char i = 0; i < cNumPackets; ++i) {
      buffer[0] = 'A' + i;
      EXPECT_EQ(1, a->Send(buffer.data(), 1));
    }

    time_controller_.AdvanceTime(TimeDelta::Seconds(2));

    for (char i = 0; i < cNumPackets; ++i) {
      EXPECT_EQ(1, b->Recv(buffer.data(), buffer.size(), nullptr));
      EXPECT_EQ(static_cast<char>('A' + i), buffer[0]);
    }
  }

  // It is important that initial_addr's port has to be 0 such that the
  // incremental port behavior could ensure the 2 Binds result in different
  // address.
  void BandwidthTest(const SocketAddress& initial_addr) {
    std::unique_ptr<Socket> send_socket =
        ss_.Create(initial_addr.family(), SOCK_DGRAM);
    std::unique_ptr<Socket> recv_socket =
        ss_.Create(initial_addr.family(), SOCK_DGRAM);
    ASSERT_EQ(0, send_socket->Bind(initial_addr));
    ASSERT_EQ(0, recv_socket->Bind(initial_addr));
    EXPECT_EQ(send_socket->GetLocalAddress().family(), initial_addr.family());
    EXPECT_EQ(recv_socket->GetLocalAddress().family(), initial_addr.family());
    ASSERT_EQ(0, send_socket->Connect(recv_socket->GetLocalAddress()));

    uint32_t bandwidth = 64 * 1024;
    ss_.set_bandwidth(bandwidth);

    Thread* pthMain = time_controller_.GetMainThread();
    Sender sender(env_, pthMain, std::move(send_socket), 80 * 1024);
    Receiver receiver(env_, pthMain, std::move(recv_socket), bandwidth);

    // Allow the sender to run for 5 (simulated) seconds, then be stopped for 5
    // seconds.
    time_controller_.AdvanceTime(TimeDelta::Millis(5000));
    sender.periodic.Stop();
    time_controller_.AdvanceTime(TimeDelta::Millis(5000));

    // Ensure the observed bandwidth fell within a reasonable margin of error.
    EXPECT_TRUE(receiver.count >= 5 * 3 * bandwidth / 4);
    EXPECT_TRUE(receiver.count <= 6 * bandwidth);  // queue could drain for 1s

    ss_.set_bandwidth(0);
  }

  // It is important that initial_addr's port has to be 0 such that the
  // incremental port behavior could ensure the 2 Binds result in different
  // address.
  void DelayTest(const SocketAddress& initial_addr) {
    time_t seed = ::time(nullptr);
    RTC_LOG(LS_VERBOSE) << "seed = " << seed;
    srand(static_cast<unsigned int>(seed));

    const uint32_t mean = 2000;
    const uint32_t stddev = 500;

    ss_.set_delay_mean(mean);
    ss_.set_delay_stddev(stddev);
    ss_.UpdateDelayDistribution();

    std::unique_ptr<Socket> send_socket =
        ss_.Create(initial_addr.family(), SOCK_DGRAM);
    std::unique_ptr<Socket> recv_socket =
        ss_.Create(initial_addr.family(), SOCK_DGRAM);
    ASSERT_EQ(0, send_socket->Bind(initial_addr));
    ASSERT_EQ(0, recv_socket->Bind(initial_addr));
    EXPECT_EQ(send_socket->GetLocalAddress().family(), initial_addr.family());
    EXPECT_EQ(recv_socket->GetLocalAddress().family(), initial_addr.family());
    ASSERT_EQ(0, send_socket->Connect(recv_socket->GetLocalAddress()));

    Thread* pthMain = time_controller_.GetMainThread();
    // Avg packet size is 2K, so at 200KB/s for 10s, we should see about
    // 1000 packets, which is necessary to get a good distribution.
    Sender sender(env_, pthMain, std::move(send_socket), 100 * 2 * 1024);
    Receiver receiver(env_, pthMain, std::move(recv_socket), 0);

    // Simulate 10 seconds of packets being sent, then check the observed delay
    // distribution.
    time_controller_.AdvanceTime(TimeDelta::Millis(10000));
    sender.periodic.Stop();
    receiver.periodic.Stop();
    time_controller_.AdvanceTime(TimeDelta::Zero());

    const double sample_mean = receiver.sum / receiver.samples;
    double num =
        receiver.samples * receiver.sum_sq - receiver.sum * receiver.sum;
    double den = receiver.samples * (receiver.samples - 1);
    const double sample_stddev = sqrt(num / den);
    RTC_LOG(LS_VERBOSE) << "mean=" << sample_mean
                        << " stddev=" << sample_stddev;

    EXPECT_LE(500u, receiver.samples);
    // We initially used a 0.1 fudge factor, but on the build machine, we
    // have seen the value differ by as much as 0.13.
    EXPECT_NEAR(mean, sample_mean, 0.15 * mean);
    EXPECT_NEAR(stddev, sample_stddev, 0.15 * stddev);

    ss_.set_delay_mean(0);
    ss_.set_delay_stddev(0);
    ss_.UpdateDelayDistribution();
  }

  // Test cross-family communication between a client bound to client_addr and a
  // server bound to server_addr. shouldSucceed indicates if communication is
  // expected to work or not.
  void CrossFamilyConnectionTest(const SocketAddress& client_addr,
                                 const SocketAddress& server_addr,
                                 bool shouldSucceed) {
    StreamSink sink;
    SocketAddress accept_address;
    const SocketAddress kEmptyAddr;

    // Client gets a IPv4 address
    std::unique_ptr<Socket> client =
        ss_.Create(client_addr.family(), SOCK_STREAM);
    sink.Monitor(client.get());
    EXPECT_EQ(client->GetState(), Socket::CS_CLOSED);
    EXPECT_EQ(client->GetLocalAddress(), kEmptyAddr);
    client->Bind(client_addr);

    // Server gets a non-mapped non-any IPv6 address.
    // IPv4 sockets should not be able to connect to this.
    std::unique_ptr<Socket> server =
        ss_.Create(server_addr.family(), SOCK_STREAM);
    sink.Monitor(server.get());
    server->Bind(server_addr);
    server->Listen(5);

    if (shouldSucceed) {
      EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
      time_controller_.AdvanceTime(TimeDelta::Zero());
      EXPECT_TRUE(sink.Check(server.get(), SSE_READ));
      std::unique_ptr<Socket> accepted =
          absl::WrapUnique(server->Accept(&accept_address));
      EXPECT_TRUE(nullptr != accepted);
      EXPECT_NE(kEmptyAddr, accept_address);
      time_controller_.AdvanceTime(TimeDelta::Zero());
      EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
      EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
    } else {
      // Check that the connection failed.
      EXPECT_EQ(-1, client->Connect(server->GetLocalAddress()));
      time_controller_.AdvanceTime(TimeDelta::Zero());

      EXPECT_FALSE(sink.Check(server.get(), SSE_READ));
      EXPECT_TRUE(nullptr == server->Accept(&accept_address));
      EXPECT_EQ(accept_address, kEmptyAddr);
      EXPECT_EQ(client->GetState(), Socket::CS_CLOSED);
      EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
      EXPECT_EQ(client->GetRemoteAddress(), kEmptyAddr);
    }
  }

  // Test cross-family datagram sending between a client bound to client_addr
  // and a server bound to server_addr. shouldSucceed indicates if sending is
  // expected to succeed or not.
  void CrossFamilyDatagramTest(const SocketAddress& client_addr,
                               const SocketAddress& server_addr,
                               bool shouldSucceed) {
    std::unique_ptr<Socket> socket = ss_.Create(AF_INET, SOCK_DGRAM);
    socket->Bind(server_addr);
    SocketAddress bound_server_addr = socket->GetLocalAddress();
    TestClient client1(
        std::make_unique<AsyncUDPSocket>(env_, std::move(socket)),
        &time_controller_);

    std::unique_ptr<Socket> socket2 = ss_.Create(AF_INET, SOCK_DGRAM);
    socket2->Bind(client_addr);
    TestClient client2(
        std::make_unique<AsyncUDPSocket>(env_, std::move(socket2)),
        &time_controller_);
    SocketAddress client2_addr;

    if (shouldSucceed) {
      EXPECT_EQ(3, client2.SendTo("foo", 3, bound_server_addr));
      EXPECT_TRUE(client1.CheckNextPacket("foo", 3, &client2_addr));
      SocketAddress client1_addr;
      EXPECT_EQ(6, client1.SendTo("bizbaz", 6, client2_addr));
      EXPECT_TRUE(client2.CheckNextPacket("bizbaz", 6, &client1_addr));
      EXPECT_EQ(client1_addr, bound_server_addr);
    } else {
      EXPECT_EQ(-1, client2.SendTo("foo", 3, bound_server_addr));
      EXPECT_TRUE(client1.CheckNoPacket());
    }
  }

  void SendReceiveEcn(const SocketAddress& initial_addr) {
    std::unique_ptr<Socket> socket =
        ss_.Create(initial_addr.family(), SOCK_DGRAM);
    socket->Bind(initial_addr);
    SocketAddress server_addr = socket->GetLocalAddress();

    TestClient client1(
        std::make_unique<AsyncUDPSocket>(env_, std::move(socket)),
        &time_controller_);

    SocketAddress client2_addr;
    std::unique_ptr<Socket> socket2 =
        ss_.Create(initial_addr.family(), SOCK_DGRAM);
    TestClient client2(
        std::make_unique<AsyncUDPSocket>(env_, std::move(socket2)),
        &time_controller_);

    client2.SendTo("foo", 3, server_addr);
    std::unique_ptr<TestClient::Packet> packet_1 = client1.NextPacket();
    ASSERT_THAT(packet_1.get(), NotNull());
    EXPECT_EQ(packet_1->ecn, EcnMarking::kNotEct);

    client2.SetOption(Socket::OPT_SEND_ECN, 1);
    client2.SendTo("bar", 3, server_addr);
    std::unique_ptr<TestClient::Packet> packet_2 = client1.NextPacket();
    ASSERT_THAT(packet_2.get(), NotNull());
    EXPECT_EQ(packet_2->ecn, EcnMarking::kNotEct);

    client1.SetOption(Socket::OPT_RECV_ECN, 1);
    client2.SendTo("bar", 3, server_addr);
    std::unique_ptr<TestClient::Packet> packet_3 = client1.NextPacket();
    ASSERT_THAT(packet_3.get(), NotNull());
    EXPECT_EQ(packet_3->ecn, EcnMarking::kEct1);
  }

 protected:
  VirtualSocketServer ss_;
  GlobalSimulatedTimeController time_controller_;
  const Environment env_;
  const SocketAddress kIPv4AnyAddress;
  const SocketAddress kIPv6AnyAddress;
};

TEST_F(VirtualSocketServerTest, basic_v4) {
  SocketAddress ipv4_test_addr(IPAddress(INADDR_ANY), 5000);
  BasicTest(ipv4_test_addr);
}

TEST_F(VirtualSocketServerTest, basic_v6) {
  SocketAddress ipv6_test_addr(IPAddress(in6addr_any), 5000);
  BasicTest(ipv6_test_addr);
}

TEST_F(VirtualSocketServerTest, TestDefaultRoute_v4) {
  IPAddress ipv4_default_addr(0x01020304);
  TestDefaultSourceAddress(ipv4_default_addr);
}

TEST_F(VirtualSocketServerTest, TestDefaultRoute_v6) {
  IPAddress ipv6_default_addr;
  EXPECT_TRUE(
      IPFromString("2401:fa00:4:1000:be30:5bff:fee5:c3", &ipv6_default_addr));
  TestDefaultSourceAddress(ipv6_default_addr);
}

TEST_F(VirtualSocketServerTest, connect_v4) {
  ConnectTest(kIPv4AnyAddress);
}

TEST_F(VirtualSocketServerTest, connect_v6) {
  ConnectTest(kIPv6AnyAddress);
}

TEST_F(VirtualSocketServerTest, connect_to_non_listener_v4) {
  ConnectToNonListenerTest(kIPv4AnyAddress);
}

TEST_F(VirtualSocketServerTest, connect_to_non_listener_v6) {
  ConnectToNonListenerTest(kIPv6AnyAddress);
}

TEST_F(VirtualSocketServerTest, close_during_connect_v4) {
  CloseDuringConnectTest(kIPv4AnyAddress);
}

TEST_F(VirtualSocketServerTest, close_during_connect_v6) {
  CloseDuringConnectTest(kIPv6AnyAddress);
}

TEST_F(VirtualSocketServerTest, close_v4) {
  CloseTest(kIPv4AnyAddress);
}

TEST_F(VirtualSocketServerTest, close_v6) {
  CloseTest(kIPv6AnyAddress);
}

TEST_F(VirtualSocketServerTest, SendReceiveEcn) {
  SendReceiveEcn(kIPv4AnyAddress);
}

TEST_F(VirtualSocketServerTest, tcp_send_v4) {
  TcpSendTest(kIPv4AnyAddress);
}

TEST_F(VirtualSocketServerTest, tcp_send_v6) {
  TcpSendTest(kIPv6AnyAddress);
}

TEST_F(VirtualSocketServerTest, TcpSendsPacketsInOrder_v4) {
  TcpSendsPacketsInOrderTest(kIPv4AnyAddress);
}

TEST_F(VirtualSocketServerTest, TcpSendsPacketsInOrder_v6) {
  TcpSendsPacketsInOrderTest(kIPv6AnyAddress);
}

TEST_F(VirtualSocketServerTest, bandwidth_v4) {
  BandwidthTest(kIPv4AnyAddress);
}

TEST_F(VirtualSocketServerTest, bandwidth_v6) {
  BandwidthTest(kIPv6AnyAddress);
}

TEST_F(VirtualSocketServerTest, delay_v4) {
  DelayTest(kIPv4AnyAddress);
}

TEST_F(VirtualSocketServerTest, delay_v6) {
  DelayTest(kIPv6AnyAddress);
}

// Works, receiving socket sees 127.0.0.2.
TEST_F(VirtualSocketServerTest, CanConnectFromMappedIPv6ToIPv4Any) {
  CrossFamilyConnectionTest(SocketAddress("::ffff:127.0.0.2", 0),
                            SocketAddress("0.0.0.0", 5000), true);
}

// Fails.
TEST_F(VirtualSocketServerTest, CantConnectFromUnMappedIPv6ToIPv4Any) {
  CrossFamilyConnectionTest(SocketAddress("::2", 0),
                            SocketAddress("0.0.0.0", 5000), false);
}

// Fails.
TEST_F(VirtualSocketServerTest, CantConnectFromUnMappedIPv6ToMappedIPv6) {
  CrossFamilyConnectionTest(SocketAddress("::2", 0),
                            SocketAddress("::ffff:127.0.0.1", 5000), false);
}

// Works. receiving socket sees ::ffff:127.0.0.2.
TEST_F(VirtualSocketServerTest, CanConnectFromIPv4ToIPv6Any) {
  CrossFamilyConnectionTest(SocketAddress("127.0.0.2", 0),
                            SocketAddress("::", 5000), true);
}

// Fails.
TEST_F(VirtualSocketServerTest, CantConnectFromIPv4ToUnMappedIPv6) {
  CrossFamilyConnectionTest(SocketAddress("127.0.0.2", 0),
                            SocketAddress("::1", 5000), false);
}

// Works. Receiving socket sees ::ffff:127.0.0.1.
TEST_F(VirtualSocketServerTest, CanConnectFromIPv4ToMappedIPv6) {
  CrossFamilyConnectionTest(SocketAddress("127.0.0.1", 0),
                            SocketAddress("::ffff:127.0.0.2", 5000), true);
}

// Works, receiving socket sees a result from GetNextIP.
TEST_F(VirtualSocketServerTest, CanConnectFromUnboundIPv6ToIPv4Any) {
  CrossFamilyConnectionTest(SocketAddress("::", 0),
                            SocketAddress("0.0.0.0", 5000), true);
}

// Works, receiving socket sees whatever GetNextIP gave the client.
TEST_F(VirtualSocketServerTest, CanConnectFromUnboundIPv4ToIPv6Any) {
  CrossFamilyConnectionTest(SocketAddress("0.0.0.0", 0),
                            SocketAddress("::", 5000), true);
}

TEST_F(VirtualSocketServerTest, CanSendDatagramFromUnboundIPv4ToIPv6Any) {
  CrossFamilyDatagramTest(SocketAddress("0.0.0.0", 0),
                          SocketAddress("::", 5000), true);
}

TEST_F(VirtualSocketServerTest, CanSendDatagramFromMappedIPv6ToIPv4Any) {
  CrossFamilyDatagramTest(SocketAddress("::ffff:127.0.0.1", 0),
                          SocketAddress("0.0.0.0", 5000), true);
}

TEST_F(VirtualSocketServerTest, CantSendDatagramFromUnMappedIPv6ToIPv4Any) {
  CrossFamilyDatagramTest(SocketAddress("::2", 0),
                          SocketAddress("0.0.0.0", 5000), false);
}

TEST_F(VirtualSocketServerTest, CantSendDatagramFromUnMappedIPv6ToMappedIPv6) {
  CrossFamilyDatagramTest(SocketAddress("::2", 0),
                          SocketAddress("::ffff:127.0.0.1", 5000), false);
}

TEST_F(VirtualSocketServerTest, CanSendDatagramFromIPv4ToIPv6Any) {
  CrossFamilyDatagramTest(SocketAddress("127.0.0.2", 0),
                          SocketAddress("::", 5000), true);
}

TEST_F(VirtualSocketServerTest, CantSendDatagramFromIPv4ToUnMappedIPv6) {
  CrossFamilyDatagramTest(SocketAddress("127.0.0.2", 0),
                          SocketAddress("::1", 5000), false);
}

TEST_F(VirtualSocketServerTest, CanSendDatagramFromIPv4ToMappedIPv6) {
  CrossFamilyDatagramTest(SocketAddress("127.0.0.1", 0),
                          SocketAddress("::ffff:127.0.0.2", 5000), true);
}

TEST_F(VirtualSocketServerTest, CanSendDatagramFromUnboundIPv6ToIPv4Any) {
  CrossFamilyDatagramTest(SocketAddress("::", 0),
                          SocketAddress("0.0.0.0", 5000), true);
}

TEST_F(VirtualSocketServerTest, SetSendingBlockedWithUdpSocket) {
  std::unique_ptr<Socket> socket1 =
      ss_.Create(kIPv4AnyAddress.family(), SOCK_DGRAM);
  Socket& socket1_ref = *socket1;
  std::unique_ptr<Socket> socket2 =
      ss_.Create(kIPv4AnyAddress.family(), SOCK_DGRAM);
  socket1->Bind(kIPv4AnyAddress);
  socket2->Bind(kIPv4AnyAddress);
  TestClient client1(std::make_unique<AsyncUDPSocket>(env_, std::move(socket1)),
                     &time_controller_);

  ss_.SetSendingBlocked(true);
  EXPECT_EQ(-1, client1.SendTo("foo", 3, socket2->GetLocalAddress()));
  EXPECT_TRUE(socket1_ref.IsBlocking());
  EXPECT_EQ(0, client1.ready_to_send_count());

  ss_.SetSendingBlocked(false);
  EXPECT_EQ(1, client1.ready_to_send_count());
  EXPECT_EQ(3, client1.SendTo("foo", 3, socket2->GetLocalAddress()));
}

TEST_F(VirtualSocketServerTest, SetSendingBlockedWithTcpSocket) {
  constexpr size_t kBufferSize = 1024;
  ss_.set_send_buffer_capacity(kBufferSize);
  ss_.set_recv_buffer_capacity(kBufferSize);

  StreamSink sink;
  std::unique_ptr<Socket> socket1 =
      ss_.Create(kIPv4AnyAddress.family(), SOCK_STREAM);
  std::unique_ptr<Socket> socket2 =
      ss_.Create(kIPv4AnyAddress.family(), SOCK_STREAM);
  sink.Monitor(socket1.get());
  sink.Monitor(socket2.get());
  socket1->Bind(kIPv4AnyAddress);
  socket2->Bind(kIPv4AnyAddress);

  // Connect sockets.
  EXPECT_EQ(0, socket1->Connect(socket2->GetLocalAddress()));
  EXPECT_EQ(0, socket2->Connect(socket1->GetLocalAddress()));
  time_controller_.AdvanceTime(TimeDelta::Zero());

  std::vector<char> data(kBufferSize);

  // First Send call will fill the send buffer but not send anything.
  ss_.SetSendingBlocked(true);
  EXPECT_EQ(static_cast<int>(kBufferSize),
            socket1->Send(data.data(), kBufferSize));
  time_controller_.AdvanceTime(TimeDelta::Zero());
  EXPECT_FALSE(sink.Check(socket1.get(), SSE_WRITE));
  EXPECT_FALSE(sink.Check(socket2.get(), SSE_READ));
  EXPECT_FALSE(socket1->IsBlocking());

  // Since the send buffer is full, next Send will result in EWOULDBLOCK.
  EXPECT_EQ(-1, socket1->Send(data.data(), kBufferSize));
  EXPECT_FALSE(sink.Check(socket1.get(), SSE_WRITE));
  EXPECT_FALSE(sink.Check(socket2.get(), SSE_READ));
  EXPECT_TRUE(socket1->IsBlocking());

  // When sending is unblocked, the buffered data should be sent and
  // SignalWriteEvent should fire.
  ss_.SetSendingBlocked(false);
  time_controller_.AdvanceTime(TimeDelta::Zero());
  EXPECT_TRUE(sink.Check(socket1.get(), SSE_WRITE));
  EXPECT_TRUE(sink.Check(socket2.get(), SSE_READ));
}

TEST_F(VirtualSocketServerTest, CreatesStandardDistribution) {
  const uint32_t kTestMean[] = {10, 100, 333, 1000};
  const double kTestDev[] = {0.25, 0.1, 0.01};
  // TODO(deadbeef): The current code only works for 1000 data points or more.
  const uint32_t kTestSamples[] = {/*10, 100,*/ 1000};
  for (uint32_t test_mean : kTestMean) {
    for (double test_dev : kTestDev) {
      for (uint32_t test_sample : kTestSamples) {
        ASSERT_LT(0u, test_sample);
        const uint32_t kStdDev = static_cast<uint32_t>(test_dev * test_mean);
        std::unique_ptr<VirtualSocketServer::Function> f =
            VirtualSocketServer::CreateDistribution(test_mean, kStdDev,
                                                    test_sample);
        ASSERT_TRUE(nullptr != f.get());
        ASSERT_EQ(test_sample, f->size());
        double sum = 0;
        for (uint32_t i = 0; i < f->size(); ++i) {
          sum += (*f)[i].second;
        }
        const double mean = sum / f->size();
        double sum_sq_dev = 0;
        for (uint32_t i = 0; i < f->size(); ++i) {
          double dev = (*f)[i].second - mean;
          sum_sq_dev += dev * dev;
        }
        const double stddev = sqrt(sum_sq_dev / f->size());
        EXPECT_NEAR(test_mean, mean, 0.1 * test_mean)
            << "M=" << test_mean << " SD=" << kStdDev << " N=" << test_sample;
        EXPECT_NEAR(kStdDev, stddev, 0.1 * kStdDev)
            << "M=" << test_mean << " SD=" << kStdDev << " N=" << test_sample;
      }
    }
  }
}

}  // namespace
}  // namespace webrtc
