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