- add sources.
[platform/framework/web/crosswalk.git] / src / net / tools / quic / quic_reliable_server_stream_test.cc
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.
4
5 #include "net/tools/quic/quic_reliable_server_stream.h"
6
7 #include "base/strings/string_number_conversions.h"
8 #include "net/quic/quic_spdy_compressor.h"
9 #include "net/quic/quic_utils.h"
10 #include "net/quic/test_tools/quic_test_utils.h"
11 #include "net/tools/epoll_server/epoll_server.h"
12 #include "net/tools/quic/quic_in_memory_cache.h"
13 #include "net/tools/quic/quic_spdy_server_stream.h"
14 #include "net/tools/quic/spdy_utils.h"
15 #include "net/tools/quic/test_tools/quic_in_memory_cache_peer.h"
16 #include "net/tools/quic/test_tools/quic_test_utils.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19
20 using base::StringPiece;
21 using net::tools::test::MockConnection;
22 using net::test::MockSession;
23 using std::string;
24 using testing::_;
25 using testing::AnyNumber;
26 using testing::Invoke;
27 using testing::InvokeArgument;
28 using testing::InSequence;
29 using testing::Return;
30 using testing::StrEq;
31 using testing::StrictMock;
32 using testing::WithArgs;
33
34 namespace net {
35 namespace tools {
36 namespace test {
37
38 class QuicReliableServerStreamPeer {
39  public:
40   static BalsaHeaders* GetMutableHeaders(
41       QuicReliableServerStream* stream) {
42     return &(stream->headers_);
43   }
44 };
45
46 namespace {
47
48 class QuicReliableServerStreamTest : public ::testing::Test {
49  public:
50   QuicReliableServerStreamTest()
51       : session_(new MockConnection(1, IPEndPoint(), 0, &eps_, true), true),
52         body_("hello world") {
53     BalsaHeaders request_headers;
54     request_headers.SetRequestFirstlineFromStringPieces(
55         "POST", "https://www.google.com/", "HTTP/1.1");
56     request_headers.ReplaceOrAppendHeader("content-length", "11");
57
58     headers_string_ = SpdyUtils::SerializeRequestHeaders(request_headers);
59     stream_.reset(new QuicSpdyServerStream(3, &session_));
60   }
61
62   QuicConsumedData ValidateHeaders(const struct iovec* iov) {
63     StringPiece headers =
64         StringPiece(static_cast<const char*>(iov[0].iov_base), iov[0].iov_len);
65     headers_string_ = SpdyUtils::SerializeResponseHeaders(
66         response_headers_);
67     QuicSpdyDecompressor decompressor;
68     TestDecompressorVisitor visitor;
69
70     // First the header id, then the compressed data.
71     EXPECT_EQ(1, headers[0]);
72     EXPECT_EQ(0, headers[1]);
73     EXPECT_EQ(0, headers[2]);
74     EXPECT_EQ(0, headers[3]);
75     EXPECT_EQ(static_cast<size_t>(headers.length() - 4),
76               decompressor.DecompressData(headers.substr(4), &visitor));
77
78     EXPECT_EQ(headers_string_, visitor.data());
79
80     return QuicConsumedData(headers.size(), false);
81   }
82
83   static void SetUpTestCase() {
84     QuicInMemoryCachePeer::ResetForTests();
85   }
86
87   virtual void SetUp() {
88     QuicInMemoryCache* cache = QuicInMemoryCache::GetInstance();
89
90     BalsaHeaders request_headers, response_headers;
91     StringPiece body("Yum");
92     request_headers.SetRequestFirstlineFromStringPieces(
93         "GET",
94         "https://www.google.com/foo",
95         "HTTP/1.1");
96     response_headers.SetRequestFirstlineFromStringPieces("HTTP/1.1",
97                                                          "200",
98                                                          "OK");
99     response_headers.AppendHeader("content-length",
100                                   base::IntToString(body.length()));
101
102     // Check if response already exists and matches.
103     const QuicInMemoryCache::Response* cached_response =
104         cache->GetResponse(request_headers);
105     if (cached_response != NULL) {
106       string cached_response_headers_str, response_headers_str;
107       cached_response->headers().DumpToString(&cached_response_headers_str);
108       response_headers.DumpToString(&response_headers_str);
109       CHECK_EQ(cached_response_headers_str, response_headers_str);
110       CHECK_EQ(cached_response->body(), body);
111       return;
112     }
113
114     cache->AddResponse(request_headers, response_headers, body);
115   }
116
117   BalsaHeaders response_headers_;
118   EpollServer eps_;
119   StrictMock<MockSession> session_;
120   scoped_ptr<QuicReliableServerStream> stream_;
121   string headers_string_;
122   string body_;
123 };
124
125 QuicConsumedData ConsumeAllData(QuicStreamId id,
126                                 const struct iovec* iov,
127                                 int iov_count,
128                                 QuicStreamOffset offset,
129                                 bool fin) {
130   ssize_t consumed_length = 0;
131   for (int i = 0; i < iov_count; ++i) {
132     consumed_length += iov[i].iov_len;
133   }
134   return QuicConsumedData(consumed_length, fin);
135 }
136
137 TEST_F(QuicReliableServerStreamTest, TestFraming) {
138   EXPECT_CALL(session_, WritevData(_, _, _, _, _)).Times(AnyNumber()).
139       WillRepeatedly(Invoke(ConsumeAllData));
140
141   EXPECT_EQ(headers_string_.size(), stream_->ProcessData(
142       headers_string_.c_str(), headers_string_.size()));
143   EXPECT_EQ(body_.size(), stream_->ProcessData(body_.c_str(), body_.size()));
144   EXPECT_EQ(11u, stream_->headers().content_length());
145   EXPECT_EQ("https://www.google.com/", stream_->headers().request_uri());
146   EXPECT_EQ("POST", stream_->headers().request_method());
147   EXPECT_EQ(body_, stream_->body());
148 }
149
150 TEST_F(QuicReliableServerStreamTest, TestFramingOnePacket) {
151   EXPECT_CALL(session_, WritevData(_, _, _, _, _)).Times(AnyNumber()).
152       WillRepeatedly(Invoke(ConsumeAllData));
153
154   string message = headers_string_ + body_;
155
156   EXPECT_EQ(message.size(), stream_->ProcessData(
157       message.c_str(), message.size()));
158   EXPECT_EQ(11u, stream_->headers().content_length());
159   EXPECT_EQ("https://www.google.com/",
160             stream_->headers().request_uri());
161   EXPECT_EQ("POST", stream_->headers().request_method());
162   EXPECT_EQ(body_, stream_->body());
163 }
164
165 TEST_F(QuicReliableServerStreamTest, TestFramingExtraData) {
166   string large_body = "hello world!!!!!!";
167
168   // We'll automatically write out an error (headers + body)
169   EXPECT_CALL(session_, WritevData(_, _, _, _, _)).Times(2).
170       WillRepeatedly(Invoke(ConsumeAllData));
171
172   EXPECT_EQ(headers_string_.size(), stream_->ProcessData(
173       headers_string_.c_str(), headers_string_.size()));
174   // Content length is still 11.  This will register as an error and we won't
175   // accept the bytes.
176   stream_->ProcessData(large_body.c_str(), large_body.size());
177   stream_->TerminateFromPeer(true);
178   EXPECT_EQ(11u, stream_->headers().content_length());
179   EXPECT_EQ("https://www.google.com/", stream_->headers().request_uri());
180   EXPECT_EQ("POST", stream_->headers().request_method());
181 }
182
183 TEST_F(QuicReliableServerStreamTest, TestSendResponse) {
184   BalsaHeaders* request_headers =
185       QuicReliableServerStreamPeer::GetMutableHeaders(stream_.get());
186   request_headers->SetRequestFirstlineFromStringPieces(
187       "GET",
188       "https://www.google.com/foo",
189       "HTTP/1.1");
190
191   response_headers_.SetResponseFirstlineFromStringPieces(
192       "HTTP/1.1", "200", "OK");
193   response_headers_.ReplaceOrAppendHeader("content-length", "3");
194
195   InSequence s;
196   EXPECT_CALL(session_, WritevData(_, _, 1, _, _)).Times(1)
197       .WillOnce(WithArgs<1>(Invoke(
198           this, &QuicReliableServerStreamTest::ValidateHeaders)));
199
200   EXPECT_CALL(session_, WritevData(_, _, 1, _, _)).Times(1).
201       WillOnce(Return(QuicConsumedData(3, true)));
202
203   stream_->SendResponse();
204   EXPECT_TRUE(stream_->read_side_closed());
205   EXPECT_TRUE(stream_->write_side_closed());
206 }
207
208 TEST_F(QuicReliableServerStreamTest, TestSendErrorResponse) {
209   response_headers_.SetResponseFirstlineFromStringPieces(
210       "HTTP/1.1", "500", "Server Error");
211   response_headers_.ReplaceOrAppendHeader("content-length", "3");
212
213   InSequence s;
214   EXPECT_CALL(session_, WritevData(_, _, 1, _, _)).Times(1)
215       .WillOnce(WithArgs<1>(Invoke(
216           this, &QuicReliableServerStreamTest::ValidateHeaders)));
217
218   EXPECT_CALL(session_, WritevData(_, _, 1, _, _)).Times(1).
219       WillOnce(Return(QuicConsumedData(3, true)));
220
221   stream_->SendErrorResponse();
222   EXPECT_TRUE(stream_->read_side_closed());
223   EXPECT_TRUE(stream_->write_side_closed());
224 }
225
226 }  // namespace
227 }  // namespace test
228 }  // namespace tools
229 }  // namespace net