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

Side by Side Diff: content/browser/download/download_item_impl_unittest.cc

Issue 1691543002: [Downloads] Enforce state transition integrity and state invariants. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Clarify comments. Created 4 years, 10 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/download/download_item_impl.h" 5 #include "content/browser/download/download_item_impl.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8
9 #include <iterator>
10 #include <queue>
8 #include <utility> 11 #include <utility>
9 12
10 #include "base/callback.h" 13 #include "base/callback.h"
11 #include "base/feature_list.h" 14 #include "base/feature_list.h"
12 #include "base/message_loop/message_loop.h" 15 #include "base/message_loop/message_loop.h"
16 #include "base/run_loop.h"
13 #include "base/stl_util.h" 17 #include "base/stl_util.h"
14 #include "base/threading/thread.h" 18 #include "base/threading/thread.h"
15 #include "content/browser/byte_stream.h" 19 #include "content/browser/byte_stream.h"
16 #include "content/browser/download/download_create_info.h" 20 #include "content/browser/download/download_create_info.h"
17 #include "content/browser/download/download_file_factory.h" 21 #include "content/browser/download/download_file_factory.h"
18 #include "content/browser/download/download_item_impl_delegate.h" 22 #include "content/browser/download/download_item_impl_delegate.h"
19 #include "content/browser/download/download_request_handle.h" 23 #include "content/browser/download/download_request_handle.h"
20 #include "content/browser/download/mock_download_file.h" 24 #include "content/browser/download/mock_download_file.h"
25 #include "content/public/browser/browser_thread.h"
21 #include "content/public/browser/download_destination_observer.h" 26 #include "content/public/browser/download_destination_observer.h"
22 #include "content/public/browser/download_interrupt_reasons.h" 27 #include "content/public/browser/download_interrupt_reasons.h"
23 #include "content/public/browser/download_url_parameters.h" 28 #include "content/public/browser/download_url_parameters.h"
24 #include "content/public/common/content_features.h" 29 #include "content/public/common/content_features.h"
25 #include "content/public/test/mock_download_item.h" 30 #include "content/public/test/mock_download_item.h"
26 #include "content/public/test/test_browser_context.h" 31 #include "content/public/test/test_browser_context.h"
27 #include "content/public/test/test_browser_thread.h" 32 #include "content/public/test/test_browser_thread_bundle.h"
28 #include "testing/gmock/include/gmock/gmock.h" 33 #include "testing/gmock/include/gmock/gmock.h"
29 #include "testing/gtest/include/gtest/gtest.h" 34 #include "testing/gtest/include/gtest/gtest.h"
30 35
31 using ::testing::_; 36 using ::testing::DoAll;
32 using ::testing::NiceMock; 37 using ::testing::NiceMock;
33 using ::testing::Property; 38 using ::testing::Property;
34 using ::testing::Return; 39 using ::testing::Return;
35 using ::testing::SaveArg; 40 using ::testing::SaveArg;
36 using ::testing::StrictMock; 41 using ::testing::StrictMock;
42 using ::testing::WithArg;
43 using ::testing::_;
37 44
38 const int kDownloadChunkSize = 1000; 45 const int kDownloadChunkSize = 1000;
39 const int kDownloadSpeed = 1000; 46 const int kDownloadSpeed = 1000;
40 const base::FilePath::CharType kDummyPath[] = FILE_PATH_LITERAL("/testpath"); 47 const base::FilePath::CharType kDummyTargetPath[] =
48 FILE_PATH_LITERAL("/testpath");
49 const base::FilePath::CharType kDummyIntermediatePath[] =
50 FILE_PATH_LITERAL("/testpathx");
41 51
42 namespace content { 52 namespace content {
43 53
44 namespace { 54 namespace {
45 55
46 class MockDelegate : public DownloadItemImplDelegate { 56 class MockDelegate : public DownloadItemImplDelegate {
47 public: 57 public:
48 MockDelegate() : DownloadItemImplDelegate() { 58 MockDelegate() : DownloadItemImplDelegate() {
49 SetDefaultExpectations(); 59 SetDefaultExpectations();
50 } 60 }
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 void OnDownloadOpened(DownloadItem* download) override { 162 void OnDownloadOpened(DownloadItem* download) override {
153 DVLOG(20) << " " << __FUNCTION__ 163 DVLOG(20) << " " << __FUNCTION__
154 << " download = " << download->DebugString(false); 164 << " download = " << download->DebugString(false);
155 } 165 }
156 166
157 void OnDownloadDestroyed(DownloadItem* download) override { 167 void OnDownloadDestroyed(DownloadItem* download) override {
158 DVLOG(20) << " " << __FUNCTION__ 168 DVLOG(20) << " " << __FUNCTION__
159 << " download = " << download->DebugString(false); 169 << " download = " << download->DebugString(false);
160 destroyed_ = true; 170 destroyed_ = true;
161 item_->RemoveObserver(this); 171 item_->RemoveObserver(this);
162 item_ = NULL; 172 item_ = nullptr;
163 } 173 }
164 174
165 DownloadItem* item_; 175 DownloadItem* item_;
166 DownloadItem::DownloadState last_state_; 176 DownloadItem::DownloadState last_state_;
167 bool removed_; 177 bool removed_;
168 bool destroyed_; 178 bool destroyed_;
169 bool updated_; 179 bool updated_;
170 int interrupt_count_; 180 int interrupt_count_;
171 int resume_count_; 181 int resume_count_;
172 }; 182 };
173 183
174 // Schedules a task to invoke the RenameCompletionCallback with |new_path| on 184 // Schedules a task to invoke the RenameCompletionCallback with |new_path| on
175 // the UI thread. Should only be used as the action for 185 // the UI thread. Should only be used as the action for
176 // MockDownloadFile::Rename as follows: 186 // MockDownloadFile::Rename as follows:
177 // EXPECT_CALL(download_file, Rename*(_,_)) 187 // EXPECT_CALL(download_file, Rename*(_,_))
178 // .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, 188 // .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
179 // new_path)); 189 // new_path));
180 ACTION_P2(ScheduleRenameCallback, interrupt_reason, new_path) { 190 ACTION_P2(ScheduleRenameCallback, interrupt_reason, new_path) {
181 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 191 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
182 base::Bind(arg1, interrupt_reason, new_path)); 192 base::Bind(arg1, interrupt_reason, new_path));
183 } 193 }
184 194
195 // Schedules a task to invoke a callback that's bound to the specified
196 // parameter.
197 // E.g.:
198 //
199 // EXPECT_CALL(foo, Bar(1, _))
200 // .WithArg<1>(InvokeCallbackWithParam(0));
201 //
202 // .. will invoke the second argument to Bar with 0 as the parameter.
203 ACTION_P(InvokeCallbackWithParam, param) {
204 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
205 base::Bind(arg0, param));
206 }
207
208 ACTION_P(InvokeClosure, closure) {
209 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, closure);
210 }
211
185 } // namespace 212 } // namespace
186 213
187 class DownloadItemTest : public testing::Test { 214 class DownloadItemTest : public testing::Test {
188 public: 215 public:
189 DownloadItemTest() 216 DownloadItemTest() {
190 : ui_thread_(BrowserThread::UI, &loop_),
191 file_thread_(BrowserThread::FILE, &loop_),
192 delegate_() {
193 }
194
195 ~DownloadItemTest() {
196 }
197
198 virtual void SetUp() {
199 base::FeatureList::ClearInstanceForTesting(); 217 base::FeatureList::ClearInstanceForTesting();
200 scoped_ptr<base::FeatureList> feature_list(new base::FeatureList); 218 scoped_ptr<base::FeatureList> feature_list(new base::FeatureList);
201 feature_list->InitializeFromCommandLine(features::kDownloadResumption.name, 219 feature_list->InitializeFromCommandLine(features::kDownloadResumption.name,
202 std::string()); 220 std::string());
203 base::FeatureList::SetInstance(std::move(feature_list)); 221 base::FeatureList::SetInstance(std::move(feature_list));
204 } 222 }
205 223
206 virtual void TearDown() { 224 ~DownloadItemTest() {
207 ui_thread_.DeprecatedGetThreadObject()->message_loop()->RunUntilIdle(); 225 RunAllPendingInMessageLoops();
208 STLDeleteElements(&allocated_downloads_); 226 STLDeleteElements(&allocated_downloads_);
209 } 227 }
210 228
229 DownloadItemImpl* CreateDownloadItemWithCreateInfo(
230 scoped_ptr<DownloadCreateInfo> info) {
231 DownloadItemImpl* download = new DownloadItemImpl(
232 &delegate_, next_download_id_++, *(info.get()), net::BoundNetLog());
233 allocated_downloads_.insert(download);
234 return download;
235 }
236
211 // This class keeps ownership of the created download item; it will 237 // This class keeps ownership of the created download item; it will
212 // be torn down at the end of the test unless DestroyDownloadItem is 238 // be torn down at the end of the test unless DestroyDownloadItem is
213 // called. 239 // called.
214 DownloadItemImpl* CreateDownloadItem() { 240 DownloadItemImpl* CreateDownloadItem() {
215 scoped_ptr<DownloadCreateInfo> info; 241 scoped_ptr<DownloadCreateInfo> info;
216 242
217 info.reset(new DownloadCreateInfo()); 243 info.reset(new DownloadCreateInfo());
218 info->save_info = scoped_ptr<DownloadSaveInfo>(new DownloadSaveInfo()); 244 info->save_info = scoped_ptr<DownloadSaveInfo>(new DownloadSaveInfo());
219 info->save_info->prompt_for_save_location = false; 245 info->save_info->prompt_for_save_location = false;
220 info->url_chain.push_back(GURL()); 246 info->url_chain.push_back(GURL("http://example.com/download"));
221 info->etag = "SomethingToSatisfyResumption"; 247 info->etag = "SomethingToSatisfyResumption";
222 248
223 return CreateDownloadItemWithCreateInfo(std::move(info)); 249 return CreateDownloadItemWithCreateInfo(std::move(info));
224 } 250 }
225 251
226 DownloadItemImpl* CreateDownloadItemWithCreateInfo(
227 scoped_ptr<DownloadCreateInfo> info) {
228 DownloadItemImpl* download = new DownloadItemImpl(
229 &delegate_, next_download_id_++, *(info.get()), net::BoundNetLog());
230 allocated_downloads_.insert(download);
231 return download;
232 }
233
234 // Add DownloadFile to DownloadItem 252 // Add DownloadFile to DownloadItem
235 MockDownloadFile* AddDownloadFileToDownloadItem( 253 MockDownloadFile* CallDownloadItemStart(
236 DownloadItemImpl* item, 254 DownloadItemImpl* item,
237 DownloadItemImplDelegate::DownloadTargetCallback *callback) { 255 DownloadItemImplDelegate::DownloadTargetCallback* callback) {
238 MockDownloadFile* mock_download_file(new StrictMock<MockDownloadFile>); 256 MockDownloadFile* mock_download_file(new StrictMock<MockDownloadFile>);
239 scoped_ptr<DownloadFile> download_file(mock_download_file); 257 scoped_ptr<DownloadFile> download_file(mock_download_file);
240 EXPECT_CALL(*mock_download_file, Initialize(_)); 258 EXPECT_CALL(*mock_download_file, Initialize(_));
241 if (callback) { 259 if (callback) {
242 // Save the callback. 260 // Save the callback.
243 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _)) 261 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _))
244 .WillOnce(SaveArg<1>(callback)); 262 .WillOnce(SaveArg<1>(callback));
245 } else { 263 } else {
246 // Drop it on the floor. 264 // Drop it on the floor.
247 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _)); 265 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _));
248 } 266 }
249 267
250 scoped_ptr<DownloadRequestHandleInterface> request_handle( 268 scoped_ptr<DownloadRequestHandleInterface> request_handle(
251 new NiceMock<MockRequestHandle>); 269 new NiceMock<MockRequestHandle>);
252 item->Start(std::move(download_file), std::move(request_handle)); 270 item->Start(std::move(download_file), std::move(request_handle));
253 loop_.RunUntilIdle(); 271 RunAllPendingInMessageLoops();
254 272
255 // So that we don't have a function writing to a stack variable 273 // So that we don't have a function writing to a stack variable
256 // lying around if the above failed. 274 // lying around if the above failed.
257 mock_delegate()->VerifyAndClearExpectations(); 275 mock_delegate()->VerifyAndClearExpectations();
258 EXPECT_CALL(*mock_delegate(), AssertStateConsistent(_)) 276 EXPECT_CALL(*mock_delegate(), AssertStateConsistent(_))
259 .WillRepeatedly(Return()); 277 .WillRepeatedly(Return());
260 EXPECT_CALL(*mock_delegate(), ShouldOpenFileBasedOnExtension(_)) 278 EXPECT_CALL(*mock_delegate(), ShouldOpenFileBasedOnExtension(_))
261 .WillRepeatedly(Return(false)); 279 .WillRepeatedly(Return(false));
262 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(_, _)) 280 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(_, _))
263 .WillRepeatedly(Return(true)); 281 .WillRepeatedly(Return(true));
264 282
265 return mock_download_file; 283 return mock_download_file;
266 } 284 }
267 285
268 // Perform the intermediate rename for |item|. The target path for the 286 // Perform the intermediate rename for |item|. The target path for the
269 // download will be set to kDummyPath. Returns the MockDownloadFile* that was 287 // download will be set to kDummyTargetPath. Returns the MockDownloadFile*
288 // that was
270 // added to the DownloadItem. 289 // added to the DownloadItem.
271 MockDownloadFile* DoIntermediateRename(DownloadItemImpl* item, 290 MockDownloadFile* DoIntermediateRename(DownloadItemImpl* item,
272 DownloadDangerType danger_type) { 291 DownloadDangerType danger_type) {
273 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); 292 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
274 EXPECT_TRUE(item->GetTargetFilePath().empty()); 293 EXPECT_TRUE(item->GetTargetFilePath().empty());
275 DownloadItemImplDelegate::DownloadTargetCallback callback; 294 DownloadItemImplDelegate::DownloadTargetCallback callback;
276 MockDownloadFile* download_file = 295 MockDownloadFile* download_file = CallDownloadItemStart(item, &callback);
277 AddDownloadFileToDownloadItem(item, &callback); 296 base::FilePath target_path(kDummyTargetPath);
278 base::FilePath target_path(kDummyPath); 297 base::FilePath intermediate_path(kDummyIntermediatePath);
279 base::FilePath intermediate_path(
280 target_path.InsertBeforeExtensionASCII("x"));
281 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _)) 298 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _))
282 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, 299 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
283 intermediate_path)); 300 intermediate_path));
284 callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, 301 callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
285 danger_type, intermediate_path); 302 danger_type, intermediate_path);
286 RunAllPendingInMessageLoops(); 303 RunAllPendingInMessageLoops();
287 return download_file; 304 return download_file;
288 } 305 }
289 306
307 void DoDestinationComplete(DownloadItemImpl* item,
308 MockDownloadFile* download_file) {
309 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(_, _))
310 .WillOnce(Return(true));
311 base::FilePath final_path(kDummyTargetPath);
312 EXPECT_CALL(*download_file, RenameAndAnnotate(_, _))
313 .WillOnce(
314 ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, final_path));
315 EXPECT_CALL(*download_file, FullPath())
316 .WillRepeatedly(Return(base::FilePath(kDummyTargetPath)));
317 EXPECT_CALL(*download_file, Detach());
318
319 item->DestinationObserverAsWeakPtr()->DestinationCompleted("");
320 RunAllPendingInMessageLoops();
321 }
322
290 // Cleanup a download item (specifically get rid of the DownloadFile on it). 323 // Cleanup a download item (specifically get rid of the DownloadFile on it).
291 // The item must be in the expected state. 324 // The item must be in the expected state.
292 void CleanupItem(DownloadItemImpl* item, 325 void CleanupItem(DownloadItemImpl* item,
293 MockDownloadFile* download_file, 326 MockDownloadFile* download_file,
294 DownloadItem::DownloadState expected_state) { 327 DownloadItem::DownloadState expected_state) {
295 EXPECT_EQ(expected_state, item->GetState()); 328 EXPECT_EQ(expected_state, item->GetState());
296 329
297 if (expected_state == DownloadItem::IN_PROGRESS) { 330 if (expected_state == DownloadItem::IN_PROGRESS) {
298 if (download_file) 331 if (download_file)
299 EXPECT_CALL(*download_file, Cancel()); 332 EXPECT_CALL(*download_file, Cancel());
300 item->Cancel(true); 333 item->Cancel(true);
301 loop_.RunUntilIdle(); 334 RunAllPendingInMessageLoops();
302 } 335 }
303 } 336 }
304 337
305 // Destroy a previously created download item. 338 // Destroy a previously created download item.
306 void DestroyDownloadItem(DownloadItem* item) { 339 void DestroyDownloadItem(DownloadItem* item) {
307 allocated_downloads_.erase(item); 340 allocated_downloads_.erase(item);
308 delete item; 341 delete item;
309 } 342 }
310 343
311 void RunAllPendingInMessageLoops() { 344 void RunAllPendingInMessageLoops() { base::RunLoop().RunUntilIdle(); }
312 loop_.RunUntilIdle();
313 }
314 345
315 MockDelegate* mock_delegate() { 346 MockDelegate* mock_delegate() {
316 return &delegate_; 347 return &delegate_;
317 } 348 }
318 349
319 void OnDownloadFileAcquired(base::FilePath* return_path, 350 void OnDownloadFileAcquired(base::FilePath* return_path,
320 const base::FilePath& path) { 351 const base::FilePath& path) {
321 *return_path = path; 352 *return_path = path;
322 } 353 }
323 354
324 private: 355 private:
325 int next_download_id_ = DownloadItem::kInvalidId + 1; 356 int next_download_id_ = DownloadItem::kInvalidId + 1;
326 base::MessageLoopForUI loop_;
327 TestBrowserThread ui_thread_; // UI thread
328 TestBrowserThread file_thread_; // FILE thread
329 StrictMock<MockDelegate> delegate_; 357 StrictMock<MockDelegate> delegate_;
330 std::set<DownloadItem*> allocated_downloads_; 358 std::set<DownloadItem*> allocated_downloads_;
359 TestBrowserThreadBundle thread_bundle_;
331 }; 360 };
332 361
333 // Tests to ensure calls that change a DownloadItem generate an update to 362 // Tests to ensure calls that change a DownloadItem generate an update to
334 // observers. 363 // observers.
335 // State changing functions not tested: 364 // State changing functions not tested:
336 // void OpenDownload(); 365 // void OpenDownload();
337 // void ShowDownloadInShell(); 366 // void ShowDownloadInShell();
338 // void CompleteDelayedDownload(); 367 // void CompleteDelayedDownload();
339 // set_* mutators 368 // set_* mutators
340 369
341 TEST_F(DownloadItemTest, NotificationAfterUpdate) { 370 TEST_F(DownloadItemTest, NotificationAfterUpdate) {
342 DownloadItemImpl* item = CreateDownloadItem(); 371 DownloadItemImpl* item = CreateDownloadItem();
343 TestDownloadItemObserver observer(item); 372 TestDownloadItemObserver observer(item);
344 373
345 item->DestinationUpdate(kDownloadChunkSize, kDownloadSpeed, std::string()); 374 item->DestinationUpdate(kDownloadChunkSize, kDownloadSpeed, std::string());
346 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); 375 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated());
347 EXPECT_EQ(kDownloadSpeed, item->CurrentSpeed()); 376 EXPECT_EQ(kDownloadSpeed, item->CurrentSpeed());
348 } 377 }
349 378
350 TEST_F(DownloadItemTest, NotificationAfterCancel) { 379 TEST_F(DownloadItemTest, NotificationAfterCancel) {
351 DownloadItemImpl* user_cancel = CreateDownloadItem(); 380 DownloadItemImpl* user_cancel = CreateDownloadItem();
352 MockDownloadFile* download_file = 381 MockDownloadFile* download_file = CallDownloadItemStart(user_cancel, nullptr);
353 AddDownloadFileToDownloadItem(user_cancel, NULL);
354 EXPECT_CALL(*download_file, Cancel()); 382 EXPECT_CALL(*download_file, Cancel());
355 TestDownloadItemObserver observer1(user_cancel); 383 TestDownloadItemObserver observer1(user_cancel);
356 384
357 user_cancel->Cancel(true); 385 user_cancel->Cancel(true);
358 ASSERT_TRUE(observer1.CheckAndResetDownloadUpdated()); 386 ASSERT_TRUE(observer1.CheckAndResetDownloadUpdated());
359 387
360 DownloadItemImpl* system_cancel = CreateDownloadItem(); 388 DownloadItemImpl* system_cancel = CreateDownloadItem();
361 download_file = AddDownloadFileToDownloadItem(system_cancel, NULL); 389 download_file = CallDownloadItemStart(system_cancel, nullptr);
362 EXPECT_CALL(*download_file, Cancel()); 390 EXPECT_CALL(*download_file, Cancel());
363 TestDownloadItemObserver observer2(system_cancel); 391 TestDownloadItemObserver observer2(system_cancel);
364 392
365 system_cancel->Cancel(false); 393 system_cancel->Cancel(false);
366 ASSERT_TRUE(observer2.CheckAndResetDownloadUpdated()); 394 ASSERT_TRUE(observer2.CheckAndResetDownloadUpdated());
367 } 395 }
368 396
369 TEST_F(DownloadItemTest, NotificationAfterComplete) { 397 TEST_F(DownloadItemTest, NotificationAfterComplete) {
370 DownloadItemImpl* item = CreateDownloadItem(); 398 DownloadItemImpl* item = CreateDownloadItem();
371 TestDownloadItemObserver observer(item); 399 TestDownloadItemObserver observer(item);
372 400 MockDownloadFile* download_file =
373 item->OnAllDataSaved(DownloadItem::kEmptyFileHash); 401 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
374 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); 402 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated());
375 403 DoDestinationComplete(item, download_file);
376 item->MarkAsComplete();
377 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); 404 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated());
378 } 405 }
379 406
380 TEST_F(DownloadItemTest, NotificationAfterDownloadedFileRemoved) { 407 TEST_F(DownloadItemTest, NotificationAfterDownloadedFileRemoved) {
381 DownloadItemImpl* item = CreateDownloadItem(); 408 DownloadItemImpl* item = CreateDownloadItem();
382 TestDownloadItemObserver observer(item); 409 TestDownloadItemObserver observer(item);
383 410
384 item->OnDownloadedFileRemoved(); 411 item->OnDownloadedFileRemoved();
385 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); 412 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated());
386 } 413 }
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
464 // Check we do correct cleanup for RESUME_MODE_INVALID interrupts. 491 // Check we do correct cleanup for RESUME_MODE_INVALID interrupts.
465 TEST_F(DownloadItemTest, UnresumableInterrupt) { 492 TEST_F(DownloadItemTest, UnresumableInterrupt) {
466 DownloadItemImpl* item = CreateDownloadItem(); 493 DownloadItemImpl* item = CreateDownloadItem();
467 TestDownloadItemObserver observer(item); 494 TestDownloadItemObserver observer(item);
468 MockDownloadFile* download_file = 495 MockDownloadFile* download_file =
469 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); 496 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
470 497
471 // Fail final rename with unresumable reason. 498 // Fail final rename with unresumable reason.
472 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _)) 499 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _))
473 .WillOnce(Return(true)); 500 .WillOnce(Return(true));
474 EXPECT_CALL(*download_file, RenameAndAnnotate(base::FilePath(kDummyPath), _)) 501 EXPECT_CALL(*download_file,
502 RenameAndAnnotate(base::FilePath(kDummyTargetPath), _))
475 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_FILE_BLOCKED, 503 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_FILE_BLOCKED,
476 base::FilePath(kDummyPath))); 504 base::FilePath()));
477 EXPECT_CALL(*download_file, Cancel()); 505 EXPECT_CALL(*download_file, Cancel());
478 506
479 // Complete download to trigger final rename. 507 // Complete download to trigger final rename.
480 item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string()); 508 item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string());
481 RunAllPendingInMessageLoops(); 509 RunAllPendingInMessageLoops();
482 510
483 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); 511 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated());
484 // Should not try to auto-resume. 512 // Should not try to auto-resume.
485 ASSERT_EQ(1, observer.interrupt_count()); 513 ASSERT_EQ(1, observer.interrupt_count());
486 ASSERT_EQ(0, observer.resume_count()); 514 ASSERT_EQ(0, observer.resume_count());
487 515
488 CleanupItem(item, nullptr, DownloadItem::INTERRUPTED); 516 CleanupItem(item, nullptr, DownloadItem::INTERRUPTED);
489 } 517 }
490 518
491 TEST_F(DownloadItemTest, LimitRestartsAfterInterrupted) { 519 TEST_F(DownloadItemTest, LimitRestartsAfterInterrupted) {
492 TestBrowserContext test_browser_context; 520 TestBrowserContext test_browser_context;
493 DownloadItemImpl* item = CreateDownloadItem(); 521 DownloadItemImpl* item = CreateDownloadItem();
494 base::WeakPtr<DownloadDestinationObserver> as_observer( 522 base::WeakPtr<DownloadDestinationObserver> as_observer(
495 item->DestinationObserverAsWeakPtr()); 523 item->DestinationObserverAsWeakPtr());
496 TestDownloadItemObserver observer(item); 524 TestDownloadItemObserver observer(item);
497 MockDownloadFile* mock_download_file(NULL); 525 MockDownloadFile* mock_download_file(nullptr);
498 scoped_ptr<DownloadFile> download_file; 526 scoped_ptr<DownloadFile> download_file;
499 MockRequestHandle* mock_request_handle(NULL); 527 MockRequestHandle* mock_request_handle(nullptr);
500 scoped_ptr<DownloadRequestHandleInterface> request_handle; 528 scoped_ptr<DownloadRequestHandleInterface> request_handle;
501 DownloadItemImplDelegate::DownloadTargetCallback callback; 529 DownloadItemImplDelegate::DownloadTargetCallback callback;
502 530
503 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _)) 531 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _))
504 .WillRepeatedly(SaveArg<1>(&callback)); 532 .WillRepeatedly(SaveArg<1>(&callback));
505 EXPECT_CALL(*mock_delegate(), GetBrowserContext()) 533 EXPECT_CALL(*mock_delegate(), GetBrowserContext())
506 .WillRepeatedly(Return(&test_browser_context)); 534 .WillRepeatedly(Return(&test_browser_context));
507 EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_, _)) 535 EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_, _))
508 .Times(DownloadItemImpl::kMaxAutoResumeAttempts); 536 .Times(DownloadItemImpl::kMaxAutoResumeAttempts);
509 for (int i = 0; i < (DownloadItemImpl::kMaxAutoResumeAttempts + 1); ++i) { 537 for (int i = 0; i < (DownloadItemImpl::kMaxAutoResumeAttempts + 1); ++i) {
510 DVLOG(20) << "Loop iteration " << i; 538 DVLOG(20) << "Loop iteration " << i;
511 539
512 mock_download_file = new NiceMock<MockDownloadFile>; 540 mock_download_file = new NiceMock<MockDownloadFile>;
513 download_file.reset(mock_download_file); 541 download_file.reset(mock_download_file);
514 mock_request_handle = new NiceMock<MockRequestHandle>; 542 mock_request_handle = new NiceMock<MockRequestHandle>;
515 request_handle.reset(mock_request_handle); 543 request_handle.reset(mock_request_handle);
516 544
517 ON_CALL(*mock_download_file, FullPath()) 545 ON_CALL(*mock_download_file, FullPath())
518 .WillByDefault(Return(base::FilePath())); 546 .WillByDefault(Return(base::FilePath()));
519 547
520 // Copied key parts of DoIntermediateRename & AddDownloadFileToDownloadItem 548 // Copied key parts of DoIntermediateRename & CallDownloadItemStart
521 // to allow for holding onto the request handle. 549 // to allow for holding onto the request handle.
522 item->Start(std::move(download_file), std::move(request_handle)); 550 item->Start(std::move(download_file), std::move(request_handle));
523 RunAllPendingInMessageLoops(); 551 RunAllPendingInMessageLoops();
552
553 base::FilePath target_path(kDummyTargetPath);
554 base::FilePath intermediate_path(kDummyIntermediatePath);
524 if (i == 0) { 555 if (i == 0) {
525 // Target determination is only done the first time through. 556 // RenameAndUniquify is only called the first time. In all the subsequent
526 base::FilePath target_path(kDummyPath); 557 // iterations, the intermediate file already has the correct name, hence
527 base::FilePath intermediate_path( 558 // no rename is necessary.
528 target_path.InsertBeforeExtensionASCII("x"));
529 EXPECT_CALL(*mock_download_file, RenameAndUniquify(intermediate_path, _)) 559 EXPECT_CALL(*mock_download_file, RenameAndUniquify(intermediate_path, _))
530 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, 560 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
531 intermediate_path)); 561 intermediate_path));
532 callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
533 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
534 RunAllPendingInMessageLoops();
535 } 562 }
563 callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
564 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
565 RunAllPendingInMessageLoops();
536 566
537 // Use a continuable interrupt. 567 // Use a continuable interrupt.
538 item->DestinationObserverAsWeakPtr()->DestinationError( 568 item->DestinationObserverAsWeakPtr()->DestinationError(
539 DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR); 569 DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR);
540 570
541 ::testing::Mock::VerifyAndClearExpectations(mock_download_file); 571 ::testing::Mock::VerifyAndClearExpectations(mock_download_file);
542 } 572 }
543 573
574 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState());
544 EXPECT_EQ(1, observer.interrupt_count()); 575 EXPECT_EQ(1, observer.interrupt_count());
545 CleanupItem(item, nullptr, DownloadItem::INTERRUPTED); 576 CleanupItem(item, nullptr, DownloadItem::INTERRUPTED);
546 } 577 }
547 578
548 // Test that resumption uses the final URL in a URL chain when resuming. 579 // Test that resumption uses the final URL in a URL chain when resuming.
549 TEST_F(DownloadItemTest, ResumeUsingFinalURL) { 580 TEST_F(DownloadItemTest, ResumeUsingFinalURL) {
550 TestBrowserContext test_browser_context; 581 TestBrowserContext test_browser_context;
551 scoped_ptr<DownloadCreateInfo> create_info(new DownloadCreateInfo); 582 scoped_ptr<DownloadCreateInfo> create_info(new DownloadCreateInfo);
552 create_info->save_info = scoped_ptr<DownloadSaveInfo>(new DownloadSaveInfo()); 583 create_info->save_info = scoped_ptr<DownloadSaveInfo>(new DownloadSaveInfo());
553 create_info->save_info->prompt_for_save_location = false; 584 create_info->save_info->prompt_for_save_location = false;
(...skipping 27 matching lines...) Expand all
581 // ResumeInterruptedDownload() being called is sufficient for verifying that 612 // ResumeInterruptedDownload() being called is sufficient for verifying that
582 // the resumption was triggered. 613 // the resumption was triggered.
583 RunAllPendingInMessageLoops(); 614 RunAllPendingInMessageLoops();
584 615
585 // The download is currently in RESUMING_INTERNAL, which maps to IN_PROGRESS. 616 // The download is currently in RESUMING_INTERNAL, which maps to IN_PROGRESS.
586 CleanupItem(item, nullptr, DownloadItem::IN_PROGRESS); 617 CleanupItem(item, nullptr, DownloadItem::IN_PROGRESS);
587 } 618 }
588 619
589 TEST_F(DownloadItemTest, NotificationAfterRemove) { 620 TEST_F(DownloadItemTest, NotificationAfterRemove) {
590 DownloadItemImpl* item = CreateDownloadItem(); 621 DownloadItemImpl* item = CreateDownloadItem();
591 MockDownloadFile* download_file = AddDownloadFileToDownloadItem(item, NULL); 622 MockDownloadFile* download_file = CallDownloadItemStart(item, nullptr);
592 EXPECT_CALL(*download_file, Cancel()); 623 EXPECT_CALL(*download_file, Cancel());
593 EXPECT_CALL(*mock_delegate(), DownloadRemoved(_)); 624 EXPECT_CALL(*mock_delegate(), DownloadRemoved(_));
594 TestDownloadItemObserver observer(item); 625 TestDownloadItemObserver observer(item);
595 626
596 item->Remove(); 627 item->Remove();
597 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); 628 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated());
598 ASSERT_TRUE(observer.download_removed()); 629 ASSERT_TRUE(observer.download_removed());
599 } 630 }
600 631
601 TEST_F(DownloadItemTest, NotificationAfterOnContentCheckCompleted) { 632 TEST_F(DownloadItemTest, NotificationAfterOnContentCheckCompleted) {
602 // Setting to NOT_DANGEROUS does not trigger a notification. 633 // Setting to NOT_DANGEROUS does not trigger a notification.
603 DownloadItemImpl* safe_item = CreateDownloadItem(); 634 DownloadItemImpl* safe_item = CreateDownloadItem();
635 MockDownloadFile* download_file =
636 DoIntermediateRename(safe_item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
604 TestDownloadItemObserver safe_observer(safe_item); 637 TestDownloadItemObserver safe_observer(safe_item);
605 638
606 safe_item->OnAllDataSaved(std::string()); 639 safe_item->OnAllDataSaved(std::string());
607 EXPECT_TRUE(safe_observer.CheckAndResetDownloadUpdated()); 640 EXPECT_TRUE(safe_observer.CheckAndResetDownloadUpdated());
608 safe_item->OnContentCheckCompleted(DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); 641 safe_item->OnContentCheckCompleted(DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
609 EXPECT_TRUE(safe_observer.CheckAndResetDownloadUpdated()); 642 EXPECT_TRUE(safe_observer.CheckAndResetDownloadUpdated());
643 CleanupItem(safe_item, download_file, DownloadItem::IN_PROGRESS);
610 644
611 // Setting to unsafe url or unsafe file should trigger a notification. 645 // Setting to unsafe url or unsafe file should trigger a notification.
612 DownloadItemImpl* unsafeurl_item = 646 DownloadItemImpl* unsafeurl_item =
613 CreateDownloadItem(); 647 CreateDownloadItem();
648 download_file =
649 DoIntermediateRename(unsafeurl_item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
614 TestDownloadItemObserver unsafeurl_observer(unsafeurl_item); 650 TestDownloadItemObserver unsafeurl_observer(unsafeurl_item);
615 651
616 unsafeurl_item->OnAllDataSaved(std::string()); 652 unsafeurl_item->OnAllDataSaved(std::string());
617 EXPECT_TRUE(unsafeurl_observer.CheckAndResetDownloadUpdated()); 653 EXPECT_TRUE(unsafeurl_observer.CheckAndResetDownloadUpdated());
618 unsafeurl_item->OnContentCheckCompleted(DOWNLOAD_DANGER_TYPE_DANGEROUS_URL); 654 unsafeurl_item->OnContentCheckCompleted(DOWNLOAD_DANGER_TYPE_DANGEROUS_URL);
619 EXPECT_TRUE(unsafeurl_observer.CheckAndResetDownloadUpdated()); 655 EXPECT_TRUE(unsafeurl_observer.CheckAndResetDownloadUpdated());
620 656
657 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(_, _))
658 .WillOnce(Return(true));
659 EXPECT_CALL(*download_file, RenameAndAnnotate(_, _));
621 unsafeurl_item->ValidateDangerousDownload(); 660 unsafeurl_item->ValidateDangerousDownload();
622 EXPECT_TRUE(unsafeurl_observer.CheckAndResetDownloadUpdated()); 661 EXPECT_TRUE(unsafeurl_observer.CheckAndResetDownloadUpdated());
662 CleanupItem(unsafeurl_item, download_file, DownloadItem::IN_PROGRESS);
623 663
624 DownloadItemImpl* unsafefile_item = 664 DownloadItemImpl* unsafefile_item =
625 CreateDownloadItem(); 665 CreateDownloadItem();
666 download_file =
667 DoIntermediateRename(unsafefile_item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
626 TestDownloadItemObserver unsafefile_observer(unsafefile_item); 668 TestDownloadItemObserver unsafefile_observer(unsafefile_item);
627 669
628 unsafefile_item->OnAllDataSaved(std::string()); 670 unsafefile_item->OnAllDataSaved(std::string());
629 EXPECT_TRUE(unsafefile_observer.CheckAndResetDownloadUpdated()); 671 EXPECT_TRUE(unsafefile_observer.CheckAndResetDownloadUpdated());
630 unsafefile_item->OnContentCheckCompleted(DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE); 672 unsafefile_item->OnContentCheckCompleted(DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE);
631 EXPECT_TRUE(unsafefile_observer.CheckAndResetDownloadUpdated()); 673 EXPECT_TRUE(unsafefile_observer.CheckAndResetDownloadUpdated());
632 674
675 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(_, _))
676 .WillOnce(Return(true));
677 EXPECT_CALL(*download_file, RenameAndAnnotate(_, _));
633 unsafefile_item->ValidateDangerousDownload(); 678 unsafefile_item->ValidateDangerousDownload();
634 EXPECT_TRUE(unsafefile_observer.CheckAndResetDownloadUpdated()); 679 EXPECT_TRUE(unsafefile_observer.CheckAndResetDownloadUpdated());
680 CleanupItem(unsafefile_item, download_file, DownloadItem::IN_PROGRESS);
635 } 681 }
636 682
637 // DownloadItemImpl::OnDownloadTargetDetermined will schedule a task to run 683 // DownloadItemImpl::OnDownloadTargetDetermined will schedule a task to run
638 // DownloadFile::Rename(). Once the rename 684 // DownloadFile::Rename(). Once the rename
639 // completes, DownloadItemImpl receives a notification with the new file 685 // completes, DownloadItemImpl receives a notification with the new file
640 // name. Check that observers are updated when the new filename is available and 686 // name. Check that observers are updated when the new filename is available and
641 // not before. 687 // not before.
642 TEST_F(DownloadItemTest, NotificationAfterOnDownloadTargetDetermined) { 688 TEST_F(DownloadItemTest, NotificationAfterOnDownloadTargetDetermined) {
643 DownloadItemImpl* item = CreateDownloadItem(); 689 DownloadItemImpl* item = CreateDownloadItem();
644 DownloadItemImplDelegate::DownloadTargetCallback callback; 690 DownloadItemImplDelegate::DownloadTargetCallback callback;
645 MockDownloadFile* download_file = 691 MockDownloadFile* download_file = CallDownloadItemStart(item, &callback);
646 AddDownloadFileToDownloadItem(item, &callback);
647 TestDownloadItemObserver observer(item); 692 TestDownloadItemObserver observer(item);
648 base::FilePath target_path(kDummyPath); 693 base::FilePath target_path(kDummyTargetPath);
649 base::FilePath intermediate_path(target_path.InsertBeforeExtensionASCII("x")); 694 base::FilePath intermediate_path(target_path.InsertBeforeExtensionASCII("x"));
650 base::FilePath new_intermediate_path( 695 base::FilePath new_intermediate_path(
651 target_path.InsertBeforeExtensionASCII("y")); 696 target_path.InsertBeforeExtensionASCII("y"));
652 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _)) 697 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _))
653 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, 698 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
654 new_intermediate_path)); 699 new_intermediate_path));
655 700
656 // Currently, a notification would be generated if the danger type is anything 701 // Currently, a notification would be generated if the danger type is anything
657 // other than NOT_DANGEROUS. 702 // other than NOT_DANGEROUS.
658 callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, 703 callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
(...skipping 27 matching lines...) Expand all
686 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); 731 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated());
687 732
688 RunAllPendingInMessageLoops(); 733 RunAllPendingInMessageLoops();
689 734
690 CleanupItem(item, mock_download_file, DownloadItem::IN_PROGRESS); 735 CleanupItem(item, mock_download_file, DownloadItem::IN_PROGRESS);
691 } 736 }
692 737
693 TEST_F(DownloadItemTest, DisplayName) { 738 TEST_F(DownloadItemTest, DisplayName) {
694 DownloadItemImpl* item = CreateDownloadItem(); 739 DownloadItemImpl* item = CreateDownloadItem();
695 DownloadItemImplDelegate::DownloadTargetCallback callback; 740 DownloadItemImplDelegate::DownloadTargetCallback callback;
696 MockDownloadFile* download_file = 741 MockDownloadFile* download_file = CallDownloadItemStart(item, &callback);
697 AddDownloadFileToDownloadItem(item, &callback); 742 base::FilePath target_path(
698 base::FilePath target_path(base::FilePath(kDummyPath).AppendASCII("foo.bar")); 743 base::FilePath(kDummyTargetPath).AppendASCII("foo.bar"));
699 base::FilePath intermediate_path(target_path.InsertBeforeExtensionASCII("x")); 744 base::FilePath intermediate_path(target_path.InsertBeforeExtensionASCII("x"));
700 EXPECT_EQ(FILE_PATH_LITERAL(""), 745 EXPECT_EQ(FILE_PATH_LITERAL(""),
701 item->GetFileNameToReportUser().value()); 746 item->GetFileNameToReportUser().value());
702 EXPECT_CALL(*download_file, RenameAndUniquify(_, _)) 747 EXPECT_CALL(*download_file, RenameAndUniquify(_, _))
703 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, 748 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
704 intermediate_path)); 749 intermediate_path));
705 callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, 750 callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
706 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path); 751 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
707 RunAllPendingInMessageLoops(); 752 RunAllPendingInMessageLoops();
708 EXPECT_EQ(FILE_PATH_LITERAL("foo.bar"), 753 EXPECT_EQ(FILE_PATH_LITERAL("foo.bar"),
(...skipping 16 matching lines...) Expand all
725 item->Start(std::move(download_file), std::move(request_handle)); 770 item->Start(std::move(download_file), std::move(request_handle));
726 RunAllPendingInMessageLoops(); 771 RunAllPendingInMessageLoops();
727 772
728 CleanupItem(item, mock_download_file, DownloadItem::IN_PROGRESS); 773 CleanupItem(item, mock_download_file, DownloadItem::IN_PROGRESS);
729 } 774 }
730 775
731 // Test that the delegate is invoked after the download file is renamed. 776 // Test that the delegate is invoked after the download file is renamed.
732 TEST_F(DownloadItemTest, CallbackAfterRename) { 777 TEST_F(DownloadItemTest, CallbackAfterRename) {
733 DownloadItemImpl* item = CreateDownloadItem(); 778 DownloadItemImpl* item = CreateDownloadItem();
734 DownloadItemImplDelegate::DownloadTargetCallback callback; 779 DownloadItemImplDelegate::DownloadTargetCallback callback;
735 MockDownloadFile* download_file = 780 MockDownloadFile* download_file = CallDownloadItemStart(item, &callback);
736 AddDownloadFileToDownloadItem(item, &callback); 781 base::FilePath final_path(
737 base::FilePath final_path(base::FilePath(kDummyPath).AppendASCII("foo.bar")); 782 base::FilePath(kDummyTargetPath).AppendASCII("foo.bar"));
738 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x")); 783 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x"));
739 base::FilePath new_intermediate_path( 784 base::FilePath new_intermediate_path(
740 final_path.InsertBeforeExtensionASCII("y")); 785 final_path.InsertBeforeExtensionASCII("y"));
741 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _)) 786 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _))
742 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, 787 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
743 new_intermediate_path)); 788 new_intermediate_path));
744 789
745 callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, 790 callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
746 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path); 791 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
747 RunAllPendingInMessageLoops(); 792 RunAllPendingInMessageLoops();
(...skipping 13 matching lines...) Expand all
761 RunAllPendingInMessageLoops(); 806 RunAllPendingInMessageLoops();
762 ::testing::Mock::VerifyAndClearExpectations(download_file); 807 ::testing::Mock::VerifyAndClearExpectations(download_file);
763 mock_delegate()->VerifyAndClearExpectations(); 808 mock_delegate()->VerifyAndClearExpectations();
764 } 809 }
765 810
766 // Test that the delegate is invoked after the download file is renamed and the 811 // Test that the delegate is invoked after the download file is renamed and the
767 // download item is in an interrupted state. 812 // download item is in an interrupted state.
768 TEST_F(DownloadItemTest, CallbackAfterInterruptedRename) { 813 TEST_F(DownloadItemTest, CallbackAfterInterruptedRename) {
769 DownloadItemImpl* item = CreateDownloadItem(); 814 DownloadItemImpl* item = CreateDownloadItem();
770 DownloadItemImplDelegate::DownloadTargetCallback callback; 815 DownloadItemImplDelegate::DownloadTargetCallback callback;
771 MockDownloadFile* download_file = 816 MockDownloadFile* download_file = CallDownloadItemStart(item, &callback);
772 AddDownloadFileToDownloadItem(item, &callback); 817 base::FilePath final_path(
773 base::FilePath final_path(base::FilePath(kDummyPath).AppendASCII("foo.bar")); 818 base::FilePath(kDummyTargetPath).AppendASCII("foo.bar"));
774 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x")); 819 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x"));
775 base::FilePath new_intermediate_path( 820 base::FilePath new_intermediate_path(
776 final_path.InsertBeforeExtensionASCII("y")); 821 final_path.InsertBeforeExtensionASCII("y"));
777 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _)) 822 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _))
778 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, 823 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED,
779 new_intermediate_path)); 824 new_intermediate_path));
780 EXPECT_CALL(*download_file, Cancel()) 825 EXPECT_CALL(*download_file, Cancel())
781 .Times(1); 826 .Times(1);
782 827
783 callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, 828 callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
(...skipping 23 matching lines...) Expand all
807 item->Cancel(true); 852 item->Cancel(true);
808 EXPECT_EQ(DownloadItem::CANCELLED, item->GetState()); 853 EXPECT_EQ(DownloadItem::CANCELLED, item->GetState());
809 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_USER_CANCELED, item->GetLastReason()); 854 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_USER_CANCELED, item->GetLastReason());
810 } 855 }
811 856
812 // Destination errors that occur before the intermediate rename shouldn't cause 857 // Destination errors that occur before the intermediate rename shouldn't cause
813 // the download to be marked as interrupted until after the intermediate rename. 858 // the download to be marked as interrupted until after the intermediate rename.
814 TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Restart) { 859 TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Restart) {
815 DownloadItemImpl* item = CreateDownloadItem(); 860 DownloadItemImpl* item = CreateDownloadItem();
816 DownloadItemImplDelegate::DownloadTargetCallback callback; 861 DownloadItemImplDelegate::DownloadTargetCallback callback;
817 MockDownloadFile* download_file = 862 MockDownloadFile* download_file = CallDownloadItemStart(item, &callback);
818 AddDownloadFileToDownloadItem(item, &callback);
819 item->DestinationObserverAsWeakPtr()->DestinationError( 863 item->DestinationObserverAsWeakPtr()->DestinationError(
820 DOWNLOAD_INTERRUPT_REASON_FILE_FAILED); 864 DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
821 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); 865 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
822 866
823 base::FilePath final_path(base::FilePath(kDummyPath).AppendASCII("foo.bar")); 867 base::FilePath final_path(
868 base::FilePath(kDummyTargetPath).AppendASCII("foo.bar"));
824 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x")); 869 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x"));
825 base::FilePath new_intermediate_path( 870 base::FilePath new_intermediate_path(
826 final_path.InsertBeforeExtensionASCII("y")); 871 final_path.InsertBeforeExtensionASCII("y"));
827 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _)) 872 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _))
828 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, 873 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
829 new_intermediate_path)); 874 new_intermediate_path));
830 EXPECT_CALL(*download_file, Cancel()) 875 EXPECT_CALL(*download_file, Cancel())
831 .Times(1); 876 .Times(1);
832 877
833 callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, 878 callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
834 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path); 879 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
835 RunAllPendingInMessageLoops(); 880 RunAllPendingInMessageLoops();
836 // All the callbacks should have happened by now. 881 // All the callbacks should have happened by now.
837 ::testing::Mock::VerifyAndClearExpectations(download_file); 882 ::testing::Mock::VerifyAndClearExpectations(download_file);
838 mock_delegate()->VerifyAndClearExpectations(); 883 mock_delegate()->VerifyAndClearExpectations();
839 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); 884 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState());
840 EXPECT_TRUE(item->GetFullPath().empty()); 885 EXPECT_TRUE(item->GetFullPath().empty());
841 EXPECT_EQ(final_path, item->GetTargetFilePath()); 886 EXPECT_EQ(final_path, item->GetTargetFilePath());
842 } 887 }
843 888
844 // As above. But if the download can be resumed by continuing, then the 889 // As above. But if the download can be resumed by continuing, then the
845 // intermediate path should be retained when the download is interrupted after 890 // intermediate path should be retained when the download is interrupted after
846 // the intermediate rename succeeds. 891 // the intermediate rename succeeds.
847 TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Continue) { 892 TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Continue) {
848 DownloadItemImpl* item = CreateDownloadItem(); 893 DownloadItemImpl* item = CreateDownloadItem();
849 DownloadItemImplDelegate::DownloadTargetCallback callback; 894 DownloadItemImplDelegate::DownloadTargetCallback callback;
850 MockDownloadFile* download_file = 895 MockDownloadFile* download_file = CallDownloadItemStart(item, &callback);
851 AddDownloadFileToDownloadItem(item, &callback);
852 item->DestinationObserverAsWeakPtr()->DestinationError( 896 item->DestinationObserverAsWeakPtr()->DestinationError(
853 DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED); 897 DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED);
854 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); 898 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
855 899
856 base::FilePath final_path(base::FilePath(kDummyPath).AppendASCII("foo.bar")); 900 base::FilePath final_path(
901 base::FilePath(kDummyTargetPath).AppendASCII("foo.bar"));
857 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x")); 902 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x"));
858 base::FilePath new_intermediate_path( 903 base::FilePath new_intermediate_path(
859 final_path.InsertBeforeExtensionASCII("y")); 904 final_path.InsertBeforeExtensionASCII("y"));
860 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _)) 905 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _))
861 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, 906 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
862 new_intermediate_path)); 907 new_intermediate_path));
863 EXPECT_CALL(*download_file, FullPath()) 908 EXPECT_CALL(*download_file, FullPath())
864 .WillOnce(Return(base::FilePath(new_intermediate_path))); 909 .WillOnce(Return(base::FilePath(new_intermediate_path)));
865 EXPECT_CALL(*download_file, Detach()); 910 EXPECT_CALL(*download_file, Detach());
866 911
867 callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, 912 callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
868 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path); 913 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
869 RunAllPendingInMessageLoops(); 914 RunAllPendingInMessageLoops();
870 // All the callbacks should have happened by now. 915 // All the callbacks should have happened by now.
871 ::testing::Mock::VerifyAndClearExpectations(download_file); 916 ::testing::Mock::VerifyAndClearExpectations(download_file);
872 mock_delegate()->VerifyAndClearExpectations(); 917 mock_delegate()->VerifyAndClearExpectations();
873 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); 918 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState());
874 EXPECT_EQ(new_intermediate_path, item->GetFullPath()); 919 EXPECT_EQ(new_intermediate_path, item->GetFullPath());
875 EXPECT_EQ(final_path, item->GetTargetFilePath()); 920 EXPECT_EQ(final_path, item->GetTargetFilePath());
876 } 921 }
877 922
878 // As above. If the intermediate rename fails, then the interrupt reason should 923 // As above. If the intermediate rename fails, then the interrupt reason should
879 // be set to the destination error and the intermediate path should be empty. 924 // be set to the destination error and the intermediate path should be empty.
880 TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Failed) { 925 TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Failed) {
881 DownloadItemImpl* item = CreateDownloadItem(); 926 DownloadItemImpl* item = CreateDownloadItem();
882 DownloadItemImplDelegate::DownloadTargetCallback callback; 927 DownloadItemImplDelegate::DownloadTargetCallback callback;
883 MockDownloadFile* download_file = 928 MockDownloadFile* download_file = CallDownloadItemStart(item, &callback);
884 AddDownloadFileToDownloadItem(item, &callback);
885 item->DestinationObserverAsWeakPtr()->DestinationError( 929 item->DestinationObserverAsWeakPtr()->DestinationError(
886 DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED); 930 DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED);
887 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); 931 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
888 932
889 base::FilePath final_path(base::FilePath(kDummyPath).AppendASCII("foo.bar")); 933 base::FilePath final_path(
934 base::FilePath(kDummyTargetPath).AppendASCII("foo.bar"));
890 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x")); 935 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x"));
891 base::FilePath new_intermediate_path( 936 base::FilePath new_intermediate_path(
892 final_path.InsertBeforeExtensionASCII("y")); 937 final_path.InsertBeforeExtensionASCII("y"));
893 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _)) 938 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _))
894 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, 939 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED,
895 new_intermediate_path)); 940 new_intermediate_path));
896 EXPECT_CALL(*download_file, Cancel()) 941 EXPECT_CALL(*download_file, Cancel())
897 .Times(1); 942 .Times(1);
898 943
899 callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, 944 callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
900 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path); 945 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
901 RunAllPendingInMessageLoops(); 946 RunAllPendingInMessageLoops();
902 // All the callbacks should have happened by now. 947 // All the callbacks should have happened by now.
903 ::testing::Mock::VerifyAndClearExpectations(download_file); 948 ::testing::Mock::VerifyAndClearExpectations(download_file);
904 mock_delegate()->VerifyAndClearExpectations(); 949 mock_delegate()->VerifyAndClearExpectations();
905 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); 950 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState());
906 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, item->GetLastReason()); 951 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, item->GetLastReason());
907 EXPECT_TRUE(item->GetFullPath().empty()); 952 EXPECT_TRUE(item->GetFullPath().empty());
908 EXPECT_EQ(final_path, item->GetTargetFilePath()); 953 EXPECT_EQ(final_path, item->GetTargetFilePath());
909 } 954 }
910 955
911 TEST_F(DownloadItemTest, Canceled) { 956 TEST_F(DownloadItemTest, Canceled) {
912 DownloadItemImpl* item = CreateDownloadItem(); 957 DownloadItemImpl* item = CreateDownloadItem();
913 MockDownloadFile* download_file = AddDownloadFileToDownloadItem(item, NULL); 958 MockDownloadFile* download_file = CallDownloadItemStart(item, nullptr);
914 959
915 // Confirm cancel sets state properly. 960 // Confirm cancel sets state properly.
916 EXPECT_CALL(*download_file, Cancel()); 961 EXPECT_CALL(*download_file, Cancel());
917 item->Cancel(true); 962 item->Cancel(true);
918 EXPECT_EQ(DownloadItem::CANCELLED, item->GetState()); 963 EXPECT_EQ(DownloadItem::CANCELLED, item->GetState());
919 } 964 }
920 965
921 TEST_F(DownloadItemTest, FileRemoved) { 966 TEST_F(DownloadItemTest, FileRemoved) {
922 DownloadItemImpl* item = CreateDownloadItem(); 967 DownloadItemImpl* item = CreateDownloadItem();
923 968
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
972 DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED); 1017 DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED);
973 mock_delegate()->VerifyAndClearExpectations(); 1018 mock_delegate()->VerifyAndClearExpectations();
974 EXPECT_TRUE(observer.CheckAndResetDownloadUpdated()); 1019 EXPECT_TRUE(observer.CheckAndResetDownloadUpdated());
975 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); 1020 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState());
976 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED, 1021 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED,
977 item->GetLastReason()); 1022 item->GetLastReason());
978 } 1023 }
979 1024
980 TEST_F(DownloadItemTest, DestinationCompleted) { 1025 TEST_F(DownloadItemTest, DestinationCompleted) {
981 DownloadItemImpl* item = CreateDownloadItem(); 1026 DownloadItemImpl* item = CreateDownloadItem();
1027 MockDownloadFile* download_file = CallDownloadItemStart(item, nullptr);
982 base::WeakPtr<DownloadDestinationObserver> as_observer( 1028 base::WeakPtr<DownloadDestinationObserver> as_observer(
983 item->DestinationObserverAsWeakPtr()); 1029 item->DestinationObserverAsWeakPtr());
984 TestDownloadItemObserver observer(item); 1030 TestDownloadItemObserver observer(item);
985 1031
986 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); 1032 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
987 EXPECT_EQ("", item->GetHash()); 1033 EXPECT_EQ("", item->GetHash());
988 EXPECT_EQ("", item->GetHashState()); 1034 EXPECT_EQ("", item->GetHashState());
989 EXPECT_FALSE(item->AllDataSaved()); 1035 EXPECT_FALSE(item->AllDataSaved());
990 EXPECT_FALSE(observer.CheckAndResetDownloadUpdated()); 1036 EXPECT_FALSE(observer.CheckAndResetDownloadUpdated());
991 1037
992 as_observer->DestinationUpdate(10, 20, "deadbeef"); 1038 as_observer->DestinationUpdate(10, 20, "deadbeef");
993 EXPECT_TRUE(observer.CheckAndResetDownloadUpdated()); 1039 EXPECT_TRUE(observer.CheckAndResetDownloadUpdated());
994 EXPECT_FALSE(observer.CheckAndResetDownloadUpdated()); // Confirm reset. 1040 EXPECT_FALSE(observer.CheckAndResetDownloadUpdated()); // Confirm reset.
995 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); 1041 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
996 EXPECT_EQ("", item->GetHash()); 1042 EXPECT_EQ("", item->GetHash());
997 EXPECT_EQ("deadbeef", item->GetHashState()); 1043 EXPECT_EQ("deadbeef", item->GetHashState());
998 EXPECT_FALSE(item->AllDataSaved()); 1044 EXPECT_FALSE(item->AllDataSaved());
999 1045
1000 as_observer->DestinationCompleted("livebeef"); 1046 as_observer->DestinationCompleted("livebeef");
1001 mock_delegate()->VerifyAndClearExpectations(); 1047 mock_delegate()->VerifyAndClearExpectations();
1002 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); 1048 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
1003 EXPECT_TRUE(observer.CheckAndResetDownloadUpdated()); 1049 EXPECT_TRUE(observer.CheckAndResetDownloadUpdated());
1004 EXPECT_EQ("livebeef", item->GetHash()); 1050 EXPECT_EQ("livebeef", item->GetHash());
1005 EXPECT_EQ("", item->GetHashState()); 1051 EXPECT_EQ("", item->GetHashState());
1006 EXPECT_TRUE(item->AllDataSaved()); 1052 EXPECT_TRUE(item->AllDataSaved());
1053
1054 // Even though the DownloadItem receives a DestinationCompleted() event,
1055 // target determination hasn't completed, hence the download item is stuck in
1056 // TARGET_PENDING.
1057 CleanupItem(item, download_file, DownloadItem::IN_PROGRESS);
1007 } 1058 }
1008 1059
1009 TEST_F(DownloadItemTest, EnabledActionsForNormalDownload) { 1060 TEST_F(DownloadItemTest, EnabledActionsForNormalDownload) {
1010 DownloadItemImpl* item = CreateDownloadItem(); 1061 DownloadItemImpl* item = CreateDownloadItem();
1011 MockDownloadFile* download_file = 1062 MockDownloadFile* download_file =
1012 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); 1063 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
1013 1064
1014 // InProgress 1065 // InProgress
1015 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); 1066 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
1016 ASSERT_FALSE(item->GetTargetFilePath().empty()); 1067 ASSERT_FALSE(item->GetTargetFilePath().empty());
1017 EXPECT_TRUE(item->CanShowInFolder()); 1068 EXPECT_TRUE(item->CanShowInFolder());
1018 EXPECT_TRUE(item->CanOpenDownload()); 1069 EXPECT_TRUE(item->CanOpenDownload());
1019 1070
1020 // Complete 1071 // Complete
1021 EXPECT_CALL(*download_file, RenameAndAnnotate(_, _)) 1072 EXPECT_CALL(*download_file, RenameAndAnnotate(_, _))
1022 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, 1073 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
1023 base::FilePath(kDummyPath))); 1074 base::FilePath(kDummyTargetPath)));
1024 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _)) 1075 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _))
1025 .WillOnce(Return(true)); 1076 .WillOnce(Return(true));
1026 EXPECT_CALL(*download_file, FullPath()) 1077 EXPECT_CALL(*download_file, FullPath())
1027 .WillOnce(Return(base::FilePath())); 1078 .WillOnce(Return(base::FilePath()));
1028 EXPECT_CALL(*download_file, Detach()); 1079 EXPECT_CALL(*download_file, Detach());
1029 item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string()); 1080 item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string());
1030 RunAllPendingInMessageLoops(); 1081 RunAllPendingInMessageLoops();
1031 1082
1032 ASSERT_EQ(DownloadItem::COMPLETE, item->GetState()); 1083 ASSERT_EQ(DownloadItem::COMPLETE, item->GetState());
1033 EXPECT_TRUE(item->CanShowInFolder()); 1084 EXPECT_TRUE(item->CanShowInFolder());
(...skipping 11 matching lines...) Expand all
1045 ASSERT_FALSE(item->GetTargetFilePath().empty()); 1096 ASSERT_FALSE(item->GetTargetFilePath().empty());
1046 ASSERT_TRUE(item->IsTemporary()); 1097 ASSERT_TRUE(item->IsTemporary());
1047 EXPECT_FALSE(item->CanShowInFolder()); 1098 EXPECT_FALSE(item->CanShowInFolder());
1048 EXPECT_FALSE(item->CanOpenDownload()); 1099 EXPECT_FALSE(item->CanOpenDownload());
1049 1100
1050 // Complete Temporary 1101 // Complete Temporary
1051 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _)) 1102 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _))
1052 .WillOnce(Return(true)); 1103 .WillOnce(Return(true));
1053 EXPECT_CALL(*download_file, RenameAndAnnotate(_, _)) 1104 EXPECT_CALL(*download_file, RenameAndAnnotate(_, _))
1054 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, 1105 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
1055 base::FilePath(kDummyPath))); 1106 base::FilePath(kDummyTargetPath)));
1056 EXPECT_CALL(*download_file, FullPath()) 1107 EXPECT_CALL(*download_file, FullPath())
1057 .WillOnce(Return(base::FilePath())); 1108 .WillOnce(Return(base::FilePath()));
1058 EXPECT_CALL(*download_file, Detach()); 1109 EXPECT_CALL(*download_file, Detach());
1059 item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string()); 1110 item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string());
1060 RunAllPendingInMessageLoops(); 1111 RunAllPendingInMessageLoops();
1061 1112
1062 ASSERT_EQ(DownloadItem::COMPLETE, item->GetState()); 1113 ASSERT_EQ(DownloadItem::COMPLETE, item->GetState());
1063 EXPECT_FALSE(item->CanShowInFolder()); 1114 EXPECT_FALSE(item->CanShowInFolder());
1064 EXPECT_FALSE(item->CanOpenDownload()); 1115 EXPECT_FALSE(item->CanOpenDownload());
1065 } 1116 }
1066 1117
1067 TEST_F(DownloadItemTest, EnabledActionsForInterruptedDownload) { 1118 TEST_F(DownloadItemTest, EnabledActionsForInterruptedDownload) {
1068 DownloadItemImpl* item = CreateDownloadItem(); 1119 DownloadItemImpl* item = CreateDownloadItem();
1069 MockDownloadFile* download_file = 1120 MockDownloadFile* download_file =
1070 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); 1121 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
1071 1122
1072 EXPECT_CALL(*download_file, Cancel()); 1123 EXPECT_CALL(*download_file, Cancel());
1073 item->DestinationObserverAsWeakPtr()->DestinationError( 1124 item->DestinationObserverAsWeakPtr()->DestinationError(
1074 DOWNLOAD_INTERRUPT_REASON_FILE_FAILED); 1125 DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
1075 RunAllPendingInMessageLoops(); 1126 RunAllPendingInMessageLoops();
1076 1127
1077 ASSERT_EQ(DownloadItem::INTERRUPTED, item->GetState()); 1128 ASSERT_EQ(DownloadItem::INTERRUPTED, item->GetState());
1078 ASSERT_FALSE(item->GetTargetFilePath().empty()); 1129 ASSERT_FALSE(item->GetTargetFilePath().empty());
1079 EXPECT_FALSE(item->CanShowInFolder()); 1130 EXPECT_FALSE(item->CanShowInFolder());
1080 EXPECT_FALSE(item->CanOpenDownload()); 1131 EXPECT_TRUE(item->CanOpenDownload());
1081 } 1132 }
1082 1133
1083 TEST_F(DownloadItemTest, EnabledActionsForCancelledDownload) { 1134 TEST_F(DownloadItemTest, EnabledActionsForCancelledDownload) {
1084 DownloadItemImpl* item = CreateDownloadItem(); 1135 DownloadItemImpl* item = CreateDownloadItem();
1085 MockDownloadFile* download_file = 1136 MockDownloadFile* download_file =
1086 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); 1137 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
1087 1138
1088 EXPECT_CALL(*download_file, Cancel()); 1139 EXPECT_CALL(*download_file, Cancel());
1089 item->Cancel(true); 1140 item->Cancel(true);
1090 RunAllPendingInMessageLoops(); 1141 RunAllPendingInMessageLoops();
(...skipping 14 matching lines...) Expand all
1105 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); 1156 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
1106 1157
1107 // Drive the delegate interaction. 1158 // Drive the delegate interaction.
1108 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _)) 1159 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _))
1109 .WillOnce(Return(true)); 1160 .WillOnce(Return(true));
1110 item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string()); 1161 item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string());
1111 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); 1162 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
1112 EXPECT_FALSE(item->IsDangerous()); 1163 EXPECT_FALSE(item->IsDangerous());
1113 1164
1114 // Make sure the download can complete. 1165 // Make sure the download can complete.
1115 EXPECT_CALL(*download_file, RenameAndAnnotate(base::FilePath(kDummyPath), _)) 1166 EXPECT_CALL(*download_file,
1167 RenameAndAnnotate(base::FilePath(kDummyTargetPath), _))
1116 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, 1168 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
1117 base::FilePath(kDummyPath))); 1169 base::FilePath(kDummyTargetPath)));
1118 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _)) 1170 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _))
1119 .WillOnce(Return(true)); 1171 .WillOnce(Return(true));
1120 EXPECT_CALL(*download_file, FullPath()) 1172 EXPECT_CALL(*download_file, FullPath())
1121 .WillOnce(Return(base::FilePath())); 1173 .WillOnce(Return(base::FilePath()));
1122 EXPECT_CALL(*download_file, Detach()); 1174 EXPECT_CALL(*download_file, Detach());
1123 RunAllPendingInMessageLoops(); 1175 RunAllPendingInMessageLoops();
1124 EXPECT_EQ(DownloadItem::COMPLETE, item->GetState()); 1176 EXPECT_EQ(DownloadItem::COMPLETE, item->GetState());
1125 } 1177 }
1126 1178
1127 // Just delaying completion. 1179 // Just delaying completion.
(...skipping 15 matching lines...) Expand all
1143 ASSERT_FALSE(delegate_callback.is_null()); 1195 ASSERT_FALSE(delegate_callback.is_null());
1144 copy_delegate_callback = delegate_callback; 1196 copy_delegate_callback = delegate_callback;
1145 delegate_callback.Reset(); 1197 delegate_callback.Reset();
1146 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); 1198 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
1147 copy_delegate_callback.Run(); 1199 copy_delegate_callback.Run();
1148 ASSERT_TRUE(delegate_callback.is_null()); 1200 ASSERT_TRUE(delegate_callback.is_null());
1149 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); 1201 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
1150 EXPECT_FALSE(item->IsDangerous()); 1202 EXPECT_FALSE(item->IsDangerous());
1151 1203
1152 // Make sure the download can complete. 1204 // Make sure the download can complete.
1153 EXPECT_CALL(*download_file, RenameAndAnnotate(base::FilePath(kDummyPath), _)) 1205 EXPECT_CALL(*download_file,
1206 RenameAndAnnotate(base::FilePath(kDummyTargetPath), _))
1154 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, 1207 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
1155 base::FilePath(kDummyPath))); 1208 base::FilePath(kDummyTargetPath)));
1156 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _)) 1209 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _))
1157 .WillOnce(Return(true)); 1210 .WillOnce(Return(true));
1158 EXPECT_CALL(*download_file, FullPath()) 1211 EXPECT_CALL(*download_file, FullPath())
1159 .WillOnce(Return(base::FilePath())); 1212 .WillOnce(Return(base::FilePath()));
1160 EXPECT_CALL(*download_file, Detach()); 1213 EXPECT_CALL(*download_file, Detach());
1161 RunAllPendingInMessageLoops(); 1214 RunAllPendingInMessageLoops();
1162 EXPECT_EQ(DownloadItem::COMPLETE, item->GetState()); 1215 EXPECT_EQ(DownloadItem::COMPLETE, item->GetState());
1163 } 1216 }
1164 1217
1165 // Delay and set danger. 1218 // Delay and set danger.
(...skipping 18 matching lines...) Expand all
1184 EXPECT_FALSE(item->IsDangerous()); 1237 EXPECT_FALSE(item->IsDangerous());
1185 item->OnContentCheckCompleted( 1238 item->OnContentCheckCompleted(
1186 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE); 1239 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE);
1187 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); 1240 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
1188 copy_delegate_callback.Run(); 1241 copy_delegate_callback.Run();
1189 ASSERT_TRUE(delegate_callback.is_null()); 1242 ASSERT_TRUE(delegate_callback.is_null());
1190 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); 1243 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
1191 EXPECT_TRUE(item->IsDangerous()); 1244 EXPECT_TRUE(item->IsDangerous());
1192 1245
1193 // Make sure the download doesn't complete until we've validated it. 1246 // Make sure the download doesn't complete until we've validated it.
1194 EXPECT_CALL(*download_file, RenameAndAnnotate(base::FilePath(kDummyPath), _)) 1247 EXPECT_CALL(*download_file,
1248 RenameAndAnnotate(base::FilePath(kDummyTargetPath), _))
1195 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, 1249 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
1196 base::FilePath(kDummyPath))); 1250 base::FilePath(kDummyTargetPath)));
1197 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _)) 1251 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _))
1198 .WillOnce(Return(true)); 1252 .WillOnce(Return(true));
1199 EXPECT_CALL(*download_file, FullPath()) 1253 EXPECT_CALL(*download_file, FullPath())
1200 .WillOnce(Return(base::FilePath())); 1254 .WillOnce(Return(base::FilePath()));
1201 EXPECT_CALL(*download_file, Detach()); 1255 EXPECT_CALL(*download_file, Detach());
1202 RunAllPendingInMessageLoops(); 1256 RunAllPendingInMessageLoops();
1203 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); 1257 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
1204 EXPECT_TRUE(item->IsDangerous()); 1258 EXPECT_TRUE(item->IsDangerous());
1205 1259
1206 item->ValidateDangerousDownload(); 1260 item->ValidateDangerousDownload();
(...skipping 28 matching lines...) Expand all
1235 ASSERT_FALSE(delegate_callback.is_null()); 1289 ASSERT_FALSE(delegate_callback.is_null());
1236 copy_delegate_callback = delegate_callback; 1290 copy_delegate_callback = delegate_callback;
1237 delegate_callback.Reset(); 1291 delegate_callback.Reset();
1238 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); 1292 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
1239 copy_delegate_callback.Run(); 1293 copy_delegate_callback.Run();
1240 ASSERT_TRUE(delegate_callback.is_null()); 1294 ASSERT_TRUE(delegate_callback.is_null());
1241 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); 1295 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
1242 EXPECT_FALSE(item->IsDangerous()); 1296 EXPECT_FALSE(item->IsDangerous());
1243 1297
1244 // Make sure the download can complete. 1298 // Make sure the download can complete.
1245 EXPECT_CALL(*download_file, RenameAndAnnotate(base::FilePath(kDummyPath), _)) 1299 EXPECT_CALL(*download_file,
1300 RenameAndAnnotate(base::FilePath(kDummyTargetPath), _))
1246 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, 1301 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
1247 base::FilePath(kDummyPath))); 1302 base::FilePath(kDummyTargetPath)));
1248 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _)) 1303 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _))
1249 .WillOnce(Return(true)); 1304 .WillOnce(Return(true));
1250 EXPECT_CALL(*download_file, FullPath()) 1305 EXPECT_CALL(*download_file, FullPath())
1251 .WillOnce(Return(base::FilePath())); 1306 .WillOnce(Return(base::FilePath()));
1252 EXPECT_CALL(*download_file, Detach()); 1307 EXPECT_CALL(*download_file, Detach());
1253 RunAllPendingInMessageLoops(); 1308 RunAllPendingInMessageLoops();
1254 EXPECT_EQ(DownloadItem::COMPLETE, item->GetState()); 1309 EXPECT_EQ(DownloadItem::COMPLETE, item->GetState());
1255 } 1310 }
1256 1311
1257 TEST_F(DownloadItemTest, StealDangerousDownload) { 1312 TEST_F(DownloadItemTest, StealDangerousDownload) {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1312 EXPECT_CALL(*mock_delegate(), DownloadRemoved(_)); 1367 EXPECT_CALL(*mock_delegate(), DownloadRemoved(_));
1313 base::WeakPtrFactory<DownloadItemTest> weak_ptr_factory(this); 1368 base::WeakPtrFactory<DownloadItemTest> weak_ptr_factory(this);
1314 item->StealDangerousDownload( 1369 item->StealDangerousDownload(
1315 base::Bind(&DownloadItemTest::OnDownloadFileAcquired, 1370 base::Bind(&DownloadItemTest::OnDownloadFileAcquired,
1316 weak_ptr_factory.GetWeakPtr(), 1371 weak_ptr_factory.GetWeakPtr(),
1317 base::Unretained(&returned_path))); 1372 base::Unretained(&returned_path)));
1318 RunAllPendingInMessageLoops(); 1373 RunAllPendingInMessageLoops();
1319 EXPECT_TRUE(returned_path.empty()); 1374 EXPECT_TRUE(returned_path.empty());
1320 } 1375 }
1321 1376
1377 namespace {
Randy Smith (Not in Mondays) 2016/02/12 00:03:11 Why? It seems inconsistent with the rest of the f
asanka 2016/02/12 05:04:27 Hmm? The namespace only covers the set of definiti
Randy Smith (Not in Mondays) 2016/02/12 17:37:02 Ah, ignore me; it's a combination of a prejudice a
1378
Randy Smith (Not in Mondays) 2016/02/12 00:03:11 It might be useful to have a motivating comment be
asanka 2016/02/12 05:04:27 Done.
Randy Smith (Not in Mondays) 2016/02/12 17:37:02 Nice, thank you.
1379 // A call to a DownloadDestinationObserver method that's missing the
1380 // DownloadDestinationObserver object. Currying this way allows us to bind a
1381 // call prior to constructing the object on which the method would be invoked.
1382 // This is necessary since we are going to construct various permutations of
1383 // observer calls that will then be applied to a DownloadItem in a state as yet
1384 // undetermined.
1385 using CurriedObservation =
1386 base::Callback<void(base::WeakPtr<DownloadDestinationObserver>)>;
1387
1388 // A set of observations that are to be made during some event in the
1389 // DownloadItemImpl control flow. Ordering of the observations is significant.
1390 using ObservationSet = std::deque<CurriedObservation>;
1391
1392 // An ordered list of events.
1393 //
1394 // An "event" in this context refers to some stage in the DownloadItemImpl's
1395 // workflow. For example: immediately after the initialization of the
1396 // DownloadFile.
1397 using EventList = std::deque<ObservationSet>;
Randy Smith (Not in Mondays) 2016/02/12 00:03:11 This is a bit confusing, given that the EventList
asanka 2016/02/12 05:04:26 Yeah. It's the ordering. I'll make a note of it.
1398
1399 // The following functions help us with currying the calls to
1400 // DownloadDestinationObserver. If std::bind was allowed along with
1401 // std::placeholders, it is possible to avoid these functions, but currently
1402 // Chromium doesn't allow using std::bind for good reasons.
1403 void DestinationUpdateInvoker(
1404 int64_t bytes_so_far,
1405 int64_t bytes_per_sec,
1406 const std::string& hash_state,
1407 base::WeakPtr<DownloadDestinationObserver> observer) {
1408 if (observer)
1409 observer->DestinationUpdate(bytes_so_far, bytes_per_sec, hash_state);
1410 }
1411
1412 void DestinationErrorInvoker(
1413 DownloadInterruptReason reason,
1414 base::WeakPtr<DownloadDestinationObserver> observer) {
1415 if (observer)
1416 observer->DestinationError(reason);
1417 }
1418
1419 void DestinationCompletedInvoker(
1420 const std::string& final_hash,
1421 base::WeakPtr<DownloadDestinationObserver> observer) {
1422 if (observer)
1423 observer->DestinationCompleted(final_hash);
1424 }
1425
1426 // Given a set of observations (via the range |begin|..|end|), constructs a list
1427 // of EventLists such that:
1428 //
1429 // * There are exactly |event_count| ObservationSets in each EventList.
1430 //
1431 // * Each ObservationSet in each EventList contains a subrange of observations
Randy Smith (Not in Mondays) 2016/02/12 00:03:11 suggest: "... subrange (possibly empty) of observa
asanka 2016/02/12 05:04:27 Done.
1432 // from the input range, in the same order as the input range.
1433 //
1434 // * The ordering of the ObservationSet in each EventList is such that all
1435 // observations in one ObservationSet occur earlier than all observations in
1436 // an ObservationSet that follows it.
1437 //
1438 // * The list of EventLists together describe all the possible ways in which the
1439 // list of observations can be distributed into |event_count| events.
Randy Smith (Not in Mondays) 2016/02/12 00:03:11 I'm tempted to title this "Thor's hammer" except t
asanka 2016/02/12 05:04:27 Hehe.
1440 std::vector<EventList> DistributeObservationsIntoEvents(
1441 const std::vector<CurriedObservation>::iterator begin,
1442 const std::vector<CurriedObservation>::iterator end,
1443 int event_count) {
1444 std::vector<EventList> all_observation_sets;
1445 for (auto partition = begin;; ++partition) {
1446 ObservationSet first_group_of_observations(begin, partition);
1447 if (event_count > 1) {
1448 std::vector<EventList> subsequent_bins =
1449 DistributeObservationsIntoEvents(partition, end, event_count - 1);
1450 for (const auto other_bins : subsequent_bins) {
Randy Smith (Not in Mondays) 2016/02/12 00:03:11 Reference? It's copied anyway below (IIUC).
asanka 2016/02/12 05:04:27 Done.
1451 EventList observation_set;
1452 observation_set = other_bins;
1453 observation_set.push_front(first_group_of_observations);
1454 all_observation_sets.push_back(observation_set);
1455 }
1456 } else {
1457 EventList observation_set;
1458 observation_set.push_front(first_group_of_observations);
1459 all_observation_sets.push_back(observation_set);
1460 }
1461 if (partition == end)
1462 break;
1463 }
1464 return all_observation_sets;
1465 }
1466
1467 // For the purpose of this tests, we are only concerned with 3 events:
1468 //
1469 // 1. Immediately after the DownloadFile is initialized.
1470 // 2. Immediately after the DownloadTargetCallback is invoked.
1471 // 3. Immediately after the intermediate file is renamed.
1472 //
1473 // We are going to take a couple of sets of DownloadDestinationObserver events
1474 // and distribute them into the three events described above. And then we are
1475 // going to invoke the observations while a DownloadItemImpl is carefully
1476 // stepped through its stages.
1477
1478 std::vector<EventList> GenerateSuccessfulEventLists() {
1479 std::vector<CurriedObservation> all_observations;
1480 all_observations.push_back(
1481 base::Bind(&DestinationUpdateInvoker, 100, 100, "abc"));
1482 all_observations.push_back(
1483 base::Bind(&DestinationUpdateInvoker, 200, 100, "def"));
1484 all_observations.push_back(
1485 base::Bind(&DestinationCompletedInvoker, "final-hash-1"));
1486 return DistributeObservationsIntoEvents(all_observations.begin(),
1487 all_observations.end(), 3);
Randy Smith (Not in Mondays) 2016/02/12 00:03:11 Where does event_count == 3 come from? Isn't that
asanka 2016/02/12 05:04:27 Gave it a name.
1488 }
1489
1490 std::vector<EventList> GenerateFailingEventLists() {
1491 std::vector<CurriedObservation> all_observations;
1492 all_observations.push_back(
1493 base::Bind(&DestinationUpdateInvoker, 100, 100, "abc"));
1494 all_observations.push_back(base::Bind(
1495 &DestinationErrorInvoker, DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED));
1496 return DistributeObservationsIntoEvents(all_observations.begin(),
1497 all_observations.end(), 3);
1498 }
1499
1500 class DownloadItemDestinationUpdateRaceTest
1501 : public DownloadItemTest,
1502 public ::testing::WithParamInterface<EventList> {
1503 public:
1504 DownloadItemDestinationUpdateRaceTest()
1505 : DownloadItemTest(),
1506 item_(CreateDownloadItem()),
1507 file_(new ::testing::StrictMock<MockDownloadFile>()),
1508 request_handle_(new ::testing::StrictMock<MockRequestHandle>()) {
1509 DCHECK_EQ(GetParam().size(), 3u);
1510 EXPECT_CALL(*request_handle_, GetWebContents())
1511 .WillRepeatedly(Return(nullptr));
1512 }
1513
1514 protected:
1515 const ObservationSet& PostInitializeFileObservations() {
1516 return GetParam().front();
1517 }
1518 const ObservationSet& PostTargetDeterminationObservations() {
1519 return *(GetParam().begin() + 1);
1520 }
1521 const ObservationSet& PostIntermediateRenameObservations() {
1522 return *(GetParam().begin() + 2);
1523 }
1524
1525 // Apply all the observations in |observations| to |observer|, but do so
1526 // asynchronously so that the events are applied in order behind any tasks
1527 // that are already scheduled.
1528 void ScheduleObservations(
1529 const ObservationSet& observations,
1530 base::WeakPtr<DownloadDestinationObserver> observer) {
1531 for (const auto action : observations)
1532 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
1533 base::Bind(action, observer));
1534 }
1535
1536 DownloadItemImpl* item_;
1537 scoped_ptr<MockDownloadFile> file_;
1538 scoped_ptr<MockRequestHandle> request_handle_;
1539
1540 std::queue<base::Closure> successful_update_events_;
1541 std::queue<base::Closure> failing_update_events_;
1542 };
1543
1544 INSTANTIATE_TEST_CASE_P(Success,
1545 DownloadItemDestinationUpdateRaceTest,
1546 ::testing::ValuesIn(GenerateSuccessfulEventLists()));
1547
1548 INSTANTIATE_TEST_CASE_P(Failure,
1549 DownloadItemDestinationUpdateRaceTest,
1550 ::testing::ValuesIn(GenerateFailingEventLists()));
1551
1552 } // namespace
1553
1554 TEST_P(DownloadItemDestinationUpdateRaceTest, DumpParameters) {
Randy Smith (Not in Mondays) 2016/02/12 00:03:11 Quick comment before each test sketching out what
asanka 2016/02/12 05:04:27 Done.
1555 const auto parameter = GetParam();
1556 class Dump : public DownloadDestinationObserver {
1557 public:
1558 void DestinationUpdate(int64_t bytes_so_far,
1559 int64_t bytes_per_sec,
1560 const std::string& hash_state) override {
1561 DVLOG(20) << " DestinationUpdate(bytes_so_far:" << bytes_so_far
1562 << " bytes_per_sec:" << bytes_per_sec
1563 << " hash_state:" << hash_state << ")";
1564 };
1565
1566 void DestinationError(DownloadInterruptReason reason) override {
1567 DVLOG(20) << " DestinationError(reason:"
1568 << DownloadInterruptReasonToString(reason) << ")";
1569 }
1570
1571 void DestinationCompleted(const std::string& final_hash) override {
1572 DVLOG(20) << " DestinationCompleted(final_hash:" << final_hash << ")";
1573 }
1574 } dumper;
1575 base::WeakPtrFactory<DownloadDestinationObserver> factory(&dumper);
1576 base::WeakPtr<DownloadDestinationObserver> dumper_ptr = factory.GetWeakPtr();
1577
1578 for (const auto bin : parameter) {
1579 DVLOG(20) << "New bin: " << bin.size() << " elements";
1580 for (const auto invoker : bin)
1581 invoker.Run(dumper_ptr);
1582 }
1583 }
1584
1585 TEST_P(DownloadItemDestinationUpdateRaceTest, InitDownloadFileFails) {
Randy Smith (Not in Mondays) 2016/02/12 00:03:11 I'm sure there's something I'm missing, but is the
asanka 2016/02/12 05:04:27 Yeah, this one was wasteful. I moved it to a regul
1586 // Expect that the download file and the request will be cancelled as a
1587 // result.
1588 EXPECT_CALL(*file_, Cancel());
1589 EXPECT_CALL(*request_handle_, CancelRequest());
1590
1591 EXPECT_CALL(*file_, Initialize(_))
1592 .WillOnce(InvokeCallbackWithParam(
1593 DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED));
1594 item_->Start(std::move(file_), std::move(request_handle_));
1595
1596 RunAllPendingInMessageLoops();
1597
1598 // Since the download file initialization failed, no destination updates are
1599 // expected. No need to drain any action buckets.
1600 EXPECT_EQ(DownloadItem::INTERRUPTED, item_->GetState());
1601 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED,
1602 item_->GetLastReason());
1603 }
1604
1605 TEST_P(DownloadItemDestinationUpdateRaceTest, DownloadCancelledByUser) {
1606 // Expect that the download file and the request will be cancelled as a
1607 // result.
1608 EXPECT_CALL(*file_, Cancel());
1609 EXPECT_CALL(*request_handle_, CancelRequest());
1610
1611 base::RunLoop initialize_loop;
1612 DownloadFile::InitializeCallback initialize_callback;
1613 EXPECT_CALL(*file_, Initialize(_))
1614 .WillOnce(DoAll(SaveArg<0>(&initialize_callback),
1615 InvokeClosure(initialize_loop.QuitClosure())));
1616
1617 item_->Start(std::move(file_), std::move(request_handle_));
1618 initialize_loop.Run();
1619 base::WeakPtr<DownloadDestinationObserver> destination_observer =
1620 item_->DestinationObserverAsWeakPtr();
1621
1622 base::RunLoop target_determination_loop;
1623 DownloadItemImplDelegate::DownloadTargetCallback target_callback;
1624 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(_, _))
1625 .WillOnce(DoAll(SaveArg<1>(&target_callback),
1626 InvokeClosure(target_determination_loop.QuitClosure())));
1627 ScheduleObservations(PostInitializeFileObservations(), destination_observer);
1628 initialize_callback.Run(DOWNLOAD_INTERRUPT_REASON_NONE);
1629 target_determination_loop.Run();
1630
1631 RunAllPendingInMessageLoops();
1632
1633 ASSERT_FALSE(target_callback.is_null());
1634 ScheduleObservations(PostTargetDeterminationObservations(),
1635 destination_observer);
1636 target_callback.Run(base::FilePath(),
1637 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
1638 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, base::FilePath());
1639 RunAllPendingInMessageLoops();
1640
1641 EXPECT_EQ(DownloadItem::CANCELLED, item_->GetState());
1642 }
1643
1644 TEST_P(DownloadItemDestinationUpdateRaceTest, IntermediateRenameFails) {
1645 // Expect that the download file and the request will be cancelled as a
1646 // result.
1647 EXPECT_CALL(*file_, Cancel());
1648 EXPECT_CALL(*request_handle_, CancelRequest());
1649
1650 // Intermediate rename loop is not used immediately, but let's set up the
1651 // DownloadFile expectations since we are about to transfer its ownership to
1652 // the DownloadItem.
1653 base::RunLoop intermediate_rename_loop;
1654 DownloadFile::RenameCompletionCallback intermediate_rename_callback;
1655 EXPECT_CALL(*file_, RenameAndUniquify(_, _))
1656 .WillOnce(DoAll(SaveArg<1>(&intermediate_rename_callback),
1657 InvokeClosure(intermediate_rename_loop.QuitClosure())));
1658
1659 base::RunLoop initialize_loop;
1660 DownloadFile::InitializeCallback initialize_callback;
1661 EXPECT_CALL(*file_, Initialize(_))
1662 .WillOnce(DoAll(SaveArg<0>(&initialize_callback),
1663 InvokeClosure(initialize_loop.QuitClosure())));
1664
1665 item_->Start(std::move(file_), std::move(request_handle_));
1666 initialize_loop.Run();
1667 base::WeakPtr<DownloadDestinationObserver> destination_observer =
1668 item_->DestinationObserverAsWeakPtr();
1669
1670 base::RunLoop target_determination_loop;
1671 DownloadItemImplDelegate::DownloadTargetCallback target_callback;
1672 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(_, _))
1673 .WillOnce(DoAll(SaveArg<1>(&target_callback),
1674 InvokeClosure(target_determination_loop.QuitClosure())));
1675 ScheduleObservations(PostInitializeFileObservations(), destination_observer);
1676 initialize_callback.Run(DOWNLOAD_INTERRUPT_REASON_NONE);
1677 target_determination_loop.Run();
1678
1679 RunAllPendingInMessageLoops();
1680 ASSERT_FALSE(target_callback.is_null());
1681
1682 ScheduleObservations(PostTargetDeterminationObservations(),
1683 destination_observer);
1684 target_callback.Run(base::FilePath(kDummyTargetPath),
1685 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
1686 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
1687 base::FilePath(kDummyIntermediatePath));
1688
1689 intermediate_rename_loop.Run();
1690 ASSERT_FALSE(intermediate_rename_callback.is_null());
1691
1692 ScheduleObservations(PostIntermediateRenameObservations(),
1693 destination_observer);
1694 intermediate_rename_callback.Run(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED,
1695 base::FilePath());
1696 RunAllPendingInMessageLoops();
1697
1698 EXPECT_EQ(DownloadItem::INTERRUPTED, item_->GetState());
1699 }
1700
1701 TEST_P(DownloadItemDestinationUpdateRaceTest, IntermediateRenameSucceeds) {
1702 // We expect either that the download will fail (in which case the request and
1703 // the download file will be cancelled), or it will succeed (in which case the
1704 // DownloadFile will Detach()). It depends on the list of observations that
1705 // are given to us.
1706 EXPECT_CALL(*file_, Cancel()).Times(::testing::AnyNumber());
1707 EXPECT_CALL(*request_handle_, CancelRequest()).Times(::testing::AnyNumber());
1708 EXPECT_CALL(*file_, Detach()).Times(::testing::AnyNumber());
1709
1710 EXPECT_CALL(*file_, FullPath())
1711 .WillRepeatedly(Return(base::FilePath(kDummyIntermediatePath)));
1712
1713 // Intermediate rename loop is not used immediately, but let's set up the
1714 // DownloadFile expectations since we are about to transfer its ownership to
1715 // the DownloadItem.
1716 base::RunLoop intermediate_rename_loop;
1717 DownloadFile::RenameCompletionCallback intermediate_rename_callback;
1718 EXPECT_CALL(*file_, RenameAndUniquify(_, _))
1719 .WillOnce(DoAll(SaveArg<1>(&intermediate_rename_callback),
1720 InvokeClosure(intermediate_rename_loop.QuitClosure())));
1721
1722 base::RunLoop initialize_loop;
1723 DownloadFile::InitializeCallback initialize_callback;
1724 EXPECT_CALL(*file_, Initialize(_))
1725 .WillOnce(DoAll(SaveArg<0>(&initialize_callback),
1726 InvokeClosure(initialize_loop.QuitClosure())));
1727
1728 item_->Start(std::move(file_), std::move(request_handle_));
1729 initialize_loop.Run();
1730 base::WeakPtr<DownloadDestinationObserver> destination_observer =
1731 item_->DestinationObserverAsWeakPtr();
1732
1733 base::RunLoop target_determination_loop;
1734 DownloadItemImplDelegate::DownloadTargetCallback target_callback;
1735 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(_, _))
1736 .WillOnce(DoAll(SaveArg<1>(&target_callback),
1737 InvokeClosure(target_determination_loop.QuitClosure())));
1738 ScheduleObservations(PostInitializeFileObservations(), destination_observer);
1739 initialize_callback.Run(DOWNLOAD_INTERRUPT_REASON_NONE);
1740 target_determination_loop.Run();
1741
1742 RunAllPendingInMessageLoops();
1743 ASSERT_FALSE(target_callback.is_null());
1744
1745 ScheduleObservations(PostTargetDeterminationObservations(),
1746 destination_observer);
1747 target_callback.Run(base::FilePath(kDummyTargetPath),
1748 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
1749 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
1750 base::FilePath(kDummyIntermediatePath));
1751
1752 intermediate_rename_loop.Run();
1753 ASSERT_FALSE(intermediate_rename_callback.is_null());
1754
1755 // This may or may not be called, depending on whether there are any errors in
1756 // our action list.
1757 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(_, _))
1758 .Times(::testing::AnyNumber());
1759
1760 ScheduleObservations(PostIntermediateRenameObservations(),
1761 destination_observer);
1762 intermediate_rename_callback.Run(DOWNLOAD_INTERRUPT_REASON_NONE,
1763 base::FilePath(kDummyIntermediatePath));
1764 RunAllPendingInMessageLoops();
1765
1766 // The state of the download depends on the observer events that were played
1767 // back to the DownloadItemImpl. Hence we can't establish a single expectation
1768 // here. On Debug builds, the DCHECKs will verify that the state transitions
1769 // were correct, and on Release builds, the tests should run to completion
1770 // without crashing.
1771 EXPECT_TRUE(item_->GetState() == DownloadItem::IN_PROGRESS ||
1772 item_->GetState() == DownloadItem::INTERRUPTED);
1773 if (item_->GetState() == DownloadItem::INTERRUPTED)
1774 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, item_->GetLastReason());
1775
1776 item_->Cancel(true);
1777 RunAllPendingInMessageLoops();
1778 }
1779
1780 // TODO(asanka): Write tests for resuming and auto-resuming downloads which have
1781 // their own brand of race conditions.
1782
1322 TEST(MockDownloadItem, Compiles) { 1783 TEST(MockDownloadItem, Compiles) {
1323 MockDownloadItem mock_item; 1784 MockDownloadItem mock_item;
1324 } 1785 }
1325 1786
1326 } // namespace content 1787 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698