summaryrefslogtreecommitdiffstats
path: root/net/spdy/buffered_spdy_framer_spdy2_unittest.cc
diff options
context:
space:
mode:
authorrch@chromium.org <rch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-04 04:12:23 +0000
committerrch@chromium.org <rch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-04 04:12:23 +0000
commit448d4ca50bf2216c6217acc13d000f4e451d485a (patch)
treea747072a0641d9488ef77b2a3c598e17a1f2c604 /net/spdy/buffered_spdy_framer_spdy2_unittest.cc
parentf259ea51f61f8e97117ab142606d33d859de7763 (diff)
downloadchromium_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.cc248
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