Project import generated by Copybara.

PiperOrigin-RevId: 237361882
Change-Id: I109a68f44db867b20f8c6a7732b0ce657133e52a
diff --git a/quic/quartc/simulated_packet_transport_test.cc b/quic/quartc/simulated_packet_transport_test.cc
new file mode 100644
index 0000000..3fbd18b
--- /dev/null
+++ b/quic/quartc/simulated_packet_transport_test.cc
@@ -0,0 +1,165 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quiche/src/quic/quartc/simulated_packet_transport.h"
+
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
+#include "net/third_party/quiche/src/quic/quartc/quartc_packet_writer.h"
+#include "net/third_party/quiche/src/quic/test_tools/simulator/simulator.h"
+#include "net/third_party/quiche/src/quic/test_tools/simulator/switch.h"
+
+namespace quic {
+namespace simulator {
+namespace {
+
+using ::testing::ElementsAre;
+
+const QuicBandwidth kDefaultBandwidth =
+    QuicBandwidth::FromKBitsPerSecond(10 * 1000);
+const QuicTime::Delta kDefaultPropagationDelay =
+    QuicTime::Delta::FromMilliseconds(20);
+const QuicByteCount kDefaultBdp = kDefaultBandwidth * kDefaultPropagationDelay;
+const QuicByteCount kDefaultPacketSize = 1200;
+const QuicPacketCount kDefaultQueueLength = 10;
+
+class FakeDelegate : public QuartcPacketTransport::Delegate {
+ public:
+  explicit FakeDelegate(QuartcPacketTransport* transport)
+      : transport_(transport) {
+    transport_->SetDelegate(this);
+  }
+
+  ~FakeDelegate() { transport_->SetDelegate(nullptr); }
+
+  void OnTransportCanWrite() override {
+    while (!packets_to_send_.empty()) {
+      const QuicString& packet = packets_to_send_.front();
+      if (transport_->Write(packet.data(), packet.size(),
+                            QuartcPacketTransport::PacketInfo()) <
+          static_cast<int>(packet.size())) {
+        ++write_blocked_count_;
+        return;
+      }
+      packets_to_send_.pop();
+    }
+  }
+
+  void OnTransportReceived(const char* data, size_t data_len) override {
+    packets_received_.emplace_back(data, data_len);
+  }
+
+  void AddPacketToSend(const QuicString& packet) {
+    packets_to_send_.push(packet);
+  }
+
+  size_t packets_to_send() { return packets_to_send_.size(); }
+  const std::vector<QuicString>& packets_received() {
+    return packets_received_;
+  }
+  int write_blocked_count() { return write_blocked_count_; }
+
+ private:
+  QuartcPacketTransport* const transport_ = nullptr;
+  std::queue<QuicString> packets_to_send_;
+  std::vector<QuicString> packets_received_;
+  int write_blocked_count_ = 0;
+};
+
+class SimulatedPacketTransportTest : public QuicTest {
+ protected:
+  SimulatedPacketTransportTest()
+      : switch_(&simulator_, "Switch", /*port_count=*/8, 2 * kDefaultBdp),
+        client_(&simulator_,
+                "sender",
+                "receiver",
+                kDefaultQueueLength * kDefaultPacketSize),
+        server_(&simulator_,
+                "receiver",
+                "sender",
+                kDefaultQueueLength * kDefaultPacketSize),
+        client_link_(&client_,
+                     switch_.port(1),
+                     kDefaultBandwidth,
+                     kDefaultPropagationDelay),
+        server_link_(&server_,
+                     switch_.port(2),
+                     kDefaultBandwidth,
+                     kDefaultPropagationDelay),
+        client_delegate_(&client_),
+        server_delegate_(&server_) {}
+
+  Simulator simulator_;
+  Switch switch_;
+
+  SimulatedQuartcPacketTransport client_;
+  SimulatedQuartcPacketTransport server_;
+
+  SymmetricLink client_link_;
+  SymmetricLink server_link_;
+
+  FakeDelegate client_delegate_;
+  FakeDelegate server_delegate_;
+};
+
+TEST_F(SimulatedPacketTransportTest, OneWayTransmission) {
+  QuicString packet_1(kDefaultPacketSize, 'a');
+  QuicString packet_2(kDefaultPacketSize, 'b');
+  client_delegate_.AddPacketToSend(packet_1);
+  client_delegate_.AddPacketToSend(packet_2);
+
+  simulator_.RunUntil(
+      [this] { return client_delegate_.packets_to_send() == 0; });
+  simulator_.RunFor(3 * kDefaultPropagationDelay);
+
+  EXPECT_THAT(server_delegate_.packets_received(),
+              ElementsAre(packet_1, packet_2));
+  EXPECT_THAT(client_delegate_.packets_received(), ElementsAre());
+}
+
+TEST_F(SimulatedPacketTransportTest, TwoWayTransmission) {
+  QuicString packet_1(kDefaultPacketSize, 'a');
+  QuicString packet_2(kDefaultPacketSize, 'b');
+  QuicString packet_3(kDefaultPacketSize, 'c');
+  QuicString packet_4(kDefaultPacketSize, 'd');
+
+  client_delegate_.AddPacketToSend(packet_1);
+  client_delegate_.AddPacketToSend(packet_2);
+  server_delegate_.AddPacketToSend(packet_3);
+  server_delegate_.AddPacketToSend(packet_4);
+
+  simulator_.RunUntil(
+      [this] { return client_delegate_.packets_to_send() == 0; });
+  simulator_.RunUntil(
+      [this] { return server_delegate_.packets_to_send() == 0; });
+  simulator_.RunFor(3 * kDefaultPropagationDelay);
+
+  EXPECT_THAT(server_delegate_.packets_received(),
+              ElementsAre(packet_1, packet_2));
+  EXPECT_THAT(client_delegate_.packets_received(),
+              ElementsAre(packet_3, packet_4));
+}
+
+TEST_F(SimulatedPacketTransportTest, TestWriteBlocked) {
+  // Add 10 packets beyond what fits in the egress queue.
+  std::vector<QuicString> packets;
+  for (unsigned int i = 0; i < kDefaultQueueLength + 10; ++i) {
+    packets.push_back(QuicString(kDefaultPacketSize, 'a' + i));
+    client_delegate_.AddPacketToSend(packets.back());
+  }
+
+  simulator_.RunUntil(
+      [this] { return client_delegate_.packets_to_send() == 0; });
+  simulator_.RunFor(3 * kDefaultPropagationDelay);
+
+  // Each of the 10 packets in excess of the sender's egress queue length will
+  // block the first time |client_delegate_| tries to write them.
+  EXPECT_EQ(client_delegate_.write_blocked_count(), 10);
+  EXPECT_EQ(server_delegate_.packets_received(), packets);
+}
+
+}  // namespace
+}  // namespace simulator
+}  // namespace quic