blob: 5e771336d9c1ed6acee8424d48a11234f40d1ae8 [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/core/quic_trace_visitor.h"
6
QUICHE teama6ef0a62019-03-07 20:34:33 -05007#include "net/third_party/quiche/src/quic/core/quic_constants.h"
8#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
9#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
10#include "net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint.h"
11#include "net/third_party/quiche/src/quic/test_tools/simulator/simulator.h"
12#include "net/third_party/quiche/src/quic/test_tools/simulator/switch.h"
13
14namespace quic {
15namespace {
16
dschinazi66dea072019-04-09 11:41:06 -070017const QuicByteCount kTransferSize = 1000 * kMaxOutgoingPacketSize;
QUICHE teama6ef0a62019-03-07 20:34:33 -050018const QuicByteCount kTestStreamNumber = 3;
19const QuicTime::Delta kDelay = QuicTime::Delta::FromMilliseconds(20);
20
21// The trace for this test is generated using a simulator transfer.
22class QuicTraceVisitorTest : public QuicTest {
23 public:
24 QuicTraceVisitorTest() {
25 QuicConnectionId connection_id = test::TestConnectionId();
26 simulator::Simulator simulator;
27 simulator::QuicEndpoint client(&simulator, "Client", "Server",
28 Perspective::IS_CLIENT, connection_id);
29 simulator::QuicEndpoint server(&simulator, "Server", "Client",
30 Perspective::IS_SERVER, connection_id);
31
32 const QuicBandwidth kBandwidth = QuicBandwidth::FromKBitsPerSecond(1000);
33 const QuicByteCount kBdp = kBandwidth * (2 * kDelay);
34
35 // Create parameters such that some loss is observed.
36 simulator::Switch network_switch(&simulator, "Switch", 8, 0.5 * kBdp);
37 simulator::SymmetricLink client_link(&client, network_switch.port(1),
38 2 * kBandwidth, kDelay);
39 simulator::SymmetricLink server_link(&server, network_switch.port(2),
40 kBandwidth, kDelay);
41
42 QuicTraceVisitor visitor(client.connection());
43 client.connection()->set_debug_visitor(&visitor);
44
45 // Transfer about a megabyte worth of data from client to server.
46 const QuicTime::Delta kDeadline =
47 3 * kBandwidth.TransferTime(kTransferSize);
48 client.AddBytesToTransfer(kTransferSize);
49 bool simulator_result = simulator.RunUntilOrTimeout(
50 [&]() { return server.bytes_received() >= kTransferSize; }, kDeadline);
51 CHECK(simulator_result);
52
53 // Save the trace and ensure some loss was observed.
54 trace_.Swap(visitor.trace());
55 CHECK_NE(0u, client.connection()->GetStats().packets_retransmitted);
56 packets_sent_ = client.connection()->GetStats().packets_sent;
57 }
58
59 std::vector<quic_trace::Event> AllEventsWithType(
60 quic_trace::EventType event_type) {
61 std::vector<quic_trace::Event> result;
62 for (const auto& event : trace_.events()) {
63 if (event.event_type() == event_type) {
64 result.push_back(event);
65 }
66 }
67 return result;
68 }
69
70 protected:
71 quic_trace::Trace trace_;
72 QuicPacketCount packets_sent_;
73};
74
75TEST_F(QuicTraceVisitorTest, ConnectionId) {
76 char expected_cid[] = {0, 0, 0, 0, 0, 0, 0, 42};
vasilvvc48c8712019-03-11 13:38:16 -070077 EXPECT_EQ(std::string(expected_cid, sizeof(expected_cid)),
QUICHE teama6ef0a62019-03-07 20:34:33 -050078 trace_.destination_connection_id());
79}
80
81TEST_F(QuicTraceVisitorTest, Version) {
vasilvvc48c8712019-03-11 13:38:16 -070082 std::string version = trace_.protocol_version();
QUICHE teama6ef0a62019-03-07 20:34:33 -050083 ASSERT_EQ(4u, version.size());
84 EXPECT_EQ('Q', version[0]);
85}
86
87// Check that basic metadata about sent packets is recorded.
88TEST_F(QuicTraceVisitorTest, SentPacket) {
89 auto sent_packets = AllEventsWithType(quic_trace::PACKET_SENT);
90 EXPECT_EQ(packets_sent_, sent_packets.size());
91 ASSERT_GT(sent_packets.size(), 0u);
92
93 EXPECT_EQ(sent_packets[0].packet_size(), kDefaultMaxPacketSize);
94 EXPECT_EQ(sent_packets[0].packet_number(), 1u);
95}
96
97// Ensure that every stream frame that was sent is recorded.
98TEST_F(QuicTraceVisitorTest, SentStream) {
99 auto sent_packets = AllEventsWithType(quic_trace::PACKET_SENT);
100
101 QuicIntervalSet<QuicStreamOffset> offsets;
102 for (const quic_trace::Event& packet : sent_packets) {
103 for (const quic_trace::Frame& frame : packet.frames()) {
104 if (frame.frame_type() != quic_trace::STREAM) {
105 continue;
106 }
107
108 const quic_trace::StreamFrameInfo& info = frame.stream_frame_info();
109 if (info.stream_id() != kTestStreamNumber) {
110 continue;
111 }
112
113 ASSERT_GT(info.length(), 0u);
114 offsets.Add(info.offset(), info.offset() + info.length());
115 }
116 }
117
118 ASSERT_EQ(1u, offsets.Size());
119 EXPECT_EQ(0u, offsets.begin()->min());
120 EXPECT_EQ(kTransferSize, offsets.rbegin()->max());
121}
122
123// Ensure that all packets are either acknowledged or lost.
124TEST_F(QuicTraceVisitorTest, AckPackets) {
125 QuicIntervalSet<QuicPacketNumber> packets;
126 for (const quic_trace::Event& packet : trace_.events()) {
127 if (packet.event_type() == quic_trace::PACKET_RECEIVED) {
128 for (const quic_trace::Frame& frame : packet.frames()) {
129 if (frame.frame_type() != quic_trace::ACK) {
130 continue;
131 }
132
133 const quic_trace::AckInfo& info = frame.ack_info();
134 for (const auto& block : info.acked_packets()) {
135 packets.Add(QuicPacketNumber(block.first_packet()),
136 QuicPacketNumber(block.last_packet()) + 1);
137 }
138 }
139 }
140 if (packet.event_type() == quic_trace::PACKET_LOST) {
141 packets.Add(QuicPacketNumber(packet.packet_number()),
142 QuicPacketNumber(packet.packet_number()) + 1);
143 }
144 }
145
146 ASSERT_EQ(1u, packets.Size());
147 EXPECT_EQ(QuicPacketNumber(1u), packets.begin()->min());
148 // We leave some room (20 packets) for the packets which did not receive
149 // conclusive status at the end of simulation.
150 EXPECT_GT(packets.rbegin()->max(), QuicPacketNumber(packets_sent_ - 20));
151}
152
153TEST_F(QuicTraceVisitorTest, TransportState) {
154 auto acks = AllEventsWithType(quic_trace::PACKET_RECEIVED);
155 ASSERT_EQ(1, acks[0].frames_size());
156 ASSERT_EQ(quic_trace::ACK, acks[0].frames(0).frame_type());
157
158 // Check that min-RTT at the end is a reasonable approximation.
159 EXPECT_LE((4 * kDelay).ToMicroseconds() * 1.,
160 acks.rbegin()->transport_state().min_rtt_us());
161 EXPECT_GE((4 * kDelay).ToMicroseconds() * 1.25,
162 acks.rbegin()->transport_state().min_rtt_us());
163}
164
165} // namespace
166} // namespace quic