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

Side by Side Diff: net/cert_net/cert_net_fetcher_impl_unittest.cc

Issue 908863004: Initial implementation for CertNetFetcher. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: address more feedback Created 5 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
OLDNEW
(Empty)
1 // Copyright 2015 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/cert_net/cert_net_fetcher_impl.h"
6
7 #include <string>
8
9 #include "base/compiler_specific.h"
10 #include "base/run_loop.h"
11 #include "net/cert/mock_cert_verifier.h"
12 #include "net/dns/mock_host_resolver.h"
13 #include "net/http/http_server_properties_impl.h"
14 #include "net/test/spawned_test_server/spawned_test_server.h"
15 #include "net/url_request/url_request_job_factory_impl.h"
16 #include "net/url_request/url_request_test_util.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "testing/platform_test.h"
19
20 // TODO(eroman): Test that cookies aren't sent.
21
22 using base::ASCIIToUTF16;
23
24 namespace net {
25
26 namespace {
27
28 const base::FilePath::CharType kDocRoot[] =
29 FILE_PATH_LITERAL("net/data/cert_net_fetcher_impl_unittest");
30
31 // A non-mock URLRequestContext which can access http:// urls.
32 class RequestContext : public URLRequestContext {
33 public:
34 RequestContext() : storage_(this) {
35 ProxyConfig no_proxy;
36 storage_.set_host_resolver(scoped_ptr<HostResolver>(new MockHostResolver));
37 storage_.set_cert_verifier(new MockCertVerifier);
38 storage_.set_transport_security_state(new TransportSecurityState);
39 storage_.set_proxy_service(ProxyService::CreateFixed(no_proxy));
40 storage_.set_ssl_config_service(new SSLConfigServiceDefaults);
41 storage_.set_http_server_properties(
42 scoped_ptr<HttpServerProperties>(new HttpServerPropertiesImpl()));
43
44 HttpNetworkSession::Params params;
45 params.host_resolver = host_resolver();
46 params.cert_verifier = cert_verifier();
47 params.transport_security_state = transport_security_state();
48 params.proxy_service = proxy_service();
49 params.ssl_config_service = ssl_config_service();
50 params.http_server_properties = http_server_properties();
51 scoped_refptr<HttpNetworkSession> network_session(
52 new HttpNetworkSession(params));
53 storage_.set_http_transaction_factory(new HttpCache(
54 network_session.get(), HttpCache::DefaultBackend::InMemory(0)));
55 URLRequestJobFactoryImpl* job_factory = new URLRequestJobFactoryImpl();
56 storage_.set_job_factory(job_factory);
57 }
58
59 ~RequestContext() override { AssertNoURLRequests(); }
60
61 private:
62 URLRequestContextStorage storage_;
63 };
64
65 class FetchResult {
66 public:
67 FetchResult(Error net_error, const std::vector<uint8_t>& response_body)
68 : net_error_(net_error), response_body_(response_body) {}
69
70 void VerifySuccess(const std::string& expected_body) {
71 EXPECT_EQ(OK, net_error_);
72 EXPECT_EQ(expected_body,
73 std::string(response_body_.begin(), response_body_.end()));
74 }
75
76 void VerifyFailure(Error expected_error) {
77 EXPECT_EQ(expected_error, net_error_);
78 EXPECT_EQ(0u, response_body_.size());
79 }
80
81 private:
82 const Error net_error_;
83 const std::vector<uint8_t> response_body_;
84 };
85
86 // Helper to synchronously wait for the fetch completion. This is similar to
87 // net's TestCompletionCallback, but built around FetchCallback.
88 class TestFetchCallback {
89 public:
90 TestFetchCallback()
91 : callback_(base::Bind(&TestFetchCallback::OnCallback,
92 base::Unretained(this))) {}
93
94 const CertNetFetcher::FetchCallback& callback() const { return callback_; }
95
96 scoped_ptr<FetchResult> WaitForResult() {
97 DCHECK(quit_closure_.is_null());
98 while (!HasResult()) {
99 base::RunLoop run_loop;
100 quit_closure_ = run_loop.QuitClosure();
101 run_loop.Run();
102 quit_closure_.Reset();
103 }
104 return result_.Pass();
105 }
106
107 bool HasResult() const { return result_.get(); }
108
109 // Sets an extra action (in addition to recording the result) that is run when
110 // the FetchCallback is invoked.
111 void set_extra_closure(const base::Closure& closure) {
112 extra_closure_ = closure;
113 }
114
115 private:
116 void OnCallback(Error net_error, const std::vector<uint8_t>& response_body) {
117 DCHECK(!HasResult());
118 result_.reset(new FetchResult(net_error, response_body));
119
120 if (!extra_closure_.is_null())
121 extra_closure_.Run();
122
123 if (!quit_closure_.is_null())
124 quit_closure_.Run();
125 }
126
127 CertNetFetcher::FetchCallback callback_;
128 scoped_ptr<FetchResult> result_;
129 base::Closure quit_closure_;
130 base::Closure extra_closure_;
131 };
132
133 } // namespace
134
135 class CertNetFetcherImplTest : public PlatformTest {
136 public:
137 CertNetFetcherImplTest()
138 : test_server_(SpawnedTestServer::TYPE_HTTP,
139 net::SpawnedTestServer::kLocalhost,
140 base::FilePath(kDocRoot)) {
141 context_.set_network_delegate(&network_delegate_);
142 }
143
144 protected:
145 SpawnedTestServer test_server_;
146 TestNetworkDelegate network_delegate_;
147 RequestContext context_;
148 };
149
150 // Helper to start an AIA fetch using default parameters.
151 CertNetFetcher::RequestId StartRequest(const GURL& url,
152 const TestFetchCallback& callback,
153 CertNetFetcher* fetcher) {
davidben 2015/03/31 20:52:25 Nit: Probably makes more sense for the fetcher to
eroman 2015/04/04 21:57:15 I left it last because I thought it was more style
davidben 2015/04/07 19:22:25 Hrm. I see it as more a context than an in/out par
eroman 2015/04/07 20:22:40 Done.
154 return fetcher->FetchCaIssuers(url, CertNetFetcher::DEFAULT,
155 CertNetFetcher::DEFAULT, callback.callback());
156 }
157
158 // Fetch a few unique URLs using GET in parallel. Each URL has a different body
159 // and Content-Type.
160 TEST_F(CertNetFetcherImplTest, ParallelFetchNoDupes) {
161 ASSERT_TRUE(test_server_.Start());
162
163 CertNetFetcherImpl fetcher(&context_);
164 TestFetchCallback callback1;
165 TestFetchCallback callback2;
166 TestFetchCallback callback3;
167
168 // Request a URL with Content-Type "application/pkix-cert"
169 GURL url1 = test_server_.GetURL("files/cert.crt");
170 StartRequest(url1, callback1, &fetcher);
171
172 // Request a URL with Content-Type "application/pkix-crl"
173 GURL url2 = test_server_.GetURL("files/root.crl");
174 StartRequest(url2, callback2, &fetcher);
175
176 // Request a URL with Content-Type "application/pkcs7-mime"
177 GURL url3 = test_server_.GetURL("files/certs.p7c");
178 StartRequest(url3, callback3, &fetcher);
179
180 // Wait for all of the requests to complete.
181 scoped_ptr<FetchResult> result1 = callback1.WaitForResult();
182 scoped_ptr<FetchResult> result2 = callback2.WaitForResult();
183 scoped_ptr<FetchResult> result3 = callback3.WaitForResult();
184
185 // Verify the fetch results.
186 result1->VerifySuccess("-cert.crt-\n");
187 result2->VerifySuccess("-root.crl-\n");
188 result3->VerifySuccess("-certs.p7c-\n");
189
190 EXPECT_EQ(3, network_delegate_.created_requests());
191 }
192
193 // Fetch a caIssuers URL which has an unexpected extension and Content-Type.
194 // The extension is .txt and the Content-Type is text/plain. Despite being
195 // unusual this succeeds as the extension and Content-Type are not required to
196 // be meaningful.
197 TEST_F(CertNetFetcherImplTest, ContentTypeDoesntMatter) {
198 ASSERT_TRUE(test_server_.Start());
199
200 CertNetFetcherImpl fetcher(&context_);
201
202 TestFetchCallback callback;
203 GURL url = test_server_.GetURL("files/foo.txt");
204 StartRequest(url, callback, &fetcher);
205 scoped_ptr<FetchResult> result = callback.WaitForResult();
206 result->VerifySuccess("-foo.txt-\n");
207 }
208
209 // Fetch a URLs whose HTTP response code is not 200. These are considered
210 // failures.
211 TEST_F(CertNetFetcherImplTest, HttpStatusCode) {
212 ASSERT_TRUE(test_server_.Start());
213
214 CertNetFetcherImpl fetcher(&context_);
215
216 // Response was HTTP status 404.
217 {
218 TestFetchCallback callback;
219 GURL url = test_server_.GetURL("files/404.html");
220 StartRequest(url, callback, &fetcher);
221 scoped_ptr<FetchResult> result = callback.WaitForResult();
222 result->VerifyFailure(ERR_FAILED);
223 }
224
225 // Response was HTTP status 500.
226 {
227 TestFetchCallback callback;
228 GURL url = test_server_.GetURL("files/500.html");
229 StartRequest(url, callback, &fetcher);
230 scoped_ptr<FetchResult> result = callback.WaitForResult();
231 result->VerifyFailure(ERR_FAILED);
232 }
233 }
234
235 // Fetching a URL with a Content-Disposition header should have no effect.
236 TEST_F(CertNetFetcherImplTest, ContentDisposition) {
237 ASSERT_TRUE(test_server_.Start());
238
239 CertNetFetcherImpl fetcher(&context_);
240
241 TestFetchCallback callback;
242 GURL url = test_server_.GetURL("files/downloadable.js");
243 StartRequest(url, callback, &fetcher);
244 scoped_ptr<FetchResult> result = callback.WaitForResult();
245 result->VerifySuccess("-downloadable.js-\n");
246 }
247
248 // Verifies that a cachable request will be served from the HTTP cache the
249 // second time it is requested.
250 TEST_F(CertNetFetcherImplTest, Cache) {
251 ASSERT_TRUE(test_server_.Start());
252
253 CertNetFetcherImpl fetcher(&context_);
254
255 // Fetch a URL whose HTTP headers make it cacheable for 1 hour.
256 GURL url(test_server_.GetURL("files/cacheable_1hr.crt"));
257 {
258 TestFetchCallback callback;
259 StartRequest(url, callback, &fetcher);
260 scoped_ptr<FetchResult> result = callback.WaitForResult();
261 result->VerifySuccess("-cacheable_1hr.crt-\n");
262 }
263
264 EXPECT_EQ(1, network_delegate_.created_requests());
265
266 // Kill the HTTP server.
267 ASSERT_TRUE(test_server_.Stop());
268
269 // Fetch again -- will fail unless served from cache.
270 {
271 TestFetchCallback callback;
272 StartRequest(url, callback, &fetcher);
273 scoped_ptr<FetchResult> result = callback.WaitForResult();
274 result->VerifySuccess("-cacheable_1hr.crt-\n");
275 }
276
277 EXPECT_EQ(2, network_delegate_.created_requests());
278 }
279
280 // Verify that the maximum response body constraints are enforced by fetching a
281 // resource that is larger than the limit.
282 TEST_F(CertNetFetcherImplTest, TooLarge) {
283 ASSERT_TRUE(test_server_.Start());
284
285 CertNetFetcherImpl fetcher(&context_);
286
287 // This file has a response body 12 bytes long. So setting the maximum to 11
288 // bytes will cause it to fail.
289 GURL url(test_server_.GetURL("files/certs.p7c"));
290 TestFetchCallback callback;
291 fetcher.FetchCaIssuers(url, CertNetFetcher::DEFAULT, 11, callback.callback());
292
293 scoped_ptr<FetchResult> result = callback.WaitForResult();
294 result->VerifyFailure(ERR_FILE_TOO_BIG);
295 }
296
297 // Set the timeout to 10 milliseconds, and try fetching a URL that takes 5
298 // seconds to complete. It should fail due to a timeout.
299 TEST_F(CertNetFetcherImplTest, Hang) {
300 ASSERT_TRUE(test_server_.Start());
301
302 CertNetFetcherImpl fetcher(&context_);
303
304 GURL url(test_server_.GetURL("slow/certs.p7c?5.1"));
davidben 2015/03/31 20:52:25 Why 5.1? The comment says 5. (I think 5.1 doesn't
eroman 2015/04/04 21:57:15 Changed all the floating points to integers. I ha
305 TestFetchCallback callback;
306 fetcher.FetchCaIssuers(url, 10, CertNetFetcher::DEFAULT, callback.callback());
307 scoped_ptr<FetchResult> result = callback.WaitForResult();
308 result->VerifyFailure(ERR_TIMED_OUT);
309 }
310
311 // Verify that if a response is gzip-encoded it gets inflated before being
312 // returned to the caller.
313 TEST_F(CertNetFetcherImplTest, Gzip) {
314 ASSERT_TRUE(test_server_.Start());
315
316 CertNetFetcherImpl fetcher(&context_);
317
318 GURL url(test_server_.GetURL("files/gzipped_crl"));
319 TestFetchCallback callback;
320 StartRequest(url, callback, &fetcher);
321 scoped_ptr<FetchResult> result = callback.WaitForResult();
322 result->VerifySuccess("-gzipped_crl-\n");
323 }
324
325 // Try fetching an unsupported URL scheme (https).
326 TEST_F(CertNetFetcherImplTest, HttpsNotAllowed) {
327 ASSERT_TRUE(test_server_.Start());
328
329 CertNetFetcherImpl fetcher(&context_);
330
331 GURL url("https://foopy/foo.crt");
332 TestFetchCallback callback;
333 StartRequest(url, callback, &fetcher);
334 // Should NOT complete synchronously despite being a test that could be done
335 // immediately.
336 EXPECT_FALSE(callback.HasResult());
337 scoped_ptr<FetchResult> result = callback.WaitForResult();
338 result->VerifyFailure(ERR_DISALLOWED_URL_SCHEME);
339
340 // No request was created because the URL scheme was unsupported.
341 EXPECT_EQ(0, network_delegate_.created_requests());
342 }
343
344 // Try fetching a URL which redirects to https.
345 TEST_F(CertNetFetcherImplTest, RedirectToHttpsNotAllowed) {
346 ASSERT_TRUE(test_server_.Start());
347
348 CertNetFetcherImpl fetcher(&context_);
349
350 GURL url(test_server_.GetURL("files/redirect_https"));
351 TestFetchCallback callback;
352 StartRequest(url, callback, &fetcher);
353 scoped_ptr<FetchResult> result = callback.WaitForResult();
354 result->VerifyFailure(ERR_DISALLOWED_URL_SCHEME);
355
356 EXPECT_EQ(1, network_delegate_.created_requests());
357 }
358
359 // Try fetching an unsupported URL scheme (https) and then immediately
360 // cancelling. This is a bit special because this codepath needs to post a task.
361 TEST_F(CertNetFetcherImplTest, CancelHttpsNotAllowed) {
362 ASSERT_TRUE(test_server_.Start());
363
364 CertNetFetcherImpl fetcher(&context_);
365
366 GURL url("https://foopy/foo.crt");
367 TestFetchCallback callback;
368 CertNetFetcher::RequestId id = StartRequest(url, callback, &fetcher);
369
370 // Should NOT complete synchronously despite being a test that could be done
371 // immediately.
372 EXPECT_FALSE(callback.HasResult());
373
374 EXPECT_EQ(0, network_delegate_.created_requests());
375 fetcher.CancelRequest(id);
davidben 2015/03/31 20:52:24 This probably wants a RunUntilIdle and still asser
eroman 2015/04/04 21:57:15 Done.
376 }
377
378 // Start a few requests, and cancel one of them before running the message loop
379 // again.
380 TEST_F(CertNetFetcherImplTest, CancelBeforeRunningMessageLoop) {
381 ASSERT_TRUE(test_server_.Start());
382
383 CertNetFetcherImpl fetcher(&context_);
384 TestFetchCallback callback1;
385 TestFetchCallback callback2;
386 TestFetchCallback callback3;
387
388 GURL url1 = test_server_.GetURL("files/cert.crt");
389 StartRequest(url1, callback1, &fetcher);
390
391 GURL url2 = test_server_.GetURL("files/root.crl");
392 CertNetFetcher::RequestId id2 = StartRequest(url2, callback2, &fetcher);
393
394 GURL url3 = test_server_.GetURL("files/certs.p7c");
395 StartRequest(url3, callback3, &fetcher);
396
397 EXPECT_EQ(3, network_delegate_.created_requests());
398 EXPECT_FALSE(callback1.HasResult());
399 EXPECT_FALSE(callback2.HasResult());
400 EXPECT_FALSE(callback3.HasResult());
401
402 // Cancel the second request.
403 fetcher.CancelRequest(id2);
404
405 // Wait for the non-cancelled requests to complete.
406 scoped_ptr<FetchResult> result1 = callback1.WaitForResult();
407 scoped_ptr<FetchResult> result3 = callback3.WaitForResult();
408
409 // Verify the fetch results.
410 result1->VerifySuccess("-cert.crt-\n");
411 result3->VerifySuccess("-certs.p7c-\n");
412
413 EXPECT_FALSE(callback2.HasResult());
414 }
415
416 // Start several requests, and cancel one of them after the first has completed.
417 // NOTE: The python test server is single threaded and can only service one
418 // request at a time. After a socket is opened by the server it waits for it to
419 // be completed, and any subsequent request will hang until the first socket is
420 // closed.
421 // Cancelling the first request can therefore be problematic, since if
422 // cancellation is done after the socket is opened but before reading/writing,
423 // then the socket is re-cycled and things will be stalled until the cleanup
424 // timer (10 seconds) closes it.
425 // To work around this, the last request is cancelled, and hope that the
426 // requests are given opened sockets in a FIFO order.
davidben 2015/03/31 20:52:25 Perhaps if we configured the socket pool allow a m
eroman 2015/04/04 21:57:15 I took a quick look on how to configure that and d
427 TEST_F(CertNetFetcherImplTest, CancelAfterRunningMessageLoop) {
428 ASSERT_TRUE(test_server_.Start());
429
430 CertNetFetcherImpl fetcher(&context_);
431 TestFetchCallback callback1;
432 TestFetchCallback callback2;
433 TestFetchCallback callback3;
434
435 GURL url1 = test_server_.GetURL("files/cert.crt");
436 StartRequest(url1, callback1, &fetcher);
437
438 GURL url2 = test_server_.GetURL("files/certs.p7c");
439 CertNetFetcher::RequestId id2 = StartRequest(url2, callback2, &fetcher);
440
441 GURL url3("ftp://www.not.supported.com/foo");
442 StartRequest(url3, callback3, &fetcher);
443
444 EXPECT_FALSE(callback1.HasResult());
445 EXPECT_FALSE(callback2.HasResult());
446 EXPECT_FALSE(callback3.HasResult());
447
448 // Wait for the fast request to complete.
davidben 2015/03/31 20:52:23 fast -> last?
eroman 2015/04/04 21:57:15 Fast was intentional -- The last request is for an
449 scoped_ptr<FetchResult> result3 = callback3.WaitForResult();
450 result3->VerifyFailure(ERR_DISALLOWED_URL_SCHEME);
451
452 // Cancel the second outstanding request.
453 fetcher.CancelRequest(id2);
davidben 2015/03/31 20:52:24 This assumes that callback2 hasn't fired yet. (Rea
eroman 2015/04/04 21:57:15 With the new scoped_ptr<Request> approach this is
454
455 // Wait for the first request to complete.
456 scoped_ptr<FetchResult> result2 = callback1.WaitForResult();
457
458 // Verify the fetch results.
459 result2->VerifySuccess("-cert.crt-\n");
460 }
461
462 // Delete a CertNetFetcherImpl with outstanding requests on it.
463 TEST_F(CertNetFetcherImplTest, DeleteCancels) {
464 ASSERT_TRUE(test_server_.Start());
465
466 CertNetFetcherImpl fetcher(&context_);
467
468 GURL url(test_server_.GetURL("slow/certs.p7c?20.1"));
davidben 2015/03/31 20:52:26 Why 20.1 instead of 20?
eroman 2015/04/04 21:57:15 Done.
469 TestFetchCallback callback;
470 StartRequest(url, callback, &fetcher);
471
472 // Note that the request is never completed, nor cancelled.
473 }
474
475 // Fetch the same URLs in parallel and verify that only 1 request is made per
476 // URL.
477 TEST_F(CertNetFetcherImplTest, ParallelFetchDupes) {
davidben 2015/03/31 20:52:25 Nit: Dupes is a strange word. Duplicates? :-)
eroman 2015/04/04 21:57:15 Done.
478 ASSERT_TRUE(test_server_.Start());
479
480 CertNetFetcherImpl fetcher(&context_);
481
482 GURL url1 = test_server_.GetURL("files/cert.crt");
483 GURL url2 = test_server_.GetURL("files/root.crl");
484
485 // Issue 3 requests for url1, and 3 requests for url2
486 TestFetchCallback callback1;
487 CertNetFetcher::RequestId request1 = StartRequest(url1, callback1, &fetcher);
488
489 TestFetchCallback callback2;
490 StartRequest(url2, callback2, &fetcher);
491
492 TestFetchCallback callback3;
493 CertNetFetcher::RequestId request3 = StartRequest(url1, callback3, &fetcher);
494
495 TestFetchCallback callback4;
496 StartRequest(url2, callback4, &fetcher);
497
498 TestFetchCallback callback5;
499 StartRequest(url2, callback5, &fetcher);
500
501 TestFetchCallback callback6;
502 StartRequest(url1, callback6, &fetcher);
503
504 // Cancel all but one of the requests for url1.
505 fetcher.CancelRequest(request1);
506 fetcher.CancelRequest(request3);
507
508 // Wait for the remaining requests to finish.
509 scoped_ptr<FetchResult> result2 = callback2.WaitForResult();
510 scoped_ptr<FetchResult> result4 = callback4.WaitForResult();
511 scoped_ptr<FetchResult> result5 = callback5.WaitForResult();
512 scoped_ptr<FetchResult> result6 = callback6.WaitForResult();
513
514 // Verify that none of the cancelled requests for url1 completed (since they
515 // were cancelled).
516 EXPECT_FALSE(callback1.HasResult());
517 EXPECT_FALSE(callback3.HasResult());
518
519 // Verify the fetch results.
520 result2->VerifySuccess("-root.crl-\n");
521 result4->VerifySuccess("-root.crl-\n");
522 result5->VerifySuccess("-root.crl-\n");
523 result6->VerifySuccess("-cert.crt-\n");
524
525 // Verify that only 2 URLRequests were started even though 6 requests were
526 // issued.
527 EXPECT_EQ(2, network_delegate_.created_requests());
528 }
529
530 // Cancel a request and then start another one for the same URL.
531 TEST_F(CertNetFetcherImplTest, CancelThenStart) {
532 ASSERT_TRUE(test_server_.Start());
533
534 CertNetFetcherImpl fetcher(&context_);
535 TestFetchCallback callback1;
536 CertNetFetcher::RequestId request1;
537
538 TestFetchCallback callback2;
539 CertNetFetcher::RequestId request2;
540
541 TestFetchCallback callback3;
542 CertNetFetcher::RequestId request3;
543
544 GURL url = test_server_.GetURL("files/cert.crt");
545
546 request1 = StartRequest(url, callback1, &fetcher);
547 fetcher.CancelRequest(request1);
548
549 request2 = StartRequest(url, callback2, &fetcher);
550
551 request3 = StartRequest(url, callback3, &fetcher);
552 fetcher.CancelRequest(request3);
553
554 // All but |request2| were canceled.
555 scoped_ptr<FetchResult> result = callback2.WaitForResult();
556
557 result->VerifySuccess("-cert.crt-\n");
558
559 EXPECT_FALSE(callback1.HasResult());
560 EXPECT_FALSE(callback3.HasResult());
561
562 // One URLRequest that was cancelled, then another right afterwards.
563 EXPECT_EQ(2, network_delegate_.created_requests());
564 }
565
566 // Start duplicate requests and then cancel all of them.
567 TEST_F(CertNetFetcherImplTest, CancelAll) {
568 ASSERT_TRUE(test_server_.Start());
569
570 CertNetFetcherImpl fetcher(&context_);
571 TestFetchCallback callback[3];
572 CertNetFetcher::RequestId request[3];
573
574 GURL url = test_server_.GetURL("files/cert.crt");
575
576 for (size_t i = 0; i < arraysize(callback); ++i) {
577 request[i] = StartRequest(url, callback[i], &fetcher);
578 }
davidben 2015/03/31 20:52:25 Nit: This line has curlies while the rest don't.
eroman 2015/04/04 21:57:15 Done.
579
580 for (size_t i = 0; i < arraysize(request); ++i)
581 fetcher.CancelRequest(request[i]);
582
583 EXPECT_EQ(1, network_delegate_.created_requests());
584
585 for (size_t i = 0; i < arraysize(request); ++i)
586 EXPECT_FALSE(callback[i].HasResult());
587 }
588
589 void DeleteCertNetFetcher(CertNetFetcher* fetcher) {
590 delete fetcher;
591 }
592
593 // Delete the CertNetFetcherImpl within a request callback.
594 TEST_F(CertNetFetcherImplTest, DeleteWithinCallback) {
595 ASSERT_TRUE(test_server_.Start());
596
597 // Deleted by callback2.
598 CertNetFetcher* fetcher = new CertNetFetcherImpl(&context_);
599
600 GURL url = test_server_.GetURL("files/cert.crt");
601
602 TestFetchCallback callback[4];
603 callback[1].set_extra_closure(base::Bind(DeleteCertNetFetcher, fetcher));
604
605 for (size_t i = 0; i < arraysize(callback); ++i)
606 StartRequest(url, callback[i], fetcher);
607
608 EXPECT_EQ(1, network_delegate_.created_requests());
609
610 callback[1].WaitForResult();
611
612 // Assume requests for the same URL are executed in FIFO order.
613 EXPECT_TRUE(callback[0].HasResult());
614 EXPECT_FALSE(callback[2].HasResult());
615 EXPECT_FALSE(callback[3].HasResult());
616 }
617
618 void FetchRequest(CertNetFetcher* fetcher,
619 const GURL& url,
620 TestFetchCallback* callback) {
621 StartRequest(url, *callback, fetcher);
622 }
623
624 // Make a request during callback for the same URL.
625 TEST_F(CertNetFetcherImplTest, FetchWithinCallback) {
626 ASSERT_TRUE(test_server_.Start());
627
628 CertNetFetcherImpl fetcher(&context_);
629
630 GURL url = test_server_.GetURL("files/cert.crt");
631
632 TestFetchCallback callback[5];
633 callback[1].set_extra_closure(
634 base::Bind(FetchRequest, &fetcher, url, &callback[4]));
635
636 for (size_t i = 0; i < arraysize(callback) - 1; ++i)
637 StartRequest(url, callback[i], &fetcher);
638
639 EXPECT_EQ(1, network_delegate_.created_requests());
640
641 for (size_t i = 0; i < arraysize(callback); ++i) {
642 scoped_ptr<FetchResult> result = callback[i].WaitForResult();
643 result->VerifySuccess("-cert.crt-\n");
644 }
645
646 // The fetch started within a callback should have started a new request
647 // rather than attaching to the current job.
648 EXPECT_EQ(2, network_delegate_.created_requests());
649 }
650
651 void CancelRequest(CertNetFetcher* fetcher, CertNetFetcher::RequestId request) {
652 fetcher->CancelRequest(request);
653 }
654
655 // Cancel a request while executing a callback for the same job.
656 TEST_F(CertNetFetcherImplTest, CancelWithinCallback) {
657 ASSERT_TRUE(test_server_.Start());
658
659 CertNetFetcherImpl fetcher(&context_);
660
661 GURL url = test_server_.GetURL("files/cert.crt");
662
663 TestFetchCallback callback[4];
664 CertNetFetcher::RequestId request[4];
665
666 for (size_t i = 0; i < arraysize(callback); ++i) {
667 request[i] = StartRequest(url, callback[i], &fetcher);
668 }
669
670 // Cancel request[2] when the callback for request[1] runs.
671 callback[1].set_extra_closure(
672 base::Bind(CancelRequest, &fetcher, request[2]));
673
674 EXPECT_EQ(1, network_delegate_.created_requests());
675
676 for (size_t i = 0; i < arraysize(request); ++i) {
677 if (i == 2)
678 continue;
679
680 scoped_ptr<FetchResult> result = callback[i].WaitForResult();
681 result->VerifySuccess("-cert.crt-\n");
682 }
683
684 // request[2] was cancelled.
685 EXPECT_FALSE(callback[2].HasResult());
686 }
687
688 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698