Roll src/third_party/WebKit d9c6159:8139f33 (svn 201974:201975)
[chromium-blink-merge.git] / net / tools / flip_server / http_interface_test.cc
blob6d07840becf480693edadc84d48d136f253c63c0
1 // Copyright 2013 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/tools/flip_server/http_interface.h"
7 #include <list>
9 #include "base/memory/scoped_ptr.h"
10 #include "base/stl_util.h"
11 #include "base/strings/string_piece.h"
12 #include "net/tools/balsa/balsa_enums.h"
13 #include "net/tools/balsa/balsa_frame.h"
14 #include "net/tools/balsa/balsa_headers.h"
15 #include "net/tools/flip_server/flip_config.h"
16 #include "net/tools/flip_server/flip_test_utils.h"
17 #include "net/tools/flip_server/mem_cache.h"
18 #include "testing/gmock/include/gmock/gmock.h"
19 #include "testing/gtest/include/gtest/gtest.h"
21 namespace net {
23 using ::base::StringPiece;
24 using ::testing::_;
25 using ::testing::InSequence;
27 namespace {
29 class MockSMConnection : public SMConnection {
30 public:
31 MockSMConnection(EpollServer* epoll_server,
32 SSLState* ssl_state,
33 MemoryCache* memory_cache,
34 FlipAcceptor* acceptor,
35 std::string log_prefix)
36 : SMConnection(epoll_server,
37 ssl_state,
38 memory_cache,
39 acceptor,
40 log_prefix) {}
42 MOCK_METHOD0(Cleanup, void());
43 MOCK_METHOD8(InitSMConnection,
44 void(SMConnectionPoolInterface*,
45 SMInterface*,
46 EpollServer*,
47 int,
48 std::string,
49 std::string,
50 std::string,
51 bool));
54 class FlipHttpSMTest : public ::testing::Test {
55 public:
56 explicit FlipHttpSMTest(FlipHandlerType type = FLIP_HANDLER_PROXY) {
57 SSLState* ssl_state = NULL;
58 mock_another_interface_.reset(new MockSMInterface);
59 memory_cache_.reset(new MemoryCache);
60 acceptor_.reset(new FlipAcceptor(type,
61 "127.0.0.1",
62 "8941",
63 "ssl_cert_filename",
64 "ssl_key_filename",
65 "127.0.0.1",
66 "8942",
67 "127.0.0.1",
68 "8943",
71 true,
73 false,
74 true,
75 NULL));
76 epoll_server_.reset(new EpollServer);
77 connection_.reset(new MockSMConnection(epoll_server_.get(),
78 ssl_state,
79 memory_cache_.get(),
80 acceptor_.get(),
81 "log_prefix"));
83 interface_.reset(new HttpSM(connection_.get(),
84 mock_another_interface_.get(),
85 memory_cache_.get(),
86 acceptor_.get()));
89 void TearDown() override {
90 if (acceptor_->listen_fd_ >= 0) {
91 epoll_server_->UnregisterFD(acceptor_->listen_fd_);
92 close(acceptor_->listen_fd_);
93 acceptor_->listen_fd_ = -1;
95 STLDeleteElements(connection_->output_list());
98 bool HasStream(uint32 stream_id) {
99 return interface_->output_ordering().ExistsInPriorityMaps(stream_id);
102 protected:
103 scoped_ptr<MockSMInterface> mock_another_interface_;
104 scoped_ptr<MemoryCache> memory_cache_;
105 scoped_ptr<FlipAcceptor> acceptor_;
106 scoped_ptr<EpollServer> epoll_server_;
107 scoped_ptr<MockSMConnection> connection_;
108 scoped_ptr<HttpSM> interface_;
111 class FlipHttpSMProxyTest : public FlipHttpSMTest {
112 public:
113 FlipHttpSMProxyTest() : FlipHttpSMTest(FLIP_HANDLER_PROXY) {}
114 ~FlipHttpSMProxyTest() override {}
117 class FlipHttpSMHttpTest : public FlipHttpSMTest {
118 public:
119 FlipHttpSMHttpTest() : FlipHttpSMTest(FLIP_HANDLER_HTTP_SERVER) {}
120 ~FlipHttpSMHttpTest() override {}
123 class FlipHttpSMSpdyTest : public FlipHttpSMTest {
124 public:
125 FlipHttpSMSpdyTest() : FlipHttpSMTest(FLIP_HANDLER_SPDY_SERVER) {}
126 ~FlipHttpSMSpdyTest() override {}
129 TEST_F(FlipHttpSMTest, Construct) {
130 ASSERT_FALSE(interface_->spdy_framer()->is_request());
133 TEST_F(FlipHttpSMTest, AddToOutputOrder) {
134 uint32 stream_id = 13;
135 MemCacheIter mci;
136 mci.stream_id = stream_id;
139 BalsaHeaders headers;
140 std::string filename = "foobar";
141 memory_cache_->InsertFile(&headers, filename, "");
142 mci.file_data = memory_cache_->GetFileData(filename);
145 interface_->AddToOutputOrder(mci);
146 ASSERT_TRUE(HasStream(stream_id));
149 TEST_F(FlipHttpSMTest, InitSMInterface) {
150 scoped_ptr<MockSMInterface> mock(new MockSMInterface);
152 InSequence s;
153 EXPECT_CALL(*mock_another_interface_, SendEOF(_));
154 EXPECT_CALL(*mock_another_interface_, ResetForNewInterface(_));
155 EXPECT_CALL(*mock, SendEOF(_));
156 EXPECT_CALL(*mock, ResetForNewInterface(_));
159 interface_->ResetForNewConnection();
160 interface_->InitSMInterface(mock.get(), 0);
161 interface_->ResetForNewConnection();
164 TEST_F(FlipHttpSMTest, InitSMConnection) {
165 EXPECT_CALL(*connection_, InitSMConnection(_, _, _, _, _, _, _, _));
167 interface_->InitSMConnection(NULL, NULL, NULL, 0, "", "", "", false);
170 TEST_F(FlipHttpSMTest, ProcessReadInput) {
171 std::string data =
172 "HTTP/1.1 200 OK\r\n"
173 "Content-Length: 14\r\n\r\n"
174 "hello, world\r\n";
175 testing::MockFunction<void(int)> checkpoint; // NOLINT
177 InSequence s;
178 EXPECT_CALL(*mock_another_interface_, SendSynReply(_, _));
179 EXPECT_CALL(checkpoint, Call(0));
180 EXPECT_CALL(*mock_another_interface_, SendDataFrame(_, _, _, _, _));
181 EXPECT_CALL(*mock_another_interface_, SendEOF(_));
184 ASSERT_EQ(BalsaFrameEnums::READING_HEADER_AND_FIRSTLINE,
185 interface_->spdy_framer()->ParseState());
187 size_t read = interface_->ProcessReadInput(data.data(), data.size());
188 ASSERT_EQ(39u, read);
189 checkpoint.Call(0);
190 read += interface_->ProcessReadInput(&data.data()[read], data.size() - read);
191 ASSERT_EQ(data.size(), read);
192 ASSERT_EQ(BalsaFrameEnums::MESSAGE_FULLY_READ,
193 interface_->spdy_framer()->ParseState());
194 ASSERT_TRUE(interface_->MessageFullyRead());
197 TEST_F(FlipHttpSMTest, ProcessWriteInput) {
198 std::string data = "hello, world";
199 interface_->ProcessWriteInput(data.data(), data.size());
201 ASSERT_EQ(1u, connection_->output_list()->size());
202 std::list<DataFrame*>::const_iterator i = connection_->output_list()->begin();
203 DataFrame* df = *i++;
204 ASSERT_EQ(data, StringPiece(df->data, df->size));
205 ASSERT_EQ(connection_->output_list()->end(), i);
208 TEST_F(FlipHttpSMTest, Reset) {
209 std::string data = "HTTP/1.1 200 OK\r\n\r\n";
210 testing::MockFunction<void(int)> checkpoint; // NOLINT
212 InSequence s;
213 EXPECT_CALL(*mock_another_interface_, SendSynReply(_, _));
214 EXPECT_CALL(checkpoint, Call(0));
217 ASSERT_EQ(BalsaFrameEnums::READING_HEADER_AND_FIRSTLINE,
218 interface_->spdy_framer()->ParseState());
220 interface_->ProcessReadInput(data.data(), data.size());
221 checkpoint.Call(0);
222 ASSERT_FALSE(interface_->MessageFullyRead());
223 ASSERT_EQ(BalsaFrameEnums::READING_UNTIL_CLOSE,
224 interface_->spdy_framer()->ParseState());
226 interface_->Reset();
227 ASSERT_EQ(BalsaFrameEnums::READING_HEADER_AND_FIRSTLINE,
228 interface_->spdy_framer()->ParseState());
231 TEST_F(FlipHttpSMTest, ResetForNewConnection) {
232 std::string data = "HTTP/1.1 200 OK\r\n\r\n";
233 testing::MockFunction<void(int)> checkpoint; // NOLINT
235 InSequence s;
236 EXPECT_CALL(*mock_another_interface_, SendSynReply(_, _));
237 EXPECT_CALL(checkpoint, Call(0));
238 EXPECT_CALL(*mock_another_interface_, SendEOF(_));
239 EXPECT_CALL(*mock_another_interface_, ResetForNewInterface(_));
242 ASSERT_EQ(BalsaFrameEnums::READING_HEADER_AND_FIRSTLINE,
243 interface_->spdy_framer()->ParseState());
245 interface_->ProcessReadInput(data.data(), data.size());
246 checkpoint.Call(0);
247 ASSERT_FALSE(interface_->MessageFullyRead());
248 ASSERT_EQ(BalsaFrameEnums::READING_UNTIL_CLOSE,
249 interface_->spdy_framer()->ParseState());
251 interface_->ResetForNewConnection();
252 ASSERT_EQ(BalsaFrameEnums::READING_HEADER_AND_FIRSTLINE,
253 interface_->spdy_framer()->ParseState());
256 TEST_F(FlipHttpSMTest, NewStream) {
257 uint32 stream_id = 4;
259 BalsaHeaders headers;
260 std::string filename = "foobar";
261 memory_cache_->InsertFile(&headers, filename, "");
264 interface_->NewStream(stream_id, 1, "foobar");
265 ASSERT_TRUE(HasStream(stream_id));
268 TEST_F(FlipHttpSMTest, NewStreamError) {
269 std::string syn_reply =
270 "HTTP/1.1 404 Not Found\r\n"
271 "transfer-encoding: chunked\r\n\r\n";
272 std::string body = "e\r\npage not found\r\n";
273 uint32 stream_id = 4;
275 ASSERT_FALSE(HasStream(stream_id));
276 interface_->NewStream(stream_id, 1, "foobar");
278 ASSERT_EQ(3u, connection_->output_list()->size());
279 std::list<DataFrame*>::const_iterator i = connection_->output_list()->begin();
280 DataFrame* df = *i++;
281 ASSERT_EQ(syn_reply, StringPiece(df->data, df->size));
282 df = *i++;
283 ASSERT_EQ(body, StringPiece(df->data, df->size));
284 df = *i++;
285 ASSERT_EQ("0\r\n\r\n", StringPiece(df->data, df->size));
286 ASSERT_FALSE(HasStream(stream_id));
289 TEST_F(FlipHttpSMTest, SendErrorNotFound) {
290 std::string syn_reply =
291 "HTTP/1.1 404 Not Found\r\n"
292 "transfer-encoding: chunked\r\n\r\n";
293 std::string body = "e\r\npage not found\r\n";
294 uint32 stream_id = 13;
295 MemCacheIter mci;
296 mci.stream_id = stream_id;
299 BalsaHeaders headers;
300 std::string filename = "foobar";
301 memory_cache_->InsertFile(&headers, filename, "");
302 mci.file_data = memory_cache_->GetFileData(filename);
305 interface_->AddToOutputOrder(mci);
306 ASSERT_TRUE(HasStream(stream_id));
307 interface_->SendErrorNotFound(stream_id);
309 ASSERT_EQ(3u, connection_->output_list()->size());
310 std::list<DataFrame*>::const_iterator i = connection_->output_list()->begin();
311 DataFrame* df = *i++;
312 ASSERT_EQ(syn_reply, StringPiece(df->data, df->size));
313 df = *i++;
314 ASSERT_EQ(body, StringPiece(df->data, df->size));
315 df = *i++;
316 ASSERT_EQ("0\r\n\r\n", StringPiece(df->data, df->size));
317 ASSERT_FALSE(HasStream(stream_id));
320 TEST_F(FlipHttpSMTest, SendSynStream) {
321 std::string expected =
322 "GET / HTTP/1.0\r\n"
323 "key1: value1\r\n\r\n";
324 BalsaHeaders headers;
325 headers.SetResponseFirstlineFromStringPieces("GET", "/path", "HTTP/1.0");
326 headers.AppendHeader("key1", "value1");
327 interface_->SendSynStream(18, headers);
329 // TODO(yhirano): Is this behavior correct?
330 ASSERT_EQ(0u, connection_->output_list()->size());
333 TEST_F(FlipHttpSMTest, SendSynReply) {
334 std::string expected =
335 "HTTP/1.1 200 OK\r\n"
336 "key1: value1\r\n\r\n";
337 BalsaHeaders headers;
338 headers.SetResponseFirstlineFromStringPieces("HTTP/1.1", "200", "OK");
339 headers.AppendHeader("key1", "value1");
340 interface_->SendSynReply(18, headers);
342 ASSERT_EQ(1u, connection_->output_list()->size());
343 DataFrame* df = connection_->output_list()->front();
344 ASSERT_EQ(expected, StringPiece(df->data, df->size));
347 TEST_F(FlipHttpSMTest, SendDataFrame) {
348 std::string data = "foo bar baz";
349 interface_->SendDataFrame(12, data.data(), data.size(), 0, false);
351 ASSERT_EQ(1u, connection_->output_list()->size());
352 DataFrame* df = connection_->output_list()->front();
353 ASSERT_EQ("b\r\nfoo bar baz\r\n", StringPiece(df->data, df->size));
356 TEST_F(FlipHttpSMProxyTest, ProcessBodyData) {
357 BalsaVisitorInterface* visitor = interface_.get();
358 std::string data = "hello, world";
360 InSequence s;
361 EXPECT_CALL(*mock_another_interface_,
362 SendDataFrame(0, data.data(), data.size(), 0, false));
364 visitor->ProcessBodyData(data.data(), data.size());
367 // --
368 // FlipHttpSMProxyTest
370 TEST_F(FlipHttpSMProxyTest, ProcessHeaders) {
371 BalsaVisitorInterface* visitor = interface_.get();
373 InSequence s;
374 EXPECT_CALL(*mock_another_interface_, SendSynReply(0, _));
376 BalsaHeaders headers;
377 visitor->ProcessHeaders(headers);
380 TEST_F(FlipHttpSMProxyTest, MessageDone) {
381 BalsaVisitorInterface* visitor = interface_.get();
383 InSequence s;
384 EXPECT_CALL(*mock_another_interface_, SendEOF(0));
386 visitor->MessageDone();
389 TEST_F(FlipHttpSMProxyTest, Cleanup) {
390 EXPECT_CALL(*connection_, Cleanup()).Times(0);
391 interface_->Cleanup();
394 TEST_F(FlipHttpSMProxyTest, SendEOF) {
396 InSequence s;
397 EXPECT_CALL(*mock_another_interface_, ResetForNewInterface(_));
399 interface_->SendEOF(32);
400 ASSERT_EQ(1u, connection_->output_list()->size());
401 DataFrame* df = connection_->output_list()->front();
402 ASSERT_EQ("0\r\n\r\n", StringPiece(df->data, df->size));
405 // --
406 // FlipHttpSMHttpTest
408 TEST_F(FlipHttpSMHttpTest, ProcessHeaders) {
409 BalsaVisitorInterface* visitor = interface_.get();
411 BalsaHeaders headers;
412 std::string filename = "GET_/path/file";
413 memory_cache_->InsertFile(&headers, filename, "");
416 BalsaHeaders headers;
417 headers.AppendHeader("Host", "example.com");
418 headers.SetRequestFirstlineFromStringPieces("GET", "/path/file", "HTTP/1.0");
419 uint32 stream_id = 133;
420 interface_->SetStreamID(stream_id);
421 ASSERT_FALSE(HasStream(stream_id));
422 visitor->ProcessHeaders(headers);
423 ASSERT_TRUE(HasStream(stream_id));
426 TEST_F(FlipHttpSMHttpTest, MessageDone) {
427 BalsaVisitorInterface* visitor = interface_.get();
429 InSequence s;
430 EXPECT_CALL(*mock_another_interface_, SendEOF(0)).Times(0);
432 visitor->MessageDone();
435 TEST_F(FlipHttpSMHttpTest, Cleanup) {
436 EXPECT_CALL(*connection_, Cleanup()).Times(0);
437 interface_->Cleanup();
440 TEST_F(FlipHttpSMHttpTest, SendEOF) {
442 InSequence s;
443 EXPECT_CALL(*mock_another_interface_, ResetForNewInterface(_)).Times(0);
445 interface_->SendEOF(32);
446 ASSERT_EQ(1u, connection_->output_list()->size());
447 DataFrame* df = connection_->output_list()->front();
448 ASSERT_EQ("0\r\n\r\n", StringPiece(df->data, df->size));
451 // --
452 // FlipHttpSMSpdyTest
454 TEST_F(FlipHttpSMSpdyTest, ProcessHeaders) {
455 BalsaVisitorInterface* visitor = interface_.get();
457 InSequence s;
458 EXPECT_CALL(*mock_another_interface_, SendSynReply(0, _));
460 BalsaHeaders headers;
461 visitor->ProcessHeaders(headers);
464 TEST_F(FlipHttpSMSpdyTest, MessageDone) {
465 BalsaVisitorInterface* visitor = interface_.get();
467 InSequence s;
468 EXPECT_CALL(*mock_another_interface_, SendEOF(0)).Times(0);
470 visitor->MessageDone();
473 TEST_F(FlipHttpSMSpdyTest, Cleanup) {
474 EXPECT_CALL(*connection_, Cleanup()).Times(0);
475 interface_->Cleanup();
478 TEST_F(FlipHttpSMSpdyTest, SendEOF) {
480 InSequence s;
481 EXPECT_CALL(*mock_another_interface_, ResetForNewInterface(_)).Times(0);
483 interface_->SendEOF(32);
484 ASSERT_EQ(1u, connection_->output_list()->size());
485 DataFrame* df = connection_->output_list()->front();
486 ASSERT_EQ("0\r\n\r\n", StringPiece(df->data, df->size));
489 } // namespace
491 } // namespace net