| Index: net/quic/test_tools/quic_test_utils.cc | 
| diff --git a/net/quic/test_tools/quic_test_utils.cc b/net/quic/test_tools/quic_test_utils.cc | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..a4c71bd0acf1d15c1f4cf5978b0aeb9849026de3 | 
| --- /dev/null | 
| +++ b/net/quic/test_tools/quic_test_utils.cc | 
| @@ -0,0 +1,140 @@ | 
| +// Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
| +// Use of this source code is governed by a BSD-style license that can be | 
| +// found in the LICENSE file. | 
| + | 
| +#include "net/quic/test_tools/quic_test_utils.h" | 
| +#include "net/quic/crypto/crypto_framer.h" | 
| + | 
| +using std::max; | 
| +using std::min; | 
| +using std::string; | 
| + | 
| +namespace net { | 
| +namespace test { | 
| + | 
| +MockFramerVisitor::MockFramerVisitor() { | 
| +  // By default, we want to accept packets. | 
| +  ON_CALL(*this, OnPacketHeader(testing::_)) | 
| +      .WillByDefault(testing::Return(true)); | 
| +} | 
| + | 
| +MockFramerVisitor::~MockFramerVisitor() {} | 
| + | 
| +bool NoOpFramerVisitor::OnPacketHeader(const QuicPacketHeader& header) { | 
| +  return true; | 
| +} | 
| + | 
| +namespace { | 
| + | 
| +string HexDumpWithMarks(const char* data, int length, | 
| +                        const bool* marks, int mark_length) { | 
| +  static const char kHexChars[] = "0123456789abcdef"; | 
| +  static const int kColumns = 4; | 
| + | 
| +  const int kSizeLimit = 1024; | 
| +  if (length > kSizeLimit || mark_length > kSizeLimit) { | 
| +    LOG(ERROR) << "Only dumping first " << kSizeLimit << " bytes."; | 
| +    length = min(length, kSizeLimit); | 
| +    mark_length = min(mark_length, kSizeLimit); | 
| +  } | 
| + | 
| +  string hex; | 
| +  for (const char* row = data; length > 0; | 
| +       row += kColumns, length -= kColumns) { | 
| +    for (const char *p = row; p < row + 4; ++p) { | 
| +      if (p < row + length) { | 
| +        const bool mark = | 
| +            (marks && (p - data) < mark_length && marks[p - data]); | 
| +        hex += mark ? '*' : ' '; | 
| +        hex += kHexChars[(*p & 0xf0) >> 4]; | 
| +        hex += kHexChars[*p & 0x0f]; | 
| +        hex += mark ? '*' : ' '; | 
| +      } else { | 
| +        hex += "    "; | 
| +      } | 
| +    } | 
| +    hex = hex + "  "; | 
| + | 
| +    for (const char *p = row; p < row + 4 && p < row + length; ++p) | 
| +      hex += (*p >= 0x20 && *p <= 0x7f) ? (*p) : '.'; | 
| + | 
| +    hex = hex + '\n'; | 
| +  } | 
| +  return hex; | 
| +} | 
| + | 
| +}  // namespace | 
| + | 
| +void CompareCharArraysWithHexError( | 
| +    const string& description, | 
| +    const char* actual, | 
| +    const int actual_len, | 
| +    const char* expected, | 
| +    const int expected_len) { | 
| +  const int min_len = min(actual_len, expected_len); | 
| +  const int max_len = max(actual_len, expected_len); | 
| +  scoped_array<bool> marks(new bool[max_len]); | 
| +  bool identical = (actual_len == expected_len); | 
| +  for (int i = 0; i < min_len; ++i) { | 
| +    if (actual[i] != expected[i]) { | 
| +      marks[i] = true; | 
| +      identical = false; | 
| +    } else { | 
| +      marks[i] = false; | 
| +    } | 
| +  } | 
| +  for (int i = min_len; i < max_len; ++i) { | 
| +    marks[i] = true; | 
| +  } | 
| +  if (identical) return; | 
| +  ADD_FAILURE() | 
| +      << "Description:\n" | 
| +      << description | 
| +      << "\n\nExpected:\n" | 
| +      << HexDumpWithMarks(expected, expected_len, marks.get(), max_len) | 
| +      << "\nActual:\n" | 
| +      << HexDumpWithMarks(actual, actual_len, marks.get(), max_len); | 
| +} | 
| + | 
| +void CompareQuicDataWithHexError( | 
| +    const string& description, | 
| +    QuicData* actual, | 
| +    QuicData* expected) { | 
| +  CompareCharArraysWithHexError( | 
| +      description, | 
| +      actual->data(), actual->length(), | 
| +      expected->data(), expected->length()); | 
| +} | 
| + | 
| +QuicPacket* ConstructHandshakePacket(QuicGuid guid, CryptoTag tag) { | 
| +  CryptoHandshakeMessage message; | 
| +  message.tag = tag; | 
| +  CryptoFramer crypto_framer; | 
| +  QuicData* data; | 
| +  crypto_framer.ConstructHandshakeMessage(message, &data); | 
| +  QuicFramer quic_framer(QuicDecrypter::Create(kNULL), | 
| +                         QuicEncrypter::Create(kNULL)); | 
| + | 
| +  QuicPacketHeader header; | 
| +  header.guid = guid; | 
| +  header.retransmission_count = 0; | 
| +  header.packet_sequence_number = 1; | 
| +  header.transmission_time = 0; | 
| +  header.flags = PACKET_FLAGS_NONE; | 
| +  header.fec_group = 0; | 
| + | 
| +  QuicStreamFragment stream_fragment(kCryptoStreamId, false, 0, | 
| +                                     data->AsStringPiece()); | 
| + | 
| +  QuicFragment fragment(&stream_fragment); | 
| +  QuicFragments fragments; | 
| +  fragments.push_back(fragment); | 
| +  QuicPacket* packet; | 
| +  quic_framer.ConstructFragementDataPacket(header, fragments, &packet); | 
| +  delete data; | 
| +  return packet; | 
| +} | 
| + | 
| +}  // namespace test | 
| + | 
| +}  // namespace net | 
|  |