OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "base/rand_util.h" |
| 6 #include "chrome/browser/download/download_history.h" |
| 7 #include "chrome/browser/history/history.h" |
| 8 #include "chrome/test/base/in_process_browser_test.h" |
| 9 #include "content/public/browser/download_persistent_store_info.h" |
| 10 #include "content/public/test/mock_download_item.h" |
| 11 #include "content/public/test/mock_download_manager.h" |
| 12 #include "content/public/test/test_utils.h" |
| 13 |
| 14 using ::testing::Return; |
| 15 using ::testing::ReturnRef; |
| 16 using ::testing::NiceMock; |
| 17 using ::testing::_; |
| 18 using content::BrowserThread; |
| 19 using content::DownloadItem; |
| 20 using content::DownloadManager; |
| 21 using content::DownloadPersistentStoreInfo; |
| 22 using content::MockDownloadItem; |
| 23 using content::MockDownloadManager; |
| 24 |
| 25 namespace { |
| 26 |
| 27 bool InfoEqual(const DownloadPersistentStoreInfo& left, |
| 28 const DownloadPersistentStoreInfo& right) { |
| 29 if (left.path != right.path) { |
| 30 LOG(ERROR) << __FUNCTION__ << " " << left.path.value() << " " << right.path.
value(); |
| 31 return false; |
| 32 } else if (left.url != right.url) { |
| 33 LOG(ERROR) << __FUNCTION__ << " " << left.url.spec() << " " << right.url.spe
c(); |
| 34 return false; |
| 35 } else if (left.referrer_url != right.referrer_url) { |
| 36 LOG(ERROR) << __FUNCTION__ << " " << left.referrer_url.spec() << " " << righ
t.referrer_url.spec(); |
| 37 return false; |
| 38 } else if (left.start_time != right.start_time) { |
| 39 LOG(ERROR) << __FUNCTION__ << " " << left.start_time.ToTimeT() << " " << rig
ht.start_time.ToTimeT(); |
| 40 return false; |
| 41 } else if (left.end_time != right.end_time) { |
| 42 LOG(ERROR) << __FUNCTION__ << " " << left.end_time.ToTimeT() << " " << right
.end_time.ToTimeT(); |
| 43 return false; |
| 44 } else if (left.received_bytes != right.received_bytes) { |
| 45 LOG(ERROR) << __FUNCTION__ << " " << left.received_bytes << " " << right.rec
eived_bytes; |
| 46 return false; |
| 47 } else if (left.total_bytes != right.total_bytes) { |
| 48 LOG(ERROR) << __FUNCTION__ << " " << left.total_bytes << " " << right.total_
bytes; |
| 49 return false; |
| 50 } else if (left.state != right.state) { |
| 51 LOG(ERROR) << __FUNCTION__ << " " << left.state << " " << right.state; |
| 52 return false; |
| 53 } else if (left.db_handle != right.db_handle) { |
| 54 LOG(ERROR) << __FUNCTION__ << " " << left.db_handle << " " << right.db_handl
e; |
| 55 return false; |
| 56 } else if (left.opened != right.opened) { |
| 57 LOG(ERROR) << __FUNCTION__ << " " << left.opened << " " << right.opened; |
| 58 return false; |
| 59 } |
| 60 return true; |
| 61 } |
| 62 |
| 63 class DownloadHistoryTest : public InProcessBrowserTest, |
| 64 public HistoryServiceDownloadInterface { |
| 65 public: |
| 66 DownloadHistoryTest() |
| 67 : manager_(new MockDownloadManager()), |
| 68 download_history_(NULL), |
| 69 expect_query_downloads_(NULL), |
| 70 handle_counter_(0), |
| 71 create_download_id_(-1) { |
| 72 } |
| 73 virtual ~DownloadHistoryTest() {} |
| 74 |
| 75 // HistoryServiceDownloadInterface |
| 76 virtual void QueryDownloads( |
| 77 const HistoryService::DownloadQueryCallback& callback) OVERRIDE { |
| 78 CHECK(expect_query_downloads_); |
| 79 for (DownloadHistory::InfoVector::const_iterator it = |
| 80 expect_query_downloads_->begin(); |
| 81 it != expect_query_downloads_->end(); |
| 82 ++it) { |
| 83 LOG(INFO) << "occam " << __FUNCTION__ << " " << it->db_handle; |
| 84 } |
| 85 callback.Run(expect_query_downloads_); |
| 86 expect_query_downloads_ = NULL; |
| 87 } |
| 88 |
| 89 virtual HistoryService::Handle GetVisibleVisitCountToHost( |
| 90 const GURL& referrer_url, |
| 91 const HistoryService::GetVisibleVisitCountToHostCallback& |
| 92 callback) OVERRIDE { |
| 93 NOTIMPLEMENTED(); |
| 94 return 0; |
| 95 } |
| 96 |
| 97 virtual void CreateDownload( |
| 98 int32 id, |
| 99 const content::DownloadPersistentStoreInfo& info, |
| 100 const HistoryService::DownloadCreateCallback& callback) OVERRIDE { |
| 101 LOG(INFO) << "occam " << __FUNCTION__ << " " << id; |
| 102 create_download_id_ = id; |
| 103 create_download_info_ = info; |
| 104 callback.Run(id, handle_counter_++); |
| 105 } |
| 106 |
| 107 virtual void UpdateDownload( |
| 108 const content::DownloadPersistentStoreInfo& info) OVERRIDE { |
| 109 LOG(INFO) << "occam " << __FUNCTION__ << " " << info.path.value() |
| 110 << " " << info.db_handle; |
| 111 update_download_ = info; |
| 112 } |
| 113 |
| 114 virtual void RemoveDownloads( |
| 115 const DownloadHistory::HandleSet& handles) OVERRIDE { |
| 116 LOG(INFO) << "occam " << __FUNCTION__ << " " << handles.size(); |
| 117 for (DownloadHistory::HandleSet::const_iterator it = handles.begin(); |
| 118 it != handles.end(); ++it) { |
| 119 LOG(INFO) << "occam " << __FUNCTION__ << " " << *it; |
| 120 remove_downloads_.insert(*it); |
| 121 } |
| 122 } |
| 123 |
| 124 virtual void OnDownloadHistoryDestroyed() OVERRIDE { |
| 125 } |
| 126 |
| 127 protected: |
| 128 virtual void SetUpOnMainThread() OVERRIDE { |
| 129 EXPECT_CALL(manager(), AddObserver(_)); |
| 130 EXPECT_CALL(manager(), RemoveObserver(_)); |
| 131 download_history_.reset(new DownloadHistory(&manager(), this)); |
| 132 } |
| 133 |
| 134 virtual void CleanUpOnMainThread() OVERRIDE { |
| 135 download_history_.reset(); |
| 136 } |
| 137 |
| 138 DownloadHistory* download_history() { return download_history_.get(); } |
| 139 |
| 140 MockDownloadManager& manager() { return *manager_.get(); } |
| 141 MockDownloadItem& item() { return item_; } |
| 142 |
| 143 HistoryService::DownloadQueryCallback query_callback() { |
| 144 return base::Bind(&DownloadHistoryTest::QueryCallback, |
| 145 base::Unretained(this)); |
| 146 } |
| 147 |
| 148 void ExpectQueryDownloads(DownloadHistory::InfoVector* infos) { |
| 149 expect_query_downloads_ = infos; |
| 150 } |
| 151 |
| 152 void ExpectQueryDownloadsDone() { |
| 153 CHECK(NULL == expect_query_downloads_); |
| 154 } |
| 155 |
| 156 void ExpectCreateDownload( |
| 157 const DownloadPersistentStoreInfo& info) { |
| 158 CHECK_EQ(item().GetId(), create_download_id_); |
| 159 create_download_id_ = -1; |
| 160 CHECK(InfoEqual(info, create_download_info_)); |
| 161 create_download_info_ = DownloadPersistentStoreInfo(); |
| 162 } |
| 163 |
| 164 void ExpectNoCreateDownload() { |
| 165 CHECK_EQ(-1, create_download_id_); |
| 166 CHECK(InfoEqual(DownloadPersistentStoreInfo(), create_download_info_)); |
| 167 } |
| 168 |
| 169 void ExpectUpdateDownload(const DownloadPersistentStoreInfo& info) { |
| 170 CHECK(InfoEqual(update_download_, info)); |
| 171 update_download_ = DownloadPersistentStoreInfo(); |
| 172 } |
| 173 |
| 174 void ExpectNoUpdateDownload() { |
| 175 CHECK(InfoEqual(DownloadPersistentStoreInfo(), update_download_)); |
| 176 } |
| 177 |
| 178 void ExpectRemoveDownloads(const DownloadHistory::HandleSet& handles) { |
| 179 content::RunAllPendingInMessageLoop(content::BrowserThread::UI); |
| 180 for (DownloadHistory::HandleSet::const_iterator it = handles.begin(); |
| 181 it != handles.end(); ++it) { |
| 182 LOG(INFO) << "occam " << __FUNCTION__ << " expected handle " << *it; |
| 183 } |
| 184 for (DownloadHistory::HandleSet::const_iterator it = remove_downloads_.begin
(); |
| 185 it != remove_downloads_.end(); ++it) { |
| 186 LOG(INFO) << "occam " << __FUNCTION__ << " actual handle " << *it; |
| 187 } |
| 188 DownloadHistory::HandleSet difference; |
| 189 std::insert_iterator<DownloadHistory::HandleSet> insert_it( |
| 190 difference, difference.begin()); |
| 191 std::set_difference(handles.begin(), handles.end(), |
| 192 remove_downloads_.begin(), |
| 193 remove_downloads_.end(), |
| 194 insert_it); |
| 195 CHECK(difference.empty()); |
| 196 remove_downloads_.clear(); |
| 197 } |
| 198 |
| 199 void InitItem( |
| 200 int32 id, |
| 201 const FilePath& path, |
| 202 const GURL& url, |
| 203 const GURL& referrer, |
| 204 const base::Time& start_time, |
| 205 const base::Time& end_time, |
| 206 int64 received_bytes, |
| 207 int64 total_bytes, |
| 208 DownloadItem::DownloadState state, |
| 209 int64 db_handle, |
| 210 bool opened, |
| 211 DownloadPersistentStoreInfo* info) { |
| 212 info->path = path; |
| 213 info->url = url; |
| 214 info->referrer_url = referrer; |
| 215 info->start_time = start_time; |
| 216 info->end_time = end_time; |
| 217 info->received_bytes = received_bytes; |
| 218 info->total_bytes = total_bytes; |
| 219 info->state = state; |
| 220 info->db_handle = db_handle; |
| 221 info->opened = opened; |
| 222 EXPECT_CALL(item(), GetId()).WillRepeatedly(Return(id)); |
| 223 EXPECT_CALL(item(), GetFullPath()).WillRepeatedly(ReturnRef(path)); |
| 224 EXPECT_CALL(item(), GetURL()).WillRepeatedly(ReturnRef(url)); |
| 225 EXPECT_CALL(item(), GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer)); |
| 226 EXPECT_CALL(item(), GetStartTime()).WillRepeatedly(Return(start_time)); |
| 227 EXPECT_CALL(item(), GetEndTime()).WillRepeatedly(Return(end_time)); |
| 228 EXPECT_CALL(item(), GetReceivedBytes()) |
| 229 .WillRepeatedly(Return(received_bytes)); |
| 230 EXPECT_CALL(item(), GetTotalBytes()).WillRepeatedly(Return(total_bytes)); |
| 231 EXPECT_CALL(item(), GetState()).WillRepeatedly(Return(state)); |
| 232 EXPECT_CALL(item(), GetOpened()).WillRepeatedly(Return(opened)); |
| 233 EXPECT_CALL(manager(), GetDownload(id)) |
| 234 .WillRepeatedly(Return(&item())); |
| 235 EXPECT_CALL(item(), AddObserver(_)); |
| 236 EXPECT_CALL(item(), RemoveObserver(_)); |
| 237 } |
| 238 |
| 239 private: |
| 240 void QueryCallback(DownloadHistory::InfoVector* infos) { |
| 241 } |
| 242 |
| 243 testing::NiceMock<content::MockDownloadItem> item_; |
| 244 scoped_refptr<content::MockDownloadManager> manager_; |
| 245 scoped_ptr<DownloadHistory> download_history_; |
| 246 DownloadHistory::InfoVector* expect_query_downloads_; |
| 247 int handle_counter_; |
| 248 DownloadPersistentStoreInfo update_download_; |
| 249 int32 create_download_id_; |
| 250 DownloadPersistentStoreInfo create_download_info_; |
| 251 DownloadHistory::HandleSet remove_downloads_; |
| 252 |
| 253 DISALLOW_COPY_AND_ASSIGN(DownloadHistoryTest); |
| 254 }; |
| 255 |
| 256 } // anonymous namespace |
| 257 |
| 258 IN_PROC_BROWSER_TEST_F(DownloadHistoryTest, DownloadHistoryTest_Load) { |
| 259 // Load a download from history, create the item, OnDownloadCreated, |
| 260 // OnDownloadUpdated, OnDownloadRemoved, OnDownloadDestroyed. |
| 261 DownloadPersistentStoreInfo info; |
| 262 InitItem(base::RandInt(0, 1 << 20), |
| 263 FilePath(FILE_PATH_LITERAL("/foo/bar.pdf")), |
| 264 GURL("http://example.com/bar.pdf"), |
| 265 GURL("http://example.com/referrer.html"), |
| 266 (base::Time::Now() - base::TimeDelta::FromMinutes(10)), |
| 267 (base::Time::Now() - base::TimeDelta::FromMinutes(1)), |
| 268 100, |
| 269 100, |
| 270 DownloadItem::COMPLETE, |
| 271 base::RandInt(0, 1 << 20), |
| 272 false, |
| 273 &info); |
| 274 DownloadHistory::InfoVector infos; |
| 275 infos.push_back(info); |
| 276 ExpectQueryDownloads(&infos); |
| 277 download_history()->Load(query_callback()); |
| 278 ExpectQueryDownloadsDone(); |
| 279 |
| 280 // Pretend the manager just created |item| in response to |
| 281 // OnPersistentStoreQueryComplete. |
| 282 download_history()->OnDownloadCreated(&manager(), &item()); |
| 283 ExpectNoCreateDownload(); |
| 284 |
| 285 // Pretend that something changed on the item. |
| 286 EXPECT_CALL(item(), GetOpened()).WillRepeatedly(Return(true)); |
| 287 download_history()->OnDownloadUpdated(&item()); |
| 288 info.opened = true; |
| 289 ExpectUpdateDownload(info); |
| 290 |
| 291 // Pretend that the user removed the item. |
| 292 DownloadHistory::HandleSet handles; |
| 293 handles.insert(info.db_handle); |
| 294 download_history()->OnDownloadRemoved(&item()); |
| 295 ExpectRemoveDownloads(handles); |
| 296 |
| 297 // Pretend that the browser is closing. |
| 298 download_history()->ManagerGoingDown(&manager()); |
| 299 download_history()->OnDownloadDestroyed(&item()); |
| 300 } |
| 301 |
| 302 IN_PROC_BROWSER_TEST_F(DownloadHistoryTest, DownloadHistoryTest_Create) { |
| 303 // Create a fresh item not from history, OnDownloadCreated, OnDownloadUpdated, |
| 304 // OnDownloadRemoved, OnDownloadDestroyed. |
| 305 DownloadHistory::InfoVector infos; |
| 306 ExpectQueryDownloads(&infos); |
| 307 download_history()->Load(query_callback()); |
| 308 ExpectQueryDownloadsDone(); |
| 309 |
| 310 // Note that db_handle must be -1 at first because it isn't in the db yet. |
| 311 DownloadPersistentStoreInfo info; |
| 312 InitItem(base::RandInt(0, 1 << 20), |
| 313 FilePath(FILE_PATH_LITERAL("/foo/bar.pdf")), |
| 314 GURL("http://example.com/bar.pdf"), |
| 315 GURL("http://example.com/referrer.html"), |
| 316 (base::Time::Now() - base::TimeDelta::FromMinutes(10)), |
| 317 (base::Time::Now() - base::TimeDelta::FromMinutes(1)), |
| 318 100, |
| 319 100, |
| 320 DownloadItem::COMPLETE, |
| 321 -1, |
| 322 false, |
| 323 &info); |
| 324 |
| 325 // Pretend the manager just created |item| in response to |
| 326 // OnPersistentStoreQueryComplete. |
| 327 download_history()->OnDownloadCreated(&manager(), &item()); |
| 328 ExpectCreateDownload(info); |
| 329 info.db_handle = 0; |
| 330 |
| 331 // Pretend that something changed on the item. |
| 332 EXPECT_CALL(item(), GetOpened()).WillRepeatedly(Return(true)); |
| 333 download_history()->OnDownloadUpdated(&item()); |
| 334 info.opened = true; |
| 335 ExpectUpdateDownload(info); |
| 336 |
| 337 // Pretend that the user removed the item. |
| 338 DownloadHistory::HandleSet handles; |
| 339 handles.insert(info.db_handle); |
| 340 download_history()->OnDownloadRemoved(&item()); |
| 341 ExpectRemoveDownloads(handles); |
| 342 |
| 343 // Pretend that the browser is closing. |
| 344 download_history()->ManagerGoingDown(&manager()); |
| 345 download_history()->OnDownloadDestroyed(&item()); |
| 346 } |
| 347 |
| 348 // TODO Create a fresh item, change it to temporary after it's been added. |
| 349 |
| 350 // TODO Test that OnDownloadCreated does not match up items if a field is off, |
| 351 // except for state=IN_PROGRESS->CANCELLED. |
OLD | NEW |