Speech refactoring: Reimplemented SpeechRecognitionManagerImpl as a FSM. (CL1.7)
[chromium-blink-merge.git] / net / spdy / buffered_spdy_framer_spdy3_unittest.cc
blob46a87dcb07ec847b896e91bbea7bb3fd3ee19af3
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/spdy/buffered_spdy_framer.h"
7 #include "net/spdy/spdy_test_util_spdy3.h"
8 #include "testing/platform_test.h"
10 using namespace net::test_spdy3;
12 namespace net {
14 namespace {
16 class TestBufferedSpdyVisitor : public BufferedSpdyFramerVisitorInterface {
17 public:
18 TestBufferedSpdyVisitor()
19 : buffered_spdy_framer_(3),
20 error_count_(0),
21 setting_count_(0),
22 syn_frame_count_(0),
23 syn_reply_frame_count_(0),
24 headers_frame_count_(0),
25 header_stream_id_(-1) {
28 void OnError(int error_code) {
29 LOG(INFO) << "SpdyFramer Error: " << error_code;
30 error_count_++;
33 void OnStreamError(SpdyStreamId stream_id,
34 const std::string& description) {
35 LOG(INFO) << "SpdyFramer Error on stream: " << stream_id << " "
36 << description;
37 error_count_++;
40 void OnSynStream(const SpdySynStreamControlFrame& frame,
41 const linked_ptr<SpdyHeaderBlock>& headers) {
42 header_stream_id_ = frame.stream_id();
43 EXPECT_NE(header_stream_id_, SpdyFramer::kInvalidStream);
44 syn_frame_count_++;
45 headers_ = *headers;
48 void OnSynReply(const SpdySynReplyControlFrame& frame,
49 const linked_ptr<SpdyHeaderBlock>& headers) {
50 header_stream_id_ = frame.stream_id();
51 EXPECT_NE(header_stream_id_, SpdyFramer::kInvalidStream);
52 syn_reply_frame_count_++;
53 headers_ = *headers;
56 void OnHeaders(const SpdyHeadersControlFrame& frame,
57 const linked_ptr<SpdyHeaderBlock>& headers) {
58 header_stream_id_ = frame.stream_id();
59 EXPECT_NE(header_stream_id_, SpdyFramer::kInvalidStream);
60 headers_frame_count_++;
61 headers_ = *headers;
64 void OnStreamFrameData(SpdyStreamId stream_id,
65 const char* data,
66 size_t len) {
67 LOG(FATAL) << "Unexpected OnStreamFrameData call.";
70 void OnSetting(SpdySettingsIds id, uint8 flags, uint32 value) {
71 setting_count_++;
74 bool OnCredentialFrameData(const char*, size_t) {
75 LOG(FATAL) << "Unexpected OnCredentialFrameData call.";
76 return false;
79 void OnDataFrameHeader(const SpdyDataFrame* frame) {
80 LOG(FATAL) << "Unexpected OnDataFrameHeader call.";
83 void OnControl(const SpdyControlFrame* frame) {
84 uint32 type = frame->type();
85 switch (type) {
86 case SYN_STREAM:
87 case SYN_REPLY:
88 case HEADERS:
89 header_stream_id_ = SpdyFramer::GetControlFrameStreamId(frame);
90 EXPECT_NE(header_stream_id_, SpdyFramer::kInvalidStream);
91 buffered_spdy_framer_.OnControl(frame);
92 break;
93 default:
94 LOG(FATAL) << "Unexpected frame type." << type;
98 void OnRstStream(const SpdyRstStreamControlFrame& frame) {}
99 void OnGoAway(const SpdyGoAwayControlFrame& frame) {}
100 void OnPing(const SpdyPingControlFrame& frame) {}
101 void OnWindowUpdate(const SpdyWindowUpdateControlFrame& frame) {}
102 void OnCredential(const SpdyCredentialControlFrame& frame) {}
104 // Convenience function which runs a framer simulation with particular input.
105 void SimulateInFramer(const unsigned char* input, size_t size) {
106 buffered_spdy_framer_.set_visitor(this);
107 size_t input_remaining = size;
108 const char* input_ptr = reinterpret_cast<const char*>(input);
109 while (input_remaining > 0 &&
110 buffered_spdy_framer_.error_code() == SpdyFramer::SPDY_NO_ERROR) {
111 // To make the tests more interesting, we feed random (amd small) chunks
112 // into the framer. This simulates getting strange-sized reads from
113 // the socket.
114 const size_t kMaxReadSize = 32;
115 size_t bytes_read =
116 (rand() % std::min(input_remaining, kMaxReadSize)) + 1;
117 size_t bytes_processed =
118 buffered_spdy_framer_.ProcessInput(input_ptr, bytes_read);
119 input_remaining -= bytes_processed;
120 input_ptr += bytes_processed;
121 if (buffered_spdy_framer_.state() == SpdyFramer::SPDY_DONE)
122 buffered_spdy_framer_.Reset();
126 BufferedSpdyFramer buffered_spdy_framer_;
128 // Counters from the visitor callbacks.
129 int error_count_;
130 int setting_count_;
131 int syn_frame_count_;
132 int syn_reply_frame_count_;
133 int headers_frame_count_;
135 // Header block streaming state:
136 SpdyStreamId header_stream_id_;
138 // Headers from OnSyn, OnSynReply and OnHeaders for verification.
139 SpdyHeaderBlock headers_;
142 } // namespace
144 class BufferedSpdyFramerSpdy3Test : public PlatformTest {
145 protected:
146 // Returns true if the two header blocks have equivalent content.
147 bool CompareHeaderBlocks(const SpdyHeaderBlock* expected,
148 const SpdyHeaderBlock* actual) {
149 if (expected->size() != actual->size()) {
150 LOG(ERROR) << "Expected " << expected->size() << " headers; actually got "
151 << actual->size() << ".";
152 return false;
154 for (SpdyHeaderBlock::const_iterator it = expected->begin();
155 it != expected->end();
156 ++it) {
157 SpdyHeaderBlock::const_iterator it2 = actual->find(it->first);
158 if (it2 == actual->end()) {
159 LOG(ERROR) << "Expected header name '" << it->first << "'.";
160 return false;
162 if (it->second.compare(it2->second) != 0) {
163 LOG(ERROR) << "Expected header named '" << it->first
164 << "' to have a value of '" << it->second
165 << "'. The actual value received was '" << it2->second
166 << "'.";
167 return false;
170 return true;
173 private:
174 SpdyTestStateHelper spdy_state_;
177 TEST_F(BufferedSpdyFramerSpdy3Test, OnSetting) {
178 SpdyFramer framer(3);
179 SettingsMap settings;
180 settings[SETTINGS_UPLOAD_BANDWIDTH] =
181 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, 0x00000002);
182 settings[SETTINGS_DOWNLOAD_BANDWIDTH] =
183 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, 0x00000003);
185 scoped_ptr<SpdyFrame> control_frame(framer.CreateSettings(settings));
186 TestBufferedSpdyVisitor visitor;
188 visitor.SimulateInFramer(
189 reinterpret_cast<unsigned char*>(control_frame->data()),
190 control_frame->length() + SpdyControlFrame::kHeaderSize);
191 EXPECT_EQ(0, visitor.error_count_);
192 EXPECT_EQ(2, visitor.setting_count_);
195 TEST_F(BufferedSpdyFramerSpdy3Test, ReadSynStreamHeaderBlock) {
196 SpdyHeaderBlock headers;
197 headers["aa"] = "vv";
198 headers["bb"] = "ww";
199 BufferedSpdyFramer framer(3);
200 scoped_ptr<SpdySynStreamControlFrame> control_frame(
201 framer.CreateSynStream(1, // stream_id
202 0, // associated_stream_id
203 1, // priority
204 0, // credential_slot
205 CONTROL_FLAG_NONE,
206 true, // compress
207 &headers));
208 EXPECT_TRUE(control_frame.get() != NULL);
210 TestBufferedSpdyVisitor visitor;
211 visitor.SimulateInFramer(
212 reinterpret_cast<unsigned char*>(control_frame.get()->data()),
213 control_frame.get()->length() + SpdyControlFrame::kHeaderSize);
214 EXPECT_EQ(0, visitor.error_count_);
215 EXPECT_EQ(1, visitor.syn_frame_count_);
216 EXPECT_EQ(0, visitor.syn_reply_frame_count_);
217 EXPECT_EQ(0, visitor.headers_frame_count_);
218 EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_));
221 TEST_F(BufferedSpdyFramerSpdy3Test, ReadSynReplyHeaderBlock) {
222 SpdyHeaderBlock headers;
223 headers["alpha"] = "beta";
224 headers["gamma"] = "delta";
225 BufferedSpdyFramer framer(3);
226 scoped_ptr<SpdySynReplyControlFrame> control_frame(
227 framer.CreateSynReply(1, // stream_id
228 CONTROL_FLAG_NONE,
229 true, // compress
230 &headers));
231 EXPECT_TRUE(control_frame.get() != NULL);
233 TestBufferedSpdyVisitor visitor;
234 visitor.SimulateInFramer(
235 reinterpret_cast<unsigned char*>(control_frame.get()->data()),
236 control_frame.get()->length() + SpdyControlFrame::kHeaderSize);
237 EXPECT_EQ(0, visitor.error_count_);
238 EXPECT_EQ(0, visitor.syn_frame_count_);
239 EXPECT_EQ(1, visitor.syn_reply_frame_count_);
240 EXPECT_EQ(0, visitor.headers_frame_count_);
241 EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_));
244 TEST_F(BufferedSpdyFramerSpdy3Test, ReadHeadersHeaderBlock) {
245 SpdyHeaderBlock headers;
246 headers["alpha"] = "beta";
247 headers["gamma"] = "delta";
248 BufferedSpdyFramer framer(3);
249 scoped_ptr<SpdyHeadersControlFrame> control_frame(
250 framer.CreateHeaders(1, // stream_id
251 CONTROL_FLAG_NONE,
252 true, // compress
253 &headers));
254 EXPECT_TRUE(control_frame.get() != NULL);
256 TestBufferedSpdyVisitor visitor;
257 visitor.SimulateInFramer(
258 reinterpret_cast<unsigned char*>(control_frame.get()->data()),
259 control_frame.get()->length() + SpdyControlFrame::kHeaderSize);
260 EXPECT_EQ(0, visitor.error_count_);
261 EXPECT_EQ(0, visitor.syn_frame_count_);
262 EXPECT_EQ(0, visitor.syn_reply_frame_count_);
263 EXPECT_EQ(1, visitor.headers_frame_count_);
264 EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_));
266 } // namespace net