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

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

Powered by Google App Engine
This is Rietveld 408576698