Remove PlatformFile from profile_browsertest
[chromium-blink-merge.git] / content / browser / loader / resource_loader_unittest.cc
blobc4183d0d85f6689e0f75e4bc333393b07eb70383
1 // Copyright (c) 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.
5 #include "content/browser/loader/resource_loader.h"
7 #include "base/file_util.h"
8 #include "base/files/file.h"
9 #include "base/message_loop/message_loop_proxy.h"
10 #include "base/platform_file.h"
11 #include "base/run_loop.h"
12 #include "content/browser/browser_thread_impl.h"
13 #include "content/browser/loader/redirect_to_file_resource_handler.h"
14 #include "content/browser/loader/resource_loader_delegate.h"
15 #include "content/public/browser/resource_request_info.h"
16 #include "content/public/common/resource_response.h"
17 #include "content/public/test/mock_resource_context.h"
18 #include "content/public/test/test_browser_thread_bundle.h"
19 #include "content/test/test_content_browser_client.h"
20 #include "ipc/ipc_message.h"
21 #include "net/base/mock_file_stream.h"
22 #include "net/base/request_priority.h"
23 #include "net/cert/x509_certificate.h"
24 #include "net/ssl/client_cert_store.h"
25 #include "net/ssl/ssl_cert_request_info.h"
26 #include "net/url_request/url_request.h"
27 #include "net/url_request/url_request_job_factory_impl.h"
28 #include "net/url_request/url_request_test_job.h"
29 #include "net/url_request/url_request_test_util.h"
30 #include "testing/gtest/include/gtest/gtest.h"
31 #include "webkit/common/blob/shareable_file_reference.h"
33 using webkit_blob::ShareableFileReference;
35 namespace content {
36 namespace {
38 // Stub client certificate store that returns a preset list of certificates for
39 // each request and records the arguments of the most recent request for later
40 // inspection.
41 class ClientCertStoreStub : public net::ClientCertStore {
42 public:
43 ClientCertStoreStub(const net::CertificateList& certs)
44 : response_(certs),
45 request_count_(0) {}
47 virtual ~ClientCertStoreStub() {}
49 // Returns |cert_authorities| field of the certificate request passed in the
50 // most recent call to GetClientCerts().
51 // TODO(ppi): Make the stub independent from the internal representation of
52 // SSLCertRequestInfo. For now it seems that we cannot neither save the
53 // scoped_refptr<> (since it is never passed to us) nor copy the entire
54 // CertificateRequestInfo (since there is no copy constructor).
55 std::vector<std::string> requested_authorities() {
56 return requested_authorities_;
59 // Returns the number of calls to GetClientCerts().
60 int request_count() {
61 return request_count_;
64 // net::ClientCertStore:
65 virtual void GetClientCerts(const net::SSLCertRequestInfo& cert_request_info,
66 net::CertificateList* selected_certs,
67 const base::Closure& callback) OVERRIDE {
68 ++request_count_;
69 requested_authorities_ = cert_request_info.cert_authorities;
70 *selected_certs = response_;
71 callback.Run();
74 private:
75 const net::CertificateList response_;
76 int request_count_;
77 std::vector<std::string> requested_authorities_;
80 // Dummy implementation of ResourceHandler, instance of which is needed to
81 // initialize ResourceLoader.
82 class ResourceHandlerStub : public ResourceHandler {
83 public:
84 explicit ResourceHandlerStub(net::URLRequest* request)
85 : ResourceHandler(request),
86 defer_request_on_will_start_(false),
87 received_response_completed_(false),
88 total_bytes_downloaded_(0) {
91 void set_defer_request_on_will_start(bool defer_request_on_will_start) {
92 defer_request_on_will_start_ = defer_request_on_will_start;
95 const GURL& start_url() const { return start_url_; }
96 ResourceResponse* response() const { return response_.get(); }
97 bool received_response_completed() const {
98 return received_response_completed_;
100 const net::URLRequestStatus& status() const { return status_; }
101 int total_bytes_downloaded() const { return total_bytes_downloaded_; }
103 void Resume() {
104 controller()->Resume();
107 // ResourceHandler implementation:
108 virtual bool OnUploadProgress(int request_id,
109 uint64 position,
110 uint64 size) OVERRIDE {
111 NOTREACHED();
112 return true;
115 virtual bool OnRequestRedirected(int request_id,
116 const GURL& url,
117 ResourceResponse* response,
118 bool* defer) OVERRIDE {
119 NOTREACHED();
120 return true;
123 virtual bool OnResponseStarted(int request_id,
124 ResourceResponse* response,
125 bool* defer) OVERRIDE {
126 EXPECT_FALSE(response_);
127 response_ = response;
128 return true;
131 virtual bool OnWillStart(int request_id,
132 const GURL& url,
133 bool* defer) OVERRIDE {
134 EXPECT_TRUE(start_url_.is_empty());
135 start_url_ = url;
136 *defer = defer_request_on_will_start_;
137 return true;
140 virtual bool OnBeforeNetworkStart(int request_id,
141 const GURL& url,
142 bool* defer) OVERRIDE {
143 return true;
146 virtual bool OnWillRead(int request_id,
147 scoped_refptr<net::IOBuffer>* buf,
148 int* buf_size,
149 int min_size) OVERRIDE {
150 NOTREACHED();
151 return false;
154 virtual bool OnReadCompleted(int request_id,
155 int bytes_read,
156 bool* defer) OVERRIDE {
157 NOTREACHED();
158 return false;
161 virtual void OnResponseCompleted(int request_id,
162 const net::URLRequestStatus& status,
163 const std::string& security_info,
164 bool* defer) OVERRIDE {
165 // TODO(davidben): This DCHECK currently fires everywhere. Fix the places in
166 // ResourceLoader where OnResponseCompleted is signaled twice.
167 // DCHECK(!received_response_completed_);
168 received_response_completed_ = true;
169 status_ = status;
172 virtual void OnDataDownloaded(int request_id,
173 int bytes_downloaded) OVERRIDE {
174 total_bytes_downloaded_ += bytes_downloaded;
177 private:
178 bool defer_request_on_will_start_;
179 GURL start_url_;
180 scoped_refptr<ResourceResponse> response_;
181 bool received_response_completed_;
182 net::URLRequestStatus status_;
183 int total_bytes_downloaded_;
186 // Test browser client that captures calls to SelectClientCertificates and
187 // records the arguments of the most recent call for later inspection.
188 class SelectCertificateBrowserClient : public TestContentBrowserClient {
189 public:
190 SelectCertificateBrowserClient() : call_count_(0) {}
192 virtual void SelectClientCertificate(
193 int render_process_id,
194 int render_view_id,
195 const net::HttpNetworkSession* network_session,
196 net::SSLCertRequestInfo* cert_request_info,
197 const base::Callback<void(net::X509Certificate*)>& callback) OVERRIDE {
198 ++call_count_;
199 passed_certs_ = cert_request_info->client_certs;
202 int call_count() {
203 return call_count_;
206 net::CertificateList passed_certs() {
207 return passed_certs_;
210 private:
211 net::CertificateList passed_certs_;
212 int call_count_;
215 class ResourceContextStub : public MockResourceContext {
216 public:
217 explicit ResourceContextStub(net::URLRequestContext* test_request_context)
218 : MockResourceContext(test_request_context) {}
220 virtual scoped_ptr<net::ClientCertStore> CreateClientCertStore() OVERRIDE {
221 return dummy_cert_store_.Pass();
224 void SetClientCertStore(scoped_ptr<net::ClientCertStore> store) {
225 dummy_cert_store_ = store.Pass();
228 private:
229 scoped_ptr<net::ClientCertStore> dummy_cert_store_;
232 // Fails to create a temporary file with the given error.
233 void CreateTemporaryError(
234 base::File::Error error,
235 const CreateTemporaryFileStreamCallback& callback) {
236 base::MessageLoop::current()->PostTask(
237 FROM_HERE,
238 base::Bind(callback, error, base::Passed(scoped_ptr<net::FileStream>()),
239 scoped_refptr<ShareableFileReference>()));
242 } // namespace
244 class ResourceLoaderTest : public testing::Test,
245 public ResourceLoaderDelegate {
246 protected:
247 ResourceLoaderTest()
248 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
249 resource_context_(&test_url_request_context_),
250 raw_ptr_resource_handler_(NULL),
251 raw_ptr_to_request_(NULL) {
252 job_factory_.SetProtocolHandler(
253 "test", net::URLRequestTestJob::CreateProtocolHandler());
254 test_url_request_context_.set_job_factory(&job_factory_);
257 GURL test_url() const {
258 return net::URLRequestTestJob::test_url_1();
261 std::string test_data() const {
262 return net::URLRequestTestJob::test_data_1();
265 virtual scoped_ptr<ResourceHandler> WrapResourceHandler(
266 scoped_ptr<ResourceHandlerStub> leaf_handler,
267 net::URLRequest* request) {
268 return leaf_handler.PassAs<ResourceHandler>();
271 virtual void SetUp() OVERRIDE {
272 const int kRenderProcessId = 1;
273 const int kRenderViewId = 2;
275 scoped_ptr<net::URLRequest> request(
276 new net::URLRequest(test_url(),
277 net::DEFAULT_PRIORITY,
278 NULL,
279 resource_context_.GetRequestContext()));
280 raw_ptr_to_request_ = request.get();
281 ResourceRequestInfo::AllocateForTesting(request.get(),
282 ResourceType::MAIN_FRAME,
283 &resource_context_,
284 kRenderProcessId,
285 kRenderViewId,
286 MSG_ROUTING_NONE,
287 false);
288 scoped_ptr<ResourceHandlerStub> resource_handler(
289 new ResourceHandlerStub(request.get()));
290 raw_ptr_resource_handler_ = resource_handler.get();
291 loader_.reset(new ResourceLoader(
292 request.Pass(),
293 WrapResourceHandler(resource_handler.Pass(), raw_ptr_to_request_),
294 this));
297 // ResourceLoaderDelegate:
298 virtual ResourceDispatcherHostLoginDelegate* CreateLoginDelegate(
299 ResourceLoader* loader,
300 net::AuthChallengeInfo* auth_info) OVERRIDE {
301 return NULL;
303 virtual bool HandleExternalProtocol(ResourceLoader* loader,
304 const GURL& url) OVERRIDE {
305 return false;
307 virtual void DidStartRequest(ResourceLoader* loader) OVERRIDE {}
308 virtual void DidReceiveRedirect(ResourceLoader* loader,
309 const GURL& new_url) OVERRIDE {}
310 virtual void DidReceiveResponse(ResourceLoader* loader) OVERRIDE {}
311 virtual void DidFinishLoading(ResourceLoader* loader) OVERRIDE {}
313 content::TestBrowserThreadBundle thread_bundle_;
315 net::URLRequestJobFactoryImpl job_factory_;
316 net::TestURLRequestContext test_url_request_context_;
317 ResourceContextStub resource_context_;
319 // The ResourceLoader owns the URLRequest and the ResourceHandler.
320 ResourceHandlerStub* raw_ptr_resource_handler_;
321 net::URLRequest* raw_ptr_to_request_;
322 scoped_ptr<ResourceLoader> loader_;
325 // Verifies if a call to net::UrlRequest::Delegate::OnCertificateRequested()
326 // causes client cert store to be queried for certificates and if the returned
327 // certificates are correctly passed to the content browser client for
328 // selection.
329 TEST_F(ResourceLoaderTest, ClientCertStoreLookup) {
330 // Set up the test client cert store.
331 net::CertificateList dummy_certs(1, scoped_refptr<net::X509Certificate>(
332 new net::X509Certificate("test", "test", base::Time(), base::Time())));
333 scoped_ptr<ClientCertStoreStub> test_store(
334 new ClientCertStoreStub(dummy_certs));
335 EXPECT_EQ(0, test_store->request_count());
337 // Ownership of the |test_store| is about to be turned over to ResourceLoader.
338 // We need to keep raw pointer copies to access these objects later.
339 ClientCertStoreStub* raw_ptr_to_store = test_store.get();
340 resource_context_.SetClientCertStore(
341 test_store.PassAs<net::ClientCertStore>());
343 // Prepare a dummy certificate request.
344 scoped_refptr<net::SSLCertRequestInfo> cert_request_info(
345 new net::SSLCertRequestInfo());
346 std::vector<std::string> dummy_authority(1, "dummy");
347 cert_request_info->cert_authorities = dummy_authority;
349 // Plug in test content browser client.
350 SelectCertificateBrowserClient test_client;
351 ContentBrowserClient* old_client = SetBrowserClientForTesting(&test_client);
353 // Everything is set up. Trigger the resource loader certificate request event
354 // and run the message loop.
355 loader_->OnCertificateRequested(raw_ptr_to_request_, cert_request_info.get());
356 base::RunLoop().RunUntilIdle();
358 // Restore the original content browser client.
359 SetBrowserClientForTesting(old_client);
361 // Check if the test store was queried against correct |cert_authorities|.
362 EXPECT_EQ(1, raw_ptr_to_store->request_count());
363 EXPECT_EQ(dummy_authority, raw_ptr_to_store->requested_authorities());
365 // Check if the retrieved certificates were passed to the content browser
366 // client.
367 EXPECT_EQ(1, test_client.call_count());
368 EXPECT_EQ(dummy_certs, test_client.passed_certs());
371 // Verifies if a call to net::URLRequest::Delegate::OnCertificateRequested()
372 // on a platform with a NULL client cert store still calls the content browser
373 // client for selection.
374 TEST_F(ResourceLoaderTest, ClientCertStoreNull) {
375 // Prepare a dummy certificate request.
376 scoped_refptr<net::SSLCertRequestInfo> cert_request_info(
377 new net::SSLCertRequestInfo());
378 std::vector<std::string> dummy_authority(1, "dummy");
379 cert_request_info->cert_authorities = dummy_authority;
381 // Plug in test content browser client.
382 SelectCertificateBrowserClient test_client;
383 ContentBrowserClient* old_client = SetBrowserClientForTesting(&test_client);
385 // Everything is set up. Trigger the resource loader certificate request event
386 // and run the message loop.
387 loader_->OnCertificateRequested(raw_ptr_to_request_, cert_request_info.get());
388 base::RunLoop().RunUntilIdle();
390 // Restore the original content browser client.
391 SetBrowserClientForTesting(old_client);
393 // Check if the SelectClientCertificate was called on the content browser
394 // client.
395 EXPECT_EQ(1, test_client.call_count());
396 EXPECT_EQ(net::CertificateList(), test_client.passed_certs());
399 TEST_F(ResourceLoaderTest, ResumeCancelledRequest) {
400 raw_ptr_resource_handler_->set_defer_request_on_will_start(true);
402 loader_->StartRequest();
403 loader_->CancelRequest(true);
404 static_cast<ResourceController*>(loader_.get())->Resume();
407 class ResourceLoaderRedirectToFileTest : public ResourceLoaderTest {
408 public:
409 ResourceLoaderRedirectToFileTest()
410 : file_stream_(NULL),
411 redirect_to_file_resource_handler_(NULL) {
414 base::FilePath temp_path() const { return temp_path_; }
415 ShareableFileReference* deletable_file() const {
416 return deletable_file_.get();
418 net::testing::MockFileStream* file_stream() const { return file_stream_; }
419 RedirectToFileResourceHandler* redirect_to_file_resource_handler() const {
420 return redirect_to_file_resource_handler_;
423 void ReleaseLoader() {
424 file_stream_ = NULL;
425 deletable_file_ = NULL;
426 loader_.reset();
429 virtual scoped_ptr<ResourceHandler> WrapResourceHandler(
430 scoped_ptr<ResourceHandlerStub> leaf_handler,
431 net::URLRequest* request) OVERRIDE {
432 // Make a temporary file.
433 CHECK(base::CreateTemporaryFile(&temp_path_));
434 base::PlatformFile platform_file =
435 base::CreatePlatformFile(temp_path_,
436 base::PLATFORM_FILE_WRITE |
437 base::PLATFORM_FILE_TEMPORARY |
438 base::PLATFORM_FILE_CREATE_ALWAYS |
439 base::PLATFORM_FILE_ASYNC,
440 NULL, NULL);
441 CHECK_NE(base::kInvalidPlatformFileValue, platform_file);
443 // Create mock file streams and a ShareableFileReference.
444 scoped_ptr<net::testing::MockFileStream> file_stream(
445 new net::testing::MockFileStream(
446 platform_file,
447 base::PLATFORM_FILE_WRITE | base::PLATFORM_FILE_ASYNC,
448 NULL, base::MessageLoopProxy::current()));
449 file_stream_ = file_stream.get();
450 deletable_file_ = ShareableFileReference::GetOrCreate(
451 temp_path_,
452 ShareableFileReference::DELETE_ON_FINAL_RELEASE,
453 BrowserThread::GetMessageLoopProxyForThread(
454 BrowserThread::FILE).get());
456 // Inject them into the handler.
457 scoped_ptr<RedirectToFileResourceHandler> handler(
458 new RedirectToFileResourceHandler(
459 leaf_handler.PassAs<ResourceHandler>(), request));
460 redirect_to_file_resource_handler_ = handler.get();
461 handler->SetCreateTemporaryFileStreamFunctionForTesting(
462 base::Bind(&ResourceLoaderRedirectToFileTest::PostCallback,
463 base::Unretained(this),
464 base::Passed(file_stream.PassAs<net::FileStream>())));
465 return handler.PassAs<ResourceHandler>();
468 private:
469 void PostCallback(
470 scoped_ptr<net::FileStream> file_stream,
471 const CreateTemporaryFileStreamCallback& callback) {
472 base::MessageLoop::current()->PostTask(
473 FROM_HERE,
474 base::Bind(callback, base::File::FILE_OK,
475 base::Passed(&file_stream), deletable_file_));
478 base::FilePath temp_path_;
479 scoped_refptr<ShareableFileReference> deletable_file_;
480 // These are owned by the ResourceLoader.
481 net::testing::MockFileStream* file_stream_;
482 RedirectToFileResourceHandler* redirect_to_file_resource_handler_;
485 // Tests that a RedirectToFileResourceHandler works and forwards everything
486 // downstream.
487 TEST_F(ResourceLoaderRedirectToFileTest, Basic) {
488 // Run it to completion.
489 loader_->StartRequest();
490 base::RunLoop().RunUntilIdle();
492 // Check that the handler forwarded all information to the downstream handler.
493 EXPECT_EQ(temp_path(),
494 raw_ptr_resource_handler_->response()->head.download_file_path);
495 EXPECT_EQ(test_url(), raw_ptr_resource_handler_->start_url());
496 EXPECT_TRUE(raw_ptr_resource_handler_->received_response_completed());
497 EXPECT_EQ(net::URLRequestStatus::SUCCESS,
498 raw_ptr_resource_handler_->status().status());
499 EXPECT_EQ(test_data().size(), static_cast<size_t>(
500 raw_ptr_resource_handler_->total_bytes_downloaded()));
502 // Check that the data was written to the file.
503 std::string contents;
504 ASSERT_TRUE(base::ReadFileToString(temp_path(), &contents));
505 EXPECT_EQ(test_data(), contents);
507 // Release the loader and the saved reference to file. The file should be gone
508 // now.
509 ReleaseLoader();
510 base::RunLoop().RunUntilIdle();
511 EXPECT_FALSE(base::PathExists(temp_path()));
514 // Tests that RedirectToFileResourceHandler handles errors in creating the
515 // temporary file.
516 TEST_F(ResourceLoaderRedirectToFileTest, CreateTemporaryError) {
517 // Swap out the create temporary function.
518 redirect_to_file_resource_handler()->
519 SetCreateTemporaryFileStreamFunctionForTesting(
520 base::Bind(&CreateTemporaryError, base::File::FILE_ERROR_FAILED));
522 // Run it to completion.
523 loader_->StartRequest();
524 base::RunLoop().RunUntilIdle();
526 // To downstream, the request was canceled.
527 EXPECT_TRUE(raw_ptr_resource_handler_->received_response_completed());
528 EXPECT_EQ(net::URLRequestStatus::CANCELED,
529 raw_ptr_resource_handler_->status().status());
530 EXPECT_EQ(0, raw_ptr_resource_handler_->total_bytes_downloaded());
533 // Tests that RedirectToFileResourceHandler handles synchronous write errors.
534 TEST_F(ResourceLoaderRedirectToFileTest, WriteError) {
535 file_stream()->set_forced_error(net::ERR_FAILED);
537 // Run it to completion.
538 loader_->StartRequest();
539 base::RunLoop().RunUntilIdle();
541 // To downstream, the request was canceled sometime after it started, but
542 // before any data was written.
543 EXPECT_EQ(temp_path(),
544 raw_ptr_resource_handler_->response()->head.download_file_path);
545 EXPECT_EQ(test_url(), raw_ptr_resource_handler_->start_url());
546 EXPECT_TRUE(raw_ptr_resource_handler_->received_response_completed());
547 EXPECT_EQ(net::URLRequestStatus::CANCELED,
548 raw_ptr_resource_handler_->status().status());
549 EXPECT_EQ(0, raw_ptr_resource_handler_->total_bytes_downloaded());
551 // Release the loader. The file should be gone now.
552 ReleaseLoader();
553 base::RunLoop().RunUntilIdle();
554 EXPECT_FALSE(base::PathExists(temp_path()));
557 // Tests that RedirectToFileResourceHandler handles asynchronous write errors.
558 TEST_F(ResourceLoaderRedirectToFileTest, WriteErrorAsync) {
559 file_stream()->set_forced_error_async(net::ERR_FAILED);
561 // Run it to completion.
562 loader_->StartRequest();
563 base::RunLoop().RunUntilIdle();
565 // To downstream, the request was canceled sometime after it started, but
566 // before any data was written.
567 EXPECT_EQ(temp_path(),
568 raw_ptr_resource_handler_->response()->head.download_file_path);
569 EXPECT_EQ(test_url(), raw_ptr_resource_handler_->start_url());
570 EXPECT_TRUE(raw_ptr_resource_handler_->received_response_completed());
571 EXPECT_EQ(net::URLRequestStatus::CANCELED,
572 raw_ptr_resource_handler_->status().status());
573 EXPECT_EQ(0, raw_ptr_resource_handler_->total_bytes_downloaded());
575 // Release the loader. The file should be gone now.
576 ReleaseLoader();
577 base::RunLoop().RunUntilIdle();
578 EXPECT_FALSE(base::PathExists(temp_path()));
581 // Tests that RedirectToFileHandler defers completion if there are outstanding
582 // writes and accounts for errors which occur in that time.
583 TEST_F(ResourceLoaderRedirectToFileTest, DeferCompletion) {
584 // Program the MockFileStream to error asynchronously, but throttle the
585 // callback.
586 file_stream()->set_forced_error_async(net::ERR_FAILED);
587 file_stream()->ThrottleCallbacks();
589 // Run it as far as it will go.
590 loader_->StartRequest();
591 base::RunLoop().RunUntilIdle();
593 // At this point, the request should have completed.
594 EXPECT_EQ(net::URLRequestStatus::SUCCESS,
595 raw_ptr_to_request_->status().status());
597 // However, the resource loader stack is stuck somewhere after receiving the
598 // response.
599 EXPECT_EQ(temp_path(),
600 raw_ptr_resource_handler_->response()->head.download_file_path);
601 EXPECT_EQ(test_url(), raw_ptr_resource_handler_->start_url());
602 EXPECT_FALSE(raw_ptr_resource_handler_->received_response_completed());
603 EXPECT_EQ(0, raw_ptr_resource_handler_->total_bytes_downloaded());
605 // Now, release the floodgates.
606 file_stream()->ReleaseCallbacks();
607 base::RunLoop().RunUntilIdle();
609 // Although the URLRequest was successful, the leaf handler sees a failure
610 // because the write never completed.
611 EXPECT_TRUE(raw_ptr_resource_handler_->received_response_completed());
612 EXPECT_EQ(net::URLRequestStatus::CANCELED,
613 raw_ptr_resource_handler_->status().status());
615 // Release the loader. The file should be gone now.
616 ReleaseLoader();
617 base::RunLoop().RunUntilIdle();
618 EXPECT_FALSE(base::PathExists(temp_path()));
621 // Tests that a RedirectToFileResourceHandler behaves properly when the
622 // downstream handler defers OnWillStart.
623 TEST_F(ResourceLoaderRedirectToFileTest, DownstreamDeferStart) {
624 // Defer OnWillStart.
625 raw_ptr_resource_handler_->set_defer_request_on_will_start(true);
627 // Run as far as we'll go.
628 loader_->StartRequest();
629 base::RunLoop().RunUntilIdle();
631 // The request should have stopped at OnWillStart.
632 EXPECT_EQ(test_url(), raw_ptr_resource_handler_->start_url());
633 EXPECT_FALSE(raw_ptr_resource_handler_->response());
634 EXPECT_FALSE(raw_ptr_resource_handler_->received_response_completed());
635 EXPECT_EQ(0, raw_ptr_resource_handler_->total_bytes_downloaded());
637 // Now resume the request. Now we complete.
638 raw_ptr_resource_handler_->Resume();
639 base::RunLoop().RunUntilIdle();
641 // Check that the handler forwarded all information to the downstream handler.
642 EXPECT_EQ(temp_path(),
643 raw_ptr_resource_handler_->response()->head.download_file_path);
644 EXPECT_EQ(test_url(), raw_ptr_resource_handler_->start_url());
645 EXPECT_TRUE(raw_ptr_resource_handler_->received_response_completed());
646 EXPECT_EQ(net::URLRequestStatus::SUCCESS,
647 raw_ptr_resource_handler_->status().status());
648 EXPECT_EQ(test_data().size(), static_cast<size_t>(
649 raw_ptr_resource_handler_->total_bytes_downloaded()));
651 // Check that the data was written to the file.
652 std::string contents;
653 ASSERT_TRUE(base::ReadFileToString(temp_path(), &contents));
654 EXPECT_EQ(test_data(), contents);
656 // Release the loader. The file should be gone now.
657 ReleaseLoader();
658 base::RunLoop().RunUntilIdle();
659 EXPECT_FALSE(base::PathExists(temp_path()));
662 } // namespace content