| Index: net/quic/quic_crypto_client_stream_test.cc
|
| ===================================================================
|
| --- net/quic/quic_crypto_client_stream_test.cc (revision 177030)
|
| +++ net/quic/quic_crypto_client_stream_test.cc (working copy)
|
| @@ -7,14 +7,164 @@
|
| #include "net/quic/quic_utils.h"
|
| #include "net/quic/test_tools/quic_test_utils.h"
|
|
|
| +using base::StringPiece;
|
| +using std::vector;
|
| +
|
| namespace net {
|
| namespace test {
|
| namespace {
|
|
|
| +class TestQuicVisitor : public NoOpFramerVisitor {
|
| + public:
|
| + TestQuicVisitor() {}
|
| +
|
| + // NoOpFramerVisitor
|
| + virtual void OnStreamFrame(const QuicStreamFrame& frame) {
|
| + frame_ = frame;
|
| + }
|
| +
|
| + QuicStreamFrame* frame() { return &frame_; }
|
| +
|
| + private:
|
| + QuicStreamFrame frame_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(TestQuicVisitor);
|
| +};
|
| +
|
| +class TestCryptoVisitor : public CryptoFramerVisitorInterface {
|
| + public:
|
| + TestCryptoVisitor()
|
| + : error_count_(0) {
|
| + }
|
| +
|
| + virtual void OnError(CryptoFramer* framer) {
|
| + DLOG(ERROR) << "CryptoFramer Error: " << framer->error();
|
| + ++error_count_;
|
| + }
|
| +
|
| + virtual void OnHandshakeMessage(const CryptoHandshakeMessage& message) {
|
| + messages_.push_back(message);
|
| + }
|
| +
|
| + // Counters from the visitor callbacks.
|
| + int error_count_;
|
| +
|
| + vector<CryptoHandshakeMessage> messages_;
|
| +};
|
| +
|
| +// The same as MockHelper, except that WritePacketToWire() checks whether
|
| +// the packet has the expected contents.
|
| +class TestMockHelper : public MockHelper {
|
| + public:
|
| + TestMockHelper() : packet_count_(0) {}
|
| + virtual ~TestMockHelper() {}
|
| +
|
| + virtual int WritePacketToWire(const QuicEncryptedPacket& packet,
|
| + int* error) {
|
| + packet_count_++;
|
| +
|
| + // The first packet should be ClientHello.
|
| + if (packet_count_ == 1) {
|
| + CheckClientHelloPacket(packet);
|
| + }
|
| +
|
| + return MockHelper::WritePacketToWire(packet, error);
|
| + }
|
| +
|
| + private:
|
| + void CheckClientHelloPacket(const QuicEncryptedPacket& packet);
|
| +
|
| + int packet_count_;
|
| +};
|
| +
|
| +void TestMockHelper::CheckClientHelloPacket(
|
| + const QuicEncryptedPacket& packet) {
|
| + QuicFramer quic_framer(QuicDecrypter::Create(kNULL),
|
| + QuicEncrypter::Create(kNULL));
|
| + TestQuicVisitor quic_visitor;
|
| + quic_framer.set_visitor(&quic_visitor);
|
| + ASSERT_TRUE(quic_framer.ProcessPacket(IPEndPoint(), IPEndPoint(),
|
| + packet));
|
| + EXPECT_EQ(kCryptoStreamId, quic_visitor.frame()->stream_id);
|
| + EXPECT_FALSE(quic_visitor.frame()->fin);
|
| + EXPECT_EQ(0u, quic_visitor.frame()->offset);
|
| +
|
| + // Check quic_visitor.frame()->data.
|
| + TestCryptoVisitor crypto_visitor;
|
| + CryptoFramer crypto_framer;
|
| + crypto_framer.set_visitor(&crypto_visitor);
|
| + ASSERT_TRUE(crypto_framer.ProcessInput(quic_visitor.frame()->data));
|
| + ASSERT_EQ(0u, crypto_framer.InputBytesRemaining());
|
| + ASSERT_EQ(1u, crypto_visitor.messages_.size());
|
| + EXPECT_EQ(kCHLO, crypto_visitor.messages_[0].tag);
|
| +
|
| + CryptoTagValueMap& tag_value_map =
|
| + crypto_visitor.messages_[0].tag_value_map;
|
| + ASSERT_EQ(7u, tag_value_map.size());
|
| +
|
| + // kNONC
|
| + // TODO(wtc): check the nonce.
|
| + ASSERT_EQ(32u, tag_value_map[kNONC].size());
|
| +
|
| + // kAEAD
|
| + ASSERT_EQ(8u, tag_value_map[kAEAD].size());
|
| + CryptoTag cipher[2];
|
| + memcpy(&cipher[0], &tag_value_map[kAEAD][0], 4);
|
| + memcpy(&cipher[1], &tag_value_map[kAEAD][4], 4);
|
| + EXPECT_EQ(kAESG, cipher[0]);
|
| + EXPECT_EQ(kAESH, cipher[1]);
|
| +
|
| + // kICSL
|
| + ASSERT_EQ(4u, tag_value_map[kICSL].size());
|
| + uint32 idle_lifetime;
|
| + memcpy(&idle_lifetime, tag_value_map[kICSL].data(), 4);
|
| + EXPECT_EQ(300u, idle_lifetime);
|
| +
|
| + // kKATO
|
| + ASSERT_EQ(4u, tag_value_map[kKATO].size());
|
| + uint32 keepalive_timeout;
|
| + memcpy(&keepalive_timeout, tag_value_map[kKATO].data(), 4);
|
| + EXPECT_EQ(0u, keepalive_timeout);
|
| +
|
| + // kVERS
|
| + ASSERT_EQ(2u, tag_value_map[kVERS].size());
|
| + uint16 version;
|
| + memcpy(&version, tag_value_map[kVERS].data(), 2);
|
| + EXPECT_EQ(0u, version);
|
| +
|
| + // kKEXS
|
| + ASSERT_EQ(8u, tag_value_map[kKEXS].size());
|
| + CryptoTag key_exchange[2];
|
| + memcpy(&key_exchange[0], &tag_value_map[kKEXS][0], 4);
|
| + memcpy(&key_exchange[1], &tag_value_map[kKEXS][4], 4);
|
| + EXPECT_EQ(kC255, key_exchange[0]);
|
| + EXPECT_EQ(kP256, key_exchange[1]);
|
| +
|
| + // kCGST
|
| + ASSERT_EQ(4u, tag_value_map[kCGST].size());
|
| + CryptoTag congestion[1];
|
| + memcpy(&congestion[0], &tag_value_map[kCGST][0], 4);
|
| + EXPECT_EQ(kQBIC, congestion[0]);
|
| +}
|
| +
|
| +// The same as MockSession, except that WriteData() is not mocked.
|
| +class TestMockSession : public MockSession {
|
| + public:
|
| + TestMockSession(QuicConnection* connection, bool is_server)
|
| + : MockSession(connection, is_server) {
|
| + }
|
| + virtual ~TestMockSession() {}
|
| +
|
| + virtual QuicConsumedData WriteData(QuicStreamId id, StringPiece data,
|
| + QuicStreamOffset offset, bool fin) {
|
| + return QuicSession::WriteData(id, data, offset, fin);
|
| + }
|
| +};
|
| +
|
| class QuicCryptoClientStreamTest : public ::testing::Test {
|
| public:
|
| QuicCryptoClientStreamTest()
|
| - : connection_(new MockConnection(1, addr_)),
|
| + : connection_(new MockConnection(1, addr_, new TestMockHelper())),
|
| session_(connection_, true),
|
| stream_(&session_) {
|
| message_.tag = kSHLO;
|
| @@ -30,7 +180,7 @@
|
|
|
| IPEndPoint addr_;
|
| MockConnection* connection_;
|
| - MockSession session_;
|
| + TestMockSession session_;
|
| QuicCryptoClientStream stream_;
|
| CryptoHandshakeMessage message_;
|
| scoped_ptr<QuicData> message_data_;
|
| @@ -62,6 +212,10 @@
|
| stream_.ProcessData(message_data_->data(), message_data_->length());
|
| }
|
|
|
| +TEST_F(QuicCryptoClientStreamTest, CryptoConnect) {
|
| + EXPECT_TRUE(stream_.CryptoConnect());
|
| +}
|
| +
|
| } // namespace
|
| } // namespace test
|
| } // namespace net
|
|
|