From aea80604eee7d26eeb7947bfc577acaed05ac7b1 Mon Sep 17 00:00:00 2001
From: "mbelshe@google.com"
 <mbelshe@google.com@0039d316-1c4b-4281-b951-d872f2087c98>
Date: Fri, 18 Sep 2009 00:55:08 +0000
Subject: Retry landing the flip changes.  This time with DEPS!

BUG=none
TEST=flip_session_unittest.cc flip_network_transaction_unittest.cc flip_framer_test.cc

Review URL: http://codereview.chromium.org/210016

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@26533 0039d316-1c4b-4281-b951-d872f2087c98
---
 net/flip/flip_framer_test.cc | 251 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 251 insertions(+)
 create mode 100644 net/flip/flip_framer_test.cc

(limited to 'net/flip/flip_framer_test.cc')

diff --git a/net/flip/flip_framer_test.cc b/net/flip/flip_framer_test.cc
new file mode 100644
index 0000000..a786bc2
--- /dev/null
+++ b/net/flip/flip_framer_test.cc
@@ -0,0 +1,251 @@
+// Copyright (c) 2009 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 <iostream>
+#include "base/scoped_ptr.h"
+
+#include "flip_framer.h"  // cross-google3 directory naming.
+#include "flip_protocol.h"
+#include "flip_frame_builder.h"
+#ifdef _WIN32
+#include "testing/platform_test.h"
+#else
+#include "testing/base/public/gunit.h"
+
+#define PlatformTest ::testing::Test
+#endif
+
+namespace flip {
+
+class FlipFramerTest : public PlatformTest {
+ public:
+  virtual void TearDown() {}
+};
+
+class TestFlipVisitor : public FlipFramerVisitorInterface  {
+ public:
+  explicit TestFlipVisitor(FlipFramer* framer)
+    : framer_(framer),
+      error_count_(0),
+      syn_frame_count_(0),
+      syn_reply_frame_count_(0),
+      data_frame_count_(0),
+      fin_frame_count_(0) {
+  }
+
+  void OnError(FlipFramer* f) {
+    error_count_++;
+  }
+  void OnStreamFrameData(FlipStreamId stream_id,
+                         const char* data,
+                         uint32 len) {
+    data_frame_count_++;
+#ifdef TEST_LOGGING
+    std::cerr << "OnStreamFrameData(" << stream_id << ", \"";
+    if (len > 0) {
+      for (uint32 i = 0 ; i < len; ++i) {
+        std::cerr << std::hex << (0xFF & (unsigned int)data[i]) << std::dec;
+      }
+    }
+    std::cerr << "\", " << len << ")\n";
+#endif  // TEST_LOGGING
+  }
+
+  void OnControl(const FlipControlFrame* frame) {
+    FlipHeaderBlock headers;
+    bool parsed_headers = false;
+    switch (frame->type()) {
+      case SYN_STREAM:
+        parsed_headers = framer_->ParseHeaderBlock(
+            reinterpret_cast<const FlipFrame*>(frame), &headers);
+        DCHECK(parsed_headers);
+        syn_frame_count_++;
+        VLOG(2) << "OnSyn(" << frame->stream_id() << ")\n";
+        break;
+      case SYN_REPLY:
+        parsed_headers = framer_->ParseHeaderBlock(
+            reinterpret_cast<const FlipFrame*>(frame), &headers);
+        DCHECK(parsed_headers);
+        syn_reply_frame_count_++;
+        VLOG(2) << "OnSynReply(" << frame->stream_id() << ")\n";
+        break;
+      case FIN_STREAM:
+        fin_frame_count_++;
+        VLOG(2) << "OnFin(" << frame->stream_id() << ")\n";
+        break;
+      default:
+        DCHECK(false);  // Error!
+    }
+  }
+
+  void OnLameDuck() {
+  }
+
+  FlipFramer* framer_;
+  // Counters from the visitor callbacks.
+  int error_count_;
+  int syn_frame_count_;
+  int syn_reply_frame_count_;
+  int data_frame_count_;
+  int fin_frame_count_;
+};
+
+// Test our protocol constants
+TEST_F(FlipFramerTest, ProtocolConstants) {
+  EXPECT_EQ(8, sizeof(FlipFrame));
+  EXPECT_EQ(8, sizeof(FlipDataFrame));
+  EXPECT_EQ(12, sizeof(FlipControlFrame));
+  EXPECT_EQ(16, sizeof(FlipSynStreamControlFrame));
+  EXPECT_EQ(16, sizeof(FlipSynReplyControlFrame));
+  EXPECT_EQ(16, sizeof(FlipFinStreamControlFrame));
+  EXPECT_EQ(1, SYN_STREAM);
+  EXPECT_EQ(2, SYN_REPLY);
+  EXPECT_EQ(3, FIN_STREAM);
+}
+
+// Test that we can encode and decode a FlipHeaderBlock.
+TEST_F(FlipFramerTest, HeaderBlock) {
+  FlipHeaderBlock headers;
+  headers["alpha"] = "beta";
+  headers["gamma"] = "charlie";
+  FlipFramer framer;
+
+  // Encode the header block into a SynStream frame.
+  scoped_ptr<FlipSynStreamControlFrame> frame(
+      framer.CreateSynStream(1, 1, true, &headers));
+  EXPECT_TRUE(frame.get() != NULL);
+
+  FlipHeaderBlock new_headers;
+  FlipFrame* control_frame = reinterpret_cast<FlipFrame*>(frame.get());
+  framer.ParseHeaderBlock(control_frame, &new_headers);
+
+  EXPECT_EQ(headers.size(), new_headers.size());
+  EXPECT_EQ(headers["alpha"], new_headers["alpha"]);
+  EXPECT_EQ(headers["gamma"], new_headers["gamma"]);
+}
+
+TEST_F(FlipFramerTest, HeaderBlockBarfsOnOutOfOrderHeaders) {
+  FlipFrameBuilder frame;
+
+  frame.WriteUInt16(kControlFlagMask | 1);
+  frame.WriteUInt16(SYN_STREAM);
+  frame.WriteUInt32(0);  // Placeholder for the length.
+  frame.WriteUInt32(3);  // stream_id
+  frame.WriteUInt16(0);  // Priority.
+
+  frame.WriteUInt16(2);  // Number of headers.
+  FlipHeaderBlock::iterator it;
+  frame.WriteString("gamma");
+  frame.WriteString("gamma");
+  frame.WriteString("alpha");
+  frame.WriteString("alpha");
+  // write the length
+  frame.WriteUInt32ToOffset(4, frame.length() - sizeof(FlipFrame));
+
+  FlipHeaderBlock new_headers;
+  const FlipFrame* control_frame = frame.data();
+  FlipFramer framer;
+  framer.set_enable_compression(false);
+  EXPECT_FALSE(framer.ParseHeaderBlock(control_frame, &new_headers));
+}
+
+TEST_F(FlipFramerTest, BasicCompression) {
+  FlipHeaderBlock headers;
+  headers["server"] = "FlipServer 1.0";
+  headers["date"] = "Mon 12 Jan 2009 12:12:12 PST";
+  headers["status"] = "200";
+  headers["version"] = "HTTP/1.1";
+  headers["content-type"] = "text/html";
+  headers["content-length"] = "12";
+
+  FlipFramer framer;
+  scoped_ptr<FlipSynStreamControlFrame>
+      frame1(framer.CreateSynStream(1, 1, true, &headers));
+  scoped_ptr<FlipSynStreamControlFrame>
+      frame2(framer.CreateSynStream(1, 1, true, &headers));
+
+  // Expect the second frame to be more compact than the first.
+  EXPECT_LE(frame2->length(), frame1->length());
+
+  // Decompress the first frame
+  scoped_ptr<FlipFrame> frame3(
+      framer.DecompressFrame(reinterpret_cast<FlipFrame*>(frame1.get())));
+
+  // Decompress the second frame
+  scoped_ptr<FlipFrame> frame4(
+      framer.DecompressFrame(reinterpret_cast<FlipFrame*>(frame2.get())));
+
+  // Expect frames 3 & 4 to be the same.
+  EXPECT_EQ(0,
+      memcmp(frame3.get(), frame4.get(),
+      sizeof(FlipFrame) + frame3->length()));
+}
+
+TEST_F(FlipFramerTest, Basic) {
+  const unsigned char input[] = {
+    0x80, 0x01, 0x00, 0x01,   // SYN Stream #1
+    0x00, 0x00, 0x00, 0x10,
+    0x00, 0x00, 0x00, 0x01,
+    0x00, 0x00, 0x00, 0x01,
+    0x00, 0x02, 'h', 'h',
+    0x00, 0x02, 'v', 'v',
+
+    0x00, 0x00, 0x00, 0x01,   // DATA on Stream #1
+    0x00, 0x00, 0x00, 0x0c,
+      0xde, 0xad, 0xbe, 0xef,
+      0xde, 0xad, 0xbe, 0xef,
+      0xde, 0xad, 0xbe, 0xef,
+
+    0x80, 0x01, 0x00, 0x01,   // SYN Stream #3
+    0x00, 0x00, 0x00, 0x08,
+    0x00, 0x00, 0x00, 0x03,
+    0x00, 0x00, 0x00, 0x00,
+
+    0x00, 0x00, 0x00, 0x03,   // DATA on Stream #3
+    0x00, 0x00, 0x00, 0x08,
+      0xde, 0xad, 0xbe, 0xef,
+      0xde, 0xad, 0xbe, 0xef,
+
+    0x00, 0x00, 0x00, 0x01,   // DATA on Stream #1
+    0x00, 0x00, 0x00, 0x04,
+      0xde, 0xad, 0xbe, 0xef,
+
+    0x80, 0x01, 0x00, 0x03,   // FIN on Stream #1
+    0x00, 0x00, 0x00, 0x08,
+    0x00, 0x00, 0x00, 0x01,
+    0x00, 0x00, 0x00, 0x00,
+
+    0x00, 0x00, 0x00, 0x03,   // DATA on Stream #3
+    0x00, 0x00, 0x00, 0x00,
+
+    0x80, 0x01, 0x00, 0x03,   // FIN on Stream #3
+    0x00, 0x00, 0x00, 0x08,
+    0x00, 0x00, 0x00, 0x03,
+    0x00, 0x00, 0x00, 0x00,
+  };
+
+  FlipFramer framer;
+  framer.set_enable_compression(false);
+  TestFlipVisitor visitor(&framer);
+  framer.set_visitor(&visitor);
+  size_t input_remaining = sizeof(input);
+  const char* input_ptr = reinterpret_cast<const char*>(input);
+  while (input_remaining > 0 &&
+         framer.error_code() == FlipFramer::FLIP_NO_ERROR) {
+    size_t bytes_processed = framer.ProcessInput(input_ptr, sizeof(input));
+    input_remaining -= bytes_processed;
+    input_ptr += bytes_processed;
+    if (framer.state() == FlipFramer::FLIP_DONE)
+      framer.Reset();
+  }
+  EXPECT_EQ(0, visitor.error_count_);
+  EXPECT_EQ(2, visitor.syn_frame_count_);
+  EXPECT_EQ(0, visitor.syn_reply_frame_count_);
+  EXPECT_EQ(4, visitor.data_frame_count_);
+  EXPECT_EQ(2, visitor.fin_frame_count_);
+}
+
+}  // namespace flip
+
+
-- 
cgit v1.1