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

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

Issue 10915180: Make DownloadHistory observe manager, items (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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/download_persistent_store_info.h"
8 #include "chrome/browser/history/history.h"
9 #include "chrome/test/base/in_process_browser_test.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 content::BrowserThread;
15 using testing::DoAll;
16 using testing::Invoke;
17 using testing::Return;
18 using testing::ReturnRef;
19 using testing::SetArgPointee;
20 using testing::WithArg;
21 using testing::_;
22
23 namespace {
24
25 void CheckInfoEqual(const DownloadPersistentStoreInfo& left,
26 const DownloadPersistentStoreInfo& right) {
27 CHECK_EQ(left.path.value(), right.path.value());
28 CHECK_EQ(left.url.spec(), right.url.spec());
29 CHECK_EQ(left.referrer_url.spec(), right.referrer_url.spec());
30 CHECK_EQ(left.start_time.ToTimeT(), right.start_time.ToTimeT());
31 CHECK_EQ(left.end_time.ToTimeT(), right.end_time.ToTimeT());
32 CHECK_EQ(left.received_bytes, right.received_bytes);
33 CHECK_EQ(left.total_bytes, right.total_bytes);
34 CHECK_EQ(left.state, right.state);
35 CHECK_EQ(left.db_handle, right.db_handle);
36 CHECK_EQ(left.opened, right.opened);
37 }
38
39 typedef std::set<int64> HandleSet;
40 typedef std::vector<DownloadPersistentStoreInfo> InfoVector;
41
42 class FakeHistoryService : public HistoryService {
43 public:
44 FakeHistoryService()
45 : slow_create_download_(false),
46 handle_counter_(0) {
47 }
48
49 virtual Handle QueryDownloads(
50 CancelableRequestConsumerBase* consumer,
51 const HistoryService::DownloadQueryCallback& callback) OVERRIDE {
52 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
53 base::Bind(&FakeHistoryService::QueryDownloadsDone,
54 base::Unretained(this), callback));
55 // DownloadHistory ignores the handle.
56 return -1;
57 }
58
59 void QueryDownloadsDone(
60 const HistoryService::DownloadQueryCallback& callback) {
61 CHECK(expect_query_downloads_.get());
62 callback.Run(expect_query_downloads_.get());
63 expect_query_downloads_.reset();
64 }
65
66 virtual Handle GetVisibleVisitCountToHost(
67 const GURL& referrer_url,
68 CancelableRequestConsumerBase* consumer,
69 const HistoryService::GetVisibleVisitCountToHostCallback&
70 callback) OVERRIDE {
71 NOTIMPLEMENTED();
72 return -1;
73 }
74
75 void set_slow_create_download(bool slow) { slow_create_download_ = slow; }
76
77 virtual Handle CreateDownload(
78 const DownloadPersistentStoreInfo& info,
79 CancelableRequestConsumerBase* consumer,
80 const HistoryService::DownloadCreateCallback& callback) OVERRIDE {
81 create_download_info_ = info;
82 create_download_callback_ = base::Bind(callback, handle_counter_++);
83 if (!slow_create_download_)
84 FinishCreateDownload();
85 return -1;
86 }
87
88 void FinishCreateDownload() {
89 create_download_callback_.Run();
90 create_download_callback_.Reset();
91 }
92
93 virtual void UpdateDownload(
94 const DownloadPersistentStoreInfo& info) OVERRIDE {
95 update_download_ = info;
96 }
97
98 virtual void RemoveDownloads(const HandleSet& handles) OVERRIDE {
99 for (HandleSet::const_iterator it = handles.begin();
100 it != handles.end(); ++it) {
101 remove_downloads_.insert(*it);
102 }
103 }
104
105 void ExpectWillQueryDownloads(scoped_ptr<InfoVector> infos) {
106 expect_query_downloads_ = infos.Pass();
107 }
108
109 void ExpectQueryDownloadsDone() {
110 CHECK(NULL == expect_query_downloads_.get());
111 }
112
113 void ExpectDownloadCreated(
114 const DownloadPersistentStoreInfo& info) {
115 content::RunAllPendingInMessageLoop(content::BrowserThread::UI);
116 CheckInfoEqual(info, create_download_info_);
117 create_download_info_ = DownloadPersistentStoreInfo();
118 }
119
120 void ExpectNoDownloadCreated() {
121 content::RunAllPendingInMessageLoop(content::BrowserThread::UI);
122 CheckInfoEqual(DownloadPersistentStoreInfo(), create_download_info_);
123 }
124
125 void ExpectDownloadUpdated(const DownloadPersistentStoreInfo& info) {
126 content::RunAllPendingInMessageLoop(content::BrowserThread::UI);
127 CheckInfoEqual(update_download_, info);
128 update_download_ = DownloadPersistentStoreInfo();
129 }
130
131 void ExpectNoDownloadUpdated() {
132 content::RunAllPendingInMessageLoop(content::BrowserThread::UI);
133 CheckInfoEqual(DownloadPersistentStoreInfo(), update_download_);
134 }
135
136 void ExpectNoDownloadsRemoved() {
137 content::RunAllPendingInMessageLoop(content::BrowserThread::UI);
138 CHECK_EQ(0, static_cast<int>(remove_downloads_.size()));
139 }
140
141 void ExpectDownloadsRemoved(const HandleSet& handles) {
142 content::RunAllPendingInMessageLoop(content::BrowserThread::UI);
143 HandleSet difference;
144 std::insert_iterator<HandleSet> insert_it(
145 difference, difference.begin());
146 std::set_difference(handles.begin(), handles.end(),
147 remove_downloads_.begin(),
148 remove_downloads_.end(),
149 insert_it);
150 CHECK(difference.empty());
151 remove_downloads_.clear();
152 }
153
154 private:
155 virtual ~FakeHistoryService() {}
156
157 bool slow_create_download_;
158 base::Closure create_download_callback_;
159 int handle_counter_;
160 DownloadPersistentStoreInfo update_download_;
161 scoped_ptr<InfoVector> expect_query_downloads_;
162 HandleSet remove_downloads_;
163 DownloadPersistentStoreInfo create_download_info_;
164
165 DISALLOW_COPY_AND_ASSIGN(FakeHistoryService);
166 };
167
168 class DownloadHistoryTest : public InProcessBrowserTest {
169 public:
170 DownloadHistoryTest()
171 : manager_(new content::MockDownloadManager()),
172 download_history_(NULL),
173 manager_observer_(NULL),
174 item_observer_(NULL) {
175 }
176 virtual ~DownloadHistoryTest() {}
177
178 protected:
179 virtual void CleanUpOnMainThread() OVERRIDE {
180 download_history_.reset();
181 }
182
183 content::MockDownloadManager& manager() { return *manager_.get(); }
184 content::MockDownloadItem& item() { return item_; }
185
186 void SetManagerObserver(
187 content::DownloadManager::Observer* manager_observer) {
188 manager_observer_ = manager_observer;
189 }
190 content::DownloadManager::Observer* manager_observer() {
191 return manager_observer_;
192 }
193 void SetItemObserver(
194 content::DownloadItem::Observer* item_observer) {
195 item_observer_ = item_observer;
196 }
197 content::DownloadItem::Observer* item_observer() {
198 return item_observer_;
199 }
200
201 void ExpectWillQueryDownloads(scoped_ptr<InfoVector> infos) {
202 CHECK(infos.get());
203 EXPECT_CALL(manager(), AddObserver(_)).WillOnce(WithArg<0>(Invoke(
204 this, &DownloadHistoryTest::SetManagerObserver)));
205 EXPECT_CALL(manager(), RemoveObserver(_));
206 if (infos->size() != 0) {
207 EXPECT_EQ(1, static_cast<int>(infos->size()));
208 EXPECT_CALL(manager(), CreateDownloadItem(
209 infos->at(0).path,
210 infos->at(0).url,
211 infos->at(0).referrer_url,
212 infos->at(0).start_time,
213 infos->at(0).end_time,
214 infos->at(0).received_bytes,
215 infos->at(0).total_bytes,
216 infos->at(0).state,
217 infos->at(0).opened))
218 .WillOnce(DoAll(
219 InvokeWithoutArgs(
220 this, &DownloadHistoryTest::CallOnDownloadCreated),
221 Return(&item())));
222 }
223 EXPECT_CALL(manager(), CheckForHistoryFilesRemoval());
224 history_ = new FakeHistoryService();
225 history_->ExpectWillQueryDownloads(infos.Pass());
226 EXPECT_CALL(*manager_.get(), GetAllDownloads(_)).WillRepeatedly(Return());
227 download_history_.reset(new DownloadHistory(&manager(), history_.get()));
228 content::RunAllPendingInMessageLoop(content::BrowserThread::UI);
229 history_->ExpectQueryDownloadsDone();
230 }
231
232 void CallOnDownloadCreated() {
233 manager_observer()->OnDownloadCreated(&manager(), &item());
234 }
235
236 void set_slow_create_download(bool slow) {
237 history_->set_slow_create_download(slow);
238 }
239
240 void FinishCreateDownload() {
241 history_->FinishCreateDownload();
242 }
243
244 void ExpectDownloadCreated(
245 const DownloadPersistentStoreInfo& info) {
246 history_->ExpectDownloadCreated(info);
247 }
248
249 void ExpectNoDownloadCreated() {
250 history_->ExpectNoDownloadCreated();
251 }
252
253 void ExpectDownloadUpdated(const DownloadPersistentStoreInfo& info) {
254 history_->ExpectDownloadUpdated(info);
255 }
256
257 void ExpectNoDownloadUpdated() {
258 history_->ExpectNoDownloadUpdated();
259 }
260
261 void ExpectNoDownloadsRemoved() {
262 history_->ExpectNoDownloadsRemoved();
263 }
264
265 void ExpectDownloadsRemoved(const HandleSet& handles) {
266 history_->ExpectDownloadsRemoved(handles);
267 }
268
269 void InitItem(
270 int32 id,
271 const FilePath& path,
272 const GURL& url,
273 const GURL& referrer,
274 const base::Time& start_time,
275 const base::Time& end_time,
276 int64 received_bytes,
277 int64 total_bytes,
278 content::DownloadItem::DownloadState state,
279 int64 db_handle,
280 bool opened,
281 DownloadPersistentStoreInfo* info) {
282 info->path = path;
283 info->url = url;
284 info->referrer_url = referrer;
285 info->start_time = start_time;
286 info->end_time = end_time;
287 info->received_bytes = received_bytes;
288 info->total_bytes = total_bytes;
289 info->state = state;
290 info->db_handle = db_handle;
291 info->opened = opened;
292 EXPECT_CALL(item(), GetId()).WillRepeatedly(Return(id));
293 EXPECT_CALL(item(), GetFullPath()).WillRepeatedly(ReturnRef(path));
294 EXPECT_CALL(item(), GetURL()).WillRepeatedly(ReturnRef(url));
295 EXPECT_CALL(item(), GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
296 EXPECT_CALL(item(), GetStartTime()).WillRepeatedly(Return(start_time));
297 EXPECT_CALL(item(), GetEndTime()).WillRepeatedly(Return(end_time));
298 EXPECT_CALL(item(), GetReceivedBytes())
299 .WillRepeatedly(Return(received_bytes));
300 EXPECT_CALL(item(), GetTotalBytes()).WillRepeatedly(Return(total_bytes));
301 EXPECT_CALL(item(), GetState()).WillRepeatedly(Return(state));
302 EXPECT_CALL(item(), GetOpened()).WillRepeatedly(Return(opened));
303 EXPECT_CALL(item(), GetTargetDisposition()).WillRepeatedly(Return(
304 content::DownloadItem::TARGET_DISPOSITION_OVERWRITE));
305 EXPECT_CALL(manager(), GetDownload(id))
306 .WillRepeatedly(Return(&item()));
307 EXPECT_CALL(item(), AddObserver(_)).WillOnce(WithArg<0>(Invoke(
308 this, &DownloadHistoryTest::SetItemObserver)));
309 EXPECT_CALL(item(), RemoveObserver(_));
310 std::vector<content::DownloadItem*> items;
311 items.push_back(&item());
312 EXPECT_CALL(*manager_.get(), GetAllDownloads(_))
313 .WillRepeatedly(SetArgPointee<0>(items));
314 }
315
316 private:
317 testing::NiceMock<content::MockDownloadItem> item_;
318 scoped_refptr<FakeHistoryService> history_;
319 scoped_refptr<content::MockDownloadManager> manager_;
320 scoped_ptr<DownloadHistory> download_history_;
321 content::DownloadManager::Observer* manager_observer_;
322 content::DownloadItem::Observer* item_observer_;
323
324 DISALLOW_COPY_AND_ASSIGN(DownloadHistoryTest);
325 };
326
327 } // anonymous namespace
328
329 // Test loading an item from the database, changing it, saving it back, removing
330 // it.
331 IN_PROC_BROWSER_TEST_F(DownloadHistoryTest, DownloadHistoryTest_Load) {
332 // Load a download from history, create the item, OnDownloadCreated,
333 // OnDownloadUpdated, OnDownloadRemoved.
334 DownloadPersistentStoreInfo info;
335 InitItem(base::RandInt(0, 1 << 20),
336 FilePath(FILE_PATH_LITERAL("/foo/bar.pdf")),
337 GURL("http://example.com/bar.pdf"),
338 GURL("http://example.com/referrer.html"),
339 (base::Time::Now() - base::TimeDelta::FromMinutes(10)),
340 (base::Time::Now() - base::TimeDelta::FromMinutes(1)),
341 100,
342 100,
343 content::DownloadItem::COMPLETE,
344 base::RandInt(0, 1 << 20),
345 false,
346 &info);
347 {
348 scoped_ptr<InfoVector> infos(new InfoVector());
349 infos->push_back(info);
350 ExpectWillQueryDownloads(infos.Pass());
351 ExpectNoDownloadCreated();
352 }
353
354 // Pretend that something changed on the item.
355 EXPECT_CALL(item(), GetOpened()).WillRepeatedly(Return(true));
356 item_observer()->OnDownloadUpdated(&item());
357 info.opened = true;
358 ExpectDownloadUpdated(info);
359
360 // Pretend that the user removed the item.
361 HandleSet handles;
362 handles.insert(info.db_handle);
363 item_observer()->OnDownloadRemoved(&item());
364 ExpectDownloadsRemoved(handles);
365
366 // Pretend that the browser is closing.
367 manager_observer()->ManagerGoingDown(&manager());
368 item_observer()->OnDownloadDestroyed(&item());
369 }
370
371 // Test creating an item, saving it to the database, changing it, saving it
372 // back, removing it.
373 IN_PROC_BROWSER_TEST_F(DownloadHistoryTest, DownloadHistoryTest_Create) {
374 // Create a fresh item not from history, OnDownloadCreated, OnDownloadUpdated,
375 // OnDownloadRemoved.
376 ExpectWillQueryDownloads(scoped_ptr<InfoVector>(new InfoVector()));
377
378 // Note that db_handle must be -1 at first because it isn't in the db yet.
379 DownloadPersistentStoreInfo info;
380 InitItem(base::RandInt(0, 1 << 20),
381 FilePath(FILE_PATH_LITERAL("/foo/bar.pdf")),
382 GURL("http://example.com/bar.pdf"),
383 GURL("http://example.com/referrer.html"),
384 (base::Time::Now() - base::TimeDelta::FromMinutes(10)),
385 (base::Time::Now() - base::TimeDelta::FromMinutes(1)),
386 100,
387 100,
388 content::DownloadItem::COMPLETE,
389 -1,
390 false,
391 &info);
392
393 // Pretend the manager just created |item|.
394 CallOnDownloadCreated();
395 // CreateDownload() always gets db_handle=-1.
396 ExpectDownloadCreated(info);
397 info.db_handle = 0;
398
399 // Pretend that something changed on the item.
400 EXPECT_CALL(item(), GetOpened()).WillRepeatedly(Return(true));
401 item_observer()->OnDownloadUpdated(&item());
402 info.opened = true;
403 ExpectDownloadUpdated(info);
404
405 // Pretend that the user removed the item.
406 HandleSet handles;
407 handles.insert(info.db_handle);
408 item_observer()->OnDownloadRemoved(&item());
409 ExpectDownloadsRemoved(handles);
410
411 // Pretend that the browser is closing.
412 manager_observer()->ManagerGoingDown(&manager());
413 item_observer()->OnDownloadDestroyed(&item());
414 }
415
416 // Test creating a new item, saving it, removing it by setting it Temporary,
417 // changing it without saving it back because it's Temporary, clearing
418 // IsTemporary, saving it back, changing it, saving it back because it isn't
419 // Temporary anymore.
420 IN_PROC_BROWSER_TEST_F(DownloadHistoryTest, DownloadHistoryTest_Temporary) {
421 // Create a fresh item not from history, OnDownloadCreated, OnDownloadUpdated,
422 // OnDownloadRemoved.
423 ExpectWillQueryDownloads(scoped_ptr<InfoVector>(new InfoVector()));
424
425 // Note that db_handle must be -1 at first because it isn't in the db yet.
426 DownloadPersistentStoreInfo info;
427 InitItem(base::RandInt(0, 1 << 20),
428 FilePath(FILE_PATH_LITERAL("/foo/bar.pdf")),
429 GURL("http://example.com/bar.pdf"),
430 GURL("http://example.com/referrer.html"),
431 (base::Time::Now() - base::TimeDelta::FromMinutes(10)),
432 (base::Time::Now() - base::TimeDelta::FromMinutes(1)),
433 100,
434 100,
435 content::DownloadItem::COMPLETE,
436 -1,
437 false,
438 &info);
439
440 // Pretend the manager just created |item|.
441 CallOnDownloadCreated();
442 // CreateDownload() always gets db_handle=-1.
443 ExpectDownloadCreated(info);
444 info.db_handle = 0;
445
446 // Pretend the item was marked temporary. DownloadHistory should remove it
447 // from history and start ignoring it.
448 EXPECT_CALL(item(), IsTemporary()).WillRepeatedly(Return(true));
449 item_observer()->OnDownloadUpdated(&item());
450 HandleSet handles;
451 handles.insert(info.db_handle);
452 ExpectDownloadsRemoved(handles);
453
454 // Change something that would make DownloadHistory call UpdateDownload if the
455 // item weren't temporary.
456 EXPECT_CALL(item(), GetReceivedBytes()).WillRepeatedly(Return(4200));
457 item_observer()->OnDownloadUpdated(&item());
458 ExpectNoDownloadUpdated();
459
460 // Changing a temporary item back to a non-temporary item should make
461 // DownloadHistory call CreateDownload.
462 EXPECT_CALL(item(), IsTemporary()).WillRepeatedly(Return(false));
463 item_observer()->OnDownloadUpdated(&item());
464 info.received_bytes = 4200;
465 info.db_handle = -1;
466 // CreateDownload() always gets db_handle=-1.
467 ExpectDownloadCreated(info);
468 info.db_handle = 1;
469
470 EXPECT_CALL(item(), GetReceivedBytes()).WillRepeatedly(Return(100));
471 item_observer()->OnDownloadUpdated(&item());
472 info.received_bytes = 100;
473 ExpectDownloadUpdated(info);
474
475 // Pretend that the browser is closing.
476 manager_observer()->ManagerGoingDown(&manager());
477 item_observer()->OnDownloadDestroyed(&item());
478 }
479
480 // Test removing downloads while they're still being added.
481 IN_PROC_BROWSER_TEST_F(DownloadHistoryTest,
482 DownloadHistoryTest_RemoveWhileAdding) {
483 ExpectWillQueryDownloads(scoped_ptr<InfoVector>(new InfoVector()));
484
485 // Note that db_handle must be -1 at first because it isn't in the db yet.
486 DownloadPersistentStoreInfo info;
487 InitItem(base::RandInt(0, 1 << 20),
488 FilePath(FILE_PATH_LITERAL("/foo/bar.pdf")),
489 GURL("http://example.com/bar.pdf"),
490 GURL("http://example.com/referrer.html"),
491 (base::Time::Now() - base::TimeDelta::FromMinutes(10)),
492 (base::Time::Now() - base::TimeDelta::FromMinutes(1)),
493 100,
494 100,
495 content::DownloadItem::COMPLETE,
496 -1,
497 false,
498 &info);
499
500 // Instruct CreateDownload() to not callback to DownloadHistory immediately,
501 // but to wait for FinishCreateDownload().
502 set_slow_create_download(true);
503
504 // Pretend the manager just created |item|.
505 CallOnDownloadCreated();
506 // CreateDownload() always gets db_handle=-1.
507 ExpectDownloadCreated(info);
508 info.db_handle = 0;
509
510 // Call OnDownloadRemoved before calling back to DownloadHistory::ItemAdded().
511 // Instead of calling RemoveDownloads() immediately, it should
512 item_observer()->OnDownloadRemoved(&item());
513 EXPECT_CALL(manager(), GetDownload(item().GetId()))
514 .WillRepeatedly(Return(static_cast<content::DownloadItem*>(NULL)));
515 ExpectNoDownloadsRemoved();
516
517 // Now callback to DownloadHistory::ItemAdded(), and expect a call to
518 // RemoveDownloads() for the item that was removed while it was being added.
519 FinishCreateDownload();
520 HandleSet handles;
521 handles.insert(info.db_handle);
522 ExpectDownloadsRemoved(handles);
523
524 // Pretend that the browser is closing.
525 manager_observer()->ManagerGoingDown(&manager());
526 item_observer()->OnDownloadDestroyed(&item());
527 }
Randy Smith (Not in Mondays) 2012/09/24 18:03:25 Any tests to test multiple downloads in flight at
benjhayden 2012/09/24 20:12:11 Made a note to do that before committing.
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698