// 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/quic_crypto_stream.h" #include #include #include "base/macros.h" #include "base/memory/scoped_ptr.h" #include "net/quic/crypto/crypto_handshake.h" #include "net/quic/crypto/crypto_protocol.h" #include "net/quic/test_tools/crypto_test_utils.h" #include "net/quic/test_tools/quic_test_utils.h" #include "net/quic/test_tools/reliable_quic_stream_peer.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" using std::string; using std::vector; namespace net { namespace test { namespace { class MockQuicCryptoStream : public QuicCryptoStream { public: explicit MockQuicCryptoStream(QuicSession* session) : QuicCryptoStream(session) {} void OnHandshakeMessage(const CryptoHandshakeMessage& message) override { messages_.push_back(message); } vector* messages() { return &messages_; } private: vector messages_; DISALLOW_COPY_AND_ASSIGN(MockQuicCryptoStream); }; class QuicCryptoStreamTest : public ::testing::Test { public: QuicCryptoStreamTest() : connection_(new MockConnection(&helper_, Perspective::IS_CLIENT)), session_(connection_), stream_(&session_) { message_.set_tag(kSHLO); message_.SetStringPiece(1, "abc"); message_.SetStringPiece(2, "def"); ConstructHandshakeMessage(); } void ConstructHandshakeMessage() { CryptoFramer framer; message_data_.reset(framer.ConstructHandshakeMessage(message_)); } protected: MockConnectionHelper helper_; MockConnection* connection_; MockQuicSpdySession session_; MockQuicCryptoStream stream_; CryptoHandshakeMessage message_; scoped_ptr message_data_; private: DISALLOW_COPY_AND_ASSIGN(QuicCryptoStreamTest); }; TEST_F(QuicCryptoStreamTest, NotInitiallyConected) { EXPECT_FALSE(stream_.encryption_established()); EXPECT_FALSE(stream_.handshake_confirmed()); } TEST_F(QuicCryptoStreamTest, ProcessRawData) { stream_.OnStreamFrame(QuicStreamFrame(kCryptoStreamId, /*fin=*/false, /*offset=*/0, message_data_->AsStringPiece())); ASSERT_EQ(1u, stream_.messages()->size()); const CryptoHandshakeMessage& message = (*stream_.messages())[0]; EXPECT_EQ(kSHLO, message.tag()); EXPECT_EQ(2u, message.tag_value_map().size()); EXPECT_EQ("abc", CryptoTestUtils::GetValueForTag(message, 1)); EXPECT_EQ("def", CryptoTestUtils::GetValueForTag(message, 2)); } TEST_F(QuicCryptoStreamTest, ProcessBadData) { string bad(message_data_->data(), message_data_->length()); const int kFirstTagIndex = sizeof(uint32_t) + // message tag sizeof(uint16_t) + // number of tag-value pairs sizeof(uint16_t); // padding EXPECT_EQ(1, bad[kFirstTagIndex]); bad[kFirstTagIndex] = 0x7F; // out of order tag EXPECT_CALL(*connection_, SendConnectionCloseWithDetails( QUIC_CRYPTO_TAGS_OUT_OF_ORDER, testing::_)); stream_.OnStreamFrame( QuicStreamFrame(kCryptoStreamId, /*fin=*/false, /*offset=*/0, bad)); } TEST_F(QuicCryptoStreamTest, NoConnectionLevelFlowControl) { EXPECT_FALSE(ReliableQuicStreamPeer::StreamContributesToConnectionFlowControl( &stream_)); } } // namespace } // namespace test } // namespace net