blob: c987277e1b6ae3ad6918f013ea87f95fcd13943c [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]8b37a092012-10-18 21:53:498#include "net/quic/crypto/crypto_framer.h"
[email protected]6f54ab32013-03-02 17:43:359#include "net/quic/crypto/crypto_handshake.h"
[email protected]872edd9e2013-01-16 08:51:1510#include "net/quic/crypto/crypto_utils.h"
[email protected]5351cc4b2013-03-03 07:22:4111#include "net/quic/crypto/null_encrypter.h"
[email protected]4df69842013-02-27 06:32:1612#include "net/quic/crypto/quic_decrypter.h"
13#include "net/quic/crypto/quic_encrypter.h"
[email protected]a57e0272013-04-26 07:31:4714#include "net/quic/quic_framer.h"
[email protected]5351cc4b2013-03-03 07:22:4115#include "net/quic/quic_packet_creator.h"
[email protected]c244c5a12013-05-07 20:55:0416#include "net/spdy/spdy_frame_builder.h"
[email protected]8b37a092012-10-18 21:53:4917
[email protected]c244c5a12013-05-07 20:55:0418using base::StringPiece;
[email protected]8b37a092012-10-18 21:53:4919using std::max;
20using std::min;
21using std::string;
[email protected]cff7b7b2013-01-11 08:49:0722using testing::_;
[email protected]8b37a092012-10-18 21:53:4923
24namespace net {
25namespace test {
26
27MockFramerVisitor::MockFramerVisitor() {
28 // By default, we want to accept packets.
[email protected]14e8106c2013-03-14 16:25:3329 ON_CALL(*this, OnProtocolVersionMismatch(_))
30 .WillByDefault(testing::Return(false));
31
32 // By default, we want to accept packets.
[email protected]cff7b7b2013-01-11 08:49:0733 ON_CALL(*this, OnPacketHeader(_))
[email protected]8b37a092012-10-18 21:53:4934 .WillByDefault(testing::Return(true));
[email protected]a57e0272013-04-26 07:31:4735
36 ON_CALL(*this, OnStreamFrame(_))
37 .WillByDefault(testing::Return(true));
38
39 ON_CALL(*this, OnAckFrame(_))
40 .WillByDefault(testing::Return(true));
41
42 ON_CALL(*this, OnCongestionFeedbackFrame(_))
43 .WillByDefault(testing::Return(true));
44
45 ON_CALL(*this, OnRstStreamFrame(_))
46 .WillByDefault(testing::Return(true));
47
48 ON_CALL(*this, OnConnectionCloseFrame(_))
49 .WillByDefault(testing::Return(true));
50
51 ON_CALL(*this, OnGoAwayFrame(_))
52 .WillByDefault(testing::Return(true));
[email protected]8b37a092012-10-18 21:53:4953}
54
[email protected]044ac2b2012-11-13 21:41:0655MockFramerVisitor::~MockFramerVisitor() {
56}
[email protected]8b37a092012-10-18 21:53:4957
[email protected]2532de12013-05-09 12:29:3358bool NoOpFramerVisitor::OnProtocolVersionMismatch(QuicTag version) {
[email protected]14e8106c2013-03-14 16:25:3359 return false;
60}
61
[email protected]8b37a092012-10-18 21:53:4962bool NoOpFramerVisitor::OnPacketHeader(const QuicPacketHeader& header) {
63 return true;
64}
65
[email protected]a57e0272013-04-26 07:31:4766bool NoOpFramerVisitor::OnStreamFrame(const QuicStreamFrame& frame) {
67 return true;
68}
69
70bool NoOpFramerVisitor::OnAckFrame(const QuicAckFrame& frame) {
71 return true;
72}
73
74bool NoOpFramerVisitor::OnCongestionFeedbackFrame(
75 const QuicCongestionFeedbackFrame& frame) {
76 return true;
77}
78
79bool NoOpFramerVisitor::OnRstStreamFrame(
80 const QuicRstStreamFrame& frame) {
81 return true;
82}
83
84bool NoOpFramerVisitor::OnConnectionCloseFrame(
85 const QuicConnectionCloseFrame& frame) {
86 return true;
87}
88
89bool NoOpFramerVisitor::OnGoAwayFrame(const QuicGoAwayFrame& frame) {
90 return true;
91}
92
[email protected]9db443912013-02-25 05:27:0393FramerVisitorCapturingFrames::FramerVisitorCapturingFrames() : frame_count_(0) {
[email protected]134e5c32012-12-12 19:20:3694}
95
[email protected]9db443912013-02-25 05:27:0396FramerVisitorCapturingFrames::~FramerVisitorCapturingFrames() {
[email protected]26f3f8e2012-12-13 21:07:1997}
98
[email protected]9db443912013-02-25 05:27:0399bool FramerVisitorCapturingFrames::OnPacketHeader(
[email protected]4e6f0ed2012-11-02 22:15:38100 const QuicPacketHeader& header) {
101 header_ = header;
[email protected]9db443912013-02-25 05:27:03102 frame_count_ = 0;
[email protected]4e6f0ed2012-11-02 22:15:38103 return true;
104}
105
[email protected]a57e0272013-04-26 07:31:47106bool FramerVisitorCapturingFrames::OnStreamFrame(const QuicStreamFrame& frame) {
[email protected]9db443912013-02-25 05:27:03107 // TODO(ianswett): Own the underlying string, so it will not exist outside
108 // this callback.
109 stream_frames_.push_back(frame);
110 ++frame_count_;
[email protected]a57e0272013-04-26 07:31:47111 return true;
[email protected]26f3f8e2012-12-13 21:07:19112}
113
[email protected]a57e0272013-04-26 07:31:47114bool FramerVisitorCapturingFrames::OnAckFrame(const QuicAckFrame& frame) {
[email protected]9db443912013-02-25 05:27:03115 ack_.reset(new QuicAckFrame(frame));
116 ++frame_count_;
[email protected]a57e0272013-04-26 07:31:47117 return true;
[email protected]9db443912013-02-25 05:27:03118}
119
[email protected]a57e0272013-04-26 07:31:47120bool FramerVisitorCapturingFrames::OnCongestionFeedbackFrame(
[email protected]26f3f8e2012-12-13 21:07:19121 const QuicCongestionFeedbackFrame& frame) {
122 feedback_.reset(new QuicCongestionFeedbackFrame(frame));
[email protected]9db443912013-02-25 05:27:03123 ++frame_count_;
[email protected]a57e0272013-04-26 07:31:47124 return true;
[email protected]9db443912013-02-25 05:27:03125}
126
[email protected]a57e0272013-04-26 07:31:47127bool FramerVisitorCapturingFrames::OnRstStreamFrame(
[email protected]9db443912013-02-25 05:27:03128 const QuicRstStreamFrame& frame) {
129 rst_.reset(new QuicRstStreamFrame(frame));
130 ++frame_count_;
[email protected]a57e0272013-04-26 07:31:47131 return true;
[email protected]9db443912013-02-25 05:27:03132}
133
[email protected]a57e0272013-04-26 07:31:47134bool FramerVisitorCapturingFrames::OnConnectionCloseFrame(
[email protected]9db443912013-02-25 05:27:03135 const QuicConnectionCloseFrame& frame) {
136 close_.reset(new QuicConnectionCloseFrame(frame));
137 ++frame_count_;
[email protected]a57e0272013-04-26 07:31:47138 return true;
[email protected]9db443912013-02-25 05:27:03139}
140
[email protected]a57e0272013-04-26 07:31:47141bool FramerVisitorCapturingFrames::OnGoAwayFrame(const QuicGoAwayFrame& frame) {
[email protected]9db443912013-02-25 05:27:03142 goaway_.reset(new QuicGoAwayFrame(frame));
143 ++frame_count_;
[email protected]a57e0272013-04-26 07:31:47144 return true;
[email protected]4e6f0ed2012-11-02 22:15:38145}
146
[email protected]14e8106c2013-03-14 16:25:33147void FramerVisitorCapturingFrames::OnVersionNegotiationPacket(
148 const QuicVersionNegotiationPacket& packet) {
149 version_negotiation_packet_.reset(new QuicVersionNegotiationPacket(packet));
150 frame_count_ = 0;
151}
152
[email protected]fee17f72013-02-03 07:47:41153FramerVisitorCapturingPublicReset::FramerVisitorCapturingPublicReset() {
154}
155
156FramerVisitorCapturingPublicReset::~FramerVisitorCapturingPublicReset() {
157}
158
159void FramerVisitorCapturingPublicReset::OnPublicResetPacket(
160 const QuicPublicResetPacket& public_reset) {
161 public_reset_packet_ = public_reset;
162}
163
[email protected]8d659e22013-01-19 04:26:10164MockConnectionVisitor::MockConnectionVisitor() {
165}
166
167MockConnectionVisitor::~MockConnectionVisitor() {
168}
169
[email protected]9c0b1352012-11-04 00:03:27170MockHelper::MockHelper() {
171}
172
173MockHelper::~MockHelper() {
174}
175
[email protected]97693d12012-11-16 16:05:00176const QuicClock* MockHelper::GetClock() const {
[email protected]9c0b1352012-11-04 00:03:27177 return &clock_;
178}
179
[email protected]9558c5d32012-12-22 00:08:14180QuicRandom* MockHelper::GetRandomGenerator() {
181 return &random_generator_;
182}
183
[email protected]fe053f92013-04-23 20:18:55184void MockHelper::AdvanceTime(QuicTime::Delta delta) {
185 clock_.AdvanceTime(delta);
186}
187
[email protected]14e8106c2013-03-14 16:25:33188MockConnection::MockConnection(QuicGuid guid,
189 IPEndPoint address,
190 bool is_server)
[email protected]2532de12013-05-09 12:29:33191 : QuicConnection(guid, address, new testing::NiceMock<MockHelper>(),
192 is_server),
[email protected]fe053f92013-04-23 20:18:55193 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]2532de12013-05-09 12:29:33221 STLDeleteElements(&encrypted_packets_);
[email protected]044ac2b2012-11-13 21:41:06222}
223
[email protected]fee17f72013-02-03 07:47:41224bool PacketSavingConnection::SendOrQueuePacket(
[email protected]8ba81212013-05-03 13:11:48225 EncryptionLevel level,
[email protected]fee17f72013-02-03 07:47:41226 QuicPacketSequenceNumber sequence_number,
227 QuicPacket* packet,
[email protected]ed3fc15d2013-03-08 18:37:44228 QuicPacketEntropyHash entropy_hash,
[email protected]74bda142013-03-31 02:49:11229 HasRetransmittableData retransmittable) {
[email protected]044ac2b2012-11-13 21:41:06230 packets_.push_back(packet);
[email protected]2532de12013-05-09 12:29:33231 QuicEncryptedPacket* encrypted =
232 framer_.EncryptPacket(level, sequence_number, *packet);
233 encrypted_packets_.push_back(encrypted);
[email protected]044ac2b2012-11-13 21:41:06234 return true;
235}
236
237MockSession::MockSession(QuicConnection* connection, bool is_server)
238 : QuicSession(connection, is_server) {
[email protected]cff7b7b2013-01-11 08:49:07239 ON_CALL(*this, WriteData(_, _, _, _))
240 .WillByDefault(testing::Return(QuicConsumedData(0, false)));
[email protected]044ac2b2012-11-13 21:41:06241}
242
243MockSession::~MockSession() {
244}
245
[email protected]2532de12013-05-09 12:29:33246TestSession::TestSession(QuicConnection* connection, bool is_server)
247 : QuicSession(connection, is_server),
248 crypto_stream_(NULL) {
249}
250
251TestSession::~TestSession() {
252}
253
254void TestSession::SetCryptoStream(QuicCryptoStream* stream) {
255 crypto_stream_ = stream;
256}
257
258QuicCryptoStream* TestSession::GetCryptoStream() {
259 return crypto_stream_;
260}
261
[email protected]fee17f72013-02-03 07:47:41262MockSendAlgorithm::MockSendAlgorithm() {
[email protected]8d659e22013-01-19 04:26:10263}
264
[email protected]fee17f72013-02-03 07:47:41265MockSendAlgorithm::~MockSendAlgorithm() {
[email protected]8d659e22013-01-19 04:26:10266}
267
[email protected]8b37a092012-10-18 21:53:49268namespace {
269
270string HexDumpWithMarks(const char* data, int length,
271 const bool* marks, int mark_length) {
272 static const char kHexChars[] = "0123456789abcdef";
273 static const int kColumns = 4;
274
275 const int kSizeLimit = 1024;
276 if (length > kSizeLimit || mark_length > kSizeLimit) {
277 LOG(ERROR) << "Only dumping first " << kSizeLimit << " bytes.";
278 length = min(length, kSizeLimit);
279 mark_length = min(mark_length, kSizeLimit);
280 }
281
282 string hex;
283 for (const char* row = data; length > 0;
284 row += kColumns, length -= kColumns) {
285 for (const char *p = row; p < row + 4; ++p) {
286 if (p < row + length) {
287 const bool mark =
288 (marks && (p - data) < mark_length && marks[p - data]);
289 hex += mark ? '*' : ' ';
290 hex += kHexChars[(*p & 0xf0) >> 4];
291 hex += kHexChars[*p & 0x0f];
292 hex += mark ? '*' : ' ';
293 } else {
294 hex += " ";
295 }
296 }
297 hex = hex + " ";
298
299 for (const char *p = row; p < row + 4 && p < row + length; ++p)
300 hex += (*p >= 0x20 && *p <= 0x7f) ? (*p) : '.';
301
302 hex = hex + '\n';
303 }
304 return hex;
305}
306
307} // namespace
308
309void CompareCharArraysWithHexError(
310 const string& description,
311 const char* actual,
312 const int actual_len,
313 const char* expected,
314 const int expected_len) {
315 const int min_len = min(actual_len, expected_len);
316 const int max_len = max(actual_len, expected_len);
[email protected]4356f0f2013-04-07 00:58:17317 scoped_ptr<bool[]> marks(new bool[max_len]);
[email protected]8b37a092012-10-18 21:53:49318 bool identical = (actual_len == expected_len);
319 for (int i = 0; i < min_len; ++i) {
320 if (actual[i] != expected[i]) {
321 marks[i] = true;
322 identical = false;
323 } else {
324 marks[i] = false;
325 }
326 }
327 for (int i = min_len; i < max_len; ++i) {
328 marks[i] = true;
329 }
330 if (identical) return;
331 ADD_FAILURE()
332 << "Description:\n"
333 << description
334 << "\n\nExpected:\n"
335 << HexDumpWithMarks(expected, expected_len, marks.get(), max_len)
336 << "\nActual:\n"
337 << HexDumpWithMarks(actual, actual_len, marks.get(), max_len);
338}
339
340void CompareQuicDataWithHexError(
341 const string& description,
342 QuicData* actual,
343 QuicData* expected) {
344 CompareCharArraysWithHexError(
345 description,
346 actual->data(), actual->length(),
347 expected->data(), expected->length());
348}
349
[email protected]d3d15bf2013-01-30 02:51:54350static QuicPacket* ConstructPacketFromHandshakeMessage(
351 QuicGuid guid,
[email protected]14e8106c2013-03-14 16:25:33352 const CryptoHandshakeMessage& message,
353 bool should_include_version) {
[email protected]8b37a092012-10-18 21:53:49354 CryptoFramer crypto_framer;
[email protected]dc2cc742012-10-21 13:56:13355 scoped_ptr<QuicData> data(crypto_framer.ConstructHandshakeMessage(message));
[email protected]8ba81212013-05-03 13:11:48356 QuicFramer quic_framer(kQuicVersion1, QuicTime::Zero(), false);
[email protected]8b37a092012-10-18 21:53:49357
358 QuicPacketHeader header;
[email protected]c995c572013-01-18 05:43:20359 header.public_header.guid = guid;
[email protected]9db443912013-02-25 05:27:03360 header.public_header.reset_flag = false;
[email protected]14e8106c2013-03-14 16:25:33361 header.public_header.version_flag = should_include_version;
[email protected]8b37a092012-10-18 21:53:49362 header.packet_sequence_number = 1;
[email protected]9db443912013-02-25 05:27:03363 header.entropy_flag = false;
364 header.entropy_hash = 0;
365 header.fec_flag = false;
366 header.fec_entropy_flag = false;
[email protected]8b37a092012-10-18 21:53:49367 header.fec_group = 0;
368
[email protected]be24ab22012-10-22 03:01:52369 QuicStreamFrame stream_frame(kCryptoStreamId, false, 0,
[email protected]044ac2b2012-11-13 21:41:06370 data->AsStringPiece());
[email protected]8b37a092012-10-18 21:53:49371
[email protected]be24ab22012-10-22 03:01:52372 QuicFrame frame(&stream_frame);
373 QuicFrames frames;
374 frames.push_back(frame);
[email protected]9db443912013-02-25 05:27:03375 return quic_framer.ConstructFrameDataPacket(header, frames).packet;
[email protected]8b37a092012-10-18 21:53:49376}
377
[email protected]2532de12013-05-09 12:29:33378QuicPacket* ConstructHandshakePacket(QuicGuid guid, QuicTag tag) {
[email protected]d3d15bf2013-01-30 02:51:54379 CryptoHandshakeMessage message;
[email protected]ccc66e8a2013-03-26 08:26:14380 message.set_tag(tag);
[email protected]14e8106c2013-03-14 16:25:33381 return ConstructPacketFromHandshakeMessage(guid, message, false);
[email protected]d3d15bf2013-01-30 02:51:54382}
383
[email protected]5351cc4b2013-03-03 07:22:41384size_t GetPacketLengthForOneStream(bool include_version, size_t payload) {
[email protected]14e8106c2013-03-14 16:25:33385 // TODO(wtc): the hardcoded use of NullEncrypter here seems wrong.
[email protected]a57e0272013-04-26 07:31:47386 size_t packet_length = NullEncrypter().GetCiphertextSize(payload) +
[email protected]5351cc4b2013-03-03 07:22:41387 QuicPacketCreator::StreamFramePacketOverhead(1, include_version);
[email protected]a57e0272013-04-26 07:31:47388
389 size_t ack_length = NullEncrypter().GetCiphertextSize(
390 QuicFramer::GetMinAckFrameSize()) + GetPacketHeaderSize(include_version);
391 // Make sure that if we change the size of the packet length for one stream
392 // or the ack frame; that all our test are configured correctly.
393 DCHECK_GE(packet_length, ack_length);
394 return packet_length;
[email protected]5351cc4b2013-03-03 07:22:41395}
396
[email protected]9db443912013-02-25 05:27:03397QuicPacketEntropyHash TestEntropyCalculator::ReceivedEntropyHash(
398 QuicPacketSequenceNumber sequence_number) const {
399 return 1u;
400}
401
[email protected]c244c5a12013-05-07 20:55:04402bool TestDecompressorVisitor::OnDecompressedData(StringPiece data) {
403 data.AppendToString(&data_);
404 return true;
405}
406
[email protected]8b37a092012-10-18 21:53:49407} // namespace test
[email protected]8b37a092012-10-18 21:53:49408} // namespace net