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

Side by Side Diff: content/browser/loader/resource_loader_unittest.cc

Issue 82273002: Fix various issues in RedirectToFileResourceHandler. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rename test fixture Created 6 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 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 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 "content/browser/loader/resource_loader.h" 5 #include "content/browser/loader/resource_loader.h"
6 6
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"
7 #include "base/run_loop.h" 11 #include "base/run_loop.h"
8 #include "content/browser/browser_thread_impl.h" 12 #include "content/browser/browser_thread_impl.h"
13 #include "content/browser/loader/redirect_to_file_resource_handler.h"
9 #include "content/browser/loader/resource_loader_delegate.h" 14 #include "content/browser/loader/resource_loader_delegate.h"
10 #include "content/public/browser/resource_request_info.h" 15 #include "content/public/browser/resource_request_info.h"
16 #include "content/public/common/resource_response.h"
11 #include "content/public/test/mock_resource_context.h" 17 #include "content/public/test/mock_resource_context.h"
12 #include "content/public/test/test_browser_thread_bundle.h" 18 #include "content/public/test/test_browser_thread_bundle.h"
13 #include "content/test/test_content_browser_client.h" 19 #include "content/test/test_content_browser_client.h"
14 #include "ipc/ipc_message.h" 20 #include "ipc/ipc_message.h"
21 #include "net/base/mock_file_stream.h"
15 #include "net/base/request_priority.h" 22 #include "net/base/request_priority.h"
16 #include "net/cert/x509_certificate.h" 23 #include "net/cert/x509_certificate.h"
17 #include "net/ssl/client_cert_store.h" 24 #include "net/ssl/client_cert_store.h"
18 #include "net/ssl/ssl_cert_request_info.h" 25 #include "net/ssl/ssl_cert_request_info.h"
19 #include "net/url_request/url_request.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"
20 #include "net/url_request/url_request_test_util.h" 29 #include "net/url_request/url_request_test_util.h"
21 #include "testing/gtest/include/gtest/gtest.h" 30 #include "testing/gtest/include/gtest/gtest.h"
31 #include "webkit/common/blob/shareable_file_reference.h"
32
33 using webkit_blob::ShareableFileReference;
22 34
23 namespace content { 35 namespace content {
24 namespace { 36 namespace {
25 37
26 // Stub client certificate store that returns a preset list of certificates for 38 // Stub client certificate store that returns a preset list of certificates for
27 // each request and records the arguments of the most recent request for later 39 // each request and records the arguments of the most recent request for later
28 // inspection. 40 // inspection.
29 class ClientCertStoreStub : public net::ClientCertStore { 41 class ClientCertStoreStub : public net::ClientCertStore {
30 public: 42 public:
31 ClientCertStoreStub(const net::CertificateList& certs) 43 ClientCertStoreStub(const net::CertificateList& certs)
(...skipping 30 matching lines...) Expand all
62 private: 74 private:
63 const net::CertificateList response_; 75 const net::CertificateList response_;
64 int request_count_; 76 int request_count_;
65 std::vector<std::string> requested_authorities_; 77 std::vector<std::string> requested_authorities_;
66 }; 78 };
67 79
68 // Dummy implementation of ResourceHandler, instance of which is needed to 80 // Dummy implementation of ResourceHandler, instance of which is needed to
69 // initialize ResourceLoader. 81 // initialize ResourceLoader.
70 class ResourceHandlerStub : public ResourceHandler { 82 class ResourceHandlerStub : public ResourceHandler {
71 public: 83 public:
72 ResourceHandlerStub() 84 explicit ResourceHandlerStub(net::URLRequest* request)
73 : ResourceHandler(NULL), defer_request_on_will_start_(false) {} 85 : ResourceHandler(request),
86 defer_request_on_will_start_(false),
87 received_response_completed_(false),
88 total_bytes_downloaded_(0) {
89 }
74 90
75 void set_defer_request_on_will_start(bool defer_request_on_will_start) { 91 void set_defer_request_on_will_start(bool defer_request_on_will_start) {
76 defer_request_on_will_start_ = defer_request_on_will_start; 92 defer_request_on_will_start_ = defer_request_on_will_start;
77 } 93 }
78 94
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_;
99 }
100 const net::URLRequestStatus& status() const { return status_; }
101 int total_bytes_downloaded() const { return total_bytes_downloaded_; }
102
103 void Resume() {
104 controller()->Resume();
105 }
106
107 // ResourceHandler implementation:
79 virtual bool OnUploadProgress(int request_id, 108 virtual bool OnUploadProgress(int request_id,
80 uint64 position, 109 uint64 position,
81 uint64 size) OVERRIDE { 110 uint64 size) OVERRIDE {
111 NOTREACHED();
82 return true; 112 return true;
83 } 113 }
84 114
85 virtual bool OnRequestRedirected(int request_id, 115 virtual bool OnRequestRedirected(int request_id,
86 const GURL& url, 116 const GURL& url,
87 ResourceResponse* response, 117 ResourceResponse* response,
88 bool* defer) OVERRIDE { 118 bool* defer) OVERRIDE {
119 NOTREACHED();
89 return true; 120 return true;
90 } 121 }
91 122
92 virtual bool OnResponseStarted(int request_id, 123 virtual bool OnResponseStarted(int request_id,
93 ResourceResponse* response, 124 ResourceResponse* response,
94 bool* defer) OVERRIDE { 125 bool* defer) OVERRIDE {
126 EXPECT_FALSE(response_);
127 response_ = response;
95 return true; 128 return true;
96 } 129 }
97 130
98 virtual bool OnWillStart(int request_id, 131 virtual bool OnWillStart(int request_id,
99 const GURL& url, 132 const GURL& url,
100 bool* defer) OVERRIDE { 133 bool* defer) OVERRIDE {
134 EXPECT_TRUE(start_url_.is_empty());
135 start_url_ = url;
101 *defer = defer_request_on_will_start_; 136 *defer = defer_request_on_will_start_;
102 return true; 137 return true;
103 } 138 }
104 139
105 virtual bool OnBeforeNetworkStart(int request_id, 140 virtual bool OnBeforeNetworkStart(int request_id,
106 const GURL& url, 141 const GURL& url,
107 bool* defer) OVERRIDE { 142 bool* defer) OVERRIDE {
108 return true; 143 return true;
109 } 144 }
110 145
111 virtual bool OnWillRead(int request_id, 146 virtual bool OnWillRead(int request_id,
112 scoped_refptr<net::IOBuffer>* buf, 147 scoped_refptr<net::IOBuffer>* buf,
113 int* buf_size, 148 int* buf_size,
114 int min_size) OVERRIDE { 149 int min_size) OVERRIDE {
115 return true; 150 NOTREACHED();
151 return false;
116 } 152 }
117 153
118 virtual bool OnReadCompleted(int request_id, 154 virtual bool OnReadCompleted(int request_id,
119 int bytes_read, 155 int bytes_read,
120 bool* defer) OVERRIDE { 156 bool* defer) OVERRIDE {
121 return true; 157 NOTREACHED();
158 return false;
122 } 159 }
123 160
124 virtual void OnResponseCompleted(int request_id, 161 virtual void OnResponseCompleted(int request_id,
125 const net::URLRequestStatus& status, 162 const net::URLRequestStatus& status,
126 const std::string& security_info, 163 const std::string& security_info,
127 bool* defer) OVERRIDE { 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;
128 } 170 }
129 171
130 virtual void OnDataDownloaded(int request_id, 172 virtual void OnDataDownloaded(int request_id,
131 int bytes_downloaded) OVERRIDE {} 173 int bytes_downloaded) OVERRIDE {
174 total_bytes_downloaded_ += bytes_downloaded;
175 }
132 176
133 private: 177 private:
134 bool defer_request_on_will_start_; 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_;
135 }; 184 };
136 185
137 // Test browser client that captures calls to SelectClientCertificates and 186 // Test browser client that captures calls to SelectClientCertificates and
138 // records the arguments of the most recent call for later inspection. 187 // records the arguments of the most recent call for later inspection.
139 class SelectCertificateBrowserClient : public TestContentBrowserClient { 188 class SelectCertificateBrowserClient : public TestContentBrowserClient {
140 public: 189 public:
141 SelectCertificateBrowserClient() : call_count_(0) {} 190 SelectCertificateBrowserClient() : call_count_(0) {}
142 191
143 virtual void SelectClientCertificate( 192 virtual void SelectClientCertificate(
144 int render_process_id, 193 int render_process_id,
(...skipping 28 matching lines...) Expand all
173 } 222 }
174 223
175 void SetClientCertStore(scoped_ptr<net::ClientCertStore> store) { 224 void SetClientCertStore(scoped_ptr<net::ClientCertStore> store) {
176 dummy_cert_store_ = store.Pass(); 225 dummy_cert_store_ = store.Pass();
177 } 226 }
178 227
179 private: 228 private:
180 scoped_ptr<net::ClientCertStore> dummy_cert_store_; 229 scoped_ptr<net::ClientCertStore> dummy_cert_store_;
181 }; 230 };
182 231
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>()));
240 }
241
183 } // namespace 242 } // namespace
184 243
185 class ResourceLoaderTest : public testing::Test, 244 class ResourceLoaderTest : public testing::Test,
186 public ResourceLoaderDelegate { 245 public ResourceLoaderDelegate {
187 protected: 246 protected:
188 ResourceLoaderTest() 247 ResourceLoaderTest()
189 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP), 248 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
190 resource_context_(&test_url_request_context_) { 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_);
255 }
256
257 GURL test_url() const {
258 return net::URLRequestTestJob::test_url_1();
259 }
260
261 std::string test_data() const {
262 return net::URLRequestTestJob::test_data_1();
263 }
264
265 virtual scoped_ptr<ResourceHandler> WrapResourceHandler(
266 scoped_ptr<ResourceHandlerStub> leaf_handler,
267 net::URLRequest* request) {
268 return leaf_handler.PassAs<ResourceHandler>();
191 } 269 }
192 270
193 virtual void SetUp() OVERRIDE { 271 virtual void SetUp() OVERRIDE {
194 const int kRenderProcessId = 1; 272 const int kRenderProcessId = 1;
195 const int kRenderViewId = 2; 273 const int kRenderViewId = 2;
196 274
197 scoped_ptr<net::URLRequest> request( 275 scoped_ptr<net::URLRequest> request(
198 new net::URLRequest(GURL("dummy"), 276 new net::URLRequest(test_url(),
199 net::DEFAULT_PRIORITY, 277 net::DEFAULT_PRIORITY,
200 NULL, 278 NULL,
201 resource_context_.GetRequestContext())); 279 resource_context_.GetRequestContext()));
202 raw_ptr_to_request_ = request.get(); 280 raw_ptr_to_request_ = request.get();
203 ResourceRequestInfo::AllocateForTesting(request.get(), 281 ResourceRequestInfo::AllocateForTesting(request.get(),
204 ResourceType::MAIN_FRAME, 282 ResourceType::MAIN_FRAME,
205 &resource_context_, 283 &resource_context_,
206 kRenderProcessId, 284 kRenderProcessId,
207 kRenderViewId, 285 kRenderViewId,
208 MSG_ROUTING_NONE, 286 MSG_ROUTING_NONE,
209 false); 287 false);
210 scoped_ptr<ResourceHandlerStub> resource_handler(new ResourceHandlerStub()); 288 scoped_ptr<ResourceHandlerStub> resource_handler(
289 new ResourceHandlerStub(request.get()));
211 raw_ptr_resource_handler_ = resource_handler.get(); 290 raw_ptr_resource_handler_ = resource_handler.get();
212 loader_.reset(new ResourceLoader( 291 loader_.reset(new ResourceLoader(
213 request.Pass(), resource_handler.PassAs<ResourceHandler>(), this)); 292 request.Pass(),
293 WrapResourceHandler(resource_handler.Pass(), raw_ptr_to_request_),
294 this));
214 } 295 }
215 296
216 // ResourceLoaderDelegate: 297 // ResourceLoaderDelegate:
217 virtual ResourceDispatcherHostLoginDelegate* CreateLoginDelegate( 298 virtual ResourceDispatcherHostLoginDelegate* CreateLoginDelegate(
218 ResourceLoader* loader, 299 ResourceLoader* loader,
219 net::AuthChallengeInfo* auth_info) OVERRIDE { 300 net::AuthChallengeInfo* auth_info) OVERRIDE {
220 return NULL; 301 return NULL;
221 } 302 }
222 virtual bool HandleExternalProtocol(ResourceLoader* loader, 303 virtual bool HandleExternalProtocol(ResourceLoader* loader,
223 const GURL& url) OVERRIDE { 304 const GURL& url) OVERRIDE {
224 return false; 305 return false;
225 } 306 }
226 virtual void DidStartRequest(ResourceLoader* loader) OVERRIDE {} 307 virtual void DidStartRequest(ResourceLoader* loader) OVERRIDE {}
227 virtual void DidReceiveRedirect(ResourceLoader* loader, 308 virtual void DidReceiveRedirect(ResourceLoader* loader,
228 const GURL& new_url) OVERRIDE {} 309 const GURL& new_url) OVERRIDE {}
229 virtual void DidReceiveResponse(ResourceLoader* loader) OVERRIDE {} 310 virtual void DidReceiveResponse(ResourceLoader* loader) OVERRIDE {}
230 virtual void DidFinishLoading(ResourceLoader* loader) OVERRIDE {} 311 virtual void DidFinishLoading(ResourceLoader* loader) OVERRIDE {}
231 312
232 content::TestBrowserThreadBundle thread_bundle_; 313 content::TestBrowserThreadBundle thread_bundle_;
233 314
315 net::URLRequestJobFactoryImpl job_factory_;
234 net::TestURLRequestContext test_url_request_context_; 316 net::TestURLRequestContext test_url_request_context_;
235 ResourceContextStub resource_context_; 317 ResourceContextStub resource_context_;
236 318
237 // The ResourceLoader owns the URLRequest and the ResourceHandler. 319 // The ResourceLoader owns the URLRequest and the ResourceHandler.
238 ResourceHandlerStub* raw_ptr_resource_handler_; 320 ResourceHandlerStub* raw_ptr_resource_handler_;
239 net::URLRequest* raw_ptr_to_request_; 321 net::URLRequest* raw_ptr_to_request_;
240 scoped_ptr<ResourceLoader> loader_; 322 scoped_ptr<ResourceLoader> loader_;
241 }; 323 };
242 324
243 // Verifies if a call to net::UrlRequest::Delegate::OnCertificateRequested() 325 // Verifies if a call to net::UrlRequest::Delegate::OnCertificateRequested()
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 } 397 }
316 398
317 TEST_F(ResourceLoaderTest, ResumeCancelledRequest) { 399 TEST_F(ResourceLoaderTest, ResumeCancelledRequest) {
318 raw_ptr_resource_handler_->set_defer_request_on_will_start(true); 400 raw_ptr_resource_handler_->set_defer_request_on_will_start(true);
319 401
320 loader_->StartRequest(); 402 loader_->StartRequest();
321 loader_->CancelRequest(true); 403 loader_->CancelRequest(true);
322 static_cast<ResourceController*>(loader_.get())->Resume(); 404 static_cast<ResourceController*>(loader_.get())->Resume();
323 } 405 }
324 406
407 class ResourceLoaderRedirectToFileTest : public ResourceLoaderTest {
408 public:
409 ResourceLoaderRedirectToFileTest()
410 : file_stream_(NULL),
411 redirect_to_file_resource_handler_(NULL) {
412 }
413
414 base::FilePath temp_path() const { return temp_path_; }
415 ShareableFileReference* deletable_file() const {
416 return deletable_file_.get();
417 }
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_;
421 }
422
423 void ReleaseLoader() {
424 file_stream_ = NULL;
425 deletable_file_ = NULL;
426 loader_.reset();
427 }
428
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);
442
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());
455
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>();
466 }
467
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_));
476 }
477
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_;
483 };
484
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();
491
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()));
501
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);
506
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()));
512 }
513
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));
521
522 // Run it to completion.
523 loader_->StartRequest();
524 base::RunLoop().RunUntilIdle();
525
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());
531 }
532
533 // Tests that RedirectToFileResourceHandler handles synchronous write errors.
534 TEST_F(ResourceLoaderRedirectToFileTest, WriteError) {
535 file_stream()->set_forced_error(net::ERR_FAILED);
536
537 // Run it to completion.
538 loader_->StartRequest();
539 base::RunLoop().RunUntilIdle();
540
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());
550
551 // Release the loader. The file should be gone now.
552 ReleaseLoader();
553 base::RunLoop().RunUntilIdle();
554 EXPECT_FALSE(base::PathExists(temp_path()));
555 }
556
557 // Tests that RedirectToFileResourceHandler handles asynchronous write errors.
558 TEST_F(ResourceLoaderRedirectToFileTest, WriteErrorAsync) {
559 file_stream()->set_forced_error_async(net::ERR_FAILED);
560
561 // Run it to completion.
562 loader_->StartRequest();
563 base::RunLoop().RunUntilIdle();
564
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());
574
575 // Release the loader. The file should be gone now.
576 ReleaseLoader();
577 base::RunLoop().RunUntilIdle();
578 EXPECT_FALSE(base::PathExists(temp_path()));
579 }
580
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();
588
589 // Run it as far as it will go.
590 loader_->StartRequest();
591 base::RunLoop().RunUntilIdle();
592
593 // At this point, the request should have completed.
594 EXPECT_EQ(net::URLRequestStatus::SUCCESS,
595 raw_ptr_to_request_->status().status());
596
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());
604
605 // Now, release the floodgates.
606 file_stream()->ReleaseCallbacks();
607 base::RunLoop().RunUntilIdle();
608
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());
614
615 // Release the loader. The file should be gone now.
616 ReleaseLoader();
617 base::RunLoop().RunUntilIdle();
618 EXPECT_FALSE(base::PathExists(temp_path()));
619 }
620
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);
626
627 // Run as far as we'll go.
628 loader_->StartRequest();
629 base::RunLoop().RunUntilIdle();
630
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());
636
637 // Now resume the request. Now we complete.
638 raw_ptr_resource_handler_->Resume();
639 base::RunLoop().RunUntilIdle();
640
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()));
650
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);
655
656 // Release the loader. The file should be gone now.
657 ReleaseLoader();
658 base::RunLoop().RunUntilIdle();
659 EXPECT_FALSE(base::PathExists(temp_path()));
660 }
661
325 } // namespace content 662 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/loader/resource_dispatcher_host_unittest.cc ('k') | content/browser/loader/sync_resource_handler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698