blob: 24a4f4fc49fc2dc6deb6833a8ecfae78041dc263 [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright (c) 2018 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/third_party/quiche/src/quic/quartc/simulated_packet_transport.h"
6
QUICHE teama6ef0a62019-03-07 20:34:33 -05007#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
8#include "net/third_party/quiche/src/quic/quartc/quartc_packet_writer.h"
9#include "net/third_party/quiche/src/quic/test_tools/simulator/simulator.h"
10#include "net/third_party/quiche/src/quic/test_tools/simulator/switch.h"
11
12namespace quic {
13namespace simulator {
14namespace {
15
16using ::testing::ElementsAre;
17
18const QuicBandwidth kDefaultBandwidth =
19 QuicBandwidth::FromKBitsPerSecond(10 * 1000);
20const QuicTime::Delta kDefaultPropagationDelay =
21 QuicTime::Delta::FromMilliseconds(20);
22const QuicByteCount kDefaultBdp = kDefaultBandwidth * kDefaultPropagationDelay;
23const QuicByteCount kDefaultPacketSize = 1200;
24const QuicPacketCount kDefaultQueueLength = 10;
25
26class FakeDelegate : public QuartcPacketTransport::Delegate {
27 public:
28 explicit FakeDelegate(QuartcPacketTransport* transport)
29 : transport_(transport) {
30 transport_->SetDelegate(this);
31 }
32
33 ~FakeDelegate() { transport_->SetDelegate(nullptr); }
34
35 void OnTransportCanWrite() override {
36 while (!packets_to_send_.empty()) {
vasilvvc48c8712019-03-11 13:38:16 -070037 const std::string& packet = packets_to_send_.front();
QUICHE teama6ef0a62019-03-07 20:34:33 -050038 if (transport_->Write(packet.data(), packet.size(),
39 QuartcPacketTransport::PacketInfo()) <
40 static_cast<int>(packet.size())) {
41 ++write_blocked_count_;
42 return;
43 }
44 packets_to_send_.pop();
45 }
46 }
47
48 void OnTransportReceived(const char* data, size_t data_len) override {
49 packets_received_.emplace_back(data, data_len);
50 }
51
vasilvvc48c8712019-03-11 13:38:16 -070052 void AddPacketToSend(const std::string& packet) {
QUICHE teama6ef0a62019-03-07 20:34:33 -050053 packets_to_send_.push(packet);
54 }
55
56 size_t packets_to_send() { return packets_to_send_.size(); }
vasilvvc48c8712019-03-11 13:38:16 -070057 const std::vector<std::string>& packets_received() {
QUICHE teama6ef0a62019-03-07 20:34:33 -050058 return packets_received_;
59 }
60 int write_blocked_count() { return write_blocked_count_; }
61
62 private:
63 QuartcPacketTransport* const transport_ = nullptr;
vasilvvc48c8712019-03-11 13:38:16 -070064 std::queue<std::string> packets_to_send_;
65 std::vector<std::string> packets_received_;
QUICHE teama6ef0a62019-03-07 20:34:33 -050066 int write_blocked_count_ = 0;
67};
68
69class SimulatedPacketTransportTest : public QuicTest {
70 protected:
71 SimulatedPacketTransportTest()
72 : switch_(&simulator_, "Switch", /*port_count=*/8, 2 * kDefaultBdp),
73 client_(&simulator_,
74 "sender",
75 "receiver",
76 kDefaultQueueLength * kDefaultPacketSize),
77 server_(&simulator_,
78 "receiver",
79 "sender",
80 kDefaultQueueLength * kDefaultPacketSize),
81 client_link_(&client_,
82 switch_.port(1),
83 kDefaultBandwidth,
84 kDefaultPropagationDelay),
85 server_link_(&server_,
86 switch_.port(2),
87 kDefaultBandwidth,
88 kDefaultPropagationDelay),
89 client_delegate_(&client_),
90 server_delegate_(&server_) {}
91
92 Simulator simulator_;
93 Switch switch_;
94
95 SimulatedQuartcPacketTransport client_;
96 SimulatedQuartcPacketTransport server_;
97
98 SymmetricLink client_link_;
99 SymmetricLink server_link_;
100
101 FakeDelegate client_delegate_;
102 FakeDelegate server_delegate_;
103};
104
105TEST_F(SimulatedPacketTransportTest, OneWayTransmission) {
vasilvvc48c8712019-03-11 13:38:16 -0700106 std::string packet_1(kDefaultPacketSize, 'a');
107 std::string packet_2(kDefaultPacketSize, 'b');
QUICHE teama6ef0a62019-03-07 20:34:33 -0500108 client_delegate_.AddPacketToSend(packet_1);
109 client_delegate_.AddPacketToSend(packet_2);
110
111 simulator_.RunUntil(
112 [this] { return client_delegate_.packets_to_send() == 0; });
113 simulator_.RunFor(3 * kDefaultPropagationDelay);
114
115 EXPECT_THAT(server_delegate_.packets_received(),
116 ElementsAre(packet_1, packet_2));
117 EXPECT_THAT(client_delegate_.packets_received(), ElementsAre());
118}
119
120TEST_F(SimulatedPacketTransportTest, TwoWayTransmission) {
vasilvvc48c8712019-03-11 13:38:16 -0700121 std::string packet_1(kDefaultPacketSize, 'a');
122 std::string packet_2(kDefaultPacketSize, 'b');
123 std::string packet_3(kDefaultPacketSize, 'c');
124 std::string packet_4(kDefaultPacketSize, 'd');
QUICHE teama6ef0a62019-03-07 20:34:33 -0500125
126 client_delegate_.AddPacketToSend(packet_1);
127 client_delegate_.AddPacketToSend(packet_2);
128 server_delegate_.AddPacketToSend(packet_3);
129 server_delegate_.AddPacketToSend(packet_4);
130
131 simulator_.RunUntil(
132 [this] { return client_delegate_.packets_to_send() == 0; });
133 simulator_.RunUntil(
134 [this] { return server_delegate_.packets_to_send() == 0; });
135 simulator_.RunFor(3 * kDefaultPropagationDelay);
136
137 EXPECT_THAT(server_delegate_.packets_received(),
138 ElementsAre(packet_1, packet_2));
139 EXPECT_THAT(client_delegate_.packets_received(),
140 ElementsAre(packet_3, packet_4));
141}
142
143TEST_F(SimulatedPacketTransportTest, TestWriteBlocked) {
144 // Add 10 packets beyond what fits in the egress queue.
vasilvvc48c8712019-03-11 13:38:16 -0700145 std::vector<std::string> packets;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500146 for (unsigned int i = 0; i < kDefaultQueueLength + 10; ++i) {
vasilvvc48c8712019-03-11 13:38:16 -0700147 packets.push_back(std::string(kDefaultPacketSize, 'a' + i));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500148 client_delegate_.AddPacketToSend(packets.back());
149 }
150
151 simulator_.RunUntil(
152 [this] { return client_delegate_.packets_to_send() == 0; });
153 simulator_.RunFor(3 * kDefaultPropagationDelay);
154
155 // Each of the 10 packets in excess of the sender's egress queue length will
156 // block the first time |client_delegate_| tries to write them.
157 EXPECT_EQ(client_delegate_.write_blocked_count(), 10);
158 EXPECT_EQ(server_delegate_.packets_received(), packets);
159}
160
161} // namespace
162} // namespace simulator
163} // namespace quic