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

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

Powered by Google App Engine
This is Rietveld 408576698