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

Side by Side Diff: chrome/browser/download/download_browsertest.cc

Issue 7796014: Make cancel remove cancelled download from active queues at time of cancel. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix to try to get past main waterfall failure. Created 9 years, 3 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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "base/file_path.h" 5 #include "base/file_path.h"
6 #include "base/file_util.h" 6 #include "base/file_util.h"
7 #include "base/memory/ref_counted.h" 7 #include "base/memory/ref_counted.h"
8 #include "base/path_service.h" 8 #include "base/path_service.h"
9 #include "base/scoped_temp_dir.h" 9 #include "base/scoped_temp_dir.h"
10 #include "base/stl_util.h" 10 #include "base/stl_util.h"
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 const char kGoodCrxId[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf"; 51 const char kGoodCrxId[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
52 const FilePath kGoodCrxPath(FILE_PATH_LITERAL("extensions/good.crx")); 52 const FilePath kGoodCrxPath(FILE_PATH_LITERAL("extensions/good.crx"));
53 53
54 const char kLargeThemeCrxId[] = "pjpgmfcmabopnnfonnhmdjglfpjjfkbf"; 54 const char kLargeThemeCrxId[] = "pjpgmfcmabopnnfonnhmdjglfpjjfkbf";
55 const FilePath kLargeThemePath(FILE_PATH_LITERAL("extensions/theme2.crx")); 55 const FilePath kLargeThemePath(FILE_PATH_LITERAL("extensions/theme2.crx"));
56 56
57 // Action a test should take if a dangerous download is encountered. 57 // Action a test should take if a dangerous download is encountered.
58 enum DangerousDownloadAction { 58 enum DangerousDownloadAction {
59 ON_DANGEROUS_DOWNLOAD_ACCEPT, // Accept the download 59 ON_DANGEROUS_DOWNLOAD_ACCEPT, // Accept the download
60 ON_DANGEROUS_DOWNLOAD_DENY, // Deny the download 60 ON_DANGEROUS_DOWNLOAD_DENY, // Deny the download
61 ON_DANGEROUS_DOWNLOAD_IGNORE, // Don't do anything; calling code will handle.
61 ON_DANGEROUS_DOWNLOAD_FAIL // Fail if a dangerous download is seen 62 ON_DANGEROUS_DOWNLOAD_FAIL // Fail if a dangerous download is seen
62 }; 63 };
63 64
64 // Fake user click on "Accept". 65 // Fake user click on "Accept".
65 void AcceptDangerousDownload(scoped_refptr<DownloadManager> download_manager, 66 void AcceptDangerousDownload(scoped_refptr<DownloadManager> download_manager,
66 int32 download_id) { 67 int32 download_id) {
67 DownloadItem* download = download_manager->GetDownloadItem(download_id); 68 DownloadItem* download = download_manager->GetDownloadItem(download_id);
68 download->DangerousDownloadValidated(); 69 download->DangerousDownloadValidated();
69 } 70 }
70 71
71 // Fake user click on "Deny". 72 // Fake user click on "Deny".
72 void DenyDangerousDownload(scoped_refptr<DownloadManager> download_manager, 73 void DenyDangerousDownload(scoped_refptr<DownloadManager> download_manager,
73 int32 download_id) { 74 int32 download_id) {
74 DownloadItem* download = download_manager->GetDownloadItem(download_id); 75 DownloadItem* download = download_manager->GetDownloadItem(download_id);
75 ASSERT_TRUE(download->IsPartialDownload()); 76 ASSERT_TRUE(download->IsPartialDownload());
76 download->Cancel(true); 77 download->Cancel();
77 download->Delete(DownloadItem::DELETE_DUE_TO_USER_DISCARD); 78 download->Delete(DownloadItem::DELETE_DUE_TO_USER_DISCARD);
78 } 79 }
79 80
80 // Construction of this class defines a system state, based on some number 81 // Construction of this class defines a system state, based on some number
81 // of downloads being seen in a particular state + other events that 82 // of downloads being seen in a particular state + other events that
82 // may occur in the download system. That state will be recorded if it 83 // may occur in the download system. That state will be recorded if it
83 // occurs at any point after construction. When that state occurs, the class 84 // occurs at any point after construction. When that state occurs, the class
84 // is considered finished. Callers may either probe for the finished state, or 85 // is considered finished. Callers may either probe for the finished state, or
85 // wait on it. 86 // wait on it.
86 // 87 //
87 // TODO(rdsmith): Detect manager going down, remove pointer to 88 // TODO(rdsmith): Detect manager going down, remove pointer to
88 // DownloadManager, transition to finished. (For right now we 89 // DownloadManager, transition to finished. (For right now we
89 // just use a scoped_refptr<> to keep it around, but that may cause 90 // just use a scoped_refptr<> to keep it around, but that may cause
90 // timeouts on waiting if a DownloadManager::Shutdown() occurs which 91 // timeouts on waiting if a DownloadManager::Shutdown() occurs which
91 // cancels our in-progress downloads.) 92 // cancels our in-progress downloads.)
92 class DownloadsObserver : public DownloadManager::Observer, 93 class DownloadsObserver : public DownloadManager::Observer,
93 public DownloadItem::Observer { 94 public DownloadItem::Observer {
94 public: 95 public:
96 typedef std::set<DownloadItem::DownloadState> StateSet;
97
95 // Create an object that will be considered finished when |wait_count| 98 // Create an object that will be considered finished when |wait_count|
96 // download items have entered state |download_finished_state|. 99 // download items have entered any states in |download_finished_states|.
97 // If |finish_on_select_file| is true, the object will also be 100 // If |finish_on_select_file| is true, the object will also be
98 // considered finished if the DownloadManager raises a 101 // considered finished if the DownloadManager raises a
99 // SelectFileDialogDisplayed() notification. 102 // SelectFileDialogDisplayed() notification.
100 103
101 // TODO(rdsmith): Consider rewriting the interface to take a list of events 104 // TODO(rdsmith): Consider rewriting the interface to take a list of events
102 // to treat as completion events. 105 // to treat as completion events.
103 DownloadsObserver(DownloadManager* download_manager, 106 DownloadsObserver(DownloadManager* download_manager,
104 size_t wait_count, 107 size_t wait_count,
105 DownloadItem::DownloadState download_finished_state, 108 StateSet download_finished_states,
106 bool finish_on_select_file, 109 bool finish_on_select_file,
107 DangerousDownloadAction dangerous_download_action) 110 DangerousDownloadAction dangerous_download_action)
108 : download_manager_(download_manager), 111 : download_manager_(download_manager),
109 wait_count_(wait_count), 112 wait_count_(wait_count),
110 finished_downloads_at_construction_(0), 113 finished_downloads_at_construction_(0),
111 waiting_(false), 114 waiting_(false),
112 download_finished_state_(download_finished_state), 115 download_finished_states_(download_finished_states),
113 finish_on_select_file_(finish_on_select_file), 116 finish_on_select_file_(finish_on_select_file),
114 select_file_dialog_seen_(false), 117 select_file_dialog_seen_(false),
115 dangerous_download_action_(dangerous_download_action) { 118 dangerous_download_action_(dangerous_download_action) {
116 download_manager_->AddObserver(this); // Will call initial ModelChanged(). 119 download_manager_->AddObserver(this); // Will call initial ModelChanged().
117 finished_downloads_at_construction_ = finished_downloads_.size(); 120 finished_downloads_at_construction_ = finished_downloads_.size();
118 EXPECT_NE(DownloadItem::REMOVING, download_finished_state) 121 EXPECT_TRUE(download_finished_states.find(DownloadItem::REMOVING) ==
122 download_finished_states.end())
119 << "Waiting for REMOVING is not supported. Try COMPLETE."; 123 << "Waiting for REMOVING is not supported. Try COMPLETE.";
120 } 124 }
121 125
122 ~DownloadsObserver() { 126 ~DownloadsObserver() {
123 std::set<DownloadItem*>::iterator it = downloads_observed_.begin(); 127 std::set<DownloadItem*>::iterator it = downloads_observed_.begin();
124 for (; it != downloads_observed_.end(); ++it) 128 for (; it != downloads_observed_.end(); ++it)
125 (*it)->RemoveObserver(this); 129 (*it)->RemoveObserver(this);
126 130
127 download_manager_->RemoveObserver(this); 131 download_manager_->RemoveObserver(this);
128 } 132 }
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 NewRunnableFunction( 191 NewRunnableFunction(
188 &DenyDangerousDownload, 192 &DenyDangerousDownload,
189 download_manager_, 193 download_manager_,
190 download->id())); 194 download->id()));
191 break; 195 break;
192 196
193 case ON_DANGEROUS_DOWNLOAD_FAIL: 197 case ON_DANGEROUS_DOWNLOAD_FAIL:
194 ADD_FAILURE() << "Unexpected dangerous download item."; 198 ADD_FAILURE() << "Unexpected dangerous download item.";
195 break; 199 break;
196 200
201 case ON_DANGEROUS_DOWNLOAD_IGNORE:
202 break;
203
197 default: 204 default:
198 NOTREACHED(); 205 NOTREACHED();
199 } 206 }
200 } 207 }
201 208
202 if (download->state() == download_finished_state_) { 209 if (download_finished_states_.find(download->state()) !=
210 download_finished_states_.end()) {
203 DownloadInFinalState(download); 211 DownloadInFinalState(download);
204 } 212 }
205 } 213 }
206 214
207 virtual void OnDownloadOpened(DownloadItem* download) {} 215 virtual void OnDownloadOpened(DownloadItem* download) {}
208 216
209 // DownloadManager::Observer 217 // DownloadManager::Observer
210 virtual void ModelChanged() { 218 virtual void ModelChanged() {
211 // Regenerate DownloadItem observers. If there are any download items 219 // Regenerate DownloadItem observers. If there are any download items
212 // in our final state, note them in |finished_downloads_| 220 // in our final state, note them in |finished_downloads_|
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 // construction and return from wait. But some downloads may be in our 303 // construction and return from wait. But some downloads may be in our
296 // final state (and thus be entered into |finished_downloads_|) when we 304 // final state (and thus be entered into |finished_downloads_|) when we
297 // construct this class. We don't want to count those in our transition 305 // construct this class. We don't want to count those in our transition
298 // to finished. 306 // to finished.
299 int finished_downloads_at_construction_; 307 int finished_downloads_at_construction_;
300 308
301 // Whether an internal message loop has been started and must be quit upon 309 // Whether an internal message loop has been started and must be quit upon
302 // all downloads completing. 310 // all downloads completing.
303 bool waiting_; 311 bool waiting_;
304 312
305 // The state on which to consider the DownloadItem finished. 313 // The states on which to consider the DownloadItem finished.
306 DownloadItem::DownloadState download_finished_state_; 314 StateSet download_finished_states_;
307 315
308 // True if we should transition the DownloadsObserver to finished if 316 // True if we should transition the DownloadsObserver to finished if
309 // the select file dialog comes up. 317 // the select file dialog comes up.
310 bool finish_on_select_file_; 318 bool finish_on_select_file_;
311 319
312 // True if we've seen the select file dialog. 320 // True if we've seen the select file dialog.
313 bool select_file_dialog_seen_; 321 bool select_file_dialog_seen_;
314 322
315 // Action to take if a dangerous download is encountered. 323 // Action to take if a dangerous download is encountered.
316 DangerousDownloadAction dangerous_download_action_; 324 DangerousDownloadAction dangerous_download_action_;
317 325
318 // Holds the download ids which were dangerous. 326 // Holds the download ids which were dangerous.
319 std::set<int32> dangerous_downloads_seen_; 327 std::set<int32> dangerous_downloads_seen_;
320 328
321 DISALLOW_COPY_AND_ASSIGN(DownloadsObserver); 329 DISALLOW_COPY_AND_ASSIGN(DownloadsObserver);
322 }; 330 };
323 331
324 // WaitForFlush() returns after: 332 // Ping through an arbitrary set of threads. Must be run from the UI
325 // * There are no IN_PROGRESS download items remaining on the 333 // thread.
326 // DownloadManager. 334 class ThreadPinger : public base::RefCountedThreadSafe<ThreadPinger> {
327 // * There have been two round trip messages through the file and
328 // IO threads.
329 // This almost certainly means that a Download cancel has propagated through
330 // the system.
331 class DownloadsFlushObserver
332 : public DownloadManager::Observer,
333 public DownloadItem::Observer,
334 public base::RefCountedThreadSafe<DownloadsFlushObserver> {
335 public: 335 public:
336 explicit DownloadsFlushObserver(DownloadManager* download_manager) 336 ThreadPinger(const BrowserThread::ID ids[], size_t num_ids) :
337 : download_manager_(download_manager), 337 next_thread_index_(0u),
338 waiting_for_zero_inprogress_(true) {} 338 ids_(ids, ids + num_ids) {}
339 339
340 void WaitForFlush() { 340 void Ping() {
341 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 341 if (ids_.size() == 0)
342 download_manager_->AddObserver(this); 342 return;
343 NextThread();
343 ui_test_utils::RunMessageLoop(); 344 ui_test_utils::RunMessageLoop();
344 } 345 }
345 346
346 // DownloadsManager observer methods. 347 private:
347 virtual void ModelChanged() { 348 void NextThread() {
348 // Model has changed, so there may be more DownloadItems to observe. 349 if (next_thread_index_ == ids_.size()) {
349 CheckDownloadsInProgress(true); 350 BrowserThread::PostTask(
350 } 351 BrowserThread::UI, FROM_HERE, new MessageLoop::QuitTask());
351 352 } else {
352 // DownloadItem observer methods. 353 BrowserThread::ID next_id(ids_[next_thread_index_++]);
353 virtual void OnDownloadUpdated(DownloadItem* download) { 354 BrowserThread::PostTask(
354 // No change in DownloadItem set on manager. 355 next_id, FROM_HERE,
355 CheckDownloadsInProgress(false); 356 NewRunnableMethod(this, &ThreadPinger::NextThread));
356 }
357 virtual void OnDownloadOpened(DownloadItem* download) {}
358
359 protected:
360 friend class base::RefCountedThreadSafe<DownloadsFlushObserver>;
361
362 virtual ~DownloadsFlushObserver() {
363 download_manager_->RemoveObserver(this);
364 for (std::set<DownloadItem*>::iterator it = downloads_observed_.begin();
365 it != downloads_observed_.end(); ++it) {
366 (*it)->RemoveObserver(this);
367 } 357 }
368 } 358 }
369 359
370 private: 360 size_t next_thread_index_;
371 // If we're waiting for that flush point, check the number 361 std::vector<BrowserThread::ID> ids_;
372 // of downloads in the IN_PROGRESS state and take appropriate
373 // action. If requested, also observes all downloads while iterating.
374 void CheckDownloadsInProgress(bool observe_downloads) {
375 if (waiting_for_zero_inprogress_) {
376 int count = 0;
377
378 std::vector<DownloadItem*> downloads;
379 download_manager_->SearchDownloads(string16(), &downloads);
380 std::vector<DownloadItem*>::iterator it = downloads.begin();
381 for (; it != downloads.end(); ++it) {
382 if ((*it)->state() == DownloadItem::IN_PROGRESS)
383 count++;
384 if (observe_downloads) {
385 if (downloads_observed_.find(*it) == downloads_observed_.end()) {
386 (*it)->AddObserver(this);
387 }
388 // Download items are forever, and we don't want to make
389 // assumptions about future state transitions, so once we
390 // start observing them, we don't stop until destruction.
391 }
392 }
393
394 if (count == 0) {
395 waiting_for_zero_inprogress_ = false;
396 // Stop observing DownloadItems. We maintain the observation
397 // of DownloadManager so that we don't have to independently track
398 // whether we are observing it for conditional destruction.
399 for (std::set<DownloadItem*>::iterator it = downloads_observed_.begin();
400 it != downloads_observed_.end(); ++it) {
401 (*it)->RemoveObserver(this);
402 }
403 downloads_observed_.clear();
404
405 // Trigger next step. We need to go past the IO thread twice, as
406 // there's a self-task posting in the IO thread cancel path.
407 BrowserThread::PostTask(
408 BrowserThread::FILE, FROM_HERE,
409 NewRunnableMethod(this,
410 &DownloadsFlushObserver::PingFileThread, 2));
411 }
412 }
413 }
414
415 void PingFileThread(int cycle) {
416 BrowserThread::PostTask(
417 BrowserThread::IO, FROM_HERE,
418 NewRunnableMethod(this, &DownloadsFlushObserver::PingIOThread,
419 cycle));
420 }
421
422 void PingIOThread(int cycle) {
423 if (--cycle) {
424 BrowserThread::PostTask(
425 BrowserThread::UI, FROM_HERE,
426 NewRunnableMethod(this, &DownloadsFlushObserver::PingFileThread,
427 cycle));
428 } else {
429 BrowserThread::PostTask(
430 BrowserThread::UI, FROM_HERE, new MessageLoop::QuitTask());
431 }
432 }
433
434 DownloadManager* download_manager_;
435 std::set<DownloadItem*> downloads_observed_;
436 bool waiting_for_zero_inprogress_;
437
438 DISALLOW_COPY_AND_ASSIGN(DownloadsFlushObserver);
439 }; 362 };
440 363
441 // Collect the information from FILE and IO threads needed for the Cancel 364 // Collect the information from FILE and IO threads needed for the Cancel
442 // Test, specifically the number of outstanding requests on the 365 // Test, specifically the number of outstanding requests on the
443 // ResourceDispatcherHost and the number of pending downloads on the 366 // ResourceDispatcherHost and the number of pending downloads on the
444 // DownloadFileManager. 367 // DownloadFileManager.
445 class CancelTestDataCollector 368 class CancelTestDataCollector
446 : public base::RefCountedThreadSafe<CancelTestDataCollector> { 369 : public base::RefCountedThreadSafe<CancelTestDataCollector> {
447 public: 370 public:
448 CancelTestDataCollector() 371 CancelTestDataCollector()
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 } 422 }
500 423
501 virtual void ChooseDownloadPath(TabContents* tab_contents, 424 virtual void ChooseDownloadPath(TabContents* tab_contents,
502 const FilePath& suggested_path, 425 const FilePath& suggested_path,
503 void* data) OVERRIDE { 426 void* data) OVERRIDE {
504 if (download_manager_) 427 if (download_manager_)
505 download_manager_->FileSelected(suggested_path, data); 428 download_manager_->FileSelected(suggested_path, data);
506 } 429 }
507 }; 430 };
508 431
432 // Don't respond to ChooseDownloadPath until a cancel is requested
433 // out of band. Can handle only one outstanding request at a time
434 // for a download path.
435 class BlockCancelFileDelegate : public ChromeDownloadManagerDelegate {
436 public:
437 explicit BlockCancelFileDelegate(Profile* profile)
438 : ChromeDownloadManagerDelegate(profile),
439 choose_download_path_called_(false),
440 choose_download_path_data_(NULL) {
441 SetDownloadManager(profile->GetDownloadManager());
442 }
443
444 virtual void ChooseDownloadPath(TabContents* tab_contents,
445 const FilePath& suggested_path,
446 void* data) OVERRIDE {
447 CHECK(!choose_download_path_called_);
448 choose_download_path_called_ = true;
449 choose_download_path_data_ = data;
450 }
451
452 void CancelOutstandingDownloadPathRequest() {
453 if (choose_download_path_called_) {
454 if (download_manager_)
455 download_manager_->FileSelectionCanceled(choose_download_path_data_);
456 choose_download_path_called_ = false;
457 choose_download_path_data_ = NULL;
458 }
459 }
460 private:
461 bool choose_download_path_called_;
462 void *choose_download_path_data_;
463 };
464
509 // Get History Information. 465 // Get History Information.
510 class DownloadsHistoryDataCollector { 466 class DownloadsHistoryDataCollector {
511 public: 467 public:
512 DownloadsHistoryDataCollector(int64 download_db_handle, 468 DownloadsHistoryDataCollector(int64 download_db_handle,
513 DownloadManager* manager) 469 DownloadManager* manager)
514 : result_valid_(false), 470 : result_valid_(false),
515 download_db_handle_(download_db_handle) { 471 download_db_handle_(download_db_handle) {
516 HistoryService* hs = 472 HistoryService* hs =
517 Profile::FromBrowserContext(manager->browser_context())-> 473 Profile::FromBrowserContext(manager->browser_context())->
518 GetHistoryService(Profile::EXPLICIT_ACCESS); 474 GetHistoryService(Profile::EXPLICIT_ACCESS);
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
616 (*it)->TestMockDownloadOpen(); 572 (*it)->TestMockDownloadOpen();
617 } 573 }
618 } 574 }
619 575
620 private: 576 private:
621 DownloadManager* download_manager_; 577 DownloadManager* download_manager_;
622 578
623 DISALLOW_COPY_AND_ASSIGN(MockDownloadOpeningObserver); 579 DISALLOW_COPY_AND_ASSIGN(MockDownloadOpeningObserver);
624 }; 580 };
625 581
582 static const DownloadItem::DownloadState kTerminalStates[] = {
583 DownloadItem::CANCELLED,
584 DownloadItem::INTERRUPTED,
585 DownloadItem::COMPLETE,
586 };
587
588 static const DownloadItem::DownloadState kInProgressStates[] = {
589 DownloadItem::IN_PROGRESS,
590 };
591
592 static const BrowserThread::ID kIOFileX2ThreadList[] = {
593 BrowserThread::IO, BrowserThread::FILE,
594 BrowserThread::IO, BrowserThread::FILE };
595
596 static const BrowserThread::ID kExternalTerminationThreadList[] = {
597 BrowserThread::IO, BrowserThread::IO, BrowserThread::FILE };
598
599 // Not in anonymous namespace so that friend class from DownloadManager
600 // can target it.
626 class DownloadTest : public InProcessBrowserTest { 601 class DownloadTest : public InProcessBrowserTest {
627 public: 602 public:
628 enum SelectExpectation { 603 enum SelectExpectation {
629 EXPECT_NO_SELECT_DIALOG = -1, 604 EXPECT_NO_SELECT_DIALOG = -1,
630 EXPECT_NOTHING, 605 EXPECT_NOTHING,
631 EXPECT_SELECT_DIALOG 606 EXPECT_SELECT_DIALOG
632 }; 607 };
633 608
634 DownloadTest() { 609 DownloadTest() {
635 EnableDOMAutomation(); 610 EnableDOMAutomation();
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
692 if (!downloads_directory_.CreateUniqueTempDir()) 667 if (!downloads_directory_.CreateUniqueTempDir())
693 return false; 668 return false;
694 669
695 browser->profile()->GetPrefs()->SetFilePath( 670 browser->profile()->GetPrefs()->SetFilePath(
696 prefs::kDownloadDefaultDirectory, 671 prefs::kDownloadDefaultDirectory,
697 downloads_directory_.path()); 672 downloads_directory_.path());
698 673
699 return true; 674 return true;
700 } 675 }
701 676
677 // For tests that want to test system reaction to files
678 // going away underneath them.
679 void DeleteDownloadsDirectory() {
680 EXPECT_TRUE(downloads_directory_.Delete());
681 }
682
702 DownloadPrefs* GetDownloadPrefs(Browser* browser) { 683 DownloadPrefs* GetDownloadPrefs(Browser* browser) {
703 return DownloadPrefs::FromDownloadManager( 684 return DownloadPrefs::FromDownloadManager(
704 browser->profile()->GetDownloadManager()); 685 browser->profile()->GetDownloadManager());
705 } 686 }
706 687
707 FilePath GetDownloadDirectory(Browser* browser) { 688 FilePath GetDownloadDirectory(Browser* browser) {
708 return GetDownloadPrefs(browser)->download_path(); 689 return GetDownloadPrefs(browser)->download_path();
709 } 690 }
710 691
711 // Create a DownloadsObserver that will wait for the 692 // Create a DownloadsObserver that will wait for the
712 // specified number of downloads to finish. 693 // specified number of downloads to finish.
713 DownloadsObserver* CreateWaiter(Browser* browser, int num_downloads) { 694 DownloadsObserver* CreateWaiter(Browser* browser, int num_downloads) {
714 DownloadManager* download_manager = 695 DownloadManager* download_manager =
715 browser->profile()->GetDownloadManager(); 696 browser->profile()->GetDownloadManager();
716 return new DownloadsObserver( 697 return new DownloadsObserver(
717 download_manager, num_downloads, 698 download_manager, num_downloads,
718 DownloadItem::COMPLETE, // Really done 699 DownloadsObserver::StateSet(
700 kTerminalStates, kTerminalStates + arraysize(kTerminalStates)),
719 true, // Bail on select file 701 true, // Bail on select file
720 ON_DANGEROUS_DOWNLOAD_FAIL); 702 ON_DANGEROUS_DOWNLOAD_FAIL);
721 } 703 }
722 704
723 // Create a DownloadsObserver that will wait for the 705 // Create a DownloadsObserver that will wait for the
706 // specified number of downloads to finish, and is
707 // ok with dangerous downloads. Note that use of this
708 // waiter is conditional on accepting the dangerous download.
709 DownloadsObserver* CreateDangerousWaiter(
710 Browser* browser, int num_downloads) {
711 DownloadManager* download_manager =
712 browser->profile()->GetDownloadManager();
713 return new DownloadsObserver(
714 download_manager, num_downloads,
715 DownloadsObserver::StateSet(
716 kTerminalStates, kTerminalStates + arraysize(kTerminalStates)),
717 true, // Bail on select file
718 ON_DANGEROUS_DOWNLOAD_IGNORE);
719 }
720
721 // Create a DownloadsObserver that will wait for the
724 // specified number of downloads to start. 722 // specified number of downloads to start.
725 DownloadsObserver* CreateInProgressWaiter(Browser* browser, 723 DownloadsObserver* CreateInProgressWaiter(Browser* browser,
726 int num_downloads) { 724 int num_downloads) {
727 DownloadManager* download_manager = 725 DownloadManager* download_manager =
728 browser->profile()->GetDownloadManager(); 726 browser->profile()->GetDownloadManager();
729 return new DownloadsObserver( 727 return new DownloadsObserver(
730 download_manager, num_downloads, 728 download_manager, num_downloads,
731 DownloadItem::IN_PROGRESS, // Has started 729 DownloadsObserver::StateSet(
730 kInProgressStates,
731 kInProgressStates + arraysize(kInProgressStates)),
732 true, // Bail on select file 732 true, // Bail on select file
733 ON_DANGEROUS_DOWNLOAD_FAIL); 733 ON_DANGEROUS_DOWNLOAD_IGNORE);
734 } 734 }
735 735
736 // Create a DownloadsObserver that will wait for the 736 // Create a DownloadsObserver that will wait for the
737 // specified number of downloads to finish, or for 737 // specified number of downloads to finish, or for
738 // a dangerous download warning to be shown. 738 // a dangerous download warning to be shown.
739 DownloadsObserver* DangerousInstallWaiter( 739 DownloadsObserver* DangerousInstallWaiter(
740 Browser* browser, 740 Browser* browser,
741 int num_downloads, 741 int num_downloads,
742 DownloadItem::DownloadState final_state, 742 DownloadItem::DownloadState final_state,
743 DangerousDownloadAction dangerous_download_action) { 743 DangerousDownloadAction dangerous_download_action) {
744 DownloadsObserver::StateSet states;
745 states.insert(final_state);
744 DownloadManager* download_manager = 746 DownloadManager* download_manager =
745 browser->profile()->GetDownloadManager(); 747 browser->profile()->GetDownloadManager();
746 return new DownloadsObserver( 748 return new DownloadsObserver(
747 download_manager, num_downloads, 749 download_manager, num_downloads,
748 final_state, 750 states,
749 true, // Bail on select file 751 true, // Bail on select file
750 dangerous_download_action); 752 dangerous_download_action);
751 } 753 }
752 754
753 // Download |url|, then wait for the download to finish. 755 // Download |url|, then wait for the download to finish.
754 // |disposition| indicates where the navigation occurs (current tab, new 756 // |disposition| indicates where the navigation occurs (current tab, new
755 // foreground tab, etc). 757 // foreground tab, etc).
756 // |expectation| indicates whether or not a Select File dialog should be 758 // |expectation| indicates whether or not a Select File dialog should be
757 // open when the download is finished, or if we don't care. 759 // open when the download is finished, or if we don't care.
758 // If the dialog appears, the routine exits. The only effect |expectation| 760 // If the dialog appears, the routine exits. The only effect |expectation|
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
893 if (!downloaded_path_exists) 895 if (!downloaded_path_exists)
894 return false; 896 return false;
895 897
896 // Delete the file we just downloaded. 898 // Delete the file we just downloaded.
897 EXPECT_TRUE(file_util::DieFileDie(download_path, true)); 899 EXPECT_TRUE(file_util::DieFileDie(download_path, true));
898 EXPECT_FALSE(file_util::PathExists(download_path)); 900 EXPECT_FALSE(file_util::PathExists(download_path));
899 901
900 return true; 902 return true;
901 } 903 }
902 904
903 void GetDownloads(Browser* browser, std::vector<DownloadItem*>* downloads) { 905 void GetPersistentDownloads(Browser* browser,
906 std::vector<DownloadItem*>* downloads) {
907 DCHECK(downloads);
908 downloads->clear();
909 DownloadManager* manager = browser->profile()->GetDownloadManager();
910 manager->SearchDownloads(string16(), downloads);
911 }
912
913 void GetInProgressDownloads(Browser* browser,
914 std::vector<DownloadItem*>* downloads) {
915 downloads->clear();
904 DCHECK(downloads); 916 DCHECK(downloads);
905 DownloadManager* manager = browser->profile()->GetDownloadManager(); 917 DownloadManager* manager = browser->profile()->GetDownloadManager();
906 manager->SearchDownloads(string16(), downloads); 918 manager->GetInProgressDownloads(downloads);
919 }
920
921 size_t NumberInProgressDownloads(Browser* browser) {
922 std::vector<DownloadItem*> downloads;
923 browser->profile()->GetDownloadManager()->GetInProgressDownloads(
924 &downloads);
925 return downloads.size();
926 }
927
928 void WaitForIOFileX2() {
929 scoped_refptr<ThreadPinger> pinger(
930 new ThreadPinger(kIOFileX2ThreadList, arraysize(kIOFileX2ThreadList)));
931 pinger->Ping();
907 } 932 }
908 933
909 // Check that the download UI (shelf on non-chromeos or panel on chromeos) 934 // Check that the download UI (shelf on non-chromeos or panel on chromeos)
910 // is visible or not as expected. Additionally, check that the filename 935 // is visible or not as expected. Additionally, check that the filename
911 // is present in the UI (currently only on chromeos). 936 // is present in the UI (currently only on chromeos).
912 void CheckDownloadUI(Browser* browser, bool expected_non_cros, 937 void CheckDownloadUI(Browser* browser, bool expected_non_cros,
913 bool expected_cros, const FilePath& filename) { 938 bool expected_cros, const FilePath& filename) {
914 #if defined(OS_CHROMEOS) 939 #if defined(OS_CHROMEOS)
915 #if defined(TOUCH_UI) 940 #if defined(TOUCH_UI)
916 TabContents* download_contents = ActiveDownloadsUI::GetPopup(NULL); 941 TabContents* download_contents = ActiveDownloadsUI::GetPopup(NULL);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
966 991
967 DownloadManager* manager = browser->profile()->GetDownloadManager(); 992 DownloadManager* manager = browser->profile()->GetDownloadManager();
968 993
969 new_delegate->SetDownloadManager(manager); 994 new_delegate->SetDownloadManager(manager);
970 manager->set_delegate(new_delegate); 995 manager->set_delegate(new_delegate);
971 996
972 // Gives ownership to Profile. 997 // Gives ownership to Profile.
973 browser->profile()->SetDownloadManagerDelegate(new_delegate); 998 browser->profile()->SetDownloadManagerDelegate(new_delegate);
974 } 999 }
975 1000
1001 // Arrange for select file calls on the given browser from the
1002 // download manager to block until explicitly released.
1003 // Note that the returned pointer is non-owning; the lifetime
1004 // of the object will be that of the profile.
1005 BlockCancelFileDelegate* BlockSelectFile(Browser* browser) {
1006 BlockCancelFileDelegate* new_delegate =
1007 new BlockCancelFileDelegate(browser->profile());
1008
1009 DownloadManager* manager = browser->profile()->GetDownloadManager();
1010
1011 new_delegate->SetDownloadManager(manager);
1012 manager->set_delegate(new_delegate);
1013
1014 // Gives ownership to Profile.
1015 browser->profile()->SetDownloadManagerDelegate(new_delegate);
1016
1017 return new_delegate;
1018 }
1019
1020 // Wait for an external termination (e.g. signalling
1021 // URLRequestSlowDownloadJob to return an error) to propagate through
1022 // this sytem. This involves hopping over to the IO thread (twice,
1023 // because of possible self-posts from URLRequestJob) then
1024 // chasing the (presumed) notification through the download
1025 // system (FILE->UI).
1026 void WaitForExternalTermination() {
1027 scoped_refptr<ThreadPinger> pinger(
1028 new ThreadPinger(
1029 kExternalTerminationThreadList,
1030 arraysize(kExternalTerminationThreadList)));
1031 pinger->Ping();
1032 }
1033
976 private: 1034 private:
977 // Location of the test data. 1035 // Location of the test data.
978 FilePath test_dir_; 1036 FilePath test_dir_;
979 1037
980 // Location of the downloads directory for these tests 1038 // Location of the downloads directory for these tests
981 ScopedTempDir downloads_directory_; 1039 ScopedTempDir downloads_directory_;
982 }; 1040 };
983 1041
984 // NOTES: 1042 // NOTES:
985 // 1043 //
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1032 GURL url(URLRequestMockHTTPJob::GetMockUrl(file)); 1090 GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
1033 1091
1034 NullSelectFile(browser()); 1092 NullSelectFile(browser());
1035 1093
1036 // Download the file and wait. We expect the Select File dialog to appear 1094 // Download the file and wait. We expect the Select File dialog to appear
1037 // due to the MIME type, but we still wait until the download completes. 1095 // due to the MIME type, but we still wait until the download completes.
1038 scoped_ptr<DownloadsObserver> observer( 1096 scoped_ptr<DownloadsObserver> observer(
1039 new DownloadsObserver( 1097 new DownloadsObserver(
1040 browser()->profile()->GetDownloadManager(), 1098 browser()->profile()->GetDownloadManager(),
1041 1, 1099 1,
1042 DownloadItem::COMPLETE, // Really done 1100 DownloadsObserver::StateSet(
1101 kTerminalStates, kTerminalStates + arraysize(kTerminalStates)),
1043 false, // Continue on select file. 1102 false, // Continue on select file.
1044 ON_DANGEROUS_DOWNLOAD_FAIL)); 1103 ON_DANGEROUS_DOWNLOAD_FAIL));
1045 ui_test_utils::NavigateToURLWithDisposition( 1104 ui_test_utils::NavigateToURLWithDisposition(
1046 browser(), url, CURRENT_TAB, 1105 browser(), url, CURRENT_TAB,
1047 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 1106 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1048 observer->WaitForFinished(); 1107 observer->WaitForFinished();
1049 EXPECT_TRUE(observer->select_file_dialog_seen()); 1108 EXPECT_TRUE(observer->select_file_dialog_seen());
1050 1109
1051 // Check state.
1052 EXPECT_EQ(1, browser()->tab_count()); 1110 EXPECT_EQ(1, browser()->tab_count());
1053 CheckDownload(browser(), file, file); 1111 CheckDownload(browser(), file, file);
1054 CheckDownloadUI(browser(), true, true, file); 1112 CheckDownloadUI(browser(), true, true, file);
1055 } 1113 }
1056 1114
1115 // Put up a Select File dialog when the file is downloaded, due to
1116 // prompt_for_download==true argument to InitialSetup().
1117 // Confirm that we can cancel the download in that state.
1118 IN_PROC_BROWSER_TEST_F(DownloadTest, CancelAtFileSelection) {
1119 ASSERT_TRUE(InitialSetup(true));
1120 FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
1121 GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
1122
1123 BlockCancelFileDelegate* delegate = BlockSelectFile(browser());
1124
1125 // Download the file and wait. We expect the Select File dialog to appear.
1126 DownloadAndWait(browser(), url, EXPECT_SELECT_DIALOG);
1127
1128 std::vector<DownloadItem*> active_downloads, history_downloads;
1129 GetInProgressDownloads(browser(), &active_downloads);
1130 ASSERT_EQ(1u, active_downloads.size());
1131 EXPECT_EQ(DownloadItem::IN_PROGRESS, active_downloads[0]->state());
1132 GetPersistentDownloads(browser(), &history_downloads);
1133 EXPECT_EQ(0u, history_downloads.size());
1134
1135 // This should remove the download as it hasn't yet been entered into
1136 // the history.
1137 active_downloads[0]->Cancel();
1138 MessageLoopForUI::current()->RunAllPending();
1139
1140 GetInProgressDownloads(browser(), &active_downloads);
1141 EXPECT_EQ(0u, active_downloads.size());
1142 GetPersistentDownloads(browser(), &history_downloads);
1143 EXPECT_EQ(0u, history_downloads.size());
1144
1145 // Check state.
1146 EXPECT_EQ(1, browser()->tab_count());
1147 // Since we exited while the Select File dialog was visible, there should not
1148 // be anything in the download shelf and so it should not be visible.
1149 CheckDownloadUI(browser(), false, false, FilePath());
1150
1151 // Return from file selection to release allocated data.
1152 delegate->CancelOutstandingDownloadPathRequest();
1153 }
1154
1155 // Put up a Select File dialog when the file is downloaded, due to
1156 // prompt_for_download==true argument to InitialSetup().
1157 // Confirm that we can cancel the download as if the user had hit cancel.
1158 IN_PROC_BROWSER_TEST_F(DownloadTest, CancelFromFileSelection) {
1159 ASSERT_TRUE(InitialSetup(true));
1160 FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
1161 GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
1162
1163 BlockCancelFileDelegate* delegate = BlockSelectFile(browser());
1164
1165 // Download the file and wait. We expect the Select File dialog to appear.
1166 DownloadAndWait(browser(), url, EXPECT_SELECT_DIALOG);
1167
1168 std::vector<DownloadItem*> active_downloads, history_downloads;
1169 GetInProgressDownloads(browser(), &active_downloads);
1170 ASSERT_EQ(1u, active_downloads.size());
1171 EXPECT_EQ(DownloadItem::IN_PROGRESS, active_downloads[0]->state());
1172 GetPersistentDownloads(browser(), &history_downloads);
1173 EXPECT_EQ(0u, history_downloads.size());
1174
1175 // (Effectively) Click the Cancel button. This should remove the download
1176 // as it hasn't yet been entered into the history.
1177 delegate->CancelOutstandingDownloadPathRequest();
1178 MessageLoopForUI::current()->RunAllPending();
1179
1180 GetInProgressDownloads(browser(), &active_downloads);
1181 EXPECT_EQ(0u, active_downloads.size());
1182 GetPersistentDownloads(browser(), &history_downloads);
1183 EXPECT_EQ(0u, history_downloads.size());
1184
1185 // Check state.
1186 EXPECT_EQ(1, browser()->tab_count());
1187 // Since we exited while the Select File dialog was visible, there should not
1188 // be anything in the download shelf and so it should not be visible.
1189 CheckDownloadUI(browser(), false, false, FilePath());
1190 }
1191
1192 // Put up a Select File dialog when the file is downloaded, due to
1193 // prompt_for_download==true argument to InitialSetup().
1194 // Confirm that we can remove the download in that state.
1195 IN_PROC_BROWSER_TEST_F(DownloadTest, RemoveFromFileSelection) {
1196 ASSERT_TRUE(InitialSetup(true));
1197 FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
1198 GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
1199
1200 BlockCancelFileDelegate* delegate = BlockSelectFile(browser());
1201
1202 // Download the file and wait. We expect the Select File dialog to appear.
1203 DownloadAndWait(browser(), url, EXPECT_SELECT_DIALOG);
1204
1205 std::vector<DownloadItem*> active_downloads, history_downloads;
1206 GetInProgressDownloads(browser(), &active_downloads);
1207 ASSERT_EQ(1u, active_downloads.size());
1208 EXPECT_EQ(DownloadItem::IN_PROGRESS, active_downloads[0]->state());
1209 GetPersistentDownloads(browser(), &history_downloads);
1210 EXPECT_EQ(0u, history_downloads.size());
1211
1212 // Confirm the file can be successfully removed from the select file
1213 // dialog blocked state.
1214 active_downloads[0]->Remove();
1215 MessageLoopForUI::current()->RunAllPending();
1216
1217 GetInProgressDownloads(browser(), &active_downloads);
1218 EXPECT_EQ(0u, active_downloads.size());
1219 GetPersistentDownloads(browser(), &history_downloads);
1220 EXPECT_EQ(0u, history_downloads.size());
1221
1222 EXPECT_EQ(1, browser()->tab_count());
1223 // Since we exited while the Select File dialog was visible, there should not
1224 // be anything in the download shelf and so it should not be visible.
1225 CheckDownloadUI(browser(), false, false, FilePath());
1226
1227 // Return from file selection to release allocated data.
1228 delegate->CancelOutstandingDownloadPathRequest();
1229 }
1230
1231 // Put up a Select File dialog when the file is downloaded, due to
1232 // prompt_for_download==true argument to InitialSetup().
1233 // Confirm that an error coming in from the network works properly
1234 // when in that state.
1235 IN_PROC_BROWSER_TEST_F(DownloadTest, InterruptFromFileSelection) {
1236 ASSERT_TRUE(InitialSetup(true));
1237 GURL url(URLRequestSlowDownloadJob::kKnownSizeUrl);
1238
1239 BlockCancelFileDelegate* delegate = BlockSelectFile(browser());
1240
1241 // Download the file and wait. We expect the Select File dialog to appear.
1242 DownloadAndWait(browser(), url, EXPECT_SELECT_DIALOG);
1243
1244 std::vector<DownloadItem*> active_downloads, history_downloads;
1245 GetInProgressDownloads(browser(), &active_downloads);
1246 ASSERT_EQ(1u, active_downloads.size());
1247 EXPECT_EQ(DownloadItem::IN_PROGRESS, active_downloads[0]->state());
1248 GetPersistentDownloads(browser(), &history_downloads);
1249 EXPECT_EQ(0u, history_downloads.size());
1250
1251 // Complete the download with error.
1252 GURL error_url(URLRequestSlowDownloadJob::kErrorFinishDownloadUrl);
1253 ui_test_utils::NavigateToURL(browser(), error_url);
1254 MessageLoopForUI::current()->RunAllPending();
1255 WaitForExternalTermination();
1256
1257 // Confirm that a download error before entry into history
1258 // deletes the download.
1259 GetInProgressDownloads(browser(), &active_downloads);
1260 EXPECT_EQ(0u, active_downloads.size());
1261 GetPersistentDownloads(browser(), &history_downloads);
1262 EXPECT_EQ(0u, history_downloads.size());
1263
1264 // Since we exited while the Select File dialog was visible, there should not
1265 // be anything in the download shelf and so it should not be visible.
1266 CheckDownloadUI(browser(), false, false, FilePath());
1267
1268 // Return from file selection to release allocated data.
1269 delegate->CancelOutstandingDownloadPathRequest();
1270 }
1271
1057 // Access a file with a viewable mime-type, verify that a download 1272 // Access a file with a viewable mime-type, verify that a download
1058 // did not initiate. 1273 // did not initiate.
1059 IN_PROC_BROWSER_TEST_F(DownloadTest, NoDownload) { 1274 IN_PROC_BROWSER_TEST_F(DownloadTest, NoDownload) {
1060 ASSERT_TRUE(InitialSetup(false)); 1275 ASSERT_TRUE(InitialSetup(false));
1061 FilePath file(FILE_PATH_LITERAL("download-test2.html")); 1276 FilePath file(FILE_PATH_LITERAL("download-test2.html"));
1062 GURL url(URLRequestMockHTTPJob::GetMockUrl(file)); 1277 GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
1063 FilePath file_path(DestinationFile(browser(), file)); 1278 FilePath file_path(DestinationFile(browser(), file));
1064 1279
1065 // Open a web page and wait. 1280 // Open a web page and wait.
1066 ui_test_utils::NavigateToURL(browser(), url); 1281 ui_test_utils::NavigateToURL(browser(), url);
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after
1446 ExpectWindowCountAfterDownload(1); 1661 ExpectWindowCountAfterDownload(1);
1447 #endif 1662 #endif
1448 1663
1449 EXPECT_EQ(1, browser()->tab_count()); 1664 EXPECT_EQ(1, browser()->tab_count());
1450 // Download shelf should close. Download panel stays open on ChromeOS. 1665 // Download shelf should close. Download panel stays open on ChromeOS.
1451 CheckDownloadUI(browser(), false, true, file); 1666 CheckDownloadUI(browser(), false, true, file);
1452 1667
1453 CheckDownload(browser(), file, file); 1668 CheckDownload(browser(), file, file);
1454 } 1669 }
1455 1670
1671 // Create a download, wait until it's visible on the DownloadManager,
1672 // then cancel it.
1456 IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadCancelled) { 1673 IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadCancelled) {
1457 ASSERT_TRUE(InitialSetup(false)); 1674 ASSERT_TRUE(InitialSetup(false));
1458 EXPECT_EQ(1, browser()->tab_count()); 1675 EXPECT_EQ(1, browser()->tab_count());
1459 1676
1460 // TODO(rdsmith): Fragile code warning! The code below relies on the 1677 // The code below is slightly fragile. Currently,
1461 // DownloadsObserver only finishing when the new download has reached 1678 // the DownloadsObserver will only finish when the new download has
1462 // the state of being entered into the history and being user-visible 1679 // reached the state of being entered into the history and being
1463 // (that's what's required for the Remove to be valid and for the 1680 // user-visible. However, by the pure semantics of
1464 // download shelf to be visible). By the pure semantics of
1465 // DownloadsObserver, that's not guaranteed; DownloadItems are created 1681 // DownloadsObserver, that's not guaranteed; DownloadItems are created
1466 // in the IN_PROGRESS state and made known to the DownloadManager 1682 // in the IN_PROGRESS state and made known to the DownloadManager
1467 // immediately, so any ModelChanged event on the DownloadManager after 1683 // immediately, so any ModelChanged event on the DownloadManager after
1468 // navigation would allow the observer to return. However, the only 1684 // navigation would allow the observer to return. At some point we'll
1469 // ModelChanged() event the code will currently fire is in 1685 // probably change the DownloadManager to fire a ModelChanged event
1470 // OnCreateDownloadEntryComplete, at which point the download item will 1686 // earlier in download processing. This test should continue to work,
1471 // be in the state we need. 1687 // as a cancel is valid at any point during download process. However,
1472 // The right way to fix this is to create finer grained states on the 1688 // at that point it'll be testing two different things, depending on
1473 // DownloadItem, and wait for the state that indicates the item has been 1689 // what state the download item has reached when it is cancelled:
1474 // entered in the history and made visible in the UI. 1690 // a) cancelling from a pre-history entry when the only record of a
1691 // download item is on the active_downloads_ queue, and b) cancelling
1692 // from a post-history entry when the download is present on the
1693 // history_downloads_ list.
1694 //
1695 // Note that the above is why we don't do any UI testing here--we don't
1696 // know whether or not the download item has been made visible to the user.
1697
1698 // TODO(rdsmith): After we fire ModelChanged events at finer granularity,
1699 // split this test into subtests that tests canceling from each separate
1700 // download item state. Also include UI testing as appropriate in those
1701 // split tests.
1475 1702
1476 // Create a download, wait until it's started, and confirm 1703 // Create a download, wait until it's started, and confirm
1477 // we're in the expected state. 1704 // we're in the expected state.
1478 scoped_ptr<DownloadsObserver> observer( 1705 scoped_ptr<DownloadsObserver> observer(
1479 CreateInProgressWaiter(browser(), 1)); 1706 CreateInProgressWaiter(browser(), 1));
1480 ui_test_utils::NavigateToURL( 1707 ui_test_utils::NavigateToURL(
1481 browser(), GURL(URLRequestSlowDownloadJob::kUnknownSizeUrl)); 1708 browser(), GURL(URLRequestSlowDownloadJob::kUnknownSizeUrl));
1482 observer->WaitForFinished(); 1709 observer->WaitForFinished();
1483 1710
1484 std::vector<DownloadItem*> downloads; 1711 std::vector<DownloadItem*> downloads;
1485 browser()->profile()->GetDownloadManager()->SearchDownloads( 1712 GetPersistentDownloads(browser(), &downloads);
1486 string16(), &downloads);
1487 ASSERT_EQ(1u, downloads.size()); 1713 ASSERT_EQ(1u, downloads.size());
1488 ASSERT_EQ(DownloadItem::IN_PROGRESS, downloads[0]->state()); 1714 ASSERT_EQ(DownloadItem::IN_PROGRESS, downloads[0]->state());
1489 CheckDownloadUI(browser(), true, true, FilePath());
1490 1715
1491 // Cancel the download and wait for download system quiesce. 1716 // Cancel the download and wait for download system quiesce.
1492 downloads[0]->Delete(DownloadItem::DELETE_DUE_TO_USER_DISCARD); 1717 downloads[0]->Delete(DownloadItem::DELETE_DUE_TO_USER_DISCARD);
1493 scoped_refptr<DownloadsFlushObserver> flush_observer( 1718 ASSERT_EQ(0u, NumberInProgressDownloads(browser()));
1494 new DownloadsFlushObserver(browser()->profile()->GetDownloadManager())); 1719 WaitForIOFileX2();
1495 flush_observer->WaitForFlush();
1496 1720
1497 // Get the important info from other threads and check it. 1721 // Get the important info from other threads and check it.
1498 scoped_refptr<CancelTestDataCollector> info(new CancelTestDataCollector()); 1722 scoped_refptr<CancelTestDataCollector> info(new CancelTestDataCollector());
1499 info->WaitForDataCollected(); 1723 info->WaitForDataCollected();
1500 EXPECT_EQ(0, info->rdh_pending_requests()); 1724 EXPECT_EQ(0, info->rdh_pending_requests());
1501 EXPECT_EQ(0, info->dfm_pending_downloads()); 1725 EXPECT_EQ(0, info->dfm_pending_downloads());
1726 }
1502 1727
1503 // Using "DownloadItem::Remove" follows the discard dangerous download path, 1728 // Do a dangerous download and confirm that the download does
1504 // which completely removes the browser from the shelf and closes the shelf 1729 // not complete until user accept, and that all states are
1505 // if it was there. Download panel stays open on ChromeOS. 1730 // correct along the way.
1731 IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadDangerous) {
1732 ASSERT_TRUE(InitialSetup(false));
1733 FilePath file(FILE_PATH_LITERAL("download-dangerous.jar"));
1734 GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
1735
1736 EXPECT_EQ(1, browser()->tab_count());
1737
1738 scoped_ptr<DownloadsObserver> observer(
1739 CreateInProgressWaiter(browser(), 1));
1740 ui_test_utils::NavigateToURL(browser(), url);
1741 observer->WaitForFinished();
1742
1743 // We should have one download, in history, and it should
1744 // still be dangerous.
1745 std::vector<DownloadItem*> downloads;
1746 GetPersistentDownloads(browser(), &downloads);
1747 ASSERT_EQ(1u, downloads.size());
1748 DownloadItem* download = downloads[0];
1749 EXPECT_EQ(DownloadItem::IN_PROGRESS, download->state());
1750 EXPECT_EQ(DownloadItem::DANGEROUS, download->safety_state());
1751 EXPECT_EQ(DownloadItem::DANGEROUS_FILE, download->GetDangerType());
1752 // In ChromeOS, popup will be up, but file name will be unrecognizable.
1753 CheckDownloadUI(browser(), true, true, FilePath());
1754
1755 // See if accepting completes the download and changes the safety
1756 // state.
1757 scoped_ptr<DownloadsObserver> completion_observer(
1758 CreateDangerousWaiter(browser(), 1));
1759 AcceptDangerousDownload(browser()->profile()->GetDownloadManager(),
1760 download->id());
1761 completion_observer->WaitForFinished();
1762
1763 GetPersistentDownloads(browser(), &downloads);
1764 ASSERT_EQ(1u, downloads.size());
1765 ASSERT_EQ(downloads[0], download);
1766 EXPECT_EQ(DownloadItem::COMPLETE, download->state());
1767 EXPECT_EQ(DownloadItem::DANGEROUS_BUT_VALIDATED, download->safety_state());
1768 CheckDownloadUI(browser(), true, true, file);
1769 }
1770
1771 // Confirm that a dangerous download that gets a file error before
1772 // completion ends in the right state (currently cancelled because file
1773 // errors are non-resumable). Note that this is really testing
1774 // to make sure errors from the final rename are propagated properly.
1775 IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadDangerousFileError) {
1776 ASSERT_TRUE(InitialSetup(false));
1777 FilePath file(FILE_PATH_LITERAL("download-dangerous.jar"));
1778 GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
1779
1780 EXPECT_EQ(1, browser()->tab_count());
1781
1782 scoped_ptr<DownloadsObserver> observer(
1783 CreateInProgressWaiter(browser(), 1));
1784 ui_test_utils::NavigateToURL(browser(), url);
1785 observer->WaitForFinished();
1786
1787 // We should have one download, in history, and it should
1788 // still be dangerous.
1789 std::vector<DownloadItem*> downloads;
1790 GetPersistentDownloads(browser(), &downloads);
1791 ASSERT_EQ(1u, downloads.size());
1792 DownloadItem* download = downloads[0];
1793 EXPECT_EQ(DownloadItem::IN_PROGRESS, download->state());
1794 EXPECT_EQ(DownloadItem::DANGEROUS, download->safety_state());
1795 EXPECT_EQ(DownloadItem::DANGEROUS_FILE, download->GetDangerType());
1796 // In ChromeOS, popup will be up, but file name will be unrecognizable.
1797 CheckDownloadUI(browser(), true, true, FilePath());
1798
1799 // Accept it after nuking the directory into which it's being downloaded;
1800 // that should complete the download with an error.
1801 DeleteDownloadsDirectory();
1802 scoped_ptr<DownloadsObserver> completion_observer(
1803 CreateDangerousWaiter(browser(), 1));
1804 AcceptDangerousDownload(browser()->profile()->GetDownloadManager(),
1805 download->id());
1806 completion_observer->WaitForFinished();
1807
1808 GetPersistentDownloads(browser(), &downloads);
1809 ASSERT_EQ(1u, downloads.size());
1810 ASSERT_EQ(downloads[0], download);
1811 EXPECT_EQ(DownloadItem::INTERRUPTED, download->state());
1812 EXPECT_EQ(DownloadItem::DANGEROUS_BUT_VALIDATED, download->safety_state());
1813 // In ChromeOS, popup will still be up, but the file will have been
1814 // deleted.
1815 CheckDownloadUI(browser(), true, true, FilePath());
1816 }
1817
1818 // Confirm that declining a dangerous download erases it from living memory.
1819 IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadDangerousDecline) {
1820 ASSERT_TRUE(InitialSetup(false));
1821 FilePath file(FILE_PATH_LITERAL("download-dangerous.jar"));
1822 GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
1823
1824 EXPECT_EQ(1, browser()->tab_count());
1825
1826 scoped_ptr<DownloadsObserver> observer(
1827 CreateInProgressWaiter(browser(), 1));
1828 ui_test_utils::NavigateToURL(browser(), url);
1829 observer->WaitForFinished();
1830
1831 // We should have one download, in history, and it should
1832 // still be dangerous.
1833 std::vector<DownloadItem*> downloads;
1834 GetPersistentDownloads(browser(), &downloads);
1835 ASSERT_EQ(1u, downloads.size());
1836 DownloadItem* download = downloads[0];
1837 EXPECT_EQ(DownloadItem::IN_PROGRESS, download->state());
1838 EXPECT_EQ(DownloadItem::DANGEROUS, download->safety_state());
1839 EXPECT_EQ(DownloadItem::DANGEROUS_FILE, download->GetDangerType());
1840 CheckDownloadUI(browser(), true, true, FilePath());
1841
1842 DenyDangerousDownload(browser()->profile()->GetDownloadManager(),
1843 download->id());
1844
1845 GetPersistentDownloads(browser(), &downloads);
1846 ASSERT_EQ(0u, downloads.size());
1506 CheckDownloadUI(browser(), false, true, FilePath()); 1847 CheckDownloadUI(browser(), false, true, FilePath());
1507 } 1848 }
1508 1849
1850 // Fail a download with a network error partway through, and make sure the
1851 // state is INTERRUPTED and the error is propagated.
1852 IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadInterrupted) {
1853 ASSERT_TRUE(InitialSetup(false));
1854 GURL url(URLRequestSlowDownloadJob::kKnownSizeUrl);
1855
1856 scoped_ptr<DownloadsObserver> observer(
1857 CreateInProgressWaiter(browser(), 1));
1858 ui_test_utils::NavigateToURL(browser(), url);
1859 observer->WaitForFinished();
1860
1861 DownloadItem* download1;
1862 std::vector<DownloadItem*> downloads;
1863 GetPersistentDownloads(browser(), &downloads);
1864 ASSERT_EQ(1u, downloads.size());
1865 download1 = downloads[0];
1866 ASSERT_EQ(DownloadItem::IN_PROGRESS, download1->state());
1867 FilePath filename;
1868 net::FileURLToFilePath(url, &filename);
1869 CheckDownloadUI(browser(), true, true,
1870 download_util::GetCrDownloadPath(filename.BaseName()));
1871
1872 // Fail the download
1873 GURL error_url(URLRequestSlowDownloadJob::kErrorFinishDownloadUrl);
1874 ui_test_utils::NavigateToURL(browser(), error_url);
1875 MessageLoopForUI::current()->RunAllPending();
1876 WaitForExternalTermination();
1877
1878 // Should still be visible, with INTERRUPTED state.
1879 GetPersistentDownloads(browser(), &downloads);
1880 ASSERT_EQ(1u, downloads.size());
1881 DownloadItem* download = downloads[0];
1882 ASSERT_EQ(download, download1);
1883 ASSERT_EQ(DownloadItem::INTERRUPTED, download->state());
1884 // TODO(rdsmith): Confirm error provided by URLRequest is shown
1885 // in DownloadItem.
1886 CheckDownloadUI(browser(), true, true, FilePath());
1887
1888 // Confirm cancel does nothing.
1889 download->Cancel();
1890 MessageLoopForUI::current()->RunAllPending();
1891
1892 GetPersistentDownloads(browser(), &downloads);
1893 ASSERT_EQ(1u, downloads.size());
1894 ASSERT_EQ(download, downloads[0]);
1895 ASSERT_EQ(DownloadItem::INTERRUPTED, download->state());
1896 CheckDownloadUI(browser(), true, true, FilePath());
1897
1898 // Confirm remove gets rid of it.
1899 download->Remove();
1900 download = NULL;
1901 MessageLoopForUI::current()->RunAllPending();
1902
1903 GetPersistentDownloads(browser(), &downloads);
1904 ASSERT_EQ(0u, downloads.size());
1905 CheckDownloadUI(browser(), false, true, FilePath());
1906 }
1907
1509 // Confirm a download makes it into the history properly. 1908 // Confirm a download makes it into the history properly.
1510 IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadHistoryCheck) { 1909 IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadHistoryCheck) {
1511 ASSERT_TRUE(InitialSetup(false)); 1910 ASSERT_TRUE(InitialSetup(false));
1512 FilePath file(FILE_PATH_LITERAL("download-test1.lib")); 1911 FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
1513 GURL url(URLRequestMockHTTPJob::GetMockUrl(file)); 1912 GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
1514 FilePath origin_file(OriginFile(file)); 1913 FilePath origin_file(OriginFile(file));
1515 int64 origin_size; 1914 int64 origin_size;
1516 file_util::GetFileSize(origin_file, &origin_size); 1915 file_util::GetFileSize(origin_file, &origin_size);
1517 1916
1518 // Download the file and wait. We do not expect the Select File dialog. 1917 // Download the file and wait. We do not expect the Select File dialog.
1519 DownloadAndWait(browser(), url, EXPECT_NO_SELECT_DIALOG); 1918 DownloadAndWait(browser(), url, EXPECT_NO_SELECT_DIALOG);
1520 1919
1521 // Get details of what downloads have just happened. 1920 // Get details of what downloads have just happened.
1522 std::vector<DownloadItem*> downloads; 1921 std::vector<DownloadItem*> downloads;
1523 GetDownloads(browser(), &downloads); 1922 GetPersistentDownloads(browser(), &downloads);
1524 ASSERT_EQ(1u, downloads.size()); 1923 ASSERT_EQ(1u, downloads.size());
1525 int64 db_handle = downloads[0]->db_handle(); 1924 int64 db_handle = downloads[0]->db_handle();
1526 1925
1527 // Check state. 1926 // Check state.
1528 EXPECT_EQ(1, browser()->tab_count()); 1927 EXPECT_EQ(1, browser()->tab_count());
1529 CheckDownload(browser(), file, file); 1928 CheckDownload(browser(), file, file);
1530 CheckDownloadUI(browser(), true, true, file); 1929 CheckDownloadUI(browser(), true, true, file);
1531 1930
1532 // Check history results. 1931 // Check history results.
1533 DownloadsHistoryDataCollector history_collector( 1932 DownloadsHistoryDataCollector history_collector(
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
1628 GetDownloadPrefs(browser())->EnableAutoOpenBasedOnExtension(file)); 2027 GetDownloadPrefs(browser())->EnableAutoOpenBasedOnExtension(file));
1629 2028
1630 // Mock out external opening on all downloads until end of test. 2029 // Mock out external opening on all downloads until end of test.
1631 MockDownloadOpeningObserver observer( 2030 MockDownloadOpeningObserver observer(
1632 browser()->profile()->GetDownloadManager()); 2031 browser()->profile()->GetDownloadManager());
1633 2032
1634 DownloadAndWait(browser(), url, EXPECT_NO_SELECT_DIALOG); 2033 DownloadAndWait(browser(), url, EXPECT_NO_SELECT_DIALOG);
1635 2034
1636 // Find the download and confirm it was opened. 2035 // Find the download and confirm it was opened.
1637 std::vector<DownloadItem*> downloads; 2036 std::vector<DownloadItem*> downloads;
1638 browser()->profile()->GetDownloadManager()->SearchDownloads( 2037 GetPersistentDownloads(browser(), &downloads);
1639 string16(), &downloads);
1640 ASSERT_EQ(1u, downloads.size()); 2038 ASSERT_EQ(1u, downloads.size());
1641 EXPECT_EQ(DownloadItem::COMPLETE, downloads[0]->state()); 2039 EXPECT_EQ(DownloadItem::COMPLETE, downloads[0]->state());
1642 EXPECT_TRUE(downloads[0]->opened()); 2040 EXPECT_TRUE(downloads[0]->opened());
1643 2041
1644 // As long as we're here, confirmed everything else is good. 2042 // As long as we're here, confirmed everything else is good.
1645 EXPECT_EQ(1, browser()->tab_count()); 2043 EXPECT_EQ(1, browser()->tab_count());
1646 CheckDownload(browser(), file, file); 2044 CheckDownload(browser(), file, file);
1647 // Download shelf should close. Download panel stays open on ChromeOS. 2045 // Download shelf should close. Download panel stays open on ChromeOS.
1648 CheckDownloadUI(browser(), false, true, FilePath()); 2046 CheckDownloadUI(browser(), false, true, FilePath());
1649 } 2047 }
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
1781 EXPECT_EQ(1u, observer->NumDangerousDownloadsSeen()); 2179 EXPECT_EQ(1u, observer->NumDangerousDownloadsSeen());
1782 2180
1783 // Download shelf should close. Download panel stays open on ChromeOS. 2181 // Download shelf should close. Download panel stays open on ChromeOS.
1784 CheckDownloadUI(browser(), false, true, FilePath()); 2182 CheckDownloadUI(browser(), false, true, FilePath());
1785 2183
1786 // Check that the extension was installed. 2184 // Check that the extension was installed.
1787 ExtensionService* extension_service = 2185 ExtensionService* extension_service =
1788 browser()->profile()->GetExtensionService(); 2186 browser()->profile()->GetExtensionService();
1789 ASSERT_TRUE(extension_service->GetExtensionById(kLargeThemeCrxId, false)); 2187 ASSERT_TRUE(extension_service->GetExtensionById(kLargeThemeCrxId, false));
1790 } 2188 }
OLDNEW
« no previous file with comments | « chrome/browser/download/chrome_download_manager_delegate.cc ('k') | chrome/browser/download/download_history.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698