Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(168)

Side by Side Diff: net/tools/quic/end_to_end_test.cc

Issue 1746803003: Add 3 Quic e2e tests of server push. No behavior change. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@115218980
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | net/tools/quic/test_tools/quic_test_client.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <stddef.h> 5 #include <stddef.h>
6 #include <sys/epoll.h> 6 #include <sys/epoll.h>
7 #include <string> 7 #include <string>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
(...skipping 2162 matching lines...) Expand 10 before | Expand all | Expand 10 after
2173 trailers["some-trailing-header"] = "trailing-header-value"; 2173 trailers["some-trailing-header"] = "trailing-header-value";
2174 2174
2175 QuicInMemoryCache::GetInstance()->AddResponse( 2175 QuicInMemoryCache::GetInstance()->AddResponse(
2176 "www.google.com", "/trailer_url", headers, kBody, trailers); 2176 "www.google.com", "/trailer_url", headers, kBody, trailers);
2177 2177
2178 EXPECT_EQ(kBody, client_->SendSynchronousRequest("/trailer_url")); 2178 EXPECT_EQ(kBody, client_->SendSynchronousRequest("/trailer_url"));
2179 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code()); 2179 EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
2180 EXPECT_EQ(trailers, client_->response_trailers()); 2180 EXPECT_EQ(trailers, client_->response_trailers());
2181 } 2181 }
2182 2182
2183 TEST_P(EndToEndTest, ServerPush) { 2183 class EndToEndTestServerPush : public EndToEndTest {
2184 FLAGS_quic_supports_push_promise = true; 2184 protected:
2185 const size_t kNumMaxStreams = 10;
2186
2187 EndToEndTestServerPush() : EndToEndTest() {
2188 FLAGS_quic_supports_push_promise = true;
2189 FLAGS_quic_different_max_num_open_streams = true;
2190 client_config_.SetMaxStreamsPerConnection(kNumMaxStreams, kNumMaxStreams);
2191 }
2192
2193 // Add a request with its response and |num_resources| push resources into
2194 // cache.
2195 // If |resource_size| == 0, response body of push resources use default string
2196 // concatenating with resource url. Otherwise, generate a string of
2197 // |resource_size| as body.
2198 void AddRequestAndResponseWithServerPush(string host,
2199 string path,
2200 string response_body,
2201 string* push_urls,
2202 const size_t num_resources,
2203 const size_t resource_size) {
2204 bool use_large_response = resource_size != 0;
2205 string large_resource;
2206 if (use_large_response) {
2207 // Generate a response common body larger than flow control window for
2208 // push response.
2209 test::GenerateBody(&large_resource, resource_size);
2210 }
2211 list<QuicInMemoryCache::ServerPushInfo> push_resources;
2212 for (size_t i = 0; i < num_resources; ++i) {
2213 string url = push_urls[i];
2214 GURL resource_url(url);
2215 string body = use_large_response
2216 ? large_resource
2217 : "This is server push response body for " + url;
2218 SpdyHeaderBlock response_headers;
2219 response_headers[":version"] = "HTTP/1.1";
2220 response_headers[":status"] = "200";
2221 response_headers["content-length"] = IntToString(body.size());
2222 push_resources.push_back(QuicInMemoryCache::ServerPushInfo(
2223 resource_url, response_headers, kV3LowestPriority, body));
2224 }
2225
2226 QuicInMemoryCache::GetInstance()->AddSimpleResponseWithServerPushResources(
2227 host, path, 200, response_body, push_resources);
2228 }
2229 };
2230
2231 TEST_P(EndToEndTestServerPush, ServerPush) {
2185 ASSERT_TRUE(Initialize()); 2232 ASSERT_TRUE(Initialize());
2186 client_->client()->WaitForCryptoHandshakeConfirmed(); 2233 client_->client()->WaitForCryptoHandshakeConfirmed();
2187 2234
2188 // Set reordering to ensure that body arriving before PUSH_PROMISE is ok. 2235 // Set reordering to ensure that body arriving before PUSH_PROMISE is ok.
2189 SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2)); 2236 SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
2190 SetReorderPercentage(30); 2237 SetReorderPercentage(30);
2191 2238
2192 // Add a response with headers, body, and trailers. 2239 // Add a response with headers, body, and push resources.
2193 const string kBody = "body content"; 2240 const string kBody = "body content";
2194 2241 size_t kNumResources = 4;
2195 list<QuicInMemoryCache::ServerPushInfo> push_resources;
2196
2197 string push_urls[] = { 2242 string push_urls[] = {
2198 "https://google.com/font.woff", "https://google.com/script.js", 2243 "https://google.com/font.woff", "https://google.com/script.js",
2199 "https://fonts.google.com/font.woff", "https://google.com/logo-hires.jpg", 2244 "https://fonts.google.com/font.woff", "https://google.com/logo-hires.jpg",
2200 }; 2245 };
2201 for (const string& url : push_urls) { 2246 AddRequestAndResponseWithServerPush("example.com", "/push_example", kBody,
2202 GURL resource_url(url); 2247 push_urls, kNumResources, 0);
2203 string body = "This is server push response body for " + url;
2204 SpdyHeaderBlock response_headers;
2205 response_headers[":version"] = "HTTP/1.1";
2206 response_headers[":status"] = "200";
2207 response_headers["content-length"] = IntToString(body.size());
2208 push_resources.push_back(QuicInMemoryCache::ServerPushInfo(
2209 resource_url, response_headers, kV3LowestPriority, body));
2210 }
2211
2212 QuicInMemoryCache::GetInstance()->AddSimpleResponseWithServerPushResources(
2213 "google.com", "/push_example", 200, kBody, push_resources);
2214 2248
2215 client_->client()->set_response_listener(new TestResponseListener); 2249 client_->client()->set_response_listener(new TestResponseListener);
2216 2250
2217 DVLOG(1) << "send request for /push_example"; 2251 DVLOG(1) << "send request for /push_example";
2218 EXPECT_EQ(kBody, 2252 EXPECT_EQ(kBody, client_->SendSynchronousRequest(
2219 client_->SendSynchronousRequest("https://google.com/push_example")); 2253 "https://example.com/push_example"));
2220 for (const string& url : push_urls) { 2254 for (const string& url : push_urls) {
2221 DVLOG(1) << "send request for pushed stream on url " << url; 2255 DVLOG(1) << "send request for pushed stream on url " << url;
2222 string expected_body = "This is server push response body for " + url; 2256 string expected_body = "This is server push response body for " + url;
2223 string response_body = client_->SendSynchronousRequest(url); 2257 string response_body = client_->SendSynchronousRequest(url);
2224 DVLOG(1) << "response body " << response_body; 2258 DVLOG(1) << "response body " << response_body;
2225 EXPECT_EQ(expected_body, response_body); 2259 EXPECT_EQ(expected_body, response_body);
2226 } 2260 }
2227 } 2261 }
2228 2262
2263 TEST_P(EndToEndTestServerPush, ServerPushUnderLimit) {
2264 // Tests that sending a request which has 4 push resources will trigger server
2265 // to push those 4 resources and client can handle pushed resources and match
2266 // them with requests later.
2267 ASSERT_TRUE(Initialize());
2268
2269 client_->client()->WaitForCryptoHandshakeConfirmed();
2270
2271 // Set reordering to ensure that body arriving before PUSH_PROMISE is ok.
2272 SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
2273 SetReorderPercentage(30);
2274
2275 // Add a response with headers, body, and push resources.
2276 const string kBody = "body content";
2277 size_t const kNumResources = 4;
2278 string push_urls[] = {
2279 "https://example.com/font.woff", "https://example.com/script.js",
2280 "https://fonts.example.com/font.woff",
2281 "https://example.com/logo-hires.jpg",
2282 };
2283 AddRequestAndResponseWithServerPush("example.com", "/push_example", kBody,
2284 push_urls, kNumResources, 0);
2285 client_->client()->set_response_listener(new TestResponseListener);
2286
2287 // Send the first request: this will trigger the server to send all the push
2288 // resources associated with this request, and these will be cached by the
2289 // client.
2290 EXPECT_EQ(kBody, client_->SendSynchronousRequest(
2291 "https://example.com/push_example"));
2292 EXPECT_EQ(1u + kNumResources, client_->num_responses());
2293
2294 for (string url : push_urls) {
2295 // Sending subsequent requesets will not actually send anything on the wire,
2296 // as the responses are already in the client's cache.
2297 DVLOG(1) << "send request for pushed stream on url " << url;
2298 string expected_body = "This is server push response body for " + url;
2299 string response_body = client_->SendSynchronousRequest(url);
2300 DVLOG(1) << "response body " << response_body;
2301 EXPECT_EQ(expected_body, response_body);
2302 }
2303 // Expect only original request has been sent and push responses have been
2304 // received as normal response.
2305 EXPECT_EQ(1u, client_->num_requests());
2306 }
2307
2308 TEST_P(EndToEndTestServerPush, ServerPushOverLimitNonBlocking) {
2309 // Tests that when streams are not blocked by flow control or congestion
2310 // control, pushing even more resources than max number of open outgoing
2311 // streams should still work because all response streams get closed
2312 // immediately after pushing resources.
2313 ASSERT_TRUE(Initialize());
2314 client_->client()->WaitForCryptoHandshakeConfirmed();
2315
2316 // Set reordering to ensure that body arriving before PUSH_PROMISE is ok.
2317 SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
2318 SetReorderPercentage(30);
2319
2320 // Add a response with headers, body, and push resources.
2321 const string kBody = "body content";
2322
2323 // One more resource than max number of outgoing stream of this session.
2324 const size_t kNumResources = 1 + kNumMaxStreams; // 11.
2325 string push_urls[11];
2326 for (uint32_t i = 0; i < kNumResources; ++i) {
2327 push_urls[i] = "https://example.com/push_resources" + base::UintToString(i);
2328 }
2329 AddRequestAndResponseWithServerPush("example.com", "/push_example", kBody,
2330 push_urls, kNumResources, 0);
2331 client_->client()->set_response_listener(new TestResponseListener);
2332
2333 // Send the first request: this will trigger the server to send all the push
2334 // resources associated with this request, and these will be cached by the
2335 // client.
2336 EXPECT_EQ(kBody, client_->SendSynchronousRequest(
2337 "https://example.com/push_example"));
2338 // The responses to the original request and all the promised resources
2339 // should have been received.
2340 EXPECT_EQ(12u, client_->num_responses());
2341
2342 for (const string& url : push_urls) {
2343 // Sending subsequent requesets will not actually send anything on the wire,
2344 // as the responses are already in the client's cache.
2345 EXPECT_EQ("This is server push response body for " + url,
2346 client_->SendSynchronousRequest(url));
2347 }
2348
2349 // Only 1 request should have been sent.
2350 EXPECT_EQ(1u, client_->num_requests());
2351 }
2352
2353 TEST_P(EndToEndTestServerPush, ServerPushOverLimitWithBlocking) {
2354 // Tests that when server tries to send more large resources(large enough to
2355 // be blocked by flow control window or congestion control window) than max
2356 // open outgoing streams , server can open upto max number of outgoing
2357 // streams for them, and the rest will be queued up.
2358
2359 // Reset flow control windows.
2360 size_t kFlowControlWnd = 20 * 1024; // 20KB.
2361 // Response body is larger than 1 flow controlblock window.
2362 size_t kBodySize = kFlowControlWnd * 2;
2363 set_client_initial_stream_flow_control_receive_window(kFlowControlWnd);
2364 // Make sure conntection level flow control window is large enough not to
2365 // block data being sent out though they will be blocked by stream level one.
2366 set_client_initial_session_flow_control_receive_window(
2367 kBodySize * kNumMaxStreams + 1024);
2368
2369 ASSERT_TRUE(Initialize());
2370 client_->client()->WaitForCryptoHandshakeConfirmed();
2371
2372 // Set reordering to ensure that body arriving before PUSH_PROMISE is ok.
2373 SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
2374 SetReorderPercentage(30);
2375
2376 // Add a response with headers, body, and push resources.
2377 const string kBody = "body content";
2378
2379 const size_t kNumResources = kNumMaxStreams + 1;
2380 string push_urls[11];
2381 for (uint32_t i = 0; i < kNumResources; ++i) {
2382 push_urls[i] = "http://example.com/push_resources" + base::UintToString(i);
2383 }
2384 AddRequestAndResponseWithServerPush("example.com", "/push_example", kBody,
2385 push_urls, kNumResources, kBodySize);
2386
2387 client_->client()->set_response_listener(new TestResponseListener);
2388
2389 client_->SendRequest("https://example.com/push_example");
2390
2391 // Pause after the first response arrives.
2392 while (!client_->response_complete()) {
2393 // Because of priority, the first response arrived should be to original
2394 // request.
2395 client_->WaitForResponse();
2396 }
2397
2398 // Check server session to see if it has max number of outgoing streams opened
2399 // though more resources need to be pushed.
2400 server_thread_->Pause();
2401 QuicDispatcher* dispatcher =
2402 QuicServerPeer::GetDispatcher(server_thread_->server());
2403 ASSERT_EQ(1u, dispatcher->session_map().size());
2404 QuicSession* session = dispatcher->session_map().begin()->second;
2405 EXPECT_EQ(kNumMaxStreams, session->GetNumOpenOutgoingStreams());
2406 server_thread_->Resume();
2407
2408 EXPECT_EQ(1u, client_->num_requests());
2409 EXPECT_EQ(1u, client_->num_responses());
2410 EXPECT_EQ(kBody, client_->response_body());
2411
2412 // "Send" request for a promised resources will not really send out it because
2413 // its response is being pushed(but blocked). And the following ack and
2414 // flow control behavior of SendSynchronousRequests()
2415 // will unblock the stream to finish receiving response.
2416 client_->SendSynchronousRequest(push_urls[0]);
2417 EXPECT_EQ(1u, client_->num_requests());
2418 EXPECT_EQ(2u, client_->num_responses());
2419
2420 // Do same thing for the rest 10 resources.
2421 for (uint32_t i = 1; i < kNumResources; ++i) {
2422 client_->SendSynchronousRequest(push_urls[i]);
2423 }
2424
2425 // Because of server push, client gets all pushed resources without actually
2426 // sending requests for them.
2427 EXPECT_EQ(1u, client_->num_requests());
2428 // Including response to original request, 12 responses in total were
2429 // recieved.
2430 EXPECT_EQ(12u, client_->num_responses());
2431 }
2432
2229 } // namespace 2433 } // namespace
2230 } // namespace test 2434 } // namespace test
2231 } // namespace net 2435 } // namespace net
OLDNEW
« no previous file with comments | « no previous file | net/tools/quic/test_tools/quic_test_client.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698