blob: cd8375680b863c1f3e2f06b5710e7169042d022d [file] [log] [blame]
[email protected]8b37a092012-10-18 21:53:491// Copyright (c) 2012 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/quic/test_tools/quic_test_utils.h"
[email protected]9c0b1352012-11-04 00:03:276
[email protected]701bc892013-01-17 04:51:547#include "base/stl_util.h"
[email protected]c244c5a12013-05-07 20:55:048#include "base/strings/string_piece.h"
[email protected]8b37a092012-10-18 21:53:499#include "net/quic/crypto/crypto_framer.h"
[email protected]6f54ab32013-03-02 17:43:3510#include "net/quic/crypto/crypto_handshake.h"
[email protected]872edd9e2013-01-16 08:51:1511#include "net/quic/crypto/crypto_utils.h"
[email protected]5351cc4b2013-03-03 07:22:4112#include "net/quic/crypto/null_encrypter.h"
[email protected]4df69842013-02-27 06:32:1613#include "net/quic/crypto/quic_decrypter.h"
14#include "net/quic/crypto/quic_encrypter.h"
[email protected]a57e0272013-04-26 07:31:4715#include "net/quic/quic_framer.h"
[email protected]5351cc4b2013-03-03 07:22:4116#include "net/quic/quic_packet_creator.h"
[email protected]c244c5a12013-05-07 20:55:0417#include "net/spdy/spdy_frame_builder.h"
[email protected]8b37a092012-10-18 21:53:4918
[email protected]c244c5a12013-05-07 20:55:0419using base::StringPiece;
[email protected]8b37a092012-10-18 21:53:4920using std::max;
21using std::min;
22using std::string;
[email protected]cff7b7b2013-01-11 08:49:0723using testing::_;
[email protected]8b37a092012-10-18 21:53:4924
25namespace net {
26namespace test {
27
28MockFramerVisitor::MockFramerVisitor() {
29 // By default, we want to accept packets.
[email protected]14e8106c2013-03-14 16:25:3330 ON_CALL(*this, OnProtocolVersionMismatch(_))
31 .WillByDefault(testing::Return(false));
32
33 // By default, we want to accept packets.
[email protected]cff7b7b2013-01-11 08:49:0734 ON_CALL(*this, OnPacketHeader(_))
[email protected]8b37a092012-10-18 21:53:4935 .WillByDefault(testing::Return(true));
[email protected]a57e0272013-04-26 07:31:4736
37 ON_CALL(*this, OnStreamFrame(_))
38 .WillByDefault(testing::Return(true));
39
40 ON_CALL(*this, OnAckFrame(_))
41 .WillByDefault(testing::Return(true));
42
43 ON_CALL(*this, OnCongestionFeedbackFrame(_))
44 .WillByDefault(testing::Return(true));
45
46 ON_CALL(*this, OnRstStreamFrame(_))
47 .WillByDefault(testing::Return(true));
48
49 ON_CALL(*this, OnConnectionCloseFrame(_))
50 .WillByDefault(testing::Return(true));
51
52 ON_CALL(*this, OnGoAwayFrame(_))
53 .WillByDefault(testing::Return(true));
[email protected]8b37a092012-10-18 21:53:4954}
55
[email protected]044ac2b2012-11-13 21:41:0656MockFramerVisitor::~MockFramerVisitor() {
57}
[email protected]8b37a092012-10-18 21:53:4958
[email protected]14e8106c2013-03-14 16:25:3359bool NoOpFramerVisitor::OnProtocolVersionMismatch(QuicVersionTag version) {
60 return false;
61}
62
[email protected]8b37a092012-10-18 21:53:4963bool NoOpFramerVisitor::OnPacketHeader(const QuicPacketHeader& header) {
64 return true;
65}
66
[email protected]a57e0272013-04-26 07:31:4767bool NoOpFramerVisitor::OnStreamFrame(const QuicStreamFrame& frame) {
68 return true;
69}
70
71bool NoOpFramerVisitor::OnAckFrame(const QuicAckFrame& frame) {
72 return true;
73}
74
75bool NoOpFramerVisitor::OnCongestionFeedbackFrame(
76 const QuicCongestionFeedbackFrame& frame) {
77 return true;
78}
79
80bool NoOpFramerVisitor::OnRstStreamFrame(
81 const QuicRstStreamFrame& frame) {
82 return true;
83}
84
85bool NoOpFramerVisitor::OnConnectionCloseFrame(
86 const QuicConnectionCloseFrame& frame) {
87 return true;
88}
89
90bool NoOpFramerVisitor::OnGoAwayFrame(const QuicGoAwayFrame& frame) {
91 return true;
92}
93
[email protected]9db443912013-02-25 05:27:0394FramerVisitorCapturingFrames::FramerVisitorCapturingFrames() : frame_count_(0) {
[email protected]134e5c32012-12-12 19:20:3695}
96
[email protected]9db443912013-02-25 05:27:0397FramerVisitorCapturingFrames::~FramerVisitorCapturingFrames() {
[email protected]26f3f8e2012-12-13 21:07:1998}
99
[email protected]9db443912013-02-25 05:27:03100bool FramerVisitorCapturingFrames::OnPacketHeader(
[email protected]4e6f0ed2012-11-02 22:15:38101 const QuicPacketHeader& header) {
102 header_ = header;
[email protected]9db443912013-02-25 05:27:03103 frame_count_ = 0;
[email protected]4e6f0ed2012-11-02 22:15:38104 return true;
105}
106
[email protected]a57e0272013-04-26 07:31:47107bool FramerVisitorCapturingFrames::OnStreamFrame(const QuicStreamFrame& frame) {
[email protected]9db443912013-02-25 05:27:03108 // TODO(ianswett): Own the underlying string, so it will not exist outside
109 // this callback.
110 stream_frames_.push_back(frame);
111 ++frame_count_;
[email protected]a57e0272013-04-26 07:31:47112 return true;
[email protected]26f3f8e2012-12-13 21:07:19113}
114
[email protected]a57e0272013-04-26 07:31:47115bool FramerVisitorCapturingFrames::OnAckFrame(const QuicAckFrame& frame) {
[email protected]9db443912013-02-25 05:27:03116 ack_.reset(new QuicAckFrame(frame));
117 ++frame_count_;
[email protected]a57e0272013-04-26 07:31:47118 return true;
[email protected]9db443912013-02-25 05:27:03119}
120
[email protected]a57e0272013-04-26 07:31:47121bool FramerVisitorCapturingFrames::OnCongestionFeedbackFrame(
[email protected]26f3f8e2012-12-13 21:07:19122 const QuicCongestionFeedbackFrame& frame) {
123 feedback_.reset(new QuicCongestionFeedbackFrame(frame));
[email protected]9db443912013-02-25 05:27:03124 ++frame_count_;
[email protected]a57e0272013-04-26 07:31:47125 return true;
[email protected]9db443912013-02-25 05:27:03126}
127
[email protected]a57e0272013-04-26 07:31:47128bool FramerVisitorCapturingFrames::OnRstStreamFrame(
[email protected]9db443912013-02-25 05:27:03129 const QuicRstStreamFrame& frame) {
130 rst_.reset(new QuicRstStreamFrame(frame));
131 ++frame_count_;
[email protected]a57e0272013-04-26 07:31:47132 return true;
[email protected]9db443912013-02-25 05:27:03133}
134
[email protected]a57e0272013-04-26 07:31:47135bool FramerVisitorCapturingFrames::OnConnectionCloseFrame(
[email protected]9db443912013-02-25 05:27:03136 const QuicConnectionCloseFrame& frame) {
137 close_.reset(new QuicConnectionCloseFrame(frame));
138 ++frame_count_;
[email protected]a57e0272013-04-26 07:31:47139 return true;
[email protected]9db443912013-02-25 05:27:03140}
141
[email protected]a57e0272013-04-26 07:31:47142bool FramerVisitorCapturingFrames::OnGoAwayFrame(const QuicGoAwayFrame& frame) {
[email protected]9db443912013-02-25 05:27:03143 goaway_.reset(new QuicGoAwayFrame(frame));
144 ++frame_count_;
[email protected]a57e0272013-04-26 07:31:47145 return true;
[email protected]4e6f0ed2012-11-02 22:15:38146}
147
[email protected]14e8106c2013-03-14 16:25:33148void FramerVisitorCapturingFrames::OnVersionNegotiationPacket(
149 const QuicVersionNegotiationPacket& packet) {
150 version_negotiation_packet_.reset(new QuicVersionNegotiationPacket(packet));
151 frame_count_ = 0;
152}
153
[email protected]fee17f72013-02-03 07:47:41154FramerVisitorCapturingPublicReset::FramerVisitorCapturingPublicReset() {
155}
156
157FramerVisitorCapturingPublicReset::~FramerVisitorCapturingPublicReset() {
158}
159
160void FramerVisitorCapturingPublicReset::OnPublicResetPacket(
161 const QuicPublicResetPacket& public_reset) {
162 public_reset_packet_ = public_reset;
163}
164
[email protected]8d659e22013-01-19 04:26:10165MockConnectionVisitor::MockConnectionVisitor() {
166}
167
168MockConnectionVisitor::~MockConnectionVisitor() {
169}
170
[email protected]9c0b1352012-11-04 00:03:27171MockHelper::MockHelper() {
172}
173
174MockHelper::~MockHelper() {
175}
176
[email protected]97693d12012-11-16 16:05:00177const QuicClock* MockHelper::GetClock() const {
[email protected]9c0b1352012-11-04 00:03:27178 return &clock_;
179}
180
[email protected]9558c5d32012-12-22 00:08:14181QuicRandom* MockHelper::GetRandomGenerator() {
182 return &random_generator_;
183}
184
[email protected]fe053f92013-04-23 20:18:55185void MockHelper::AdvanceTime(QuicTime::Delta delta) {
186 clock_.AdvanceTime(delta);
187}
188
[email protected]14e8106c2013-03-14 16:25:33189MockConnection::MockConnection(QuicGuid guid,
190 IPEndPoint address,
191 bool is_server)
[email protected]fe053f92013-04-23 20:18:55192 : QuicConnection(guid, address, new MockHelper(), is_server),
193 has_mock_helper_(true) {
[email protected]044ac2b2012-11-13 21:41:06194}
195
[email protected]872edd9e2013-01-16 08:51:15196MockConnection::MockConnection(QuicGuid guid,
197 IPEndPoint address,
[email protected]14e8106c2013-03-14 16:25:33198 QuicConnectionHelperInterface* helper,
199 bool is_server)
[email protected]fe053f92013-04-23 20:18:55200 : QuicConnection(guid, address, helper, is_server),
201 has_mock_helper_(false) {
[email protected]872edd9e2013-01-16 08:51:15202}
203
[email protected]044ac2b2012-11-13 21:41:06204MockConnection::~MockConnection() {
205}
206
[email protected]fe053f92013-04-23 20:18:55207void MockConnection::AdvanceTime(QuicTime::Delta delta) {
208 CHECK(has_mock_helper_) << "Cannot advance time unless a MockClock is being"
209 " used";
210 static_cast<MockHelper*>(helper())->AdvanceTime(delta);
211}
212
[email protected]044ac2b2012-11-13 21:41:06213PacketSavingConnection::PacketSavingConnection(QuicGuid guid,
[email protected]14e8106c2013-03-14 16:25:33214 IPEndPoint address,
215 bool is_server)
216 : MockConnection(guid, address, is_server) {
[email protected]044ac2b2012-11-13 21:41:06217}
218
219PacketSavingConnection::~PacketSavingConnection() {
[email protected]701bc892013-01-17 04:51:54220 STLDeleteElements(&packets_);
[email protected]044ac2b2012-11-13 21:41:06221}
222
[email protected]fee17f72013-02-03 07:47:41223bool PacketSavingConnection::SendOrQueuePacket(
[email protected]8ba81212013-05-03 13:11:48224 EncryptionLevel level,
[email protected]fee17f72013-02-03 07:47:41225 QuicPacketSequenceNumber sequence_number,
226 QuicPacket* packet,
[email protected]ed3fc15d2013-03-08 18:37:44227 QuicPacketEntropyHash entropy_hash,
[email protected]74bda142013-03-31 02:49:11228 HasRetransmittableData retransmittable) {
[email protected]044ac2b2012-11-13 21:41:06229 packets_.push_back(packet);
230 return true;
231}
232
233MockSession::MockSession(QuicConnection* connection, bool is_server)
234 : QuicSession(connection, is_server) {
[email protected]cff7b7b2013-01-11 08:49:07235 ON_CALL(*this, WriteData(_, _, _, _))
236 .WillByDefault(testing::Return(QuicConsumedData(0, false)));
[email protected]044ac2b2012-11-13 21:41:06237}
238
239MockSession::~MockSession() {
240}
241
[email protected]fee17f72013-02-03 07:47:41242MockSendAlgorithm::MockSendAlgorithm() {
[email protected]8d659e22013-01-19 04:26:10243}
244
[email protected]fee17f72013-02-03 07:47:41245MockSendAlgorithm::~MockSendAlgorithm() {
[email protected]8d659e22013-01-19 04:26:10246}
247
[email protected]8b37a092012-10-18 21:53:49248namespace {
249
250string HexDumpWithMarks(const char* data, int length,
251 const bool* marks, int mark_length) {
252 static const char kHexChars[] = "0123456789abcdef";
253 static const int kColumns = 4;
254
255 const int kSizeLimit = 1024;
256 if (length > kSizeLimit || mark_length > kSizeLimit) {
257 LOG(ERROR) << "Only dumping first " << kSizeLimit << " bytes.";
258 length = min(length, kSizeLimit);
259 mark_length = min(mark_length, kSizeLimit);
260 }
261
262 string hex;
263 for (const char* row = data; length > 0;
264 row += kColumns, length -= kColumns) {
265 for (const char *p = row; p < row + 4; ++p) {
266 if (p < row + length) {
267 const bool mark =
268 (marks && (p - data) < mark_length && marks[p - data]);
269 hex += mark ? '*' : ' ';
270 hex += kHexChars[(*p & 0xf0) >> 4];
271 hex += kHexChars[*p & 0x0f];
272 hex += mark ? '*' : ' ';
273 } else {
274 hex += " ";
275 }
276 }
277 hex = hex + " ";
278
279 for (const char *p = row; p < row + 4 && p < row + length; ++p)
280 hex += (*p >= 0x20 && *p <= 0x7f) ? (*p) : '.';
281
282 hex = hex + '\n';
283 }
284 return hex;
285}
286
287} // namespace
288
289void CompareCharArraysWithHexError(
290 const string& description,
291 const char* actual,
292 const int actual_len,
293 const char* expected,
294 const int expected_len) {
295 const int min_len = min(actual_len, expected_len);
296 const int max_len = max(actual_len, expected_len);
[email protected]4356f0f2013-04-07 00:58:17297 scoped_ptr<bool[]> marks(new bool[max_len]);
[email protected]8b37a092012-10-18 21:53:49298 bool identical = (actual_len == expected_len);
299 for (int i = 0; i < min_len; ++i) {
300 if (actual[i] != expected[i]) {
301 marks[i] = true;
302 identical = false;
303 } else {
304 marks[i] = false;
305 }
306 }
307 for (int i = min_len; i < max_len; ++i) {
308 marks[i] = true;
309 }
310 if (identical) return;
311 ADD_FAILURE()
312 << "Description:\n"
313 << description
314 << "\n\nExpected:\n"
315 << HexDumpWithMarks(expected, expected_len, marks.get(), max_len)
316 << "\nActual:\n"
317 << HexDumpWithMarks(actual, actual_len, marks.get(), max_len);
318}
319
320void CompareQuicDataWithHexError(
321 const string& description,
322 QuicData* actual,
323 QuicData* expected) {
324 CompareCharArraysWithHexError(
325 description,
326 actual->data(), actual->length(),
327 expected->data(), expected->length());
328}
329
[email protected]d3d15bf2013-01-30 02:51:54330static QuicPacket* ConstructPacketFromHandshakeMessage(
331 QuicGuid guid,
[email protected]14e8106c2013-03-14 16:25:33332 const CryptoHandshakeMessage& message,
333 bool should_include_version) {
[email protected]8b37a092012-10-18 21:53:49334 CryptoFramer crypto_framer;
[email protected]dc2cc742012-10-21 13:56:13335 scoped_ptr<QuicData> data(crypto_framer.ConstructHandshakeMessage(message));
[email protected]8ba81212013-05-03 13:11:48336 QuicFramer quic_framer(kQuicVersion1, QuicTime::Zero(), false);
[email protected]8b37a092012-10-18 21:53:49337
338 QuicPacketHeader header;
[email protected]c995c572013-01-18 05:43:20339 header.public_header.guid = guid;
[email protected]9db443912013-02-25 05:27:03340 header.public_header.reset_flag = false;
[email protected]14e8106c2013-03-14 16:25:33341 header.public_header.version_flag = should_include_version;
[email protected]8b37a092012-10-18 21:53:49342 header.packet_sequence_number = 1;
[email protected]9db443912013-02-25 05:27:03343 header.entropy_flag = false;
344 header.entropy_hash = 0;
345 header.fec_flag = false;
346 header.fec_entropy_flag = false;
[email protected]8b37a092012-10-18 21:53:49347 header.fec_group = 0;
348
[email protected]be24ab22012-10-22 03:01:52349 QuicStreamFrame stream_frame(kCryptoStreamId, false, 0,
[email protected]044ac2b2012-11-13 21:41:06350 data->AsStringPiece());
[email protected]8b37a092012-10-18 21:53:49351
[email protected]be24ab22012-10-22 03:01:52352 QuicFrame frame(&stream_frame);
353 QuicFrames frames;
354 frames.push_back(frame);
[email protected]9db443912013-02-25 05:27:03355 return quic_framer.ConstructFrameDataPacket(header, frames).packet;
[email protected]8b37a092012-10-18 21:53:49356}
357
[email protected]d3d15bf2013-01-30 02:51:54358QuicPacket* ConstructHandshakePacket(QuicGuid guid, CryptoTag tag) {
359 CryptoHandshakeMessage message;
[email protected]ccc66e8a2013-03-26 08:26:14360 message.set_tag(tag);
[email protected]14e8106c2013-03-14 16:25:33361 return ConstructPacketFromHandshakeMessage(guid, message, false);
[email protected]d3d15bf2013-01-30 02:51:54362}
363
[email protected]5351cc4b2013-03-03 07:22:41364size_t GetPacketLengthForOneStream(bool include_version, size_t payload) {
[email protected]14e8106c2013-03-14 16:25:33365 // TODO(wtc): the hardcoded use of NullEncrypter here seems wrong.
[email protected]a57e0272013-04-26 07:31:47366 size_t packet_length = NullEncrypter().GetCiphertextSize(payload) +
[email protected]5351cc4b2013-03-03 07:22:41367 QuicPacketCreator::StreamFramePacketOverhead(1, include_version);
[email protected]a57e0272013-04-26 07:31:47368
369 size_t ack_length = NullEncrypter().GetCiphertextSize(
370 QuicFramer::GetMinAckFrameSize()) + GetPacketHeaderSize(include_version);
371 // Make sure that if we change the size of the packet length for one stream
372 // or the ack frame; that all our test are configured correctly.
373 DCHECK_GE(packet_length, ack_length);
374 return packet_length;
[email protected]5351cc4b2013-03-03 07:22:41375}
376
[email protected]9db443912013-02-25 05:27:03377QuicPacketEntropyHash TestEntropyCalculator::ReceivedEntropyHash(
378 QuicPacketSequenceNumber sequence_number) const {
379 return 1u;
380}
381
[email protected]c244c5a12013-05-07 20:55:04382bool TestDecompressorVisitor::OnDecompressedData(StringPiece data) {
383 data.AppendToString(&data_);
384 return true;
385}
386
[email protected]8b37a092012-10-18 21:53:49387} // namespace test
[email protected]8b37a092012-10-18 21:53:49388} // namespace net