blob: 88213877e3b02a81e40d812730d160d9e31bbd9d [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)
[email protected]899951652013-05-16 12:52:39238 : QuicSession(connection, QuicConfig(), 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]899951652013-05-16 12:52:39246TestSession::TestSession(QuicConnection* connection,
247 const QuicConfig& config,
248 bool is_server)
249 : QuicSession(connection, config, is_server),
[email protected]2532de12013-05-09 12:29:33250 crypto_stream_(NULL) {
251}
252
253TestSession::~TestSession() {
254}
255
256void TestSession::SetCryptoStream(QuicCryptoStream* stream) {
257 crypto_stream_ = stream;
258}
259
260QuicCryptoStream* TestSession::GetCryptoStream() {
261 return crypto_stream_;
262}
263
[email protected]fee17f72013-02-03 07:47:41264MockSendAlgorithm::MockSendAlgorithm() {
[email protected]8d659e22013-01-19 04:26:10265}
266
[email protected]fee17f72013-02-03 07:47:41267MockSendAlgorithm::~MockSendAlgorithm() {
[email protected]8d659e22013-01-19 04:26:10268}
269
[email protected]8b37a092012-10-18 21:53:49270namespace {
271
272string HexDumpWithMarks(const char* data, int length,
273 const bool* marks, int mark_length) {
274 static const char kHexChars[] = "0123456789abcdef";
275 static const int kColumns = 4;
276
277 const int kSizeLimit = 1024;
278 if (length > kSizeLimit || mark_length > kSizeLimit) {
279 LOG(ERROR) << "Only dumping first " << kSizeLimit << " bytes.";
280 length = min(length, kSizeLimit);
281 mark_length = min(mark_length, kSizeLimit);
282 }
283
284 string hex;
285 for (const char* row = data; length > 0;
286 row += kColumns, length -= kColumns) {
287 for (const char *p = row; p < row + 4; ++p) {
288 if (p < row + length) {
289 const bool mark =
290 (marks && (p - data) < mark_length && marks[p - data]);
291 hex += mark ? '*' : ' ';
292 hex += kHexChars[(*p & 0xf0) >> 4];
293 hex += kHexChars[*p & 0x0f];
294 hex += mark ? '*' : ' ';
295 } else {
296 hex += " ";
297 }
298 }
299 hex = hex + " ";
300
301 for (const char *p = row; p < row + 4 && p < row + length; ++p)
302 hex += (*p >= 0x20 && *p <= 0x7f) ? (*p) : '.';
303
304 hex = hex + '\n';
305 }
306 return hex;
307}
308
309} // namespace
310
311void CompareCharArraysWithHexError(
312 const string& description,
313 const char* actual,
314 const int actual_len,
315 const char* expected,
316 const int expected_len) {
317 const int min_len = min(actual_len, expected_len);
318 const int max_len = max(actual_len, expected_len);
[email protected]4356f0f2013-04-07 00:58:17319 scoped_ptr<bool[]> marks(new bool[max_len]);
[email protected]8b37a092012-10-18 21:53:49320 bool identical = (actual_len == expected_len);
321 for (int i = 0; i < min_len; ++i) {
322 if (actual[i] != expected[i]) {
323 marks[i] = true;
324 identical = false;
325 } else {
326 marks[i] = false;
327 }
328 }
329 for (int i = min_len; i < max_len; ++i) {
330 marks[i] = true;
331 }
332 if (identical) return;
333 ADD_FAILURE()
334 << "Description:\n"
335 << description
336 << "\n\nExpected:\n"
337 << HexDumpWithMarks(expected, expected_len, marks.get(), max_len)
338 << "\nActual:\n"
339 << HexDumpWithMarks(actual, actual_len, marks.get(), max_len);
340}
341
342void CompareQuicDataWithHexError(
343 const string& description,
344 QuicData* actual,
345 QuicData* expected) {
346 CompareCharArraysWithHexError(
347 description,
348 actual->data(), actual->length(),
349 expected->data(), expected->length());
350}
351
[email protected]d3d15bf2013-01-30 02:51:54352static QuicPacket* ConstructPacketFromHandshakeMessage(
353 QuicGuid guid,
[email protected]14e8106c2013-03-14 16:25:33354 const CryptoHandshakeMessage& message,
355 bool should_include_version) {
[email protected]8b37a092012-10-18 21:53:49356 CryptoFramer crypto_framer;
[email protected]dc2cc742012-10-21 13:56:13357 scoped_ptr<QuicData> data(crypto_framer.ConstructHandshakeMessage(message));
[email protected]8ba81212013-05-03 13:11:48358 QuicFramer quic_framer(kQuicVersion1, QuicTime::Zero(), false);
[email protected]8b37a092012-10-18 21:53:49359
360 QuicPacketHeader header;
[email protected]c995c572013-01-18 05:43:20361 header.public_header.guid = guid;
[email protected]9db443912013-02-25 05:27:03362 header.public_header.reset_flag = false;
[email protected]14e8106c2013-03-14 16:25:33363 header.public_header.version_flag = should_include_version;
[email protected]8b37a092012-10-18 21:53:49364 header.packet_sequence_number = 1;
[email protected]9db443912013-02-25 05:27:03365 header.entropy_flag = false;
366 header.entropy_hash = 0;
367 header.fec_flag = false;
368 header.fec_entropy_flag = false;
[email protected]8b37a092012-10-18 21:53:49369 header.fec_group = 0;
370
[email protected]be24ab22012-10-22 03:01:52371 QuicStreamFrame stream_frame(kCryptoStreamId, false, 0,
[email protected]044ac2b2012-11-13 21:41:06372 data->AsStringPiece());
[email protected]8b37a092012-10-18 21:53:49373
[email protected]be24ab22012-10-22 03:01:52374 QuicFrame frame(&stream_frame);
375 QuicFrames frames;
376 frames.push_back(frame);
[email protected]9db443912013-02-25 05:27:03377 return quic_framer.ConstructFrameDataPacket(header, frames).packet;
[email protected]8b37a092012-10-18 21:53:49378}
379
[email protected]2532de12013-05-09 12:29:33380QuicPacket* ConstructHandshakePacket(QuicGuid guid, QuicTag tag) {
[email protected]d3d15bf2013-01-30 02:51:54381 CryptoHandshakeMessage message;
[email protected]ccc66e8a2013-03-26 08:26:14382 message.set_tag(tag);
[email protected]14e8106c2013-03-14 16:25:33383 return ConstructPacketFromHandshakeMessage(guid, message, false);
[email protected]d3d15bf2013-01-30 02:51:54384}
385
[email protected]5351cc4b2013-03-03 07:22:41386size_t GetPacketLengthForOneStream(bool include_version, size_t payload) {
[email protected]14e8106c2013-03-14 16:25:33387 // TODO(wtc): the hardcoded use of NullEncrypter here seems wrong.
[email protected]a57e0272013-04-26 07:31:47388 size_t packet_length = NullEncrypter().GetCiphertextSize(payload) +
[email protected]5351cc4b2013-03-03 07:22:41389 QuicPacketCreator::StreamFramePacketOverhead(1, include_version);
[email protected]a57e0272013-04-26 07:31:47390
391 size_t ack_length = NullEncrypter().GetCiphertextSize(
392 QuicFramer::GetMinAckFrameSize()) + GetPacketHeaderSize(include_version);
393 // Make sure that if we change the size of the packet length for one stream
394 // or the ack frame; that all our test are configured correctly.
395 DCHECK_GE(packet_length, ack_length);
396 return packet_length;
[email protected]5351cc4b2013-03-03 07:22:41397}
398
[email protected]9db443912013-02-25 05:27:03399QuicPacketEntropyHash TestEntropyCalculator::ReceivedEntropyHash(
400 QuicPacketSequenceNumber sequence_number) const {
401 return 1u;
402}
403
[email protected]c244c5a12013-05-07 20:55:04404bool TestDecompressorVisitor::OnDecompressedData(StringPiece data) {
405 data.AppendToString(&data_);
406 return true;
407}
408
[email protected]899951652013-05-16 12:52:39409void TestDecompressorVisitor::OnDecompressionError() {
410 error_ = true;
411}
412
[email protected]8b37a092012-10-18 21:53:49413} // namespace test
[email protected]8b37a092012-10-18 21:53:49414} // namespace net