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