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

Unified Diff: chrome/browser/download/save_page_browsertest.cc

Issue 10916201: Make the SavePackage use of the fake download item cleaner around cancellation. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Merged to LKGR (156083) Created 8 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | content/browser/download/download_item_impl.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/download/save_page_browsertest.cc
diff --git a/chrome/browser/download/save_page_browsertest.cc b/chrome/browser/download/save_page_browsertest.cc
index bbf65f77c2940b27a49c788b5638a4ae0699ffc0..9befc69dd1e63d4cdf5b239525a12cf2f674b54f 100644
--- a/chrome/browser/download/save_page_browsertest.cc
+++ b/chrome/browser/download/save_page_browsertest.cc
@@ -64,13 +64,16 @@ static const char* kAppendedExtension =
".html";
#endif
+void NullFunction() {
+}
+
} // namespace
// Loosely based on logic in DownloadTestObserver.
class DownloadItemCreatedObserver : public DownloadManager::Observer {
public:
explicit DownloadItemCreatedObserver(DownloadManager* manager)
- : waiting_(false), manager_(manager), created_item_(NULL) {
+ : waiting_(false), manager_(manager) {
manager->AddObserver(this);
}
@@ -83,34 +86,37 @@ class DownloadItemCreatedObserver : public DownloadManager::Observer {
// Note that this class provides no protection against the download
// being destroyed between creation and return of WaitForNewDownloadItem();
// the caller must guarantee that in some other fashion.
- DownloadItem* WaitForNewDownloadItem() {
+ void WaitForDownloadItem(std::vector<DownloadItem*>* items_seen) {
if (!manager_) {
// The manager went away before we were asked to wait; return
// what we have, even if it's null.
- return created_item_;
+ *items_seen = items_seen_;
+ return;
}
- if (!created_item_) {
+ if (items_seen_.empty()) {
waiting_ = true;
content::RunMessageLoop();
waiting_ = false;
}
- return created_item_;
+
+ *items_seen = items_seen_;
+ return;
}
private:
// DownloadManager::Observer
- void OnDownloadCreated(DownloadManager* manager, DownloadItem* item) {
+ virtual void OnDownloadCreated(
+ DownloadManager* manager, DownloadItem* item) OVERRIDE {
DCHECK_EQ(manager, manager_);
- if (!created_item_)
- created_item_ = item;
+ items_seen_.push_back(item);
if (waiting_)
MessageLoopForUI::current()->Quit();
}
- void ManagerGoingDownload(DownloadManager* manager) {
+ virtual void ManagerGoingDown(DownloadManager* manager) OVERRIDE {
manager_->RemoveObserver(this);
manager_ = NULL;
if (waiting_)
@@ -119,11 +125,65 @@ class DownloadItemCreatedObserver : public DownloadManager::Observer {
bool waiting_;
DownloadManager* manager_;
- DownloadItem* created_item_;
+ std::vector<DownloadItem*> items_seen_;
DISALLOW_COPY_AND_ASSIGN(DownloadItemCreatedObserver);
};
+class DownloadPersistedObserver : public DownloadItem::Observer {
+ public:
+ explicit DownloadPersistedObserver(DownloadItem* item)
+ : waiting_(false), item_(item) {
+ item->AddObserver(this);
+ }
+
+ ~DownloadPersistedObserver() {
+ if (item_)
+ item_->RemoveObserver(this);
+ }
+
+ // Wait for download item to get the persisted bit set.
+ // Note that this class provides no protection against the download
+ // being destroyed between creation and return of WaitForPersisted();
+ // the caller must guarantee that in some other fashion.
+ void WaitForPersisted() {
+ // In combination with OnDownloadDestroyed() below, verify the
+ // above interface contract.
+ DCHECK(item_);
+
+ if (item_->IsPersisted())
+ return;
+
+ waiting_ = true;
+ content::RunMessageLoop();
+ waiting_ = false;
+
+ return;
+ }
+
+ private:
+ // DownloadItem::Observer
+ virtual void OnDownloadUpdated(DownloadItem* item) OVERRIDE {
+ DCHECK_EQ(item, item_);
+
+ if (waiting_ && item->IsPersisted())
+ MessageLoopForUI::current()->Quit();
+ }
+
+ virtual void OnDownloadDestroyed(DownloadItem* item) OVERRIDE {
+ if (item != item_)
+ return;
+
+ item_->RemoveObserver(this);
+ item_ = NULL;
+ }
+
+ bool waiting_;
+ DownloadItem* item_;
+
+ DISALLOW_COPY_AND_ASSIGN(DownloadPersistedObserver);
+};
+
class SavePageBrowserTest : public InProcessBrowserTest {
public:
SavePageBrowserTest() {}
@@ -142,6 +202,8 @@ class SavePageBrowserTest : public InProcessBrowserTest {
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled, true));
+ item_creation_observer_.reset(
+ new DownloadItemCreatedObserver(GetDownloadManager()));
}
GURL NavigateToMockURL(const std::string& prefix) {
@@ -165,14 +227,39 @@ class SavePageBrowserTest : public InProcessBrowserTest {
return current_tab;
}
-
- GURL WaitForSavePackageToFinish() const {
+ bool WaitForSavePackageToFinish(GURL* url_at_finish) const {
content::WindowedNotificationObserver observer(
content::NOTIFICATION_SAVE_PACKAGE_SUCCESSFULLY_FINISHED,
content::NotificationService::AllSources());
observer.Wait();
- return content::Details<DownloadItem>(observer.details()).ptr()->
+
+ // Generally, there should only be one download item created
+ // in all of these tests. Wait for it, and wait for it to
+ // be persisted.
+ std::vector<DownloadItem*> items;
+ item_creation_observer_->WaitForDownloadItem(&items);
+
+ EXPECT_EQ(1u, items.size());
+ if (1u != items.size())
+ return false;
+ DownloadItem* download_item(items[0]);
+
+ // Note on synchronization:
+ //
+ // For each Save Page As operation, we create a corresponding shell
+ // DownloadItem to display progress to the user. That DownloadItem
+ // goes through its own state transitions, including being persisted
+ // out to the history database, and the download shelf is not shown
+ // until after the persistence occurs. Save Package completion (and
+ // marking the DownloadItem as completed) occurs asynchronously from
+ // persistence. Thus if we want to examine either UI state or DB
+ // state, we need to wait until both the save package operation is
+ // complete and the relevant download item has been persisted.
+ DownloadPersistedObserver(download_item).WaitForPersisted();
+
+ *url_at_finish = content::Details<DownloadItem>(observer.details()).ptr()->
GetOriginalUrl();
+ return true;
}
DownloadManager* GetDownloadManager() const {
@@ -209,11 +296,12 @@ class SavePageBrowserTest : public InProcessBrowserTest {
DownloadPersistentStoreInfoMatch(const GURL& url,
const FilePath& path,
- int64 num_files)
+ int64 num_files,
+ DownloadItem::DownloadState state)
: url_(url),
path_(path),
- num_files_(num_files) {
- }
+ num_files_(num_files),
+ state_(state) {}
bool operator() (const DownloadPersistentStoreInfo& info) const {
return info.url == url_ &&
@@ -223,22 +311,30 @@ class SavePageBrowserTest : public InProcessBrowserTest {
((num_files_ < 0) ||
(info.received_bytes == num_files_)) &&
info.total_bytes == 0 &&
- info.state == DownloadItem::COMPLETE;
+ info.state == state_;
}
GURL url_;
FilePath path_;
int64 num_files_;
+ DownloadItem::DownloadState state_;
};
void CheckDownloadHistory(const GURL& url,
const FilePath& path,
- int64 num_files) {
+ int64 num_files,
+ DownloadItem::DownloadState state) {
+ // Make sure the relevant download item made it into the history.
+ std::vector<DownloadItem*> downloads;
+ GetDownloadManager()->SearchDownloads(string16(), &downloads);
+ ASSERT_EQ(1u, downloads.size());
+
QueryDownloadHistory();
std::vector<DownloadPersistentStoreInfo>::iterator found =
std::find_if(history_entries_.begin(), history_entries_.end(),
- DownloadPersistentStoreInfoMatch(url, path, num_files));
+ DownloadPersistentStoreInfoMatch(url, path, num_files,
+ state));
if (found == history_entries_.end()) {
LOG(ERROR) << "Missing url=" << url.spec()
@@ -265,6 +361,8 @@ class SavePageBrowserTest : public InProcessBrowserTest {
ScopedTempDir save_dir_;
private:
+ scoped_ptr<DownloadItemCreatedObserver> item_creation_observer_;
+
DISALLOW_COPY_AND_ASSIGN(SavePageBrowserTest);
};
@@ -279,10 +377,13 @@ IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, SaveHTMLOnly) {
ASSERT_TRUE(GetCurrentTab()->SavePage(full_file_name, dir,
content::SAVE_PAGE_TYPE_AS_ONLY_HTML));
- EXPECT_EQ(url, WaitForSavePackageToFinish());
+ GURL output_url;
+ ASSERT_TRUE(WaitForSavePackageToFinish(&output_url));
+ EXPECT_EQ(url, output_url);
EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
- CheckDownloadHistory(url, full_file_name, 1); // a.htm is 1 file.
+ // a.htm is 1 file.
+ CheckDownloadHistory(url, full_file_name, 1, DownloadItem::COMPLETE);
EXPECT_TRUE(file_util::PathExists(full_file_name));
EXPECT_FALSE(file_util::PathExists(dir));
@@ -303,15 +404,23 @@ IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, SaveHTMLOnlyCancel) {
DownloadItemCreatedObserver creation_observer(manager);
ASSERT_TRUE(GetCurrentTab()->SavePage(full_file_name, dir,
content::SAVE_PAGE_TYPE_AS_ONLY_HTML));
- DownloadItem* item = creation_observer.WaitForNewDownloadItem();
- item->Cancel(true);
+ std::vector<DownloadItem*> items;
+ creation_observer.WaitForDownloadItem(&items);
+ ASSERT_TRUE(items.size() == 1);
+ items[0]->Cancel(true);
// TODO(rdsmith): Fix DII::Cancel() to actually cancel the save package.
// Currently it's ignored.
- EXPECT_EQ(url, WaitForSavePackageToFinish());
+ GURL output_url;
+ ASSERT_TRUE(WaitForSavePackageToFinish(&output_url));
+ EXPECT_EQ(url, output_url);
+
+ // -1 to disable number of files check; we don't update after cancel, and
+ // we don't know when the single file completed in relationship to
+ // the cancel.
+ CheckDownloadHistory(url, full_file_name, -1, DownloadItem::CANCELLED);
EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
- CheckDownloadHistory(url, full_file_name, 1); // a.htm is 1 file.
EXPECT_TRUE(file_util::PathExists(full_file_name));
EXPECT_FALSE(file_util::PathExists(dir));
@@ -334,11 +443,13 @@ IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, DISABLED_SaveHTMLOnlyTabDestroy) {
DownloadItemCreatedObserver creation_observer(manager);
ASSERT_TRUE(GetCurrentTab()->SavePage(full_file_name, dir,
content::SAVE_PAGE_TYPE_AS_ONLY_HTML));
- DownloadItem* item = creation_observer.WaitForNewDownloadItem();
+ std::vector<DownloadItem*> items;
+ creation_observer.WaitForDownloadItem(&items);
+ ASSERT_TRUE(items.size() == 1);
// Close the tab; does this cancel the download?
GetCurrentTab()->Close();
- EXPECT_TRUE(item->IsCancelled());
+ EXPECT_TRUE(items[0]->IsCancelled());
EXPECT_FALSE(file_util::PathExists(full_file_name));
EXPECT_FALSE(file_util::PathExists(dir));
@@ -357,10 +468,14 @@ IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, SaveViewSourceHTMLOnly) {
ASSERT_TRUE(GetCurrentTab()->SavePage(full_file_name, dir,
content::SAVE_PAGE_TYPE_AS_ONLY_HTML));
- EXPECT_EQ(actual_page_url, WaitForSavePackageToFinish());
+ GURL output_url;
+ ASSERT_TRUE(WaitForSavePackageToFinish(&output_url));
+ EXPECT_EQ(actual_page_url, output_url);
EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
- CheckDownloadHistory(actual_page_url, full_file_name, 1); // a.htm is 1 file.
+ // a.htm is 1 file.
+ CheckDownloadHistory(actual_page_url, full_file_name, 1,
+ DownloadItem::COMPLETE);
EXPECT_TRUE(file_util::PathExists(full_file_name));
EXPECT_FALSE(file_util::PathExists(dir));
@@ -377,10 +492,13 @@ IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, SaveCompleteHTML) {
ASSERT_TRUE(GetCurrentTab()->SavePage(
full_file_name, dir, content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML));
- EXPECT_EQ(url, WaitForSavePackageToFinish());
+ GURL output_url;
+ ASSERT_TRUE(WaitForSavePackageToFinish(&output_url));
+ EXPECT_EQ(url, output_url);
EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
- CheckDownloadHistory(url, full_file_name, 3); // b.htm is 3 files.
+ // b.htm is 3 files.
+ CheckDownloadHistory(url, full_file_name, 3, DownloadItem::COMPLETE);
EXPECT_TRUE(file_util::PathExists(full_file_name));
EXPECT_TRUE(file_util::PathExists(dir));
@@ -410,10 +528,13 @@ IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, FileNameFromPageTitle) {
ASSERT_TRUE(GetCurrentTab()->SavePage(
full_file_name, dir, content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML));
- EXPECT_EQ(url, WaitForSavePackageToFinish());
+ GURL output_url;
+ ASSERT_TRUE(WaitForSavePackageToFinish(&output_url));
+ EXPECT_EQ(url, output_url);
EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
- CheckDownloadHistory(url, full_file_name, 3); // b.htm is 3 files.
+ // b.htm is 3 files.
+ CheckDownloadHistory(url, full_file_name, 3, DownloadItem::COMPLETE);
EXPECT_TRUE(file_util::PathExists(full_file_name));
EXPECT_TRUE(file_util::PathExists(dir));
@@ -436,17 +557,21 @@ IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, RemoveFromList) {
ASSERT_TRUE(GetCurrentTab()->SavePage(full_file_name, dir,
content::SAVE_PAGE_TYPE_AS_ONLY_HTML));
- EXPECT_EQ(url, WaitForSavePackageToFinish());
+ GURL output_url;
+ ASSERT_TRUE(WaitForSavePackageToFinish(&output_url));
+ EXPECT_EQ(url, output_url);
EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
- CheckDownloadHistory(url, full_file_name, 1); // a.htm is 1 file.
+ // a.htm is 1 file.
+ CheckDownloadHistory(url, full_file_name, 1, DownloadItem::COMPLETE);
EXPECT_EQ(GetDownloadManager()->RemoveAllDownloads(), 1);
// Should not be in history.
QueryDownloadHistory();
EXPECT_EQ(std::find_if(history_entries_.begin(), history_entries_.end(),
- DownloadPersistentStoreInfoMatch(url, full_file_name, 1)),
+ DownloadPersistentStoreInfoMatch(
+ url, full_file_name, 1, DownloadItem::COMPLETE)),
history_entries_.end());
EXPECT_TRUE(file_util::PathExists(full_file_name));
@@ -520,7 +645,7 @@ IN_PROC_BROWSER_TEST_F(SavePageAsMHTMLBrowserTest, SavePageAsMHTML) {
content::NotificationService::AllSources());
chrome::SavePage(browser());
observer.Wait();
- CheckDownloadHistory(url, full_file_name, -1);
+ CheckDownloadHistory(url, full_file_name, -1, DownloadItem::COMPLETE);
EXPECT_TRUE(file_util::PathExists(full_file_name));
int64 actual_file_size = -1;
« no previous file with comments | « no previous file | content/browser/download/download_item_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698