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

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

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

Powered by Google App Engine
This is Rietveld 408576698