diff options
author | rch@chromium.org <rch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-04 04:12:23 +0000 |
---|---|---|
committer | rch@chromium.org <rch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-04 04:12:23 +0000 |
commit | 448d4ca50bf2216c6217acc13d000f4e451d485a (patch) | |
tree | a747072a0641d9488ef77b2a3c598e17a1f2c604 /net/spdy/buffered_spdy_framer_spdy2_unittest.cc | |
parent | f259ea51f61f8e97117ab142606d33d859de7763 (diff) | |
download | chromium_src-448d4ca50bf2216c6217acc13d000f4e451d485a.zip chromium_src-448d4ca50bf2216c6217acc13d000f4e451d485a.tar.gz chromium_src-448d4ca50bf2216c6217acc13d000f4e451d485a.tar.bz2 |
Fork SPDY/2 and SPDY/3 versions of our SPDY tests, in preparation for landing
spdy 3 framer changes.
Review URL: https://chromiumcodereview.appspot.com/9582034
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@124886 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/spdy/buffered_spdy_framer_spdy2_unittest.cc')
-rw-r--r-- | net/spdy/buffered_spdy_framer_spdy2_unittest.cc | 248 |
1 files changed, 248 insertions, 0 deletions
diff --git a/net/spdy/buffered_spdy_framer_spdy2_unittest.cc b/net/spdy/buffered_spdy_framer_spdy2_unittest.cc new file mode 100644 index 0000000..135a635 --- /dev/null +++ b/net/spdy/buffered_spdy_framer_spdy2_unittest.cc @@ -0,0 +1,248 @@ +// 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/spdy/buffered_spdy_framer.h" + +#include "net/spdy/spdy_test_util_spdy2.h" +#include "testing/platform_test.h" + +using namespace net::test_spdy2; + +namespace spdy { + +namespace { + +class TestBufferedSpdyVisitor : public BufferedSpdyFramerVisitorInterface { + public: + TestBufferedSpdyVisitor() + : error_count_(0), + syn_frame_count_(0), + syn_reply_frame_count_(0), + headers_frame_count_(0), + header_stream_id_(-1) { + } + + void OnError(int error_code) { + LOG(INFO) << "SpdyFramer Error: " << error_code; + error_count_++; + } + + void OnStreamError(spdy::SpdyStreamId stream_id, + const std::string& description) { + LOG(INFO) << "SpdyFramer Error on stream: " << stream_id << " " + << description; + error_count_++; + } + + void OnSynStream(const SpdySynStreamControlFrame& frame, + const linked_ptr<SpdyHeaderBlock>& headers) { + header_stream_id_ = frame.stream_id(); + EXPECT_NE(header_stream_id_, SpdyFramer::kInvalidStream); + syn_frame_count_++; + headers_ = *headers; + } + + void OnSynReply(const SpdySynReplyControlFrame& frame, + const linked_ptr<SpdyHeaderBlock>& headers) { + header_stream_id_ = frame.stream_id(); + EXPECT_NE(header_stream_id_, SpdyFramer::kInvalidStream); + syn_reply_frame_count_++; + headers_ = *headers; + } + + void OnHeaders(const SpdyHeadersControlFrame& frame, + const linked_ptr<SpdyHeaderBlock>& headers) { + header_stream_id_ = frame.stream_id(); + EXPECT_NE(header_stream_id_, SpdyFramer::kInvalidStream); + headers_frame_count_++; + headers_ = *headers; + } + + void OnStreamFrameData(SpdyStreamId stream_id, + const char* data, + size_t len) { + LOG(FATAL) << "Unexpected OnStreamFrameData call."; + } + + bool OnCredentialFrameData(const char*, size_t) { + LOG(FATAL) << "Unexpected OnCredentialFrameData call."; + return false; + } + + void OnDataFrameHeader(const SpdyDataFrame* frame) { + LOG(FATAL) << "Unexpected OnDataFrameHeader call."; + } + + void OnControl(const SpdyControlFrame* frame) { + uint32 type = frame->type(); + switch (type) { + case SYN_STREAM: + case SYN_REPLY: + case HEADERS: + header_stream_id_ = SpdyFramer::GetControlFrameStreamId(frame); + EXPECT_NE(header_stream_id_, SpdyFramer::kInvalidStream); + buffered_spdy_framer_.OnControl(frame); + break; + default: + LOG(FATAL) << "Unexpected frame type." << type; + } + } + + void OnRstStream(const spdy::SpdyRstStreamControlFrame& frame) {} + void OnGoAway(const spdy::SpdyGoAwayControlFrame& frame) {} + void OnPing(const spdy::SpdyPingControlFrame& frame) {} + void OnSettings(const spdy::SpdySettingsControlFrame& frame) {} + void OnWindowUpdate(const spdy::SpdyWindowUpdateControlFrame& frame) {} + void OnCredential(const spdy::SpdyCredentialControlFrame& frame) {} + + // Convenience function which runs a framer simulation with particular input. + void SimulateInFramer(const unsigned char* input, size_t size) { + buffered_spdy_framer_.set_visitor(this); + size_t input_remaining = size; + const char* input_ptr = reinterpret_cast<const char*>(input); + while (input_remaining > 0 && + buffered_spdy_framer_.error_code() == SpdyFramer::SPDY_NO_ERROR) { + // To make the tests more interesting, we feed random (amd small) chunks + // into the framer. This simulates getting strange-sized reads from + // the socket. + const size_t kMaxReadSize = 32; + size_t bytes_read = + (rand() % std::min(input_remaining, kMaxReadSize)) + 1; + size_t bytes_processed = + buffered_spdy_framer_.ProcessInput(input_ptr, bytes_read); + input_remaining -= bytes_processed; + input_ptr += bytes_processed; + if (buffered_spdy_framer_.state() == SpdyFramer::SPDY_DONE) + buffered_spdy_framer_.Reset(); + } + } + + BufferedSpdyFramer buffered_spdy_framer_; + + // Counters from the visitor callbacks. + int error_count_; + int syn_frame_count_; + int syn_reply_frame_count_; + int headers_frame_count_; + + // Header block streaming state: + SpdyStreamId header_stream_id_; + + // Headers from OnSyn, OnSynReply and OnHeaders for verification. + SpdyHeaderBlock headers_; +}; + +} // namespace + +class BufferedSpdyFramerSpdy2Test : public PlatformTest { + protected: + void EnableCompression(bool enabled) { + SpdyFramer::set_enable_compression_default(enabled); + } + + // Returns true if the two header blocks have equivalent content. + bool CompareHeaderBlocks(const SpdyHeaderBlock* expected, + const SpdyHeaderBlock* actual) { + if (expected->size() != actual->size()) { + LOG(ERROR) << "Expected " << expected->size() << " headers; actually got " + << actual->size() << "."; + return false; + } + for (SpdyHeaderBlock::const_iterator it = expected->begin(); + it != expected->end(); + ++it) { + SpdyHeaderBlock::const_iterator it2 = actual->find(it->first); + if (it2 == actual->end()) { + LOG(ERROR) << "Expected header name '" << it->first << "'."; + return false; + } + if (it->second.compare(it2->second) != 0) { + LOG(ERROR) << "Expected header named '" << it->first + << "' to have a value of '" << it->second + << "'. The actual value received was '" << it2->second + << "'."; + return false; + } + } + return true; + } +}; + +TEST_F(BufferedSpdyFramerSpdy2Test, ReadSynStreamHeaderBlock) { + EnableCompression(false); + + SpdyHeaderBlock headers; + headers["aa"] = "vv"; + headers["bb"] = "ww"; + BufferedSpdyFramer framer; + scoped_ptr<SpdySynStreamControlFrame> control_frame( + framer.CreateSynStream(1, // stream_id + 0, // associated_stream_id + 1, // priority + CONTROL_FLAG_NONE, + true, // compress + &headers)); + EXPECT_TRUE(control_frame.get() != NULL); + + TestBufferedSpdyVisitor visitor; + visitor.SimulateInFramer( + reinterpret_cast<unsigned char*>(control_frame.get()->data()), + control_frame.get()->length() + SpdyControlFrame::kHeaderSize); + EXPECT_EQ(0, visitor.error_count_); + EXPECT_EQ(1, visitor.syn_frame_count_); + EXPECT_EQ(0, visitor.syn_reply_frame_count_); + EXPECT_EQ(0, visitor.headers_frame_count_); + EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_)); +} + +TEST_F(BufferedSpdyFramerSpdy2Test, ReadSynReplyHeaderBlock) { + EnableCompression(false); + + SpdyHeaderBlock headers; + headers["alpha"] = "beta"; + headers["gamma"] = "delta"; + BufferedSpdyFramer framer; + scoped_ptr<SpdySynReplyControlFrame> control_frame( + framer.CreateSynReply(1, // stream_id + CONTROL_FLAG_NONE, + true, // compress + &headers)); + EXPECT_TRUE(control_frame.get() != NULL); + + TestBufferedSpdyVisitor visitor; + visitor.SimulateInFramer( + reinterpret_cast<unsigned char*>(control_frame.get()->data()), + control_frame.get()->length() + SpdyControlFrame::kHeaderSize); + EXPECT_EQ(0, visitor.error_count_); + EXPECT_EQ(0, visitor.syn_frame_count_); + EXPECT_EQ(1, visitor.syn_reply_frame_count_); + EXPECT_EQ(0, visitor.headers_frame_count_); + EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_)); +} + +TEST_F(BufferedSpdyFramerSpdy2Test, ReadHeadersHeaderBlock) { + EnableCompression(false); + + SpdyHeaderBlock headers; + headers["alpha"] = "beta"; + headers["gamma"] = "delta"; + BufferedSpdyFramer framer; + scoped_ptr<SpdyHeadersControlFrame> control_frame( + framer.CreateHeaders(1, // stream_id + CONTROL_FLAG_NONE, + true, // compress + &headers)); + EXPECT_TRUE(control_frame.get() != NULL); + + TestBufferedSpdyVisitor visitor; + visitor.SimulateInFramer( + reinterpret_cast<unsigned char*>(control_frame.get()->data()), + control_frame.get()->length() + SpdyControlFrame::kHeaderSize); + EXPECT_EQ(0, visitor.error_count_); + EXPECT_EQ(0, visitor.syn_frame_count_); + EXPECT_EQ(0, visitor.syn_reply_frame_count_); + EXPECT_EQ(1, visitor.headers_frame_count_); + EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_)); +} +} // namespace spdy |