Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / net / tools / flip_server / http_interface_test.cc
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.
4
5 #include "net/tools/flip_server/http_interface.h"
6
7 #include <list>
8
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"
20
21 namespace net {
22
23 using ::base::StringPiece;
24 using ::testing::_;
25 using ::testing::InSequence;
26
27 namespace {
28
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) {}
41
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));
52 };
53
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",
69                                      1,
70                                      0,
71                                      true,
72                                      1,
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"));
82
83     interface_.reset(new HttpSM(connection_.get(),
84                                 mock_another_interface_.get(),
85                                 memory_cache_.get(),
86                                 acceptor_.get()));
87   }
88
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;
94     }
95     STLDeleteElements(connection_->output_list());
96   }
97
98   bool HasStream(uint32 stream_id) {
99     return interface_->output_ordering().ExistsInPriorityMaps(stream_id);
100   }
101
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_;
109 };
110
111 class FlipHttpSMProxyTest : public FlipHttpSMTest {
112  public:
113   FlipHttpSMProxyTest() : FlipHttpSMTest(FLIP_HANDLER_PROXY) {}
114   ~FlipHttpSMProxyTest() override {}
115 };
116
117 class FlipHttpSMHttpTest : public FlipHttpSMTest {
118  public:
119   FlipHttpSMHttpTest() : FlipHttpSMTest(FLIP_HANDLER_HTTP_SERVER) {}
120   ~FlipHttpSMHttpTest() override {}
121 };
122
123 class FlipHttpSMSpdyTest : public FlipHttpSMTest {
124  public:
125   FlipHttpSMSpdyTest() : FlipHttpSMTest(FLIP_HANDLER_SPDY_SERVER) {}
126   ~FlipHttpSMSpdyTest() override {}
127 };
128
129 TEST_F(FlipHttpSMTest, Construct) {
130   ASSERT_FALSE(interface_->spdy_framer()->is_request());
131 }
132
133 TEST_F(FlipHttpSMTest, AddToOutputOrder) {
134   uint32 stream_id = 13;
135   MemCacheIter mci;
136   mci.stream_id = stream_id;
137
138   {
139     BalsaHeaders headers;
140     std::string filename = "foobar";
141     memory_cache_->InsertFile(&headers, filename, "");
142     mci.file_data = memory_cache_->GetFileData(filename);
143   }
144
145   interface_->AddToOutputOrder(mci);
146   ASSERT_TRUE(HasStream(stream_id));
147 }
148
149 TEST_F(FlipHttpSMTest, InitSMInterface) {
150   scoped_ptr<MockSMInterface> mock(new MockSMInterface);
151   {
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(_));
157   }
158
159   interface_->ResetForNewConnection();
160   interface_->InitSMInterface(mock.get(), 0);
161   interface_->ResetForNewConnection();
162 }
163
164 TEST_F(FlipHttpSMTest, InitSMConnection) {
165   EXPECT_CALL(*connection_, InitSMConnection(_, _, _, _, _, _, _, _));
166
167   interface_->InitSMConnection(NULL, NULL, NULL, 0, "", "", "", false);
168 }
169
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
176   {
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(_));
182   }
183
184   ASSERT_EQ(BalsaFrameEnums::READING_HEADER_AND_FIRSTLINE,
185             interface_->spdy_framer()->ParseState());
186
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());
195 }
196
197 TEST_F(FlipHttpSMTest, ProcessWriteInput) {
198   std::string data = "hello, world";
199   interface_->ProcessWriteInput(data.data(), data.size());
200
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);
206 }
207
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
211   {
212     InSequence s;
213     EXPECT_CALL(*mock_another_interface_, SendSynReply(_, _));
214     EXPECT_CALL(checkpoint, Call(0));
215   }
216
217   ASSERT_EQ(BalsaFrameEnums::READING_HEADER_AND_FIRSTLINE,
218             interface_->spdy_framer()->ParseState());
219
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());
225
226   interface_->Reset();
227   ASSERT_EQ(BalsaFrameEnums::READING_HEADER_AND_FIRSTLINE,
228             interface_->spdy_framer()->ParseState());
229 }
230
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
234   {
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(_));
240   }
241
242   ASSERT_EQ(BalsaFrameEnums::READING_HEADER_AND_FIRSTLINE,
243             interface_->spdy_framer()->ParseState());
244
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());
250
251   interface_->ResetForNewConnection();
252   ASSERT_EQ(BalsaFrameEnums::READING_HEADER_AND_FIRSTLINE,
253             interface_->spdy_framer()->ParseState());
254 }
255
256 TEST_F(FlipHttpSMTest, NewStream) {
257   uint32 stream_id = 4;
258   {
259     BalsaHeaders headers;
260     std::string filename = "foobar";
261     memory_cache_->InsertFile(&headers, filename, "");
262   }
263
264   interface_->NewStream(stream_id, 1, "foobar");
265   ASSERT_TRUE(HasStream(stream_id));
266 }
267
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;
274
275   ASSERT_FALSE(HasStream(stream_id));
276   interface_->NewStream(stream_id, 1, "foobar");
277
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));
287 }
288
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;
297
298   {
299     BalsaHeaders headers;
300     std::string filename = "foobar";
301     memory_cache_->InsertFile(&headers, filename, "");
302     mci.file_data = memory_cache_->GetFileData(filename);
303   }
304
305   interface_->AddToOutputOrder(mci);
306   ASSERT_TRUE(HasStream(stream_id));
307   interface_->SendErrorNotFound(stream_id);
308
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));
318 }
319
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);
328
329   // TODO(yhirano): Is this behavior correct?
330   ASSERT_EQ(0u, connection_->output_list()->size());
331 }
332
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);
341
342   ASSERT_EQ(1u, connection_->output_list()->size());
343   DataFrame* df = connection_->output_list()->front();
344   ASSERT_EQ(expected, StringPiece(df->data, df->size));
345 }
346
347 TEST_F(FlipHttpSMTest, SendDataFrame) {
348   std::string data = "foo bar baz";
349   interface_->SendDataFrame(12, data.data(), data.size(), 0, false);
350
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));
354 }
355
356 TEST_F(FlipHttpSMProxyTest, ProcessBodyData) {
357   BalsaVisitorInterface* visitor = interface_.get();
358   std::string data = "hello, world";
359   {
360     InSequence s;
361     EXPECT_CALL(*mock_another_interface_,
362                 SendDataFrame(0, data.data(), data.size(), 0, false));
363   }
364   visitor->ProcessBodyData(data.data(), data.size());
365 }
366
367 // --
368 // FlipHttpSMProxyTest
369
370 TEST_F(FlipHttpSMProxyTest, ProcessHeaders) {
371   BalsaVisitorInterface* visitor = interface_.get();
372   {
373     InSequence s;
374     EXPECT_CALL(*mock_another_interface_, SendSynReply(0, _));
375   }
376   BalsaHeaders headers;
377   visitor->ProcessHeaders(headers);
378 }
379
380 TEST_F(FlipHttpSMProxyTest, MessageDone) {
381   BalsaVisitorInterface* visitor = interface_.get();
382   {
383     InSequence s;
384     EXPECT_CALL(*mock_another_interface_, SendEOF(0));
385   }
386   visitor->MessageDone();
387 }
388
389 TEST_F(FlipHttpSMProxyTest, Cleanup) {
390   EXPECT_CALL(*connection_, Cleanup()).Times(0);
391   interface_->Cleanup();
392 }
393
394 TEST_F(FlipHttpSMProxyTest, SendEOF) {
395   {
396     InSequence s;
397     EXPECT_CALL(*mock_another_interface_, ResetForNewInterface(_));
398   }
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));
403 }
404
405 // --
406 // FlipHttpSMHttpTest
407
408 TEST_F(FlipHttpSMHttpTest, ProcessHeaders) {
409   BalsaVisitorInterface* visitor = interface_.get();
410   {
411     BalsaHeaders headers;
412     std::string filename = "GET_/path/file";
413     memory_cache_->InsertFile(&headers, filename, "");
414   }
415
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));
424 }
425
426 TEST_F(FlipHttpSMHttpTest, MessageDone) {
427   BalsaVisitorInterface* visitor = interface_.get();
428   {
429     InSequence s;
430     EXPECT_CALL(*mock_another_interface_, SendEOF(0)).Times(0);
431   }
432   visitor->MessageDone();
433 }
434
435 TEST_F(FlipHttpSMHttpTest, Cleanup) {
436   EXPECT_CALL(*connection_, Cleanup()).Times(0);
437   interface_->Cleanup();
438 }
439
440 TEST_F(FlipHttpSMHttpTest, SendEOF) {
441   {
442     InSequence s;
443     EXPECT_CALL(*mock_another_interface_, ResetForNewInterface(_)).Times(0);
444   }
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));
449 }
450
451 // --
452 // FlipHttpSMSpdyTest
453
454 TEST_F(FlipHttpSMSpdyTest, ProcessHeaders) {
455   BalsaVisitorInterface* visitor = interface_.get();
456   {
457     InSequence s;
458     EXPECT_CALL(*mock_another_interface_, SendSynReply(0, _));
459   }
460   BalsaHeaders headers;
461   visitor->ProcessHeaders(headers);
462 }
463
464 TEST_F(FlipHttpSMSpdyTest, MessageDone) {
465   BalsaVisitorInterface* visitor = interface_.get();
466   {
467     InSequence s;
468     EXPECT_CALL(*mock_another_interface_, SendEOF(0)).Times(0);
469   }
470   visitor->MessageDone();
471 }
472
473 TEST_F(FlipHttpSMSpdyTest, Cleanup) {
474   EXPECT_CALL(*connection_, Cleanup()).Times(0);
475   interface_->Cleanup();
476 }
477
478 TEST_F(FlipHttpSMSpdyTest, SendEOF) {
479   {
480     InSequence s;
481     EXPECT_CALL(*mock_another_interface_, ResetForNewInterface(_)).Times(0);
482   }
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));
487 }
488
489 }  // namespace
490
491 }  // namespace net