- add sources.
[platform/framework/web/crosswalk.git] / src / net / quic / quic_end_to_end_unittest.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 "base/basictypes.h"
6 #include "base/compiler_specific.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/stl_util.h"
9 #include "base/strings/string_number_conversions.h"
10 #include "net/base/test_completion_callback.h"
11 #include "net/base/upload_bytes_element_reader.h"
12 #include "net/base/upload_data_stream.h"
13 #include "net/cert/mock_cert_verifier.h"
14 #include "net/dns/mapped_host_resolver.h"
15 #include "net/dns/mock_host_resolver.h"
16 #include "net/http/http_auth_handler_factory.h"
17 #include "net/http/http_network_session.h"
18 #include "net/http/http_network_transaction.h"
19 #include "net/http/http_server_properties_impl.h"
20 #include "net/http/http_transaction_unittest.h"
21 #include "net/http/transport_security_state.h"
22 #include "net/proxy/proxy_service.h"
23 #include "net/ssl/ssl_config_service_defaults.h"
24 #include "net/tools/quic/quic_in_memory_cache.h"
25 #include "net/tools/quic/test_tools/quic_in_memory_cache_peer.h"
26 #include "net/tools/quic/test_tools/server_thread.h"
27 #include "testing/gtest/include/gtest/gtest.h"
28 #include "testing/platform_test.h"
29
30 extern int FLAGS_fake_packet_loss_percentage;
31
32 using base::StringPiece;
33 using net::tools::QuicInMemoryCache;
34 using net::tools::test::QuicInMemoryCachePeer;
35 using net::tools::test::ServerThread;
36
37 namespace net {
38 namespace test {
39
40 namespace {
41
42 const char kResponseBody[] = "some arbitrary response body";
43
44 // Factory for creating HttpTransactions, used by TestTransactionConsumer.
45 class TestTransactionFactory : public HttpTransactionFactory {
46  public:
47   TestTransactionFactory(const HttpNetworkSession::Params& params)
48       : session_(new HttpNetworkSession(params)) {}
49
50   virtual ~TestTransactionFactory() {
51     FLAGS_fake_packet_loss_percentage = 0;
52   }
53
54   // HttpTransactionFactory methods
55   virtual int CreateTransaction(RequestPriority priority,
56                                 scoped_ptr<HttpTransaction>* trans,
57                                 HttpTransactionDelegate* delegate) OVERRIDE {
58     EXPECT_TRUE(delegate == NULL);
59     trans->reset(new HttpNetworkTransaction(priority, session_));
60     return OK;
61   }
62
63   virtual HttpCache* GetCache() OVERRIDE {
64     return NULL;
65   }
66
67   virtual HttpNetworkSession* GetSession() OVERRIDE {
68     return session_;
69   };
70
71  private:
72   scoped_refptr<HttpNetworkSession> session_;
73 };
74
75 }  // namespace
76
77 class QuicEndToEndTest : public PlatformTest {
78  protected:
79   QuicEndToEndTest()
80       : host_resolver_impl_(CreateResolverImpl()),
81         host_resolver_(host_resolver_impl_.PassAs<HostResolver>()),
82         ssl_config_service_(new SSLConfigServiceDefaults),
83         proxy_service_(ProxyService::CreateDirect()),
84         auth_handler_factory_(
85             HttpAuthHandlerFactory::CreateDefault(&host_resolver_)),
86         strike_register_no_startup_period_(false) {
87     request_.method = "GET";
88     request_.url = GURL("http://www.google.com/");
89     request_.load_flags = 0;
90
91     params_.enable_quic = true;
92     params_.quic_clock = NULL;
93     params_.quic_random = NULL;
94     params_.host_resolver = &host_resolver_;
95     params_.cert_verifier = &cert_verifier_;
96     params_.transport_security_state = &transport_security_state_;
97     params_.proxy_service = proxy_service_.get();
98     params_.ssl_config_service = ssl_config_service_.get();
99     params_.http_auth_handler_factory = auth_handler_factory_.get();
100     params_.http_server_properties = http_server_properties.GetWeakPtr();
101   }
102
103   // Creates a mock host resolver in which www.google.com
104   // resolves to localhost.
105   static MockHostResolver* CreateResolverImpl() {
106     MockHostResolver* resolver = new MockHostResolver();
107     resolver->rules()->AddRule("www.google.com", "127.0.0.1");
108     return resolver;
109   }
110
111   virtual void SetUp() {
112     QuicInMemoryCachePeer::ResetForTests();
113     StartServer();
114
115     // Use a mapped host resolver so that request for www.google.com (port 80)
116     // reach the server running on localhost.
117     std::string map_rule = "MAP www.google.com www.google.com:" +
118         base::IntToString(server_thread_->GetPort());
119     EXPECT_TRUE(host_resolver_.AddRuleFromString(map_rule));
120
121     // To simplify the test, and avoid the race with the HTTP request, we force
122     // QUIC for these requests.
123     params_.origin_to_force_quic_on =
124         HostPortPair::FromString("www.google.com:80");
125
126     transaction_factory_.reset(new TestTransactionFactory(params_));
127   }
128
129   virtual void TearDown() {
130     StopServer();
131     QuicInMemoryCachePeer::ResetForTests();
132   }
133
134   // Starts the QUIC server listening on a random port.
135   void StartServer() {
136     net::IPAddressNumber ip;
137     CHECK(net::ParseIPLiteralToNumber("127.0.0.1", &ip));
138     server_address_ = IPEndPoint(ip, 0);
139     server_config_.SetDefaults();
140     server_thread_.reset(new ServerThread(server_address_, server_config_,
141                                           QuicSupportedVersions(),
142                                           strike_register_no_startup_period_));
143     server_thread_->Start();
144     server_thread_->listening()->Wait();
145     server_address_ = IPEndPoint(server_address_.address(),
146                                  server_thread_->GetPort());
147     server_started_ = true;
148   }
149
150   // Stops the QUIC server.
151   void StopServer() {
152     if (!server_started_) {
153       return;
154     }
155     if (server_thread_.get()) {
156       server_thread_->quit()->Signal();
157       server_thread_->Join();
158     }
159   }
160
161   // Adds an entry to the cache used by the QUIC server to serve
162   // responses.
163   void AddToCache(const StringPiece& method,
164                   const StringPiece& path,
165                   const StringPiece& version,
166                   const StringPiece& response_code,
167                   const StringPiece& response_detail,
168                   const StringPiece& body) {
169     QuicInMemoryCache::GetInstance()->AddSimpleResponse(
170         method, path, version, response_code, response_detail, body);
171   }
172
173   // Populates |request_body_| with |length_| ASCII bytes.
174   void GenerateBody(size_t length) {
175     request_body_.clear();
176     request_body_.reserve(length);
177     for (size_t i = 0; i < length; ++i) {
178       request_body_.append(1, static_cast<char>(32 + i % (126 - 32)));
179     }
180   }
181
182   // Initializes |request_| for a post of |length| bytes.
183   void InitializePostRequest(size_t length) {
184     GenerateBody(length);
185     ScopedVector<UploadElementReader> element_readers;
186     element_readers.push_back(
187         new UploadBytesElementReader(request_body_.data(),
188                                      request_body_.length()));
189     upload_data_stream_.reset(new UploadDataStream(element_readers.Pass(), 0));
190     request_.method = "POST";
191     request_.url = GURL("http://www.google.com/");
192     request_.upload_data_stream = upload_data_stream_.get();
193     ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback()));
194   }
195
196   // Checks that |consumer| completed and received |status_line| and |body|.
197   void CheckResponse(const TestTransactionConsumer& consumer,
198                      const std::string& status_line,
199                      const std::string& body) {
200     ASSERT_TRUE(consumer.is_done());
201     EXPECT_EQ(OK, consumer.error());
202     EXPECT_EQ(status_line,
203               consumer.response_info()->headers->GetStatusLine());
204     EXPECT_EQ(body, consumer.content());
205   }
206
207   scoped_ptr<MockHostResolver> host_resolver_impl_;
208   MappedHostResolver host_resolver_;
209   MockCertVerifier cert_verifier_;
210   TransportSecurityState transport_security_state_;
211   scoped_refptr<SSLConfigServiceDefaults> ssl_config_service_;
212   scoped_ptr<ProxyService> proxy_service_;
213   scoped_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
214   HttpServerPropertiesImpl http_server_properties;
215   HttpNetworkSession::Params params_;
216   scoped_ptr<TestTransactionFactory> transaction_factory_;
217   HttpRequestInfo request_;
218   std::string request_body_;
219   scoped_ptr<UploadDataStream> upload_data_stream_;
220   scoped_ptr<ServerThread> server_thread_;
221   IPEndPoint server_address_;
222   std::string server_hostname_;
223   QuicConfig server_config_;
224   bool server_started_;
225   bool strike_register_no_startup_period_;
226 };
227
228 TEST_F(QuicEndToEndTest, LargeGetWithNoPacketLoss) {
229   std::string response(10 * 1024, 'x');
230
231   AddToCache("GET", request_.url.spec(),
232              "HTTP/1.1", "200", "OK",
233              response);
234
235   TestTransactionConsumer consumer(DEFAULT_PRIORITY,
236                                    transaction_factory_.get());
237   consumer.Start(&request_, BoundNetLog());
238
239   // Will terminate when the last consumer completes.
240   base::MessageLoop::current()->Run();
241
242   CheckResponse(consumer, "HTTP/1.1 200 OK", response);
243 }
244
245 // http://crbug.com/307284
246 TEST_F(QuicEndToEndTest, DISABLED_LargePostWithNoPacketLoss) {
247   InitializePostRequest(10 * 1024 * 1024);
248
249   AddToCache("POST", request_.url.spec(),
250              "HTTP/1.1", "200", "OK",
251              kResponseBody);
252
253   TestTransactionConsumer consumer(DEFAULT_PRIORITY,
254                                    transaction_factory_.get());
255   consumer.Start(&request_, BoundNetLog());
256
257   // Will terminate when the last consumer completes.
258   base::MessageLoop::current()->Run();
259
260   CheckResponse(consumer, "HTTP/1.1 200 OK", kResponseBody);
261 }
262
263 TEST_F(QuicEndToEndTest, LargePostWithPacketLoss) {
264   // FLAGS_fake_packet_loss_percentage = 30;
265   InitializePostRequest(1024 * 1024);
266
267   const char kResponseBody[] = "some really big response body";
268   AddToCache("POST", request_.url.spec(),
269              "HTTP/1.1", "200", "OK",
270              kResponseBody);
271
272   TestTransactionConsumer consumer(DEFAULT_PRIORITY,
273                                    transaction_factory_.get());
274   consumer.Start(&request_, BoundNetLog());
275
276   // Will terminate when the last consumer completes.
277   base::MessageLoop::current()->Run();
278
279   CheckResponse(consumer, "HTTP/1.1 200 OK", kResponseBody);
280 }
281
282 TEST_F(QuicEndToEndTest, UberTest) {
283   // FLAGS_fake_packet_loss_percentage = 30;
284
285   const char kResponseBody[] = "some really big response body";
286   AddToCache("GET", request_.url.spec(),
287              "HTTP/1.1", "200", "OK",
288              kResponseBody);
289
290   std::vector<TestTransactionConsumer*> consumers;
291   size_t num_requests = 100;
292   for (size_t i = 0; i < num_requests; ++i) {
293       TestTransactionConsumer* consumer =
294           new TestTransactionConsumer(DEFAULT_PRIORITY,
295                                       transaction_factory_.get());
296       consumers.push_back(consumer);
297       consumer->Start(&request_, BoundNetLog());
298   }
299
300   // Will terminate when the last consumer completes.
301   base::MessageLoop::current()->Run();
302
303   for (size_t i = 0; i < num_requests; ++i) {
304     CheckResponse(*consumers[i], "HTTP/1.1 200 OK", kResponseBody);
305   }
306   STLDeleteElements(&consumers);
307 }
308
309 }  // namespace test
310 }  // namespace net