Using pre-existing constants instead of hard-coding
[chromium-blink-merge.git] / net / spdy / buffered_spdy_framer_unittest.cc
blob30abe9601d645c19ac145d382051970d80cdc369
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_common.h"
8 #include "testing/platform_test.h"
10 namespace net {
12 namespace {
14 class TestBufferedSpdyVisitor : public BufferedSpdyFramerVisitorInterface {
15 public:
16 explicit TestBufferedSpdyVisitor(SpdyMajorVersion spdy_version)
17 : buffered_spdy_framer_(spdy_version, true),
18 error_count_(0),
19 setting_count_(0),
20 syn_frame_count_(0),
21 syn_reply_frame_count_(0),
22 headers_frame_count_(0),
23 push_promise_frame_count_(0),
24 header_stream_id_(-1),
25 promised_stream_id_(-1) {
28 virtual void OnError(SpdyFramer::SpdyError error_code) OVERRIDE {
29 LOG(INFO) << "SpdyFramer Error: " << error_code;
30 error_count_++;
33 virtual void OnStreamError(
34 SpdyStreamId stream_id,
35 const std::string& description) OVERRIDE {
36 LOG(INFO) << "SpdyFramer Error on stream: " << stream_id << " "
37 << description;
38 error_count_++;
41 virtual void OnSynStream(SpdyStreamId stream_id,
42 SpdyStreamId associated_stream_id,
43 SpdyPriority priority,
44 bool fin,
45 bool unidirectional,
46 const SpdyHeaderBlock& headers) OVERRIDE {
47 header_stream_id_ = stream_id;
48 EXPECT_NE(header_stream_id_, SpdyFramer::kInvalidStream);
49 syn_frame_count_++;
50 headers_ = headers;
53 virtual void OnSynReply(SpdyStreamId stream_id,
54 bool fin,
55 const SpdyHeaderBlock& headers) OVERRIDE {
56 header_stream_id_ = stream_id;
57 EXPECT_NE(header_stream_id_, SpdyFramer::kInvalidStream);
58 syn_reply_frame_count_++;
59 headers_ = headers;
62 virtual void OnHeaders(SpdyStreamId stream_id,
63 bool fin,
64 const SpdyHeaderBlock& headers) OVERRIDE {
65 header_stream_id_ = stream_id;
66 EXPECT_NE(header_stream_id_, SpdyFramer::kInvalidStream);
67 headers_frame_count_++;
68 headers_ = headers;
71 virtual void OnDataFrameHeader(SpdyStreamId stream_id,
72 size_t length,
73 bool fin) OVERRIDE {
74 ADD_FAILURE() << "Unexpected OnDataFrameHeader call.";
77 virtual void OnStreamFrameData(SpdyStreamId stream_id,
78 const char* data,
79 size_t len,
80 bool fin) OVERRIDE {
81 LOG(FATAL) << "Unexpected OnStreamFrameData call.";
84 virtual void OnSettings(bool clear_persisted) OVERRIDE {}
86 virtual void OnSetting(SpdySettingsIds id,
87 uint8 flags,
88 uint32 value) OVERRIDE {
89 setting_count_++;
92 virtual void OnPing(SpdyPingId unique_id, bool is_ack) OVERRIDE {}
94 virtual void OnRstStream(SpdyStreamId stream_id,
95 SpdyRstStreamStatus status) OVERRIDE {
98 virtual void OnGoAway(SpdyStreamId last_accepted_stream_id,
99 SpdyGoAwayStatus status) OVERRIDE {
102 bool OnCredentialFrameData(const char*, size_t) {
103 LOG(FATAL) << "Unexpected OnCredentialFrameData call.";
104 return false;
107 void OnDataFrameHeader(const SpdyFrame* frame) {
108 LOG(FATAL) << "Unexpected OnDataFrameHeader call.";
111 void OnRstStream(const SpdyFrame& frame) {}
112 void OnGoAway(const SpdyFrame& frame) {}
113 void OnPing(const SpdyFrame& frame) {}
114 virtual void OnWindowUpdate(SpdyStreamId stream_id,
115 uint32 delta_window_size) OVERRIDE {}
117 virtual void OnPushPromise(SpdyStreamId stream_id,
118 SpdyStreamId promised_stream_id,
119 const SpdyHeaderBlock& headers) OVERRIDE {
120 header_stream_id_ = stream_id;
121 EXPECT_NE(header_stream_id_, SpdyFramer::kInvalidStream);
122 push_promise_frame_count_++;
123 promised_stream_id_ = promised_stream_id;
124 EXPECT_NE(promised_stream_id_, SpdyFramer::kInvalidStream);
125 headers_ = headers;
128 void OnCredential(const SpdyFrame& frame) {}
130 // Convenience function which runs a framer simulation with particular input.
131 void SimulateInFramer(const unsigned char* input, size_t size) {
132 buffered_spdy_framer_.set_visitor(this);
133 size_t input_remaining = size;
134 const char* input_ptr = reinterpret_cast<const char*>(input);
135 while (input_remaining > 0 &&
136 buffered_spdy_framer_.error_code() == SpdyFramer::SPDY_NO_ERROR) {
137 // To make the tests more interesting, we feed random (amd small) chunks
138 // into the framer. This simulates getting strange-sized reads from
139 // the socket.
140 const size_t kMaxReadSize = 32;
141 size_t bytes_read =
142 (rand() % std::min(input_remaining, kMaxReadSize)) + 1;
143 size_t bytes_processed =
144 buffered_spdy_framer_.ProcessInput(input_ptr, bytes_read);
145 input_remaining -= bytes_processed;
146 input_ptr += bytes_processed;
150 BufferedSpdyFramer buffered_spdy_framer_;
152 // Counters from the visitor callbacks.
153 int error_count_;
154 int setting_count_;
155 int syn_frame_count_;
156 int syn_reply_frame_count_;
157 int headers_frame_count_;
158 int push_promise_frame_count_;
160 // Header block streaming state:
161 SpdyStreamId header_stream_id_;
162 SpdyStreamId promised_stream_id_;
164 // Headers from OnSyn, OnSynReply, OnHeaders and OnPushPromise for
165 // verification.
166 SpdyHeaderBlock headers_;
169 } // namespace
171 class BufferedSpdyFramerTest
172 : public PlatformTest,
173 public ::testing::WithParamInterface<NextProto> {
174 protected:
175 // Returns true if the two header blocks have equivalent content.
176 bool CompareHeaderBlocks(const SpdyHeaderBlock* expected,
177 const SpdyHeaderBlock* actual) {
178 if (expected->size() != actual->size()) {
179 LOG(ERROR) << "Expected " << expected->size() << " headers; actually got "
180 << actual->size() << ".";
181 return false;
183 for (SpdyHeaderBlock::const_iterator it = expected->begin();
184 it != expected->end();
185 ++it) {
186 SpdyHeaderBlock::const_iterator it2 = actual->find(it->first);
187 if (it2 == actual->end()) {
188 LOG(ERROR) << "Expected header name '" << it->first << "'.";
189 return false;
191 if (it->second.compare(it2->second) != 0) {
192 LOG(ERROR) << "Expected header named '" << it->first
193 << "' to have a value of '" << it->second
194 << "'. The actual value received was '" << it2->second
195 << "'.";
196 return false;
199 return true;
202 SpdyMajorVersion spdy_version() {
203 return NextProtoToSpdyMajorVersion(GetParam());
207 INSTANTIATE_TEST_CASE_P(
208 NextProto,
209 BufferedSpdyFramerTest,
210 testing::Values(kProtoDeprecatedSPDY2,
211 kProtoSPDY3, kProtoSPDY31, kProtoSPDY4));
213 TEST_P(BufferedSpdyFramerTest, OnSetting) {
214 SpdyFramer framer(spdy_version());
215 SpdySettingsIR settings_ir;
216 settings_ir.AddSetting(SETTINGS_INITIAL_WINDOW_SIZE, false, false, 2);
217 settings_ir.AddSetting(SETTINGS_MAX_CONCURRENT_STREAMS, false, false, 3);
218 scoped_ptr<SpdyFrame> control_frame(framer.SerializeSettings(settings_ir));
219 TestBufferedSpdyVisitor visitor(spdy_version());
221 visitor.SimulateInFramer(
222 reinterpret_cast<unsigned char*>(control_frame->data()),
223 control_frame->size());
224 EXPECT_EQ(0, visitor.error_count_);
225 EXPECT_EQ(2, visitor.setting_count_);
228 TEST_P(BufferedSpdyFramerTest, ReadSynStreamHeaderBlock) {
229 SpdyHeaderBlock headers;
230 headers["aa"] = "vv";
231 headers["bb"] = "ww";
232 BufferedSpdyFramer framer(spdy_version(), true);
233 scoped_ptr<SpdyFrame> control_frame(
234 framer.CreateSynStream(1, // stream_id
235 0, // associated_stream_id
236 1, // priority
237 CONTROL_FLAG_NONE,
238 &headers));
239 EXPECT_TRUE(control_frame.get() != NULL);
241 TestBufferedSpdyVisitor visitor(spdy_version());
242 visitor.SimulateInFramer(
243 reinterpret_cast<unsigned char*>(control_frame.get()->data()),
244 control_frame.get()->size());
245 EXPECT_EQ(0, visitor.error_count_);
246 EXPECT_EQ(1, visitor.syn_frame_count_);
247 EXPECT_EQ(0, visitor.syn_reply_frame_count_);
248 EXPECT_EQ(0, visitor.headers_frame_count_);
249 EXPECT_EQ(0, visitor.push_promise_frame_count_);
250 EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_));
253 TEST_P(BufferedSpdyFramerTest, ReadSynReplyHeaderBlock) {
254 SpdyHeaderBlock headers;
255 headers["alpha"] = "beta";
256 headers["gamma"] = "delta";
257 BufferedSpdyFramer framer(spdy_version(), true);
258 scoped_ptr<SpdyFrame> control_frame(
259 framer.CreateSynReply(1, // stream_id
260 CONTROL_FLAG_NONE,
261 &headers));
262 EXPECT_TRUE(control_frame.get() != NULL);
264 TestBufferedSpdyVisitor visitor(spdy_version());
265 visitor.SimulateInFramer(
266 reinterpret_cast<unsigned char*>(control_frame.get()->data()),
267 control_frame.get()->size());
268 EXPECT_EQ(0, visitor.error_count_);
269 EXPECT_EQ(0, visitor.syn_frame_count_);
270 EXPECT_EQ(0, visitor.push_promise_frame_count_);
271 if(spdy_version() < SPDY4) {
272 EXPECT_EQ(1, visitor.syn_reply_frame_count_);
273 EXPECT_EQ(0, visitor.headers_frame_count_);
274 } else {
275 EXPECT_EQ(0, visitor.syn_reply_frame_count_);
276 EXPECT_EQ(1, visitor.headers_frame_count_);
278 EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_));
281 TEST_P(BufferedSpdyFramerTest, ReadHeadersHeaderBlock) {
282 SpdyHeaderBlock headers;
283 headers["alpha"] = "beta";
284 headers["gamma"] = "delta";
285 BufferedSpdyFramer framer(spdy_version(), true);
286 scoped_ptr<SpdyFrame> control_frame(
287 framer.CreateHeaders(1, // stream_id
288 CONTROL_FLAG_NONE,
289 &headers));
290 EXPECT_TRUE(control_frame.get() != NULL);
292 TestBufferedSpdyVisitor visitor(spdy_version());
293 visitor.SimulateInFramer(
294 reinterpret_cast<unsigned char*>(control_frame.get()->data()),
295 control_frame.get()->size());
296 EXPECT_EQ(0, visitor.error_count_);
297 EXPECT_EQ(0, visitor.syn_frame_count_);
298 EXPECT_EQ(0, visitor.syn_reply_frame_count_);
299 EXPECT_EQ(1, visitor.headers_frame_count_);
300 EXPECT_EQ(0, visitor.push_promise_frame_count_);
301 EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_));
304 TEST_P(BufferedSpdyFramerTest, ReadPushPromiseHeaderBlock) {
305 if (spdy_version() < SPDY4)
306 return;
307 SpdyHeaderBlock headers;
308 headers["alpha"] = "beta";
309 headers["gamma"] = "delta";
310 BufferedSpdyFramer framer(spdy_version(), true);
311 scoped_ptr<SpdyFrame> control_frame(
312 framer.CreatePushPromise(1, 2, &headers));
313 EXPECT_TRUE(control_frame.get() != NULL);
315 TestBufferedSpdyVisitor visitor(spdy_version());
316 visitor.SimulateInFramer(
317 reinterpret_cast<unsigned char*>(control_frame.get()->data()),
318 control_frame.get()->size());
319 EXPECT_EQ(0, visitor.error_count_);
320 EXPECT_EQ(0, visitor.syn_frame_count_);
321 EXPECT_EQ(0, visitor.syn_reply_frame_count_);
322 EXPECT_EQ(0, visitor.headers_frame_count_);
323 EXPECT_EQ(1, visitor.push_promise_frame_count_);
324 EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_));
325 EXPECT_EQ(1u, visitor.header_stream_id_);
326 EXPECT_EQ(2u, visitor.promised_stream_id_);
329 } // namespace net