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

Side by Side Diff: net/url_request/url_request_quic_unittest.cc

Issue 2692813002: Server push cancellation: add a finch trial parameter (Closed)
Patch Set: Spin the message loop to ensure the client receives the response Created 3 years, 8 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
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 <memory> 5 #include <memory>
6 6
7 #include "base/files/file_path.h" 7 #include "base/files/file_path.h"
8 #include "base/macros.h" 8 #include "base/macros.h"
9 #include "base/memory/ptr_util.h" 9 #include "base/memory/ptr_util.h"
10 #include "base/run_loop.h" 10 #include "base/run_loop.h"
11 #include "base/strings/string_number_conversions.h" 11 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/stringprintf.h" 12 #include "base/strings/stringprintf.h"
13 #include "net/base/load_timing_info.h" 13 #include "net/base/load_timing_info.h"
14 #include "net/base/network_delegate.h" 14 #include "net/base/network_delegate.h"
15 #include "net/cert/mock_cert_verifier.h" 15 #include "net/cert/mock_cert_verifier.h"
16 #include "net/dns/mapped_host_resolver.h" 16 #include "net/dns/mapped_host_resolver.h"
17 #include "net/dns/mock_host_resolver.h" 17 #include "net/dns/mock_host_resolver.h"
18 #include "net/log/net_log_event_type.h"
19 #include "net/log/test_net_log.h"
20 #include "net/log/test_net_log_entry.h"
18 #include "net/quic/chromium/crypto/proof_source_chromium.h" 21 #include "net/quic/chromium/crypto/proof_source_chromium.h"
19 #include "net/quic/test_tools/crypto_test_utils.h" 22 #include "net/quic/test_tools/crypto_test_utils.h"
20 #include "net/test/cert_test_util.h" 23 #include "net/test/cert_test_util.h"
21 #include "net/test/gtest_util.h" 24 #include "net/test/gtest_util.h"
22 #include "net/test/test_data_directory.h" 25 #include "net/test/test_data_directory.h"
26 #include "net/tools/quic/quic_dispatcher.h"
23 #include "net/tools/quic/quic_http_response_cache.h" 27 #include "net/tools/quic/quic_http_response_cache.h"
28 #include "net/tools/quic/quic_simple_dispatcher.h"
24 #include "net/tools/quic/quic_simple_server.h" 29 #include "net/tools/quic/quic_simple_server.h"
25 #include "net/url_request/url_request.h" 30 #include "net/url_request/url_request.h"
26 #include "net/url_request/url_request_test_util.h" 31 #include "net/url_request/url_request_test_util.h"
27 #include "testing/gmock/include/gmock/gmock.h" 32 #include "testing/gmock/include/gmock/gmock.h"
28 #include "testing/gtest/include/gtest/gtest.h" 33 #include "testing/gtest/include/gtest/gtest.h"
29 #include "url/gurl.h" 34 #include "url/gurl.h"
30 35
31 namespace net { 36 namespace net {
32 37
33 namespace { 38 namespace {
(...skipping 23 matching lines...) Expand all
57 verify_result.verified_cert = ImportCertFromFile( 62 verify_result.verified_cert = ImportCertFromFile(
58 GetTestCertsDirectory(), "quic_test_ecc.example.com.crt"); 63 GetTestCertsDirectory(), "quic_test_ecc.example.com.crt");
59 cert_verifier_.AddResultForCertAndHost(verify_result.verified_cert.get(), 64 cert_verifier_.AddResultForCertAndHost(verify_result.verified_cert.get(),
60 "test.example.com", verify_result, 65 "test.example.com", verify_result,
61 OK); 66 OK);
62 // To simplify the test, and avoid the race with the HTTP request, we force 67 // To simplify the test, and avoid the race with the HTTP request, we force
63 // QUIC for these requests. 68 // QUIC for these requests.
64 params->origins_to_force_quic_on.insert(HostPortPair(kTestServerHost, 443)); 69 params->origins_to_force_quic_on.insert(HostPortPair(kTestServerHost, 443));
65 params->cert_verifier = &cert_verifier_; 70 params->cert_verifier = &cert_verifier_;
66 params->enable_quic = true; 71 params->enable_quic = true;
72 params->enable_server_push_cancellation = true;
67 context_->set_host_resolver(host_resolver_.get()); 73 context_->set_host_resolver(host_resolver_.get());
68 context_->set_http_network_session_params(std::move(params)); 74 context_->set_http_network_session_params(std::move(params));
69 context_->set_cert_verifier(&cert_verifier_); 75 context_->set_cert_verifier(&cert_verifier_);
76 context_->set_net_log(&net_log_);
70 } 77 }
71 78
72 void TearDown() override { 79 void TearDown() override {
73 if (server_) 80 if (server_) {
74 server_->Shutdown(); 81 server_->Shutdown();
82 // If possible, deliver the conncetion close packet to the client before
83 // destruct the TestURLRequestContext.
84 base::RunLoop().RunUntilIdle();
85 }
75 } 86 }
76 87
77 // Sets a NetworkDelegate to use for |context_|. Must be done before Init(). 88 // Sets a NetworkDelegate to use for |context_|. Must be done before Init().
78 void SetNetworkDelegate(NetworkDelegate* network_delegate) { 89 void SetNetworkDelegate(NetworkDelegate* network_delegate) {
79 context_->set_network_delegate(network_delegate); 90 context_->set_network_delegate(network_delegate);
80 } 91 }
81 92
82 // Initializes the TestURLRequestContext |context_|. 93 // Initializes the TestURLRequestContext |context_|.
83 void Init() { context_->Init(); } 94 void Init() { context_->Init(); }
84 95
85 std::unique_ptr<URLRequest> CreateRequest(const GURL& url, 96 std::unique_ptr<URLRequest> CreateRequest(const GURL& url,
86 RequestPriority priority, 97 RequestPriority priority,
87 URLRequest::Delegate* delegate) { 98 URLRequest::Delegate* delegate) {
88 return context_->CreateRequest(url, priority, delegate); 99 return context_->CreateRequest(url, priority, delegate);
89 } 100 }
90 101
102 void ExtractNetLog(NetLogEventType type,
103 TestNetLogEntry::List* entry_list) const {
104 net::TestNetLogEntry::List entries;
105 net_log_.GetEntries(&entries);
106
107 for (const auto& entry : entries) {
108 if (entry.type == type)
109 entry_list->push_back(entry);
110 }
111 }
112
113 unsigned int GetRstErrorCountReceivedByServer(
114 QuicRstStreamErrorCode error_code) const {
115 return (static_cast<QuicSimpleDispatcher*>(server_->dispatcher()))
116 ->GetRstErrorCount(error_code);
117 }
118
91 private: 119 private:
92 void StartQuicServer() { 120 void StartQuicServer() {
93 // Set up in-memory cache. 121 // Set up in-memory cache.
94 response_cache_.AddSimpleResponse(kTestServerHost, kHelloPath, kHelloStatus, 122 response_cache_.AddSimpleResponse(kTestServerHost, kHelloPath, kHelloStatus,
95 kHelloBodyValue); 123 kHelloBodyValue);
124 response_cache_.InitializeFromDirectory(ServerPushCacheDirectory());
96 net::QuicConfig config; 125 net::QuicConfig config;
97 // Set up server certs. 126 // Set up server certs.
98 std::unique_ptr<net::ProofSourceChromium> proof_source( 127 std::unique_ptr<net::ProofSourceChromium> proof_source(
99 new net::ProofSourceChromium()); 128 new net::ProofSourceChromium());
100 base::FilePath directory = GetTestCertsDirectory(); 129 base::FilePath directory = GetTestCertsDirectory();
101 CHECK(proof_source->Initialize( 130 CHECK(proof_source->Initialize(
102 directory.Append(FILE_PATH_LITERAL("quic_test.example.com.crt")), 131 directory.Append(FILE_PATH_LITERAL("quic_test.example.com.crt")),
103 directory.Append(FILE_PATH_LITERAL("quic_test.example.com.key.pkcs8")), 132 directory.Append(FILE_PATH_LITERAL("quic_test.example.com.key.pkcs8")),
104 directory.Append(FILE_PATH_LITERAL("quic_test.example.com.key.sct")))); 133 directory.Append(FILE_PATH_LITERAL("quic_test.example.com.key.sct"))));
105 server_.reset(new QuicSimpleServer( 134 server_.reset(new QuicSimpleServer(
106 test::crypto_test_utils::ProofSourceForTesting(), config, 135 test::crypto_test_utils::ProofSourceForTesting(), config,
107 net::QuicCryptoServerConfig::ConfigOptions(), AllSupportedVersions(), 136 net::QuicCryptoServerConfig::ConfigOptions(), AllSupportedVersions(),
108 &response_cache_)); 137 &response_cache_));
109 int rv = server_->Listen( 138 int rv = server_->Listen(
110 net::IPEndPoint(net::IPAddress::IPv4AllZeros(), kTestServerPort)); 139 net::IPEndPoint(net::IPAddress::IPv4AllZeros(), kTestServerPort));
111 EXPECT_GE(rv, 0) << "Quic server fails to start"; 140 EXPECT_GE(rv, 0) << "Quic server fails to start";
112 141
113 std::unique_ptr<MockHostResolver> resolver(new MockHostResolver()); 142 std::unique_ptr<MockHostResolver> resolver(new MockHostResolver());
114 resolver->rules()->AddRule("test.example.com", "127.0.0.1"); 143 resolver->rules()->AddRule("test.example.com", "127.0.0.1");
115 host_resolver_.reset(new MappedHostResolver(std::move(resolver))); 144 host_resolver_.reset(new MappedHostResolver(std::move(resolver)));
116 // Use a mapped host resolver so that request for test.example.com 145 // Use a mapped host resolver so that request for test.example.com
117 // reach the server running on localhost. 146 // reach the server running on localhost.
118 std::string map_rule = "MAP test.example.com test.example.com:" + 147 std::string map_rule = "MAP test.example.com test.example.com:" +
119 base::IntToString(server_->server_address().port()); 148 base::IntToString(server_->server_address().port());
120 EXPECT_TRUE(host_resolver_->AddRuleFromString(map_rule)); 149 EXPECT_TRUE(host_resolver_->AddRuleFromString(map_rule));
121 } 150 }
122 151
152 std::string ServerPushCacheDirectory() {
153 base::FilePath path;
154 PathService::Get(base::DIR_SOURCE_ROOT, &path);
155 path = path.AppendASCII("net").AppendASCII("data").AppendASCII(
156 "quic_http_response_cache_data_with_push");
157 // The file path is known to be an ascii string.
158 return path.MaybeAsASCII();
159 }
160
123 std::unique_ptr<MappedHostResolver> host_resolver_; 161 std::unique_ptr<MappedHostResolver> host_resolver_;
124 std::unique_ptr<QuicSimpleServer> server_; 162 std::unique_ptr<QuicSimpleServer> server_;
125 std::unique_ptr<TestURLRequestContext> context_; 163 std::unique_ptr<TestURLRequestContext> context_;
164 TestNetLog net_log_;
126 QuicHttpResponseCache response_cache_; 165 QuicHttpResponseCache response_cache_;
127 MockCertVerifier cert_verifier_; 166 MockCertVerifier cert_verifier_;
128 }; 167 };
129 168
130 // A URLRequest::Delegate that checks LoadTimingInfo when response headers are 169 // A URLRequest::Delegate that checks LoadTimingInfo when response headers are
131 // received. 170 // received.
132 class CheckLoadTimingDelegate : public TestDelegate { 171 class CheckLoadTimingDelegate : public TestDelegate {
133 public: 172 public:
134 CheckLoadTimingDelegate(bool session_reused) 173 CheckLoadTimingDelegate(bool session_reused)
135 : session_reused_(session_reused) {} 174 : session_reused_(session_reused) {}
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 CreateRequest(GURL(url), DEFAULT_PRIORITY, &delegate); 243 CreateRequest(GURL(url), DEFAULT_PRIORITY, &delegate);
205 244
206 request->Start(); 245 request->Start();
207 ASSERT_TRUE(request->is_pending()); 246 ASSERT_TRUE(request->is_pending());
208 base::RunLoop().Run(); 247 base::RunLoop().Run();
209 248
210 EXPECT_TRUE(request->status().is_success()); 249 EXPECT_TRUE(request->status().is_success());
211 EXPECT_EQ(kHelloBodyValue, delegate.data_received()); 250 EXPECT_EQ(kHelloBodyValue, delegate.data_received());
212 } 251 }
213 252
253 TEST_F(URLRequestQuicTest, CancelPushIfCached) {
254 base::RunLoop run_loop;
255 Init();
256
257 // Send a request to the pushed url: /kitten-1.jpg to pull the resource into
258 // cache.
259 CheckLoadTimingDelegate delegate_0(false);
260 std::string url_0 =
261 base::StringPrintf("https://%s%s", kTestServerHost, "/kitten-1.jpg");
262 std::unique_ptr<URLRequest> request_0 =
263 CreateRequest(GURL(url_0), DEFAULT_PRIORITY, &delegate_0);
264
265 request_0->Start();
266 ASSERT_TRUE(request_0->is_pending());
267
268 // Spin the message loop until the client receives the response for the first
269 // request.
270 do {
271 base::RunLoop().RunUntilIdle();
272 } while (request_0->status().is_io_pending());
273 EXPECT_TRUE(request_0->status().is_success());
274
275 // Send a request to /index2.html which pushes /kitten-1.jpg and /favicon.ico.
276 // Should cancel push for /kitten-1.jpg.
277 CheckLoadTimingDelegate delegate(true);
278 std::string url =
279 base::StringPrintf("https://%s%s", kTestServerHost, "/index2.html");
280 std::unique_ptr<URLRequest> request =
281 CreateRequest(GURL(url), DEFAULT_PRIORITY, &delegate);
282
283 request->Start();
284 ASSERT_TRUE(request->is_pending());
285
286 // Spin the message loop until the client receives the response for the second
287 // request.
288 do {
289 base::RunLoop().RunUntilIdle();
290 } while (request->status().is_io_pending());
291 EXPECT_TRUE(request->status().is_success());
292
293 // Extract net logs on client side to verify push lookup transactions.
294 net::TestNetLogEntry::List entries;
295 ExtractNetLog(NetLogEventType::SERVER_PUSH_LOOKUP_TRANSACTION, &entries);
296
297 EXPECT_EQ(4u, entries.size());
298
299 std::string value;
300 int net_error;
301 std::string push_url_1 =
302 base::StringPrintf("https://%s%s", kTestServerHost, "/kitten-1.jpg");
303 std::string push_url_2 =
304 base::StringPrintf("https://%s%s", kTestServerHost, "/favicon.ico");
305
306 EXPECT_TRUE(entries[0].GetStringValue("push_url", &value));
307 EXPECT_EQ(value, push_url_1);
308 // No net error code for this lookup transaction, the push is found.
309 EXPECT_FALSE(entries[1].GetIntegerValue("net_error", &net_error));
310
311 EXPECT_TRUE(entries[2].GetStringValue("push_url", &value));
312 EXPECT_EQ(value, push_url_2);
313 // Net error code -400 is found for this lookup transaction, the push is not
314 // found in the cache.
315 EXPECT_TRUE(entries[3].GetIntegerValue("net_error", &net_error));
316 EXPECT_EQ(net_error, -400);
317
318 // Verify the reset error count received on the server side.
319 EXPECT_LE(1u, GetRstErrorCountReceivedByServer(QUIC_STREAM_CANCELLED));
320 }
321
322 TEST_F(URLRequestQuicTest, CancelPushIfCached2) {
323 base::RunLoop run_loop;
324 Init();
325
326 // Send a request to the pushed url: /kitten-1.jpg to pull the resource into
327 // cache.
328 CheckLoadTimingDelegate delegate_0(false);
329 std::string url_0 =
330 base::StringPrintf("https://%s%s", kTestServerHost, "/kitten-1.jpg");
331 std::unique_ptr<URLRequest> request_0 =
332 CreateRequest(GURL(url_0), DEFAULT_PRIORITY, &delegate_0);
333
334 request_0->Start();
335 ASSERT_TRUE(request_0->is_pending());
336
337 // Spin the message loop until the client receives the response for the first
338 // request.
339 do {
340 base::RunLoop().RunUntilIdle();
341 } while (request_0->status().is_io_pending());
342 EXPECT_TRUE(request_0->status().is_success());
343
344 // Send a request to the pushed url: /favicon.ico to pull the resource into
345 // cache.
346 CheckLoadTimingDelegate delegate_1(true);
347 std::string url_1 =
348 base::StringPrintf("https://%s%s", kTestServerHost, "/favicon.ico");
349 std::unique_ptr<URLRequest> request_1 =
350 CreateRequest(GURL(url_1), DEFAULT_PRIORITY, &delegate_1);
351
352 request_1->Start();
353 ASSERT_TRUE(request_1->is_pending());
354
355 // Spin the message loop until the client receives the response for the second
356 // request.
357 do {
358 base::RunLoop().RunUntilIdle();
359 } while (request_1->status().is_io_pending());
360 EXPECT_TRUE(request_1->status().is_success());
361
362 // Send a request to /index2.html which pushes /kitten-1.jpg and /favicon.ico.
363 // Should cancel push for /kitten-1.jpg.
364 CheckLoadTimingDelegate delegate(true);
365 std::string url =
366 base::StringPrintf("https://%s%s", kTestServerHost, "/index2.html");
367 std::unique_ptr<URLRequest> request =
368 CreateRequest(GURL(url), DEFAULT_PRIORITY, &delegate);
369
370 request->Start();
371 ASSERT_TRUE(request->is_pending());
372
373 // Spin the message loop until the client receives the response for the third
374 // request.
375 do {
376 base::RunLoop().RunUntilIdle();
377 } while (request->status().is_io_pending());
378 EXPECT_TRUE(request->status().is_success());
379
380 // Extract net logs on client side to verify push lookup transactions.
381 net::TestNetLogEntry::List entries;
382 ExtractNetLog(NetLogEventType::SERVER_PUSH_LOOKUP_TRANSACTION, &entries);
383
384 EXPECT_EQ(4u, entries.size());
385
386 std::string value;
387 int net_error;
388 std::string push_url_1 =
389 base::StringPrintf("https://%s%s", kTestServerHost, "/kitten-1.jpg");
390 std::string push_url_2 =
391 base::StringPrintf("https://%s%s", kTestServerHost, "/favicon.ico");
392
393 EXPECT_TRUE(entries[0].GetStringValue("push_url", &value));
394 EXPECT_EQ(value, push_url_1);
395 // No net error code for this lookup transaction, the push is found.
396 EXPECT_FALSE(entries[1].GetIntegerValue("net_error", &net_error));
397
398 EXPECT_TRUE(entries[2].GetStringValue("push_url", &value));
399 EXPECT_EQ(value, push_url_2);
400 // No net error code for this lookup transaction, the push is found.
401 EXPECT_FALSE(entries[3].GetIntegerValue("net_error", &net_error));
402
403 // Verify the reset error count received on the server side.
404 EXPECT_LE(2u, GetRstErrorCountReceivedByServer(QUIC_STREAM_CANCELLED));
405 }
406
407 TEST_F(URLRequestQuicTest, DoNotCancelPushIfNotFoundInCache) {
408 base::RunLoop run_loop;
409 Init();
410
411 // Send a request to /index2.hmtl which pushes /kitten-1.jpg and /favicon.ico
412 // and shouldn't cancel any since neither is in cache.
413 CheckLoadTimingDelegate delegate(false);
414 std::string url =
415 base::StringPrintf("https://%s%s", kTestServerHost, "/index2.html");
416 std::unique_ptr<URLRequest> request =
417 CreateRequest(GURL(url), DEFAULT_PRIORITY, &delegate);
418
419 request->Start();
420 ASSERT_TRUE(request->is_pending());
421
422 // Spin the message loop until the client receives response.
423 do {
424 base::RunLoop().RunUntilIdle();
425 } while (request->status().is_io_pending());
426 EXPECT_TRUE(request->status().is_success());
427
428 // Extract net logs on client side to verify push lookup transactions.
429 net::TestNetLogEntry::List entries;
430 ExtractNetLog(NetLogEventType::SERVER_PUSH_LOOKUP_TRANSACTION, &entries);
431
432 EXPECT_EQ(4u, entries.size());
433
434 std::string value;
435 int net_error;
436 std::string push_url_1 =
437 base::StringPrintf("https://%s%s", kTestServerHost, "/kitten-1.jpg");
438 std::string push_url_2 =
439 base::StringPrintf("https://%s%s", kTestServerHost, "/favicon.ico");
440
441 EXPECT_TRUE(entries[0].GetStringValue("push_url", &value));
442 EXPECT_EQ(value, push_url_1);
443 EXPECT_TRUE(entries[1].GetIntegerValue("net_error", &net_error));
444 EXPECT_EQ(net_error, -400);
445
446 EXPECT_TRUE(entries[2].GetStringValue("push_url", &value));
447 EXPECT_EQ(value, push_url_2);
448 EXPECT_TRUE(entries[3].GetIntegerValue("net_error", &net_error));
449 EXPECT_EQ(net_error, -400);
450
451 // Verify the reset error count received on the server side.
452 EXPECT_EQ(0u, GetRstErrorCountReceivedByServer(QUIC_STREAM_CANCELLED));
453 }
454
214 // Tests that if two requests use the same QUIC session, the second request 455 // Tests that if two requests use the same QUIC session, the second request
215 // should not have |LoadTimingInfo::connect_timing|. 456 // should not have |LoadTimingInfo::connect_timing|.
216 TEST_F(URLRequestQuicTest, TestTwoRequests) { 457 TEST_F(URLRequestQuicTest, TestTwoRequests) {
217 base::RunLoop run_loop; 458 base::RunLoop run_loop;
218 WaitForCompletionNetworkDelegate network_delegate( 459 WaitForCompletionNetworkDelegate network_delegate(
219 run_loop.QuitClosure(), /*num_expected_requests=*/2); 460 run_loop.QuitClosure(), /*num_expected_requests=*/2);
220 SetNetworkDelegate(&network_delegate); 461 SetNetworkDelegate(&network_delegate);
221 Init(); 462 Init();
222 CheckLoadTimingDelegate delegate(false); 463 CheckLoadTimingDelegate delegate(false);
223 delegate.set_quit_on_complete(false); 464 delegate.set_quit_on_complete(false);
(...skipping 12 matching lines...) Expand all
236 ASSERT_TRUE(request2->is_pending()); 477 ASSERT_TRUE(request2->is_pending());
237 run_loop.Run(); 478 run_loop.Run();
238 479
239 EXPECT_TRUE(request->status().is_success()); 480 EXPECT_TRUE(request->status().is_success());
240 EXPECT_TRUE(request2->status().is_success()); 481 EXPECT_TRUE(request2->status().is_success());
241 EXPECT_EQ(kHelloBodyValue, delegate.data_received()); 482 EXPECT_EQ(kHelloBodyValue, delegate.data_received());
242 EXPECT_EQ(kHelloBodyValue, delegate2.data_received()); 483 EXPECT_EQ(kHelloBodyValue, delegate2.data_received());
243 } 484 }
244 485
245 } // namespace net 486 } // namespace net
OLDNEW
« no previous file with comments | « net/tools/quic/test_tools/mock_quic_session_visitor.h ('k') | net/url_request/url_request_test_util.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698