quic_test_utils.cc revision e5d81f57cb97b3b6b7fccc9c5610d21eb81db09d
1// 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"
6
7#include "base/stl_util.h"
8#include "base/strings/string_number_conversions.h"
9#include "net/quic/crypto/crypto_framer.h"
10#include "net/quic/crypto/crypto_handshake.h"
11#include "net/quic/crypto/crypto_utils.h"
12#include "net/quic/crypto/null_encrypter.h"
13#include "net/quic/crypto/quic_decrypter.h"
14#include "net/quic/crypto/quic_encrypter.h"
15#include "net/quic/quic_framer.h"
16#include "net/quic/quic_packet_creator.h"
17#include "net/quic/quic_utils.h"
18#include "net/quic/test_tools/quic_connection_peer.h"
19#include "net/spdy/spdy_frame_builder.h"
20
21using base::StringPiece;
22using std::max;
23using std::min;
24using std::string;
25using testing::_;
26using testing::AnyNumber;
27
28namespace net {
29namespace test {
30namespace {
31
32// No-op alarm implementation used by MockHelper.
33class TestAlarm : public QuicAlarm {
34 public:
35  explicit TestAlarm(QuicAlarm::Delegate* delegate)
36      : QuicAlarm(delegate) {
37  }
38
39  virtual void SetImpl() OVERRIDE {}
40  virtual void CancelImpl() OVERRIDE {}
41};
42
43}  // namespace
44
45MockFramerVisitor::MockFramerVisitor() {
46  // By default, we want to accept packets.
47  ON_CALL(*this, OnProtocolVersionMismatch(_))
48      .WillByDefault(testing::Return(false));
49
50  // By default, we want to accept packets.
51  ON_CALL(*this, OnUnauthenticatedHeader(_))
52      .WillByDefault(testing::Return(true));
53
54  ON_CALL(*this, OnUnauthenticatedPublicHeader(_))
55      .WillByDefault(testing::Return(true));
56
57  ON_CALL(*this, OnPacketHeader(_))
58      .WillByDefault(testing::Return(true));
59
60  ON_CALL(*this, OnStreamFrame(_))
61      .WillByDefault(testing::Return(true));
62
63  ON_CALL(*this, OnAckFrame(_))
64      .WillByDefault(testing::Return(true));
65
66  ON_CALL(*this, OnCongestionFeedbackFrame(_))
67      .WillByDefault(testing::Return(true));
68
69  ON_CALL(*this, OnStopWaitingFrame(_))
70      .WillByDefault(testing::Return(true));
71
72  ON_CALL(*this, OnRstStreamFrame(_))
73      .WillByDefault(testing::Return(true));
74
75  ON_CALL(*this, OnConnectionCloseFrame(_))
76      .WillByDefault(testing::Return(true));
77
78  ON_CALL(*this, OnGoAwayFrame(_))
79      .WillByDefault(testing::Return(true));
80}
81
82MockFramerVisitor::~MockFramerVisitor() {
83}
84
85bool NoOpFramerVisitor::OnProtocolVersionMismatch(QuicVersion version) {
86  return false;
87}
88
89bool NoOpFramerVisitor::OnUnauthenticatedPublicHeader(
90    const QuicPacketPublicHeader& header) {
91  return true;
92}
93
94bool NoOpFramerVisitor::OnUnauthenticatedHeader(
95    const QuicPacketHeader& header) {
96  return true;
97}
98
99bool NoOpFramerVisitor::OnPacketHeader(const QuicPacketHeader& header) {
100  return true;
101}
102
103bool NoOpFramerVisitor::OnStreamFrame(const QuicStreamFrame& frame) {
104  return true;
105}
106
107bool NoOpFramerVisitor::OnAckFrame(const QuicAckFrame& frame) {
108  return true;
109}
110
111bool NoOpFramerVisitor::OnCongestionFeedbackFrame(
112    const QuicCongestionFeedbackFrame& frame) {
113  return true;
114}
115
116bool NoOpFramerVisitor::OnStopWaitingFrame(
117    const QuicStopWaitingFrame& frame) {
118  return true;
119}
120
121bool NoOpFramerVisitor::OnRstStreamFrame(
122    const QuicRstStreamFrame& frame) {
123  return true;
124}
125
126bool NoOpFramerVisitor::OnConnectionCloseFrame(
127    const QuicConnectionCloseFrame& frame) {
128  return true;
129}
130
131bool NoOpFramerVisitor::OnGoAwayFrame(const QuicGoAwayFrame& frame) {
132  return true;
133}
134
135bool NoOpFramerVisitor::OnWindowUpdateFrame(
136    const QuicWindowUpdateFrame& frame) {
137  return true;
138}
139
140bool NoOpFramerVisitor::OnBlockedFrame(const QuicBlockedFrame& frame) {
141  return true;
142}
143
144FramerVisitorCapturingFrames::FramerVisitorCapturingFrames() : frame_count_(0) {
145}
146
147FramerVisitorCapturingFrames::~FramerVisitorCapturingFrames() {
148  Reset();
149}
150
151void FramerVisitorCapturingFrames::Reset() {
152  STLDeleteElements(&stream_data_);
153  stream_frames_.clear();
154  frame_count_ = 0;
155  ack_.reset();
156  feedback_.reset();
157  rst_.reset();
158  close_.reset();
159  goaway_.reset();
160  version_negotiation_packet_.reset();
161}
162
163bool FramerVisitorCapturingFrames::OnPacketHeader(
164    const QuicPacketHeader& header) {
165  header_ = header;
166  frame_count_ = 0;
167  return true;
168}
169
170bool FramerVisitorCapturingFrames::OnStreamFrame(const QuicStreamFrame& frame) {
171  // Make a copy of the frame and store a copy of underlying string, since
172  // frame.data may not exist outside this callback.
173  stream_data_.push_back(frame.GetDataAsString());
174  QuicStreamFrame frame_copy = frame;
175  frame_copy.data.Clear();
176  frame_copy.data.Append(const_cast<char*>(stream_data_.back()->data()),
177                         stream_data_.back()->size());
178  stream_frames_.push_back(frame_copy);
179  ++frame_count_;
180  return true;
181}
182
183bool FramerVisitorCapturingFrames::OnAckFrame(const QuicAckFrame& frame) {
184  ack_.reset(new QuicAckFrame(frame));
185  ++frame_count_;
186  return true;
187}
188
189bool FramerVisitorCapturingFrames::OnCongestionFeedbackFrame(
190    const QuicCongestionFeedbackFrame& frame) {
191  feedback_.reset(new QuicCongestionFeedbackFrame(frame));
192  ++frame_count_;
193  return true;
194}
195
196bool FramerVisitorCapturingFrames::OnStopWaitingFrame(
197    const QuicStopWaitingFrame& frame) {
198  stop_waiting_.reset(new QuicStopWaitingFrame(frame));
199  ++frame_count_;
200  return true;
201}
202
203bool FramerVisitorCapturingFrames::OnRstStreamFrame(
204    const QuicRstStreamFrame& frame) {
205  rst_.reset(new QuicRstStreamFrame(frame));
206  ++frame_count_;
207  return true;
208}
209
210bool FramerVisitorCapturingFrames::OnConnectionCloseFrame(
211    const QuicConnectionCloseFrame& frame) {
212  close_.reset(new QuicConnectionCloseFrame(frame));
213  ++frame_count_;
214  return true;
215}
216
217bool FramerVisitorCapturingFrames::OnGoAwayFrame(const QuicGoAwayFrame& frame) {
218  goaway_.reset(new QuicGoAwayFrame(frame));
219  ++frame_count_;
220  return true;
221}
222
223void FramerVisitorCapturingFrames::OnVersionNegotiationPacket(
224    const QuicVersionNegotiationPacket& packet) {
225  version_negotiation_packet_.reset(new QuicVersionNegotiationPacket(packet));
226  frame_count_ = 0;
227}
228
229FramerVisitorCapturingPublicReset::FramerVisitorCapturingPublicReset() {
230}
231
232FramerVisitorCapturingPublicReset::~FramerVisitorCapturingPublicReset() {
233}
234
235void FramerVisitorCapturingPublicReset::OnPublicResetPacket(
236    const QuicPublicResetPacket& public_reset) {
237  public_reset_packet_ = public_reset;
238}
239
240MockConnectionVisitor::MockConnectionVisitor() {
241}
242
243MockConnectionVisitor::~MockConnectionVisitor() {
244}
245
246MockHelper::MockHelper() {
247}
248
249MockHelper::~MockHelper() {
250}
251
252const QuicClock* MockHelper::GetClock() const {
253  return &clock_;
254}
255
256QuicRandom* MockHelper::GetRandomGenerator() {
257  return &random_generator_;
258}
259
260QuicAlarm* MockHelper::CreateAlarm(QuicAlarm::Delegate* delegate) {
261  return new TestAlarm(delegate);
262}
263
264void MockHelper::AdvanceTime(QuicTime::Delta delta) {
265  clock_.AdvanceTime(delta);
266}
267
268MockConnection::MockConnection(bool is_server)
269    : QuicConnection(kTestConnectionId,
270                     IPEndPoint(TestPeerIPAddress(), kTestPort),
271                     new testing::NiceMock<MockHelper>(),
272                     new testing::NiceMock<MockPacketWriter>(),
273                     is_server, QuicSupportedVersions(),
274                     kInitialFlowControlWindowForTest),
275      writer_(QuicConnectionPeer::GetWriter(this)),
276      helper_(helper()) {
277}
278
279MockConnection::MockConnection(IPEndPoint address,
280                               bool is_server)
281    : QuicConnection(kTestConnectionId, address,
282                     new testing::NiceMock<MockHelper>(),
283                     new testing::NiceMock<MockPacketWriter>(),
284                     is_server, QuicSupportedVersions(),
285                     kInitialFlowControlWindowForTest),
286      writer_(QuicConnectionPeer::GetWriter(this)),
287      helper_(helper()) {
288}
289
290MockConnection::MockConnection(QuicConnectionId connection_id,
291                               bool is_server)
292    : QuicConnection(connection_id,
293                     IPEndPoint(TestPeerIPAddress(), kTestPort),
294                     new testing::NiceMock<MockHelper>(),
295                     new testing::NiceMock<MockPacketWriter>(),
296                     is_server, QuicSupportedVersions(),
297                     kInitialFlowControlWindowForTest),
298      writer_(QuicConnectionPeer::GetWriter(this)),
299      helper_(helper()) {
300}
301
302MockConnection::MockConnection(bool is_server,
303                               const QuicVersionVector& supported_versions)
304    : QuicConnection(kTestConnectionId,
305                     IPEndPoint(TestPeerIPAddress(), kTestPort),
306                     new testing::NiceMock<MockHelper>(),
307                     new testing::NiceMock<MockPacketWriter>(),
308                     is_server, supported_versions,
309                     kInitialFlowControlWindowForTest),
310      writer_(QuicConnectionPeer::GetWriter(this)),
311      helper_(helper()) {
312}
313
314MockConnection::~MockConnection() {
315}
316
317void MockConnection::AdvanceTime(QuicTime::Delta delta) {
318  static_cast<MockHelper*>(helper())->AdvanceTime(delta);
319}
320
321PacketSavingConnection::PacketSavingConnection(bool is_server)
322    : MockConnection(is_server) {
323}
324
325PacketSavingConnection::PacketSavingConnection(
326    bool is_server,
327    const QuicVersionVector& supported_versions)
328    : MockConnection(is_server, supported_versions) {
329}
330
331PacketSavingConnection::~PacketSavingConnection() {
332  STLDeleteElements(&packets_);
333  STLDeleteElements(&encrypted_packets_);
334}
335
336bool PacketSavingConnection::SendOrQueuePacket(
337    EncryptionLevel level,
338    const SerializedPacket& packet,
339    TransmissionType transmission_type) {
340  packets_.push_back(packet.packet);
341  QuicEncryptedPacket* encrypted = QuicConnectionPeer::GetFramer(this)->
342      EncryptPacket(level, packet.sequence_number, *packet.packet);
343  encrypted_packets_.push_back(encrypted);
344  return true;
345}
346
347MockSession::MockSession(QuicConnection* connection)
348    : QuicSession(connection, DefaultQuicConfig()) {
349  ON_CALL(*this, WritevData(_, _, _, _, _))
350      .WillByDefault(testing::Return(QuicConsumedData(0, false)));
351}
352
353MockSession::~MockSession() {
354}
355
356TestSession::TestSession(QuicConnection* connection,
357                         const QuicConfig& config)
358    : QuicSession(connection, config),
359      crypto_stream_(NULL) {
360}
361
362TestSession::~TestSession() {}
363
364void TestSession::SetCryptoStream(QuicCryptoStream* stream) {
365  crypto_stream_ = stream;
366}
367
368QuicCryptoStream* TestSession::GetCryptoStream() {
369  return crypto_stream_;
370}
371
372TestClientSession::TestClientSession(QuicConnection* connection,
373                                     const QuicConfig& config)
374    : QuicClientSessionBase(connection, config),
375      crypto_stream_(NULL) {
376    EXPECT_CALL(*this, OnProofValid(_)).Times(AnyNumber());
377}
378
379TestClientSession::~TestClientSession() {}
380
381void TestClientSession::SetCryptoStream(QuicCryptoStream* stream) {
382  crypto_stream_ = stream;
383}
384
385QuicCryptoStream* TestClientSession::GetCryptoStream() {
386  return crypto_stream_;
387}
388
389MockPacketWriter::MockPacketWriter() {
390}
391
392MockPacketWriter::~MockPacketWriter() {
393}
394
395MockSendAlgorithm::MockSendAlgorithm() {
396}
397
398MockSendAlgorithm::~MockSendAlgorithm() {
399}
400
401MockLossAlgorithm::MockLossAlgorithm() {
402}
403
404MockLossAlgorithm::~MockLossAlgorithm() {
405}
406
407MockAckNotifierDelegate::MockAckNotifierDelegate() {
408}
409
410MockAckNotifierDelegate::~MockAckNotifierDelegate() {
411}
412
413namespace {
414
415string HexDumpWithMarks(const char* data, int length,
416                        const bool* marks, int mark_length) {
417  static const char kHexChars[] = "0123456789abcdef";
418  static const int kColumns = 4;
419
420  const int kSizeLimit = 1024;
421  if (length > kSizeLimit || mark_length > kSizeLimit) {
422    LOG(ERROR) << "Only dumping first " << kSizeLimit << " bytes.";
423    length = min(length, kSizeLimit);
424    mark_length = min(mark_length, kSizeLimit);
425  }
426
427  string hex;
428  for (const char* row = data; length > 0;
429       row += kColumns, length -= kColumns) {
430    for (const char *p = row; p < row + 4; ++p) {
431      if (p < row + length) {
432        const bool mark =
433            (marks && (p - data) < mark_length && marks[p - data]);
434        hex += mark ? '*' : ' ';
435        hex += kHexChars[(*p & 0xf0) >> 4];
436        hex += kHexChars[*p & 0x0f];
437        hex += mark ? '*' : ' ';
438      } else {
439        hex += "    ";
440      }
441    }
442    hex = hex + "  ";
443
444    for (const char *p = row; p < row + 4 && p < row + length; ++p)
445      hex += (*p >= 0x20 && *p <= 0x7f) ? (*p) : '.';
446
447    hex = hex + '\n';
448  }
449  return hex;
450}
451
452}  // namespace
453
454IPAddressNumber TestPeerIPAddress() { return Loopback4(); }
455
456QuicVersion QuicVersionMax() { return QuicSupportedVersions().front(); }
457
458QuicVersion QuicVersionMin() { return QuicSupportedVersions().back(); }
459
460IPAddressNumber Loopback4() {
461  IPAddressNumber addr;
462  CHECK(ParseIPLiteralToNumber("127.0.0.1", &addr));
463  return addr;
464}
465
466void GenerateBody(string* body, int length) {
467  body->clear();
468  body->reserve(length);
469  for (int i = 0; i < length; ++i) {
470    body->append(1, static_cast<char>(32 + i % (126 - 32)));
471  }
472}
473
474QuicEncryptedPacket* ConstructEncryptedPacket(
475    QuicConnectionId connection_id,
476    bool version_flag,
477    bool reset_flag,
478    QuicPacketSequenceNumber sequence_number,
479    const string& data) {
480  QuicPacketHeader header;
481  header.public_header.connection_id = connection_id;
482  header.public_header.connection_id_length = PACKET_8BYTE_CONNECTION_ID;
483  header.public_header.version_flag = version_flag;
484  header.public_header.reset_flag = reset_flag;
485  header.public_header.sequence_number_length = PACKET_6BYTE_SEQUENCE_NUMBER;
486  header.packet_sequence_number = sequence_number;
487  header.entropy_flag = false;
488  header.entropy_hash = 0;
489  header.fec_flag = false;
490  header.is_in_fec_group = NOT_IN_FEC_GROUP;
491  header.fec_group = 0;
492  QuicStreamFrame stream_frame(1, false, 0, MakeIOVector(data));
493  QuicFrame frame(&stream_frame);
494  QuicFrames frames;
495  frames.push_back(frame);
496  QuicFramer framer(QuicSupportedVersions(), QuicTime::Zero(), false);
497  scoped_ptr<QuicPacket> packet(
498      framer.BuildUnsizedDataPacket(header, frames).packet);
499  EXPECT_TRUE(packet != NULL);
500  QuicEncryptedPacket* encrypted = framer.EncryptPacket(ENCRYPTION_NONE,
501                                                        sequence_number,
502                                                        *packet);
503  EXPECT_TRUE(encrypted != NULL);
504  return encrypted;
505}
506
507void CompareCharArraysWithHexError(
508    const string& description,
509    const char* actual,
510    const int actual_len,
511    const char* expected,
512    const int expected_len) {
513  EXPECT_EQ(actual_len, expected_len);
514  const int min_len = min(actual_len, expected_len);
515  const int max_len = max(actual_len, expected_len);
516  scoped_ptr<bool[]> marks(new bool[max_len]);
517  bool identical = (actual_len == expected_len);
518  for (int i = 0; i < min_len; ++i) {
519    if (actual[i] != expected[i]) {
520      marks[i] = true;
521      identical = false;
522    } else {
523      marks[i] = false;
524    }
525  }
526  for (int i = min_len; i < max_len; ++i) {
527    marks[i] = true;
528  }
529  if (identical) return;
530  ADD_FAILURE()
531      << "Description:\n"
532      << description
533      << "\n\nExpected:\n"
534      << HexDumpWithMarks(expected, expected_len, marks.get(), max_len)
535      << "\nActual:\n"
536      << HexDumpWithMarks(actual, actual_len, marks.get(), max_len);
537}
538
539bool DecodeHexString(const base::StringPiece& hex, std::string* bytes) {
540  bytes->clear();
541  if (hex.empty())
542    return true;
543  std::vector<uint8> v;
544  if (!base::HexStringToBytes(hex.as_string(), &v))
545    return false;
546  if (!v.empty())
547    bytes->assign(reinterpret_cast<const char*>(&v[0]), v.size());
548  return true;
549}
550
551static QuicPacket* ConstructPacketFromHandshakeMessage(
552    QuicConnectionId connection_id,
553    const CryptoHandshakeMessage& message,
554    bool should_include_version) {
555  CryptoFramer crypto_framer;
556  scoped_ptr<QuicData> data(crypto_framer.ConstructHandshakeMessage(message));
557  QuicFramer quic_framer(QuicSupportedVersions(), QuicTime::Zero(), false);
558
559  QuicPacketHeader header;
560  header.public_header.connection_id = connection_id;
561  header.public_header.reset_flag = false;
562  header.public_header.version_flag = should_include_version;
563  header.packet_sequence_number = 1;
564  header.entropy_flag = false;
565  header.entropy_hash = 0;
566  header.fec_flag = false;
567  header.fec_group = 0;
568
569  QuicStreamFrame stream_frame(kCryptoStreamId, false, 0,
570                               MakeIOVector(data->AsStringPiece()));
571
572  QuicFrame frame(&stream_frame);
573  QuicFrames frames;
574  frames.push_back(frame);
575  return quic_framer.BuildUnsizedDataPacket(header, frames).packet;
576}
577
578QuicPacket* ConstructHandshakePacket(QuicConnectionId connection_id,
579                                     QuicTag tag) {
580  CryptoHandshakeMessage message;
581  message.set_tag(tag);
582  return ConstructPacketFromHandshakeMessage(connection_id, message, false);
583}
584
585size_t GetPacketLengthForOneStream(
586    QuicVersion version,
587    bool include_version,
588    QuicSequenceNumberLength sequence_number_length,
589    InFecGroup is_in_fec_group,
590    size_t* payload_length) {
591  *payload_length = 1;
592  const size_t stream_length =
593      NullEncrypter().GetCiphertextSize(*payload_length) +
594      QuicPacketCreator::StreamFramePacketOverhead(
595          version, PACKET_8BYTE_CONNECTION_ID, include_version,
596          sequence_number_length, is_in_fec_group);
597  const size_t ack_length = NullEncrypter().GetCiphertextSize(
598      QuicFramer::GetMinAckFrameSize(
599          version, sequence_number_length, PACKET_1BYTE_SEQUENCE_NUMBER)) +
600      GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, include_version,
601                          sequence_number_length, is_in_fec_group);
602  if (stream_length < ack_length) {
603    *payload_length = 1 + ack_length - stream_length;
604  }
605
606  return NullEncrypter().GetCiphertextSize(*payload_length) +
607      QuicPacketCreator::StreamFramePacketOverhead(
608          version, PACKET_8BYTE_CONNECTION_ID, include_version,
609          sequence_number_length, is_in_fec_group);
610}
611
612TestEntropyCalculator::TestEntropyCalculator() { }
613
614TestEntropyCalculator::~TestEntropyCalculator() { }
615
616QuicPacketEntropyHash TestEntropyCalculator::EntropyHash(
617    QuicPacketSequenceNumber sequence_number) const {
618  return 1u;
619}
620
621MockEntropyCalculator::MockEntropyCalculator() { }
622
623MockEntropyCalculator::~MockEntropyCalculator() { }
624
625QuicConfig DefaultQuicConfig() {
626  QuicConfig config;
627  config.SetDefaults();
628  return config;
629}
630
631QuicVersionVector SupportedVersions(QuicVersion version) {
632  QuicVersionVector versions;
633  versions.push_back(version);
634  return versions;
635}
636
637}  // namespace test
638}  // namespace net
639