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

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: Address 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
« no previous file with comments | « content/browser/download/download_item_impl.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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>(ScheduleCallbackWithParam(0));
201 //
202 // .. will invoke the second argument to Bar with 0 as the parameter.
203 ACTION_P(ScheduleCallbackWithParam, param) {
204 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
205 base::Bind(arg0, param));
206 }
207
208 ACTION_P(ScheduleClosure, 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*
270 // added to the DownloadItem. 288 // that was added to the DownloadItem.
271 MockDownloadFile* DoIntermediateRename(DownloadItemImpl* item, 289 MockDownloadFile* DoIntermediateRename(DownloadItemImpl* item,
272 DownloadDangerType danger_type) { 290 DownloadDangerType danger_type) {
273 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); 291 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
274 EXPECT_TRUE(item->GetTargetFilePath().empty()); 292 EXPECT_TRUE(item->GetTargetFilePath().empty());
275 DownloadItemImplDelegate::DownloadTargetCallback callback; 293 DownloadItemImplDelegate::DownloadTargetCallback callback;
276 MockDownloadFile* download_file = 294 MockDownloadFile* download_file = CallDownloadItemStart(item, &callback);
277 AddDownloadFileToDownloadItem(item, &callback); 295 base::FilePath target_path(kDummyTargetPath);
278 base::FilePath target_path(kDummyPath); 296 base::FilePath intermediate_path(kDummyIntermediatePath);
279 base::FilePath intermediate_path(
280 target_path.InsertBeforeExtensionASCII("x"));
281 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _)) 297 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _))
282 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, 298 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
283 intermediate_path)); 299 intermediate_path));
284 callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, 300 callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
285 danger_type, intermediate_path); 301 danger_type, intermediate_path);
286 RunAllPendingInMessageLoops(); 302 RunAllPendingInMessageLoops();
287 return download_file; 303 return download_file;
288 } 304 }
289 305
306 void DoDestinationComplete(DownloadItemImpl* item,
307 MockDownloadFile* download_file) {
308 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(_, _))
309 .WillOnce(Return(true));
310 base::FilePath final_path(kDummyTargetPath);
311 EXPECT_CALL(*download_file, RenameAndAnnotate(_, _))
312 .WillOnce(
313 ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, final_path));
314 EXPECT_CALL(*download_file, FullPath())
315 .WillRepeatedly(Return(base::FilePath(kDummyTargetPath)));
316 EXPECT_CALL(*download_file, Detach());
317
318 item->DestinationObserverAsWeakPtr()->DestinationCompleted("");
319 RunAllPendingInMessageLoops();
320 }
321
290 // Cleanup a download item (specifically get rid of the DownloadFile on it). 322 // Cleanup a download item (specifically get rid of the DownloadFile on it).
291 // The item must be in the expected state. 323 // The item must be in the expected state.
292 void CleanupItem(DownloadItemImpl* item, 324 void CleanupItem(DownloadItemImpl* item,
293 MockDownloadFile* download_file, 325 MockDownloadFile* download_file,
294 DownloadItem::DownloadState expected_state) { 326 DownloadItem::DownloadState expected_state) {
295 EXPECT_EQ(expected_state, item->GetState()); 327 EXPECT_EQ(expected_state, item->GetState());
296 328
297 if (expected_state == DownloadItem::IN_PROGRESS) { 329 if (expected_state == DownloadItem::IN_PROGRESS) {
298 if (download_file) 330 if (download_file)
299 EXPECT_CALL(*download_file, Cancel()); 331 EXPECT_CALL(*download_file, Cancel());
300 item->Cancel(true); 332 item->Cancel(true);
301 loop_.RunUntilIdle(); 333 RunAllPendingInMessageLoops();
302 } 334 }
303 } 335 }
304 336
305 // Destroy a previously created download item. 337 // Destroy a previously created download item.
306 void DestroyDownloadItem(DownloadItem* item) { 338 void DestroyDownloadItem(DownloadItem* item) {
307 allocated_downloads_.erase(item); 339 allocated_downloads_.erase(item);
308 delete item; 340 delete item;
309 } 341 }
310 342
311 void RunAllPendingInMessageLoops() { 343 void RunAllPendingInMessageLoops() { base::RunLoop().RunUntilIdle(); }
312 loop_.RunUntilIdle();
313 }
314 344
315 MockDelegate* mock_delegate() { 345 MockDelegate* mock_delegate() {
316 return &delegate_; 346 return &delegate_;
317 } 347 }
318 348
319 void OnDownloadFileAcquired(base::FilePath* return_path, 349 void OnDownloadFileAcquired(base::FilePath* return_path,
320 const base::FilePath& path) { 350 const base::FilePath& path) {
321 *return_path = path; 351 *return_path = path;
322 } 352 }
323 353
324 private: 354 private:
325 int next_download_id_ = DownloadItem::kInvalidId + 1; 355 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_; 356 StrictMock<MockDelegate> delegate_;
330 std::set<DownloadItem*> allocated_downloads_; 357 std::set<DownloadItem*> allocated_downloads_;
358 TestBrowserThreadBundle thread_bundle_;
331 }; 359 };
332 360
333 // Tests to ensure calls that change a DownloadItem generate an update to 361 // Tests to ensure calls that change a DownloadItem generate an update to
334 // observers. 362 // observers.
335 // State changing functions not tested: 363 // State changing functions not tested:
336 // void OpenDownload(); 364 // void OpenDownload();
337 // void ShowDownloadInShell(); 365 // void ShowDownloadInShell();
338 // void CompleteDelayedDownload(); 366 // void CompleteDelayedDownload();
339 // set_* mutators 367 // set_* mutators
340 368
341 TEST_F(DownloadItemTest, NotificationAfterUpdate) { 369 TEST_F(DownloadItemTest, NotificationAfterUpdate) {
342 DownloadItemImpl* item = CreateDownloadItem(); 370 DownloadItemImpl* item = CreateDownloadItem();
371 MockDownloadFile* file =
372 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
373 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
343 TestDownloadItemObserver observer(item); 374 TestDownloadItemObserver observer(item);
344 375
345 item->DestinationUpdate(kDownloadChunkSize, kDownloadSpeed, std::string()); 376 item->DestinationUpdate(kDownloadChunkSize, kDownloadSpeed, std::string());
346 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); 377 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated());
347 EXPECT_EQ(kDownloadSpeed, item->CurrentSpeed()); 378 EXPECT_EQ(kDownloadSpeed, item->CurrentSpeed());
379 CleanupItem(item, file, DownloadItem::IN_PROGRESS);
348 } 380 }
349 381
350 TEST_F(DownloadItemTest, NotificationAfterCancel) { 382 TEST_F(DownloadItemTest, NotificationAfterCancel) {
351 DownloadItemImpl* user_cancel = CreateDownloadItem(); 383 DownloadItemImpl* user_cancel = CreateDownloadItem();
352 MockDownloadFile* download_file = 384 MockDownloadFile* download_file = CallDownloadItemStart(user_cancel, nullptr);
353 AddDownloadFileToDownloadItem(user_cancel, NULL);
354 EXPECT_CALL(*download_file, Cancel()); 385 EXPECT_CALL(*download_file, Cancel());
355 TestDownloadItemObserver observer1(user_cancel); 386 TestDownloadItemObserver observer1(user_cancel);
356 387
357 user_cancel->Cancel(true); 388 user_cancel->Cancel(true);
358 ASSERT_TRUE(observer1.CheckAndResetDownloadUpdated()); 389 ASSERT_TRUE(observer1.CheckAndResetDownloadUpdated());
359 390
360 DownloadItemImpl* system_cancel = CreateDownloadItem(); 391 DownloadItemImpl* system_cancel = CreateDownloadItem();
361 download_file = AddDownloadFileToDownloadItem(system_cancel, NULL); 392 download_file = CallDownloadItemStart(system_cancel, nullptr);
362 EXPECT_CALL(*download_file, Cancel()); 393 EXPECT_CALL(*download_file, Cancel());
363 TestDownloadItemObserver observer2(system_cancel); 394 TestDownloadItemObserver observer2(system_cancel);
364 395
365 system_cancel->Cancel(false); 396 system_cancel->Cancel(false);
366 ASSERT_TRUE(observer2.CheckAndResetDownloadUpdated()); 397 ASSERT_TRUE(observer2.CheckAndResetDownloadUpdated());
367 } 398 }
368 399
369 TEST_F(DownloadItemTest, NotificationAfterComplete) { 400 TEST_F(DownloadItemTest, NotificationAfterComplete) {
370 DownloadItemImpl* item = CreateDownloadItem(); 401 DownloadItemImpl* item = CreateDownloadItem();
371 TestDownloadItemObserver observer(item); 402 TestDownloadItemObserver observer(item);
372 403 MockDownloadFile* download_file =
373 item->OnAllDataSaved(DownloadItem::kEmptyFileHash); 404 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
374 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); 405 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated());
375 406 DoDestinationComplete(item, download_file);
376 item->MarkAsComplete();
377 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); 407 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated());
378 } 408 }
379 409
380 TEST_F(DownloadItemTest, NotificationAfterDownloadedFileRemoved) { 410 TEST_F(DownloadItemTest, NotificationAfterDownloadedFileRemoved) {
381 DownloadItemImpl* item = CreateDownloadItem(); 411 DownloadItemImpl* item = CreateDownloadItem();
382 TestDownloadItemObserver observer(item); 412 TestDownloadItemObserver observer(item);
383 413
384 item->OnDownloadedFileRemoved(); 414 item->OnDownloadedFileRemoved();
385 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); 415 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated());
386 } 416 }
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
464 // Check we do correct cleanup for RESUME_MODE_INVALID interrupts. 494 // Check we do correct cleanup for RESUME_MODE_INVALID interrupts.
465 TEST_F(DownloadItemTest, UnresumableInterrupt) { 495 TEST_F(DownloadItemTest, UnresumableInterrupt) {
466 DownloadItemImpl* item = CreateDownloadItem(); 496 DownloadItemImpl* item = CreateDownloadItem();
467 TestDownloadItemObserver observer(item); 497 TestDownloadItemObserver observer(item);
468 MockDownloadFile* download_file = 498 MockDownloadFile* download_file =
469 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); 499 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
470 500
471 // Fail final rename with unresumable reason. 501 // Fail final rename with unresumable reason.
472 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _)) 502 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _))
473 .WillOnce(Return(true)); 503 .WillOnce(Return(true));
474 EXPECT_CALL(*download_file, RenameAndAnnotate(base::FilePath(kDummyPath), _)) 504 EXPECT_CALL(*download_file,
505 RenameAndAnnotate(base::FilePath(kDummyTargetPath), _))
475 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_FILE_BLOCKED, 506 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_FILE_BLOCKED,
476 base::FilePath(kDummyPath))); 507 base::FilePath()));
477 EXPECT_CALL(*download_file, Cancel()); 508 EXPECT_CALL(*download_file, Cancel());
478 509
479 // Complete download to trigger final rename. 510 // Complete download to trigger final rename.
480 item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string()); 511 item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string());
481 RunAllPendingInMessageLoops(); 512 RunAllPendingInMessageLoops();
482 513
483 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); 514 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated());
484 // Should not try to auto-resume. 515 // Should not try to auto-resume.
485 ASSERT_EQ(1, observer.interrupt_count()); 516 ASSERT_EQ(1, observer.interrupt_count());
486 ASSERT_EQ(0, observer.resume_count()); 517 ASSERT_EQ(0, observer.resume_count());
487 518
488 CleanupItem(item, nullptr, DownloadItem::INTERRUPTED); 519 CleanupItem(item, nullptr, DownloadItem::INTERRUPTED);
489 } 520 }
490 521
491 TEST_F(DownloadItemTest, LimitRestartsAfterInterrupted) { 522 TEST_F(DownloadItemTest, LimitRestartsAfterInterrupted) {
492 TestBrowserContext test_browser_context; 523 TestBrowserContext test_browser_context;
493 DownloadItemImpl* item = CreateDownloadItem(); 524 DownloadItemImpl* item = CreateDownloadItem();
494 base::WeakPtr<DownloadDestinationObserver> as_observer( 525 base::WeakPtr<DownloadDestinationObserver> as_observer(
495 item->DestinationObserverAsWeakPtr()); 526 item->DestinationObserverAsWeakPtr());
496 TestDownloadItemObserver observer(item); 527 TestDownloadItemObserver observer(item);
497 MockDownloadFile* mock_download_file(NULL); 528 MockDownloadFile* mock_download_file(nullptr);
498 scoped_ptr<DownloadFile> download_file; 529 scoped_ptr<DownloadFile> download_file;
499 MockRequestHandle* mock_request_handle(NULL); 530 MockRequestHandle* mock_request_handle(nullptr);
500 scoped_ptr<DownloadRequestHandleInterface> request_handle; 531 scoped_ptr<DownloadRequestHandleInterface> request_handle;
501 DownloadItemImplDelegate::DownloadTargetCallback callback; 532 DownloadItemImplDelegate::DownloadTargetCallback callback;
502 533
503 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _)) 534 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _))
504 .WillRepeatedly(SaveArg<1>(&callback)); 535 .WillRepeatedly(SaveArg<1>(&callback));
505 EXPECT_CALL(*mock_delegate(), GetBrowserContext()) 536 EXPECT_CALL(*mock_delegate(), GetBrowserContext())
506 .WillRepeatedly(Return(&test_browser_context)); 537 .WillRepeatedly(Return(&test_browser_context));
507 EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_, _)) 538 EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_, _))
508 .Times(DownloadItemImpl::kMaxAutoResumeAttempts); 539 .Times(DownloadItemImpl::kMaxAutoResumeAttempts);
509 for (int i = 0; i < (DownloadItemImpl::kMaxAutoResumeAttempts + 1); ++i) { 540 for (int i = 0; i < (DownloadItemImpl::kMaxAutoResumeAttempts + 1); ++i) {
510 DVLOG(20) << "Loop iteration " << i; 541 DVLOG(20) << "Loop iteration " << i;
511 542
512 mock_download_file = new NiceMock<MockDownloadFile>; 543 mock_download_file = new NiceMock<MockDownloadFile>;
513 download_file.reset(mock_download_file); 544 download_file.reset(mock_download_file);
514 mock_request_handle = new NiceMock<MockRequestHandle>; 545 mock_request_handle = new NiceMock<MockRequestHandle>;
515 request_handle.reset(mock_request_handle); 546 request_handle.reset(mock_request_handle);
516 547
517 ON_CALL(*mock_download_file, FullPath()) 548 ON_CALL(*mock_download_file, FullPath())
518 .WillByDefault(Return(base::FilePath())); 549 .WillByDefault(Return(base::FilePath()));
519 550
520 // Copied key parts of DoIntermediateRename & AddDownloadFileToDownloadItem 551 // Copied key parts of DoIntermediateRename & CallDownloadItemStart
521 // to allow for holding onto the request handle. 552 // to allow for holding onto the request handle.
522 item->Start(std::move(download_file), std::move(request_handle)); 553 item->Start(std::move(download_file), std::move(request_handle));
523 RunAllPendingInMessageLoops(); 554 RunAllPendingInMessageLoops();
555
556 base::FilePath target_path(kDummyTargetPath);
557 base::FilePath intermediate_path(kDummyIntermediatePath);
524 if (i == 0) { 558 if (i == 0) {
525 // Target determination is only done the first time through. 559 // RenameAndUniquify is only called the first time. In all the subsequent
526 base::FilePath target_path(kDummyPath); 560 // iterations, the intermediate file already has the correct name, hence
527 base::FilePath intermediate_path( 561 // no rename is necessary.
528 target_path.InsertBeforeExtensionASCII("x"));
529 EXPECT_CALL(*mock_download_file, RenameAndUniquify(intermediate_path, _)) 562 EXPECT_CALL(*mock_download_file, RenameAndUniquify(intermediate_path, _))
530 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, 563 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
531 intermediate_path)); 564 intermediate_path));
532 callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
533 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
534 RunAllPendingInMessageLoops();
535 } 565 }
566 callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
567 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
568 RunAllPendingInMessageLoops();
536 569
537 // Use a continuable interrupt. 570 // Use a continuable interrupt.
538 item->DestinationObserverAsWeakPtr()->DestinationError( 571 item->DestinationObserverAsWeakPtr()->DestinationError(
539 DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR); 572 DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR);
540 573
541 ::testing::Mock::VerifyAndClearExpectations(mock_download_file); 574 ::testing::Mock::VerifyAndClearExpectations(mock_download_file);
542 } 575 }
543 576
577 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState());
544 EXPECT_EQ(1, observer.interrupt_count()); 578 EXPECT_EQ(1, observer.interrupt_count());
545 CleanupItem(item, nullptr, DownloadItem::INTERRUPTED); 579 CleanupItem(item, nullptr, DownloadItem::INTERRUPTED);
546 } 580 }
547 581
548 // Test that resumption uses the final URL in a URL chain when resuming. 582 // Test that resumption uses the final URL in a URL chain when resuming.
549 TEST_F(DownloadItemTest, ResumeUsingFinalURL) { 583 TEST_F(DownloadItemTest, ResumeUsingFinalURL) {
550 TestBrowserContext test_browser_context; 584 TestBrowserContext test_browser_context;
551 scoped_ptr<DownloadCreateInfo> create_info(new DownloadCreateInfo); 585 scoped_ptr<DownloadCreateInfo> create_info(new DownloadCreateInfo);
552 create_info->save_info = scoped_ptr<DownloadSaveInfo>(new DownloadSaveInfo()); 586 create_info->save_info = scoped_ptr<DownloadSaveInfo>(new DownloadSaveInfo());
553 create_info->save_info->prompt_for_save_location = false; 587 create_info->save_info->prompt_for_save_location = false;
(...skipping 27 matching lines...) Expand all
581 // ResumeInterruptedDownload() being called is sufficient for verifying that 615 // ResumeInterruptedDownload() being called is sufficient for verifying that
582 // the resumption was triggered. 616 // the resumption was triggered.
583 RunAllPendingInMessageLoops(); 617 RunAllPendingInMessageLoops();
584 618
585 // The download is currently in RESUMING_INTERNAL, which maps to IN_PROGRESS. 619 // The download is currently in RESUMING_INTERNAL, which maps to IN_PROGRESS.
586 CleanupItem(item, nullptr, DownloadItem::IN_PROGRESS); 620 CleanupItem(item, nullptr, DownloadItem::IN_PROGRESS);
587 } 621 }
588 622
589 TEST_F(DownloadItemTest, NotificationAfterRemove) { 623 TEST_F(DownloadItemTest, NotificationAfterRemove) {
590 DownloadItemImpl* item = CreateDownloadItem(); 624 DownloadItemImpl* item = CreateDownloadItem();
591 MockDownloadFile* download_file = AddDownloadFileToDownloadItem(item, NULL); 625 MockDownloadFile* download_file = CallDownloadItemStart(item, nullptr);
592 EXPECT_CALL(*download_file, Cancel()); 626 EXPECT_CALL(*download_file, Cancel());
593 EXPECT_CALL(*mock_delegate(), DownloadRemoved(_)); 627 EXPECT_CALL(*mock_delegate(), DownloadRemoved(_));
594 TestDownloadItemObserver observer(item); 628 TestDownloadItemObserver observer(item);
595 629
596 item->Remove(); 630 item->Remove();
597 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); 631 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated());
598 ASSERT_TRUE(observer.download_removed()); 632 ASSERT_TRUE(observer.download_removed());
599 } 633 }
600 634
601 TEST_F(DownloadItemTest, NotificationAfterOnContentCheckCompleted) { 635 TEST_F(DownloadItemTest, NotificationAfterOnContentCheckCompleted) {
602 // Setting to NOT_DANGEROUS does not trigger a notification. 636 // Setting to NOT_DANGEROUS does not trigger a notification.
603 DownloadItemImpl* safe_item = CreateDownloadItem(); 637 DownloadItemImpl* safe_item = CreateDownloadItem();
638 MockDownloadFile* download_file =
639 DoIntermediateRename(safe_item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
604 TestDownloadItemObserver safe_observer(safe_item); 640 TestDownloadItemObserver safe_observer(safe_item);
605 641
606 safe_item->OnAllDataSaved(std::string()); 642 safe_item->OnAllDataSaved(std::string());
607 EXPECT_TRUE(safe_observer.CheckAndResetDownloadUpdated()); 643 EXPECT_TRUE(safe_observer.CheckAndResetDownloadUpdated());
608 safe_item->OnContentCheckCompleted(DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); 644 safe_item->OnContentCheckCompleted(DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
609 EXPECT_TRUE(safe_observer.CheckAndResetDownloadUpdated()); 645 EXPECT_TRUE(safe_observer.CheckAndResetDownloadUpdated());
646 CleanupItem(safe_item, download_file, DownloadItem::IN_PROGRESS);
610 647
611 // Setting to unsafe url or unsafe file should trigger a notification. 648 // Setting to unsafe url or unsafe file should trigger a notification.
612 DownloadItemImpl* unsafeurl_item = 649 DownloadItemImpl* unsafeurl_item =
613 CreateDownloadItem(); 650 CreateDownloadItem();
651 download_file =
652 DoIntermediateRename(unsafeurl_item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
614 TestDownloadItemObserver unsafeurl_observer(unsafeurl_item); 653 TestDownloadItemObserver unsafeurl_observer(unsafeurl_item);
615 654
616 unsafeurl_item->OnAllDataSaved(std::string()); 655 unsafeurl_item->OnAllDataSaved(std::string());
617 EXPECT_TRUE(unsafeurl_observer.CheckAndResetDownloadUpdated()); 656 EXPECT_TRUE(unsafeurl_observer.CheckAndResetDownloadUpdated());
618 unsafeurl_item->OnContentCheckCompleted(DOWNLOAD_DANGER_TYPE_DANGEROUS_URL); 657 unsafeurl_item->OnContentCheckCompleted(DOWNLOAD_DANGER_TYPE_DANGEROUS_URL);
619 EXPECT_TRUE(unsafeurl_observer.CheckAndResetDownloadUpdated()); 658 EXPECT_TRUE(unsafeurl_observer.CheckAndResetDownloadUpdated());
620 659
660 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(_, _))
661 .WillOnce(Return(true));
662 EXPECT_CALL(*download_file, RenameAndAnnotate(_, _));
621 unsafeurl_item->ValidateDangerousDownload(); 663 unsafeurl_item->ValidateDangerousDownload();
622 EXPECT_TRUE(unsafeurl_observer.CheckAndResetDownloadUpdated()); 664 EXPECT_TRUE(unsafeurl_observer.CheckAndResetDownloadUpdated());
665 CleanupItem(unsafeurl_item, download_file, DownloadItem::IN_PROGRESS);
623 666
624 DownloadItemImpl* unsafefile_item = 667 DownloadItemImpl* unsafefile_item =
625 CreateDownloadItem(); 668 CreateDownloadItem();
669 download_file =
670 DoIntermediateRename(unsafefile_item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
626 TestDownloadItemObserver unsafefile_observer(unsafefile_item); 671 TestDownloadItemObserver unsafefile_observer(unsafefile_item);
627 672
628 unsafefile_item->OnAllDataSaved(std::string()); 673 unsafefile_item->OnAllDataSaved(std::string());
629 EXPECT_TRUE(unsafefile_observer.CheckAndResetDownloadUpdated()); 674 EXPECT_TRUE(unsafefile_observer.CheckAndResetDownloadUpdated());
630 unsafefile_item->OnContentCheckCompleted(DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE); 675 unsafefile_item->OnContentCheckCompleted(DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE);
631 EXPECT_TRUE(unsafefile_observer.CheckAndResetDownloadUpdated()); 676 EXPECT_TRUE(unsafefile_observer.CheckAndResetDownloadUpdated());
632 677
678 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(_, _))
679 .WillOnce(Return(true));
680 EXPECT_CALL(*download_file, RenameAndAnnotate(_, _));
633 unsafefile_item->ValidateDangerousDownload(); 681 unsafefile_item->ValidateDangerousDownload();
634 EXPECT_TRUE(unsafefile_observer.CheckAndResetDownloadUpdated()); 682 EXPECT_TRUE(unsafefile_observer.CheckAndResetDownloadUpdated());
683 CleanupItem(unsafefile_item, download_file, DownloadItem::IN_PROGRESS);
635 } 684 }
636 685
637 // DownloadItemImpl::OnDownloadTargetDetermined will schedule a task to run 686 // DownloadItemImpl::OnDownloadTargetDetermined will schedule a task to run
638 // DownloadFile::Rename(). Once the rename 687 // DownloadFile::Rename(). Once the rename
639 // completes, DownloadItemImpl receives a notification with the new file 688 // completes, DownloadItemImpl receives a notification with the new file
640 // name. Check that observers are updated when the new filename is available and 689 // name. Check that observers are updated when the new filename is available and
641 // not before. 690 // not before.
642 TEST_F(DownloadItemTest, NotificationAfterOnDownloadTargetDetermined) { 691 TEST_F(DownloadItemTest, NotificationAfterOnDownloadTargetDetermined) {
643 DownloadItemImpl* item = CreateDownloadItem(); 692 DownloadItemImpl* item = CreateDownloadItem();
644 DownloadItemImplDelegate::DownloadTargetCallback callback; 693 DownloadItemImplDelegate::DownloadTargetCallback callback;
645 MockDownloadFile* download_file = 694 MockDownloadFile* download_file = CallDownloadItemStart(item, &callback);
646 AddDownloadFileToDownloadItem(item, &callback);
647 TestDownloadItemObserver observer(item); 695 TestDownloadItemObserver observer(item);
648 base::FilePath target_path(kDummyPath); 696 base::FilePath target_path(kDummyTargetPath);
649 base::FilePath intermediate_path(target_path.InsertBeforeExtensionASCII("x")); 697 base::FilePath intermediate_path(target_path.InsertBeforeExtensionASCII("x"));
650 base::FilePath new_intermediate_path( 698 base::FilePath new_intermediate_path(
651 target_path.InsertBeforeExtensionASCII("y")); 699 target_path.InsertBeforeExtensionASCII("y"));
652 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _)) 700 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _))
653 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, 701 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
654 new_intermediate_path)); 702 new_intermediate_path));
655 703
656 // Currently, a notification would be generated if the danger type is anything 704 // Currently, a notification would be generated if the danger type is anything
657 // other than NOT_DANGEROUS. 705 // other than NOT_DANGEROUS.
658 callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, 706 callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
(...skipping 27 matching lines...) Expand all
686 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); 734 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated());
687 735
688 RunAllPendingInMessageLoops(); 736 RunAllPendingInMessageLoops();
689 737
690 CleanupItem(item, mock_download_file, DownloadItem::IN_PROGRESS); 738 CleanupItem(item, mock_download_file, DownloadItem::IN_PROGRESS);
691 } 739 }
692 740
693 TEST_F(DownloadItemTest, DisplayName) { 741 TEST_F(DownloadItemTest, DisplayName) {
694 DownloadItemImpl* item = CreateDownloadItem(); 742 DownloadItemImpl* item = CreateDownloadItem();
695 DownloadItemImplDelegate::DownloadTargetCallback callback; 743 DownloadItemImplDelegate::DownloadTargetCallback callback;
696 MockDownloadFile* download_file = 744 MockDownloadFile* download_file = CallDownloadItemStart(item, &callback);
697 AddDownloadFileToDownloadItem(item, &callback); 745 base::FilePath target_path(
698 base::FilePath target_path(base::FilePath(kDummyPath).AppendASCII("foo.bar")); 746 base::FilePath(kDummyTargetPath).AppendASCII("foo.bar"));
699 base::FilePath intermediate_path(target_path.InsertBeforeExtensionASCII("x")); 747 base::FilePath intermediate_path(target_path.InsertBeforeExtensionASCII("x"));
700 EXPECT_EQ(FILE_PATH_LITERAL(""), 748 EXPECT_EQ(FILE_PATH_LITERAL(""),
701 item->GetFileNameToReportUser().value()); 749 item->GetFileNameToReportUser().value());
702 EXPECT_CALL(*download_file, RenameAndUniquify(_, _)) 750 EXPECT_CALL(*download_file, RenameAndUniquify(_, _))
703 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, 751 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
704 intermediate_path)); 752 intermediate_path));
705 callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, 753 callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
706 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path); 754 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
707 RunAllPendingInMessageLoops(); 755 RunAllPendingInMessageLoops();
708 EXPECT_EQ(FILE_PATH_LITERAL("foo.bar"), 756 EXPECT_EQ(FILE_PATH_LITERAL("foo.bar"),
(...skipping 12 matching lines...) Expand all
721 EXPECT_CALL(*mock_download_file, Initialize(_)); 769 EXPECT_CALL(*mock_download_file, Initialize(_));
722 scoped_ptr<DownloadRequestHandleInterface> request_handle( 770 scoped_ptr<DownloadRequestHandleInterface> request_handle(
723 new NiceMock<MockRequestHandle>); 771 new NiceMock<MockRequestHandle>);
724 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _)); 772 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _));
725 item->Start(std::move(download_file), std::move(request_handle)); 773 item->Start(std::move(download_file), std::move(request_handle));
726 RunAllPendingInMessageLoops(); 774 RunAllPendingInMessageLoops();
727 775
728 CleanupItem(item, mock_download_file, DownloadItem::IN_PROGRESS); 776 CleanupItem(item, mock_download_file, DownloadItem::IN_PROGRESS);
729 } 777 }
730 778
779 // Download file and the request should be cancelled as a result of download
780 // file initialization failing.
781 TEST_F(DownloadItemTest, InitDownloadFileFails) {
782 scoped_ptr<MockDownloadFile> file(new MockDownloadFile());
783 scoped_ptr<MockRequestHandle> request_handle(new MockRequestHandle());
784 EXPECT_CALL(*file, Cancel());
785 EXPECT_CALL(*request_handle, CancelRequest());
786 EXPECT_CALL(*file, Initialize(_))
787 .WillOnce(ScheduleCallbackWithParam(
788 DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED));
789
790 DownloadItemImpl* item = CreateDownloadItem();
791 item->Start(std::move(file), std::move(request_handle));
792 RunAllPendingInMessageLoops();
793
794 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState());
795 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED,
796 item->GetLastReason());
797 }
798
731 // Test that the delegate is invoked after the download file is renamed. 799 // Test that the delegate is invoked after the download file is renamed.
732 TEST_F(DownloadItemTest, CallbackAfterRename) { 800 TEST_F(DownloadItemTest, CallbackAfterRename) {
733 DownloadItemImpl* item = CreateDownloadItem(); 801 DownloadItemImpl* item = CreateDownloadItem();
734 DownloadItemImplDelegate::DownloadTargetCallback callback; 802 DownloadItemImplDelegate::DownloadTargetCallback callback;
735 MockDownloadFile* download_file = 803 MockDownloadFile* download_file = CallDownloadItemStart(item, &callback);
736 AddDownloadFileToDownloadItem(item, &callback); 804 base::FilePath final_path(
737 base::FilePath final_path(base::FilePath(kDummyPath).AppendASCII("foo.bar")); 805 base::FilePath(kDummyTargetPath).AppendASCII("foo.bar"));
738 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x")); 806 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x"));
739 base::FilePath new_intermediate_path( 807 base::FilePath new_intermediate_path(
740 final_path.InsertBeforeExtensionASCII("y")); 808 final_path.InsertBeforeExtensionASCII("y"));
741 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _)) 809 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _))
742 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, 810 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
743 new_intermediate_path)); 811 new_intermediate_path));
744 812
745 callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, 813 callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
746 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path); 814 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
747 RunAllPendingInMessageLoops(); 815 RunAllPendingInMessageLoops();
(...skipping 13 matching lines...) Expand all
761 RunAllPendingInMessageLoops(); 829 RunAllPendingInMessageLoops();
762 ::testing::Mock::VerifyAndClearExpectations(download_file); 830 ::testing::Mock::VerifyAndClearExpectations(download_file);
763 mock_delegate()->VerifyAndClearExpectations(); 831 mock_delegate()->VerifyAndClearExpectations();
764 } 832 }
765 833
766 // Test that the delegate is invoked after the download file is renamed and the 834 // Test that the delegate is invoked after the download file is renamed and the
767 // download item is in an interrupted state. 835 // download item is in an interrupted state.
768 TEST_F(DownloadItemTest, CallbackAfterInterruptedRename) { 836 TEST_F(DownloadItemTest, CallbackAfterInterruptedRename) {
769 DownloadItemImpl* item = CreateDownloadItem(); 837 DownloadItemImpl* item = CreateDownloadItem();
770 DownloadItemImplDelegate::DownloadTargetCallback callback; 838 DownloadItemImplDelegate::DownloadTargetCallback callback;
771 MockDownloadFile* download_file = 839 MockDownloadFile* download_file = CallDownloadItemStart(item, &callback);
772 AddDownloadFileToDownloadItem(item, &callback); 840 base::FilePath final_path(
773 base::FilePath final_path(base::FilePath(kDummyPath).AppendASCII("foo.bar")); 841 base::FilePath(kDummyTargetPath).AppendASCII("foo.bar"));
774 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x")); 842 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x"));
775 base::FilePath new_intermediate_path( 843 base::FilePath new_intermediate_path(
776 final_path.InsertBeforeExtensionASCII("y")); 844 final_path.InsertBeforeExtensionASCII("y"));
777 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _)) 845 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _))
778 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, 846 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED,
779 new_intermediate_path)); 847 new_intermediate_path));
780 EXPECT_CALL(*download_file, Cancel()) 848 EXPECT_CALL(*download_file, Cancel())
781 .Times(1); 849 .Times(1);
782 850
783 callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, 851 callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
(...skipping 23 matching lines...) Expand all
807 item->Cancel(true); 875 item->Cancel(true);
808 EXPECT_EQ(DownloadItem::CANCELLED, item->GetState()); 876 EXPECT_EQ(DownloadItem::CANCELLED, item->GetState());
809 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_USER_CANCELED, item->GetLastReason()); 877 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_USER_CANCELED, item->GetLastReason());
810 } 878 }
811 879
812 // Destination errors that occur before the intermediate rename shouldn't cause 880 // Destination errors that occur before the intermediate rename shouldn't cause
813 // the download to be marked as interrupted until after the intermediate rename. 881 // the download to be marked as interrupted until after the intermediate rename.
814 TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Restart) { 882 TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Restart) {
815 DownloadItemImpl* item = CreateDownloadItem(); 883 DownloadItemImpl* item = CreateDownloadItem();
816 DownloadItemImplDelegate::DownloadTargetCallback callback; 884 DownloadItemImplDelegate::DownloadTargetCallback callback;
817 MockDownloadFile* download_file = 885 MockDownloadFile* download_file = CallDownloadItemStart(item, &callback);
818 AddDownloadFileToDownloadItem(item, &callback);
819 item->DestinationObserverAsWeakPtr()->DestinationError( 886 item->DestinationObserverAsWeakPtr()->DestinationError(
820 DOWNLOAD_INTERRUPT_REASON_FILE_FAILED); 887 DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
821 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); 888 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
822 889
823 base::FilePath final_path(base::FilePath(kDummyPath).AppendASCII("foo.bar")); 890 base::FilePath final_path(
891 base::FilePath(kDummyTargetPath).AppendASCII("foo.bar"));
824 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x")); 892 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x"));
825 base::FilePath new_intermediate_path( 893 base::FilePath new_intermediate_path(
826 final_path.InsertBeforeExtensionASCII("y")); 894 final_path.InsertBeforeExtensionASCII("y"));
827 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _)) 895 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _))
828 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, 896 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
829 new_intermediate_path)); 897 new_intermediate_path));
830 EXPECT_CALL(*download_file, Cancel()) 898 EXPECT_CALL(*download_file, Cancel())
831 .Times(1); 899 .Times(1);
832 900
833 callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, 901 callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
834 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path); 902 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
835 RunAllPendingInMessageLoops(); 903 RunAllPendingInMessageLoops();
836 // All the callbacks should have happened by now. 904 // All the callbacks should have happened by now.
837 ::testing::Mock::VerifyAndClearExpectations(download_file); 905 ::testing::Mock::VerifyAndClearExpectations(download_file);
838 mock_delegate()->VerifyAndClearExpectations(); 906 mock_delegate()->VerifyAndClearExpectations();
839 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); 907 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState());
840 EXPECT_TRUE(item->GetFullPath().empty()); 908 EXPECT_TRUE(item->GetFullPath().empty());
841 EXPECT_EQ(final_path, item->GetTargetFilePath()); 909 EXPECT_EQ(final_path, item->GetTargetFilePath());
842 } 910 }
843 911
844 // As above. But if the download can be resumed by continuing, then the 912 // 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 913 // intermediate path should be retained when the download is interrupted after
846 // the intermediate rename succeeds. 914 // the intermediate rename succeeds.
847 TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Continue) { 915 TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Continue) {
848 DownloadItemImpl* item = CreateDownloadItem(); 916 DownloadItemImpl* item = CreateDownloadItem();
849 DownloadItemImplDelegate::DownloadTargetCallback callback; 917 DownloadItemImplDelegate::DownloadTargetCallback callback;
850 MockDownloadFile* download_file = 918 MockDownloadFile* download_file = CallDownloadItemStart(item, &callback);
851 AddDownloadFileToDownloadItem(item, &callback);
852 item->DestinationObserverAsWeakPtr()->DestinationError( 919 item->DestinationObserverAsWeakPtr()->DestinationError(
853 DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED); 920 DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED);
854 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); 921 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
855 922
856 base::FilePath final_path(base::FilePath(kDummyPath).AppendASCII("foo.bar")); 923 base::FilePath final_path(
924 base::FilePath(kDummyTargetPath).AppendASCII("foo.bar"));
857 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x")); 925 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x"));
858 base::FilePath new_intermediate_path( 926 base::FilePath new_intermediate_path(
859 final_path.InsertBeforeExtensionASCII("y")); 927 final_path.InsertBeforeExtensionASCII("y"));
860 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _)) 928 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _))
861 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, 929 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
862 new_intermediate_path)); 930 new_intermediate_path));
863 EXPECT_CALL(*download_file, FullPath()) 931 EXPECT_CALL(*download_file, FullPath())
864 .WillOnce(Return(base::FilePath(new_intermediate_path))); 932 .WillOnce(Return(base::FilePath(new_intermediate_path)));
865 EXPECT_CALL(*download_file, Detach()); 933 EXPECT_CALL(*download_file, Detach());
866 934
867 callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, 935 callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
868 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path); 936 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
869 RunAllPendingInMessageLoops(); 937 RunAllPendingInMessageLoops();
870 // All the callbacks should have happened by now. 938 // All the callbacks should have happened by now.
871 ::testing::Mock::VerifyAndClearExpectations(download_file); 939 ::testing::Mock::VerifyAndClearExpectations(download_file);
872 mock_delegate()->VerifyAndClearExpectations(); 940 mock_delegate()->VerifyAndClearExpectations();
873 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); 941 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState());
874 EXPECT_EQ(new_intermediate_path, item->GetFullPath()); 942 EXPECT_EQ(new_intermediate_path, item->GetFullPath());
875 EXPECT_EQ(final_path, item->GetTargetFilePath()); 943 EXPECT_EQ(final_path, item->GetTargetFilePath());
876 } 944 }
877 945
878 // As above. If the intermediate rename fails, then the interrupt reason should 946 // 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. 947 // be set to the destination error and the intermediate path should be empty.
880 TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Failed) { 948 TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Failed) {
881 DownloadItemImpl* item = CreateDownloadItem(); 949 DownloadItemImpl* item = CreateDownloadItem();
882 DownloadItemImplDelegate::DownloadTargetCallback callback; 950 DownloadItemImplDelegate::DownloadTargetCallback callback;
883 MockDownloadFile* download_file = 951 MockDownloadFile* download_file = CallDownloadItemStart(item, &callback);
884 AddDownloadFileToDownloadItem(item, &callback);
885 item->DestinationObserverAsWeakPtr()->DestinationError( 952 item->DestinationObserverAsWeakPtr()->DestinationError(
886 DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED); 953 DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED);
887 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); 954 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
888 955
889 base::FilePath final_path(base::FilePath(kDummyPath).AppendASCII("foo.bar")); 956 base::FilePath final_path(
957 base::FilePath(kDummyTargetPath).AppendASCII("foo.bar"));
890 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x")); 958 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x"));
891 base::FilePath new_intermediate_path( 959 base::FilePath new_intermediate_path(
892 final_path.InsertBeforeExtensionASCII("y")); 960 final_path.InsertBeforeExtensionASCII("y"));
893 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _)) 961 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _))
894 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, 962 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED,
895 new_intermediate_path)); 963 new_intermediate_path));
896 EXPECT_CALL(*download_file, Cancel()) 964 EXPECT_CALL(*download_file, Cancel())
897 .Times(1); 965 .Times(1);
898 966
899 callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, 967 callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
900 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path); 968 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
901 RunAllPendingInMessageLoops(); 969 RunAllPendingInMessageLoops();
902 // All the callbacks should have happened by now. 970 // All the callbacks should have happened by now.
903 ::testing::Mock::VerifyAndClearExpectations(download_file); 971 ::testing::Mock::VerifyAndClearExpectations(download_file);
904 mock_delegate()->VerifyAndClearExpectations(); 972 mock_delegate()->VerifyAndClearExpectations();
905 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); 973 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState());
906 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, item->GetLastReason()); 974 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, item->GetLastReason());
907 EXPECT_TRUE(item->GetFullPath().empty()); 975 EXPECT_TRUE(item->GetFullPath().empty());
908 EXPECT_EQ(final_path, item->GetTargetFilePath()); 976 EXPECT_EQ(final_path, item->GetTargetFilePath());
909 } 977 }
910 978
911 TEST_F(DownloadItemTest, Canceled) { 979 TEST_F(DownloadItemTest, Canceled) {
912 DownloadItemImpl* item = CreateDownloadItem(); 980 DownloadItemImpl* item = CreateDownloadItem();
913 MockDownloadFile* download_file = AddDownloadFileToDownloadItem(item, NULL); 981 MockDownloadFile* download_file = CallDownloadItemStart(item, nullptr);
914 982
915 // Confirm cancel sets state properly. 983 // Confirm cancel sets state properly.
916 EXPECT_CALL(*download_file, Cancel()); 984 EXPECT_CALL(*download_file, Cancel());
917 item->Cancel(true); 985 item->Cancel(true);
918 EXPECT_EQ(DownloadItem::CANCELLED, item->GetState()); 986 EXPECT_EQ(DownloadItem::CANCELLED, item->GetState());
919 } 987 }
920 988
921 TEST_F(DownloadItemTest, FileRemoved) { 989 TEST_F(DownloadItemTest, FileRemoved) {
922 DownloadItemImpl* item = CreateDownloadItem(); 990 DownloadItemImpl* item = CreateDownloadItem();
923 991
924 EXPECT_FALSE(item->GetFileExternallyRemoved()); 992 EXPECT_FALSE(item->GetFileExternallyRemoved());
925 item->OnDownloadedFileRemoved(); 993 item->OnDownloadedFileRemoved();
926 EXPECT_TRUE(item->GetFileExternallyRemoved()); 994 EXPECT_TRUE(item->GetFileExternallyRemoved());
927 } 995 }
928 996
929 TEST_F(DownloadItemTest, DestinationUpdate) { 997 TEST_F(DownloadItemTest, DestinationUpdate) {
930 DownloadItemImpl* item = CreateDownloadItem(); 998 DownloadItemImpl* item = CreateDownloadItem();
999 MockDownloadFile* file =
1000 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
931 base::WeakPtr<DownloadDestinationObserver> as_observer( 1001 base::WeakPtr<DownloadDestinationObserver> as_observer(
932 item->DestinationObserverAsWeakPtr()); 1002 item->DestinationObserverAsWeakPtr());
933 TestDownloadItemObserver observer(item); 1003 TestDownloadItemObserver observer(item);
934 1004
935 EXPECT_EQ(0l, item->CurrentSpeed()); 1005 EXPECT_EQ(0l, item->CurrentSpeed());
936 EXPECT_EQ("", item->GetHashState()); 1006 EXPECT_EQ("", item->GetHashState());
937 EXPECT_EQ(0l, item->GetReceivedBytes()); 1007 EXPECT_EQ(0l, item->GetReceivedBytes());
938 EXPECT_EQ(0l, item->GetTotalBytes()); 1008 EXPECT_EQ(0l, item->GetTotalBytes());
939 EXPECT_FALSE(observer.CheckAndResetDownloadUpdated()); 1009 EXPECT_FALSE(observer.CheckAndResetDownloadUpdated());
940 item->SetTotalBytes(100l); 1010 item->SetTotalBytes(100l);
941 EXPECT_EQ(100l, item->GetTotalBytes()); 1011 EXPECT_EQ(100l, item->GetTotalBytes());
942 1012
943 as_observer->DestinationUpdate(10, 20, "deadbeef"); 1013 as_observer->DestinationUpdate(10, 20, "deadbeef");
944 EXPECT_EQ(20l, item->CurrentSpeed()); 1014 EXPECT_EQ(20l, item->CurrentSpeed());
945 EXPECT_EQ("deadbeef", item->GetHashState()); 1015 EXPECT_EQ("deadbeef", item->GetHashState());
946 EXPECT_EQ(10l, item->GetReceivedBytes()); 1016 EXPECT_EQ(10l, item->GetReceivedBytes());
947 EXPECT_EQ(100l, item->GetTotalBytes()); 1017 EXPECT_EQ(100l, item->GetTotalBytes());
948 EXPECT_TRUE(observer.CheckAndResetDownloadUpdated()); 1018 EXPECT_TRUE(observer.CheckAndResetDownloadUpdated());
949 1019
950 as_observer->DestinationUpdate(200, 20, "livebeef"); 1020 as_observer->DestinationUpdate(200, 20, "livebeef");
951 EXPECT_EQ(20l, item->CurrentSpeed()); 1021 EXPECT_EQ(20l, item->CurrentSpeed());
952 EXPECT_EQ("livebeef", item->GetHashState()); 1022 EXPECT_EQ("livebeef", item->GetHashState());
953 EXPECT_EQ(200l, item->GetReceivedBytes()); 1023 EXPECT_EQ(200l, item->GetReceivedBytes());
954 EXPECT_EQ(0l, item->GetTotalBytes()); 1024 EXPECT_EQ(0l, item->GetTotalBytes());
955 EXPECT_TRUE(observer.CheckAndResetDownloadUpdated()); 1025 EXPECT_TRUE(observer.CheckAndResetDownloadUpdated());
1026
1027 CleanupItem(item, file, DownloadItem::IN_PROGRESS);
956 } 1028 }
957 1029
958 TEST_F(DownloadItemTest, DestinationError) { 1030 TEST_F(DownloadItemTest, DestinationError) {
959 DownloadItemImpl* item = CreateDownloadItem(); 1031 DownloadItemImpl* item = CreateDownloadItem();
960 MockDownloadFile* download_file = 1032 MockDownloadFile* download_file =
961 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); 1033 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
962 base::WeakPtr<DownloadDestinationObserver> as_observer( 1034 base::WeakPtr<DownloadDestinationObserver> as_observer(
963 item->DestinationObserverAsWeakPtr()); 1035 item->DestinationObserverAsWeakPtr());
964 TestDownloadItemObserver observer(item); 1036 TestDownloadItemObserver observer(item);
965 1037
966 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); 1038 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
967 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, item->GetLastReason()); 1039 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, item->GetLastReason());
968 EXPECT_FALSE(observer.CheckAndResetDownloadUpdated()); 1040 EXPECT_FALSE(observer.CheckAndResetDownloadUpdated());
969 1041
970 EXPECT_CALL(*download_file, Cancel()); 1042 EXPECT_CALL(*download_file, Cancel());
971 as_observer->DestinationError( 1043 as_observer->DestinationError(
972 DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED); 1044 DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED);
973 mock_delegate()->VerifyAndClearExpectations(); 1045 mock_delegate()->VerifyAndClearExpectations();
974 EXPECT_TRUE(observer.CheckAndResetDownloadUpdated()); 1046 EXPECT_TRUE(observer.CheckAndResetDownloadUpdated());
975 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); 1047 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState());
976 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED, 1048 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED,
977 item->GetLastReason()); 1049 item->GetLastReason());
978 } 1050 }
979 1051
980 TEST_F(DownloadItemTest, DestinationCompleted) { 1052 TEST_F(DownloadItemTest, DestinationCompleted) {
981 DownloadItemImpl* item = CreateDownloadItem(); 1053 DownloadItemImpl* item = CreateDownloadItem();
1054 MockDownloadFile* download_file = CallDownloadItemStart(item, nullptr);
982 base::WeakPtr<DownloadDestinationObserver> as_observer( 1055 base::WeakPtr<DownloadDestinationObserver> as_observer(
983 item->DestinationObserverAsWeakPtr()); 1056 item->DestinationObserverAsWeakPtr());
984 TestDownloadItemObserver observer(item); 1057 TestDownloadItemObserver observer(item);
985 1058
986 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); 1059 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
987 EXPECT_EQ("", item->GetHash()); 1060 EXPECT_EQ("", item->GetHash());
988 EXPECT_EQ("", item->GetHashState()); 1061 EXPECT_EQ("", item->GetHashState());
989 EXPECT_FALSE(item->AllDataSaved()); 1062 EXPECT_FALSE(item->AllDataSaved());
990 EXPECT_FALSE(observer.CheckAndResetDownloadUpdated()); 1063 EXPECT_FALSE(observer.CheckAndResetDownloadUpdated());
991 1064
992 as_observer->DestinationUpdate(10, 20, "deadbeef"); 1065 as_observer->DestinationUpdate(10, 20, "deadbeef");
993 EXPECT_TRUE(observer.CheckAndResetDownloadUpdated()); 1066 EXPECT_TRUE(observer.CheckAndResetDownloadUpdated());
994 EXPECT_FALSE(observer.CheckAndResetDownloadUpdated()); // Confirm reset. 1067 EXPECT_FALSE(observer.CheckAndResetDownloadUpdated()); // Confirm reset.
995 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); 1068 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
996 EXPECT_EQ("", item->GetHash()); 1069 EXPECT_EQ("", item->GetHash());
997 EXPECT_EQ("deadbeef", item->GetHashState()); 1070 EXPECT_EQ("deadbeef", item->GetHashState());
998 EXPECT_FALSE(item->AllDataSaved()); 1071 EXPECT_FALSE(item->AllDataSaved());
999 1072
1000 as_observer->DestinationCompleted("livebeef"); 1073 as_observer->DestinationCompleted("livebeef");
1001 mock_delegate()->VerifyAndClearExpectations(); 1074 mock_delegate()->VerifyAndClearExpectations();
1002 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); 1075 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
1003 EXPECT_TRUE(observer.CheckAndResetDownloadUpdated()); 1076 EXPECT_TRUE(observer.CheckAndResetDownloadUpdated());
1004 EXPECT_EQ("livebeef", item->GetHash()); 1077 EXPECT_EQ("livebeef", item->GetHash());
1005 EXPECT_EQ("", item->GetHashState()); 1078 EXPECT_EQ("", item->GetHashState());
1006 EXPECT_TRUE(item->AllDataSaved()); 1079 EXPECT_TRUE(item->AllDataSaved());
1080
1081 // Even though the DownloadItem receives a DestinationCompleted() event,
1082 // target determination hasn't completed, hence the download item is stuck in
1083 // TARGET_PENDING.
1084 CleanupItem(item, download_file, DownloadItem::IN_PROGRESS);
1007 } 1085 }
1008 1086
1009 TEST_F(DownloadItemTest, EnabledActionsForNormalDownload) { 1087 TEST_F(DownloadItemTest, EnabledActionsForNormalDownload) {
1010 DownloadItemImpl* item = CreateDownloadItem(); 1088 DownloadItemImpl* item = CreateDownloadItem();
1011 MockDownloadFile* download_file = 1089 MockDownloadFile* download_file =
1012 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); 1090 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
1013 1091
1014 // InProgress 1092 // InProgress
1015 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); 1093 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
1016 ASSERT_FALSE(item->GetTargetFilePath().empty()); 1094 ASSERT_FALSE(item->GetTargetFilePath().empty());
1017 EXPECT_TRUE(item->CanShowInFolder()); 1095 EXPECT_TRUE(item->CanShowInFolder());
1018 EXPECT_TRUE(item->CanOpenDownload()); 1096 EXPECT_TRUE(item->CanOpenDownload());
1019 1097
1020 // Complete 1098 // Complete
1021 EXPECT_CALL(*download_file, RenameAndAnnotate(_, _)) 1099 EXPECT_CALL(*download_file, RenameAndAnnotate(_, _))
1022 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, 1100 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
1023 base::FilePath(kDummyPath))); 1101 base::FilePath(kDummyTargetPath)));
1024 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _)) 1102 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _))
1025 .WillOnce(Return(true)); 1103 .WillOnce(Return(true));
1026 EXPECT_CALL(*download_file, FullPath()) 1104 EXPECT_CALL(*download_file, FullPath())
1027 .WillOnce(Return(base::FilePath())); 1105 .WillOnce(Return(base::FilePath()));
1028 EXPECT_CALL(*download_file, Detach()); 1106 EXPECT_CALL(*download_file, Detach());
1029 item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string()); 1107 item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string());
1030 RunAllPendingInMessageLoops(); 1108 RunAllPendingInMessageLoops();
1031 1109
1032 ASSERT_EQ(DownloadItem::COMPLETE, item->GetState()); 1110 ASSERT_EQ(DownloadItem::COMPLETE, item->GetState());
1033 EXPECT_TRUE(item->CanShowInFolder()); 1111 EXPECT_TRUE(item->CanShowInFolder());
(...skipping 11 matching lines...) Expand all
1045 ASSERT_FALSE(item->GetTargetFilePath().empty()); 1123 ASSERT_FALSE(item->GetTargetFilePath().empty());
1046 ASSERT_TRUE(item->IsTemporary()); 1124 ASSERT_TRUE(item->IsTemporary());
1047 EXPECT_FALSE(item->CanShowInFolder()); 1125 EXPECT_FALSE(item->CanShowInFolder());
1048 EXPECT_FALSE(item->CanOpenDownload()); 1126 EXPECT_FALSE(item->CanOpenDownload());
1049 1127
1050 // Complete Temporary 1128 // Complete Temporary
1051 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _)) 1129 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _))
1052 .WillOnce(Return(true)); 1130 .WillOnce(Return(true));
1053 EXPECT_CALL(*download_file, RenameAndAnnotate(_, _)) 1131 EXPECT_CALL(*download_file, RenameAndAnnotate(_, _))
1054 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, 1132 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
1055 base::FilePath(kDummyPath))); 1133 base::FilePath(kDummyTargetPath)));
1056 EXPECT_CALL(*download_file, FullPath()) 1134 EXPECT_CALL(*download_file, FullPath())
1057 .WillOnce(Return(base::FilePath())); 1135 .WillOnce(Return(base::FilePath()));
1058 EXPECT_CALL(*download_file, Detach()); 1136 EXPECT_CALL(*download_file, Detach());
1059 item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string()); 1137 item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string());
1060 RunAllPendingInMessageLoops(); 1138 RunAllPendingInMessageLoops();
1061 1139
1062 ASSERT_EQ(DownloadItem::COMPLETE, item->GetState()); 1140 ASSERT_EQ(DownloadItem::COMPLETE, item->GetState());
1063 EXPECT_FALSE(item->CanShowInFolder()); 1141 EXPECT_FALSE(item->CanShowInFolder());
1064 EXPECT_FALSE(item->CanOpenDownload()); 1142 EXPECT_FALSE(item->CanOpenDownload());
1065 } 1143 }
1066 1144
1067 TEST_F(DownloadItemTest, EnabledActionsForInterruptedDownload) { 1145 TEST_F(DownloadItemTest, EnabledActionsForInterruptedDownload) {
1068 DownloadItemImpl* item = CreateDownloadItem(); 1146 DownloadItemImpl* item = CreateDownloadItem();
1069 MockDownloadFile* download_file = 1147 MockDownloadFile* download_file =
1070 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); 1148 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
1071 1149
1072 EXPECT_CALL(*download_file, Cancel()); 1150 EXPECT_CALL(*download_file, Cancel());
1073 item->DestinationObserverAsWeakPtr()->DestinationError( 1151 item->DestinationObserverAsWeakPtr()->DestinationError(
1074 DOWNLOAD_INTERRUPT_REASON_FILE_FAILED); 1152 DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
1075 RunAllPendingInMessageLoops(); 1153 RunAllPendingInMessageLoops();
1076 1154
1077 ASSERT_EQ(DownloadItem::INTERRUPTED, item->GetState()); 1155 ASSERT_EQ(DownloadItem::INTERRUPTED, item->GetState());
1078 ASSERT_FALSE(item->GetTargetFilePath().empty()); 1156 ASSERT_FALSE(item->GetTargetFilePath().empty());
1079 EXPECT_FALSE(item->CanShowInFolder()); 1157 EXPECT_FALSE(item->CanShowInFolder());
1080 EXPECT_FALSE(item->CanOpenDownload()); 1158 EXPECT_TRUE(item->CanOpenDownload());
1081 } 1159 }
1082 1160
1083 TEST_F(DownloadItemTest, EnabledActionsForCancelledDownload) { 1161 TEST_F(DownloadItemTest, EnabledActionsForCancelledDownload) {
1084 DownloadItemImpl* item = CreateDownloadItem(); 1162 DownloadItemImpl* item = CreateDownloadItem();
1085 MockDownloadFile* download_file = 1163 MockDownloadFile* download_file =
1086 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); 1164 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
1087 1165
1088 EXPECT_CALL(*download_file, Cancel()); 1166 EXPECT_CALL(*download_file, Cancel());
1089 item->Cancel(true); 1167 item->Cancel(true);
1090 RunAllPendingInMessageLoops(); 1168 RunAllPendingInMessageLoops();
(...skipping 14 matching lines...) Expand all
1105 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); 1183 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
1106 1184
1107 // Drive the delegate interaction. 1185 // Drive the delegate interaction.
1108 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _)) 1186 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _))
1109 .WillOnce(Return(true)); 1187 .WillOnce(Return(true));
1110 item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string()); 1188 item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string());
1111 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); 1189 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
1112 EXPECT_FALSE(item->IsDangerous()); 1190 EXPECT_FALSE(item->IsDangerous());
1113 1191
1114 // Make sure the download can complete. 1192 // Make sure the download can complete.
1115 EXPECT_CALL(*download_file, RenameAndAnnotate(base::FilePath(kDummyPath), _)) 1193 EXPECT_CALL(*download_file,
1194 RenameAndAnnotate(base::FilePath(kDummyTargetPath), _))
1116 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, 1195 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
1117 base::FilePath(kDummyPath))); 1196 base::FilePath(kDummyTargetPath)));
1118 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _)) 1197 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _))
1119 .WillOnce(Return(true)); 1198 .WillOnce(Return(true));
1120 EXPECT_CALL(*download_file, FullPath()) 1199 EXPECT_CALL(*download_file, FullPath())
1121 .WillOnce(Return(base::FilePath())); 1200 .WillOnce(Return(base::FilePath()));
1122 EXPECT_CALL(*download_file, Detach()); 1201 EXPECT_CALL(*download_file, Detach());
1123 RunAllPendingInMessageLoops(); 1202 RunAllPendingInMessageLoops();
1124 EXPECT_EQ(DownloadItem::COMPLETE, item->GetState()); 1203 EXPECT_EQ(DownloadItem::COMPLETE, item->GetState());
1125 } 1204 }
1126 1205
1127 // Just delaying completion. 1206 // Just delaying completion.
(...skipping 15 matching lines...) Expand all
1143 ASSERT_FALSE(delegate_callback.is_null()); 1222 ASSERT_FALSE(delegate_callback.is_null());
1144 copy_delegate_callback = delegate_callback; 1223 copy_delegate_callback = delegate_callback;
1145 delegate_callback.Reset(); 1224 delegate_callback.Reset();
1146 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); 1225 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
1147 copy_delegate_callback.Run(); 1226 copy_delegate_callback.Run();
1148 ASSERT_TRUE(delegate_callback.is_null()); 1227 ASSERT_TRUE(delegate_callback.is_null());
1149 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); 1228 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
1150 EXPECT_FALSE(item->IsDangerous()); 1229 EXPECT_FALSE(item->IsDangerous());
1151 1230
1152 // Make sure the download can complete. 1231 // Make sure the download can complete.
1153 EXPECT_CALL(*download_file, RenameAndAnnotate(base::FilePath(kDummyPath), _)) 1232 EXPECT_CALL(*download_file,
1233 RenameAndAnnotate(base::FilePath(kDummyTargetPath), _))
1154 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, 1234 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
1155 base::FilePath(kDummyPath))); 1235 base::FilePath(kDummyTargetPath)));
1156 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _)) 1236 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _))
1157 .WillOnce(Return(true)); 1237 .WillOnce(Return(true));
1158 EXPECT_CALL(*download_file, FullPath()) 1238 EXPECT_CALL(*download_file, FullPath())
1159 .WillOnce(Return(base::FilePath())); 1239 .WillOnce(Return(base::FilePath()));
1160 EXPECT_CALL(*download_file, Detach()); 1240 EXPECT_CALL(*download_file, Detach());
1161 RunAllPendingInMessageLoops(); 1241 RunAllPendingInMessageLoops();
1162 EXPECT_EQ(DownloadItem::COMPLETE, item->GetState()); 1242 EXPECT_EQ(DownloadItem::COMPLETE, item->GetState());
1163 } 1243 }
1164 1244
1165 // Delay and set danger. 1245 // Delay and set danger.
(...skipping 18 matching lines...) Expand all
1184 EXPECT_FALSE(item->IsDangerous()); 1264 EXPECT_FALSE(item->IsDangerous());
1185 item->OnContentCheckCompleted( 1265 item->OnContentCheckCompleted(
1186 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE); 1266 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE);
1187 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); 1267 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
1188 copy_delegate_callback.Run(); 1268 copy_delegate_callback.Run();
1189 ASSERT_TRUE(delegate_callback.is_null()); 1269 ASSERT_TRUE(delegate_callback.is_null());
1190 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); 1270 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
1191 EXPECT_TRUE(item->IsDangerous()); 1271 EXPECT_TRUE(item->IsDangerous());
1192 1272
1193 // Make sure the download doesn't complete until we've validated it. 1273 // Make sure the download doesn't complete until we've validated it.
1194 EXPECT_CALL(*download_file, RenameAndAnnotate(base::FilePath(kDummyPath), _)) 1274 EXPECT_CALL(*download_file,
1275 RenameAndAnnotate(base::FilePath(kDummyTargetPath), _))
1195 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, 1276 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
1196 base::FilePath(kDummyPath))); 1277 base::FilePath(kDummyTargetPath)));
1197 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _)) 1278 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _))
1198 .WillOnce(Return(true)); 1279 .WillOnce(Return(true));
1199 EXPECT_CALL(*download_file, FullPath()) 1280 EXPECT_CALL(*download_file, FullPath())
1200 .WillOnce(Return(base::FilePath())); 1281 .WillOnce(Return(base::FilePath()));
1201 EXPECT_CALL(*download_file, Detach()); 1282 EXPECT_CALL(*download_file, Detach());
1202 RunAllPendingInMessageLoops(); 1283 RunAllPendingInMessageLoops();
1203 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); 1284 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
1204 EXPECT_TRUE(item->IsDangerous()); 1285 EXPECT_TRUE(item->IsDangerous());
1205 1286
1206 item->ValidateDangerousDownload(); 1287 item->ValidateDangerousDownload();
(...skipping 28 matching lines...) Expand all
1235 ASSERT_FALSE(delegate_callback.is_null()); 1316 ASSERT_FALSE(delegate_callback.is_null());
1236 copy_delegate_callback = delegate_callback; 1317 copy_delegate_callback = delegate_callback;
1237 delegate_callback.Reset(); 1318 delegate_callback.Reset();
1238 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); 1319 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
1239 copy_delegate_callback.Run(); 1320 copy_delegate_callback.Run();
1240 ASSERT_TRUE(delegate_callback.is_null()); 1321 ASSERT_TRUE(delegate_callback.is_null());
1241 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); 1322 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
1242 EXPECT_FALSE(item->IsDangerous()); 1323 EXPECT_FALSE(item->IsDangerous());
1243 1324
1244 // Make sure the download can complete. 1325 // Make sure the download can complete.
1245 EXPECT_CALL(*download_file, RenameAndAnnotate(base::FilePath(kDummyPath), _)) 1326 EXPECT_CALL(*download_file,
1327 RenameAndAnnotate(base::FilePath(kDummyTargetPath), _))
1246 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, 1328 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE,
1247 base::FilePath(kDummyPath))); 1329 base::FilePath(kDummyTargetPath)));
1248 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _)) 1330 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _))
1249 .WillOnce(Return(true)); 1331 .WillOnce(Return(true));
1250 EXPECT_CALL(*download_file, FullPath()) 1332 EXPECT_CALL(*download_file, FullPath())
1251 .WillOnce(Return(base::FilePath())); 1333 .WillOnce(Return(base::FilePath()));
1252 EXPECT_CALL(*download_file, Detach()); 1334 EXPECT_CALL(*download_file, Detach());
1253 RunAllPendingInMessageLoops(); 1335 RunAllPendingInMessageLoops();
1254 EXPECT_EQ(DownloadItem::COMPLETE, item->GetState()); 1336 EXPECT_EQ(DownloadItem::COMPLETE, item->GetState());
1255 } 1337 }
1256 1338
1257 TEST_F(DownloadItemTest, StealDangerousDownload) { 1339 TEST_F(DownloadItemTest, StealDangerousDownload) {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1312 EXPECT_CALL(*mock_delegate(), DownloadRemoved(_)); 1394 EXPECT_CALL(*mock_delegate(), DownloadRemoved(_));
1313 base::WeakPtrFactory<DownloadItemTest> weak_ptr_factory(this); 1395 base::WeakPtrFactory<DownloadItemTest> weak_ptr_factory(this);
1314 item->StealDangerousDownload( 1396 item->StealDangerousDownload(
1315 base::Bind(&DownloadItemTest::OnDownloadFileAcquired, 1397 base::Bind(&DownloadItemTest::OnDownloadFileAcquired,
1316 weak_ptr_factory.GetWeakPtr(), 1398 weak_ptr_factory.GetWeakPtr(),
1317 base::Unretained(&returned_path))); 1399 base::Unretained(&returned_path)));
1318 RunAllPendingInMessageLoops(); 1400 RunAllPendingInMessageLoops();
1319 EXPECT_TRUE(returned_path.empty()); 1401 EXPECT_TRUE(returned_path.empty());
1320 } 1402 }
1321 1403
1404 namespace {
1405
1406 // The DownloadItemDestinationUpdateRaceTest fixture (defined below) is used to
1407 // test for race conditions between download destination events received via the
1408 // DownloadDestinationObserver interface, and the target determination logic.
1409 //
1410 // The general control flow for DownloadItemImpl looks like this:
1411 //
1412 // * Start() called, which in turn calls DownloadFile::Initialize().
1413 //
1414 // Even though OnDownloadFileInitialized hasn't been called, there could now
1415 // be destination observer calls queued prior to the task that calls
1416 // OnDownloadFileInitialized. Let's call this point in the workflow "A".
1417 //
1418 // * DownloadItemImpl::OnDownloadFileInitialized() called.
1419 //
1420 // * Assuming the result is successful, DII now invokes the delegate's
1421 // DetermineDownloadTarget method.
1422 //
1423 // At this point DonwnloadFile acts as the source of
1424 // DownloadDestinationObserver events, and may invoke callbacks. Let's call
1425 // this point in the workflow "B".
1426 //
1427 // * DII::OnDownloadTargetDetermined() invoked after delegate is done with
1428 // target determination.
1429 //
1430 // * DII attempts to rename the DownloadFile to its intermediate name.
1431 //
1432 // More DownloadDestinationObserver events can happen here. Let's call this
1433 // point in the workflow "C".
1434 //
1435 // * DII::OnDownloadRenamedToIntermediateName() invoked. Assuming all went well,
1436 // DII is now in IN_PROGRESS state.
1437 //
1438 // More DownloadDestinationObserver events can happen here. Let's call this
1439 // point in the workflow "D".
1440 //
1441 // The DownloadItemDestinationUpdateRaceTest works by generating various
1442 // combinations of DownloadDestinationObserver events that might occur at the
1443 // points "A", "B", "C", and "D" above. Each test in this suite cranks a
1444 // DownloadItemImpl through the states listed above and invokes the events
1445 // assigned to each position.
1446
1447 // This type of callback represents a call to a DownloadDestinationObserver
1448 // method that's missing the DownloadDestinationObserver object. Currying this
1449 // way allows us to bind a call prior to constructing the object on which the
1450 // method would be invoked. This is necessary since we are going to construct
1451 // various permutations of observer calls that will then be applied to a
1452 // DownloadItem in a state as yet undetermined.
1453 using CurriedObservation =
1454 base::Callback<void(base::WeakPtr<DownloadDestinationObserver>)>;
1455
1456 // A list of observations that are to be made during some event in the
1457 // DownloadItemImpl control flow. Ordering of the observations is significant.
1458 using ObservationList = std::deque<CurriedObservation>;
1459
1460 // An ordered list of events.
1461 //
1462 // An "event" in this context refers to some stage in the DownloadItemImpl's
1463 // workflow described as "A", "B", "C", or "D" above. An EventList is expected
1464 // to always contains kEventCount events.
1465 using EventList = std::deque<ObservationList>;
1466
1467 // Number of events in an EventList. This is always 4 for now as described
1468 // above.
1469 const int kEventCount = 4;
1470
1471 // The following functions help us with currying the calls to
1472 // DownloadDestinationObserver. If std::bind was allowed along with
1473 // std::placeholders, it is possible to avoid these functions, but currently
1474 // Chromium doesn't allow using std::bind for good reasons.
1475 void DestinationUpdateInvoker(
1476 int64_t bytes_so_far,
1477 int64_t bytes_per_sec,
1478 const std::string& hash_state,
1479 base::WeakPtr<DownloadDestinationObserver> observer) {
1480 DVLOG(20) << "DestinationUpdate(bytes_so_far:" << bytes_so_far
1481 << ", bytes_per_sec:" << bytes_per_sec
1482 << ", hash_state:" << hash_state << ") observer:" << !!observer;
1483 if (observer)
1484 observer->DestinationUpdate(bytes_so_far, bytes_per_sec, hash_state);
1485 }
1486
1487 void DestinationErrorInvoker(
1488 DownloadInterruptReason reason,
1489 base::WeakPtr<DownloadDestinationObserver> observer) {
1490 DVLOG(20) << "DestinationError(reason:"
1491 << DownloadInterruptReasonToString(reason)
1492 << ") observer:" << !!observer;
1493 if (observer)
1494 observer->DestinationError(reason);
1495 }
1496
1497 void DestinationCompletedInvoker(
1498 const std::string& final_hash,
1499 base::WeakPtr<DownloadDestinationObserver> observer) {
1500 DVLOG(20) << "DestinationComplete(final_hash:" << final_hash
1501 << ") observer:" << !!observer;
1502 if (observer)
1503 observer->DestinationCompleted(final_hash);
1504 }
1505
1506 // Given a set of observations (via the range |begin|..|end|), constructs a list
1507 // of EventLists such that:
1508 //
1509 // * There are exactly |event_count| ObservationSets in each EventList.
1510 //
1511 // * Each ObservationList in each EventList contains a subrange (possibly empty)
1512 // of observations from the input range, in the same order as the input range.
1513 //
1514 // * The ordering of the ObservationList in each EventList is such that all
1515 // observations in one ObservationList occur earlier than all observations in
1516 // an ObservationList that follows it.
1517 //
1518 // * The list of EventLists together describe all the possible ways in which the
1519 // list of observations can be distributed into |event_count| events.
1520 std::vector<EventList> DistributeObservationsIntoEvents(
1521 const std::vector<CurriedObservation>::iterator begin,
1522 const std::vector<CurriedObservation>::iterator end,
1523 int event_count) {
1524 std::vector<EventList> all_event_lists;
1525 for (auto partition = begin;; ++partition) {
1526 ObservationList first_group_of_observations(begin, partition);
1527 if (event_count > 1) {
1528 std::vector<EventList> list_of_subsequent_events =
1529 DistributeObservationsIntoEvents(partition, end, event_count - 1);
1530 for (const auto& subsequent_events : list_of_subsequent_events) {
1531 EventList event_list;
1532 event_list = subsequent_events;
1533 event_list.push_front(first_group_of_observations);
1534 all_event_lists.push_back(event_list);
1535 }
1536 } else {
1537 EventList event_list;
1538 event_list.push_front(first_group_of_observations);
1539 all_event_lists.push_back(event_list);
1540 }
1541 if (partition == end)
1542 break;
1543 }
1544 return all_event_lists;
1545 }
1546
1547 // For the purpose of this tests, we are only concerned with 3 events:
1548 //
1549 // 1. Immediately after the DownloadFile is initialized.
1550 // 2. Immediately after the DownloadTargetCallback is invoked.
1551 // 3. Immediately after the intermediate file is renamed.
1552 //
1553 // We are going to take a couple of sets of DownloadDestinationObserver events
1554 // and distribute them into the three events described above. And then we are
1555 // going to invoke the observations while a DownloadItemImpl is carefully
1556 // stepped through its stages.
1557
1558 std::vector<EventList> GenerateSuccessfulEventLists() {
1559 std::vector<CurriedObservation> all_observations;
1560 all_observations.push_back(
1561 base::Bind(&DestinationUpdateInvoker, 100, 100, "abc"));
1562 all_observations.push_back(
1563 base::Bind(&DestinationUpdateInvoker, 200, 100, "def"));
1564 all_observations.push_back(
1565 base::Bind(&DestinationCompletedInvoker, "final-hash-1"));
1566 return DistributeObservationsIntoEvents(all_observations.begin(),
1567 all_observations.end(), kEventCount);
1568 }
1569
1570 std::vector<EventList> GenerateFailingEventLists() {
1571 std::vector<CurriedObservation> all_observations;
1572 all_observations.push_back(
1573 base::Bind(&DestinationUpdateInvoker, 100, 100, "abc"));
1574 all_observations.push_back(base::Bind(
1575 &DestinationErrorInvoker, DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED));
1576 return DistributeObservationsIntoEvents(all_observations.begin(),
1577 all_observations.end(), kEventCount);
1578 }
1579
1580 class DownloadItemDestinationUpdateRaceTest
1581 : public DownloadItemTest,
1582 public ::testing::WithParamInterface<EventList> {
1583 public:
1584 DownloadItemDestinationUpdateRaceTest()
1585 : DownloadItemTest(),
1586 item_(CreateDownloadItem()),
1587 file_(new ::testing::StrictMock<MockDownloadFile>()),
1588 request_handle_(new ::testing::StrictMock<MockRequestHandle>()) {
1589 DCHECK_EQ(GetParam().size(), static_cast<unsigned>(kEventCount));
1590 EXPECT_CALL(*request_handle_, GetWebContents())
1591 .WillRepeatedly(Return(nullptr));
1592 }
1593
1594 protected:
1595 const ObservationList& PreInitializeFileObservations() {
1596 return GetParam().front();
1597 }
1598 const ObservationList& PostInitializeFileObservations() {
1599 return *(GetParam().begin() + 1);
1600 }
1601 const ObservationList& PostTargetDeterminationObservations() {
1602 return *(GetParam().begin() + 2);
1603 }
1604 const ObservationList& PostIntermediateRenameObservations() {
1605 return *(GetParam().begin() + 3);
1606 }
1607
1608 // Apply all the observations in |observations| to |observer|, but do so
1609 // asynchronously so that the events are applied in order behind any tasks
1610 // that are already scheduled.
1611 void ScheduleObservations(
1612 const ObservationList& observations,
1613 base::WeakPtr<DownloadDestinationObserver> observer) {
1614 for (const auto action : observations)
1615 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
1616 base::Bind(action, observer));
1617 }
1618
1619 DownloadItemImpl* item_;
1620 scoped_ptr<MockDownloadFile> file_;
1621 scoped_ptr<MockRequestHandle> request_handle_;
1622
1623 std::queue<base::Closure> successful_update_events_;
1624 std::queue<base::Closure> failing_update_events_;
1625 };
1626
1627 INSTANTIATE_TEST_CASE_P(Success,
1628 DownloadItemDestinationUpdateRaceTest,
1629 ::testing::ValuesIn(GenerateSuccessfulEventLists()));
1630
1631 INSTANTIATE_TEST_CASE_P(Failure,
1632 DownloadItemDestinationUpdateRaceTest,
1633 ::testing::ValuesIn(GenerateFailingEventLists()));
1634
1635 } // namespace
1636
1637 // Run through the DII workflow but the embedder cancels the download at target
1638 // determination.
1639 TEST_P(DownloadItemDestinationUpdateRaceTest, DownloadCancelledByUser) {
1640 // Expect that the download file and the request will be cancelled as a
1641 // result.
1642 EXPECT_CALL(*file_, Cancel());
1643 EXPECT_CALL(*request_handle_, CancelRequest());
1644
1645 base::RunLoop download_start_loop;
1646 DownloadFile::InitializeCallback initialize_callback;
1647 EXPECT_CALL(*file_, Initialize(_))
1648 .WillOnce(DoAll(SaveArg<0>(&initialize_callback),
1649 ScheduleClosure(download_start_loop.QuitClosure())));
1650 item_->Start(std::move(file_), std::move(request_handle_));
1651 download_start_loop.Run();
1652
1653 base::WeakPtr<DownloadDestinationObserver> destination_observer =
1654 item_->DestinationObserverAsWeakPtr();
1655
1656 ScheduleObservations(PreInitializeFileObservations(), destination_observer);
1657 RunAllPendingInMessageLoops();
1658
1659 base::RunLoop initialize_completion_loop;
1660 DownloadItemImplDelegate::DownloadTargetCallback target_callback;
1661 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(_, _))
1662 .WillOnce(
1663 DoAll(SaveArg<1>(&target_callback),
1664 ScheduleClosure(initialize_completion_loop.QuitClosure())));
1665 ScheduleObservations(PostInitializeFileObservations(), destination_observer);
1666 initialize_callback.Run(DOWNLOAD_INTERRUPT_REASON_NONE);
1667 initialize_completion_loop.Run();
1668
1669 RunAllPendingInMessageLoops();
1670
1671 ASSERT_FALSE(target_callback.is_null());
1672 ScheduleObservations(PostTargetDeterminationObservations(),
1673 destination_observer);
1674 target_callback.Run(base::FilePath(),
1675 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
1676 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, base::FilePath());
1677 EXPECT_EQ(DownloadItem::CANCELLED, item_->GetState());
1678 RunAllPendingInMessageLoops();
1679 }
1680
1681 // Run through the DII workflow, but the intermediate rename fails.
1682 TEST_P(DownloadItemDestinationUpdateRaceTest, IntermediateRenameFails) {
1683 // Expect that the download file and the request will be cancelled as a
1684 // result.
1685 EXPECT_CALL(*file_, Cancel());
1686 EXPECT_CALL(*request_handle_, CancelRequest());
1687
1688 // Intermediate rename loop is not used immediately, but let's set up the
1689 // DownloadFile expectations since we are about to transfer its ownership to
1690 // the DownloadItem.
1691 base::RunLoop intermediate_rename_loop;
1692 DownloadFile::RenameCompletionCallback intermediate_rename_callback;
1693 EXPECT_CALL(*file_, RenameAndUniquify(_, _))
1694 .WillOnce(DoAll(SaveArg<1>(&intermediate_rename_callback),
1695 ScheduleClosure(intermediate_rename_loop.QuitClosure())));
1696
1697 base::RunLoop download_start_loop;
1698 DownloadFile::InitializeCallback initialize_callback;
1699 EXPECT_CALL(*file_, Initialize(_))
1700 .WillOnce(DoAll(SaveArg<0>(&initialize_callback),
1701 ScheduleClosure(download_start_loop.QuitClosure())));
1702
1703 item_->Start(std::move(file_), std::move(request_handle_));
1704 download_start_loop.Run();
1705 base::WeakPtr<DownloadDestinationObserver> destination_observer =
1706 item_->DestinationObserverAsWeakPtr();
1707
1708 ScheduleObservations(PreInitializeFileObservations(), destination_observer);
1709 RunAllPendingInMessageLoops();
1710
1711 base::RunLoop initialize_completion_loop;
1712 DownloadItemImplDelegate::DownloadTargetCallback target_callback;
1713 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(_, _))
1714 .WillOnce(
1715 DoAll(SaveArg<1>(&target_callback),
1716 ScheduleClosure(initialize_completion_loop.QuitClosure())));
1717 ScheduleObservations(PostInitializeFileObservations(), destination_observer);
1718 initialize_callback.Run(DOWNLOAD_INTERRUPT_REASON_NONE);
1719 initialize_completion_loop.Run();
1720
1721 RunAllPendingInMessageLoops();
1722 ASSERT_FALSE(target_callback.is_null());
1723
1724 ScheduleObservations(PostTargetDeterminationObservations(),
1725 destination_observer);
1726 target_callback.Run(base::FilePath(kDummyTargetPath),
1727 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
1728 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
1729 base::FilePath(kDummyIntermediatePath));
1730
1731 intermediate_rename_loop.Run();
1732 ASSERT_FALSE(intermediate_rename_callback.is_null());
1733
1734 ScheduleObservations(PostIntermediateRenameObservations(),
1735 destination_observer);
1736 intermediate_rename_callback.Run(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED,
1737 base::FilePath());
1738 RunAllPendingInMessageLoops();
1739
1740 EXPECT_EQ(DownloadItem::INTERRUPTED, item_->GetState());
1741 }
1742
1743 // Run through the DII workflow. Download file initialization, target
1744 // determination and intermediate rename all succeed.
1745 TEST_P(DownloadItemDestinationUpdateRaceTest, IntermediateRenameSucceeds) {
1746 // We expect either that the download will fail (in which case the request and
1747 // the download file will be cancelled), or it will succeed (in which case the
1748 // DownloadFile will Detach()). It depends on the list of observations that
1749 // are given to us.
1750 EXPECT_CALL(*file_, Cancel()).Times(::testing::AnyNumber());
1751 EXPECT_CALL(*request_handle_, CancelRequest()).Times(::testing::AnyNumber());
1752 EXPECT_CALL(*file_, Detach()).Times(::testing::AnyNumber());
1753
1754 EXPECT_CALL(*file_, FullPath())
1755 .WillRepeatedly(Return(base::FilePath(kDummyIntermediatePath)));
1756
1757 // Intermediate rename loop is not used immediately, but let's set up the
1758 // DownloadFile expectations since we are about to transfer its ownership to
1759 // the DownloadItem.
1760 base::RunLoop intermediate_rename_loop;
1761 DownloadFile::RenameCompletionCallback intermediate_rename_callback;
1762 EXPECT_CALL(*file_, RenameAndUniquify(_, _))
1763 .WillOnce(DoAll(SaveArg<1>(&intermediate_rename_callback),
1764 ScheduleClosure(intermediate_rename_loop.QuitClosure())));
1765
1766 base::RunLoop download_start_loop;
1767 DownloadFile::InitializeCallback initialize_callback;
1768 EXPECT_CALL(*file_, Initialize(_))
1769 .WillOnce(DoAll(SaveArg<0>(&initialize_callback),
1770 ScheduleClosure(download_start_loop.QuitClosure())));
1771
1772 item_->Start(std::move(file_), std::move(request_handle_));
1773 download_start_loop.Run();
1774 base::WeakPtr<DownloadDestinationObserver> destination_observer =
1775 item_->DestinationObserverAsWeakPtr();
1776
1777 ScheduleObservations(PreInitializeFileObservations(), destination_observer);
1778 RunAllPendingInMessageLoops();
1779
1780 base::RunLoop initialize_completion_loop;
1781 DownloadItemImplDelegate::DownloadTargetCallback target_callback;
1782 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(_, _))
1783 .WillOnce(
1784 DoAll(SaveArg<1>(&target_callback),
1785 ScheduleClosure(initialize_completion_loop.QuitClosure())));
1786 ScheduleObservations(PostInitializeFileObservations(), destination_observer);
1787 initialize_callback.Run(DOWNLOAD_INTERRUPT_REASON_NONE);
1788 initialize_completion_loop.Run();
1789
1790 RunAllPendingInMessageLoops();
1791 ASSERT_FALSE(target_callback.is_null());
1792
1793 ScheduleObservations(PostTargetDeterminationObservations(),
1794 destination_observer);
1795 target_callback.Run(base::FilePath(kDummyTargetPath),
1796 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
1797 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
1798 base::FilePath(kDummyIntermediatePath));
1799
1800 intermediate_rename_loop.Run();
1801 ASSERT_FALSE(intermediate_rename_callback.is_null());
1802
1803 // This may or may not be called, depending on whether there are any errors in
1804 // our action list.
1805 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(_, _))
1806 .Times(::testing::AnyNumber());
1807
1808 ScheduleObservations(PostIntermediateRenameObservations(),
1809 destination_observer);
1810 intermediate_rename_callback.Run(DOWNLOAD_INTERRUPT_REASON_NONE,
1811 base::FilePath(kDummyIntermediatePath));
1812 RunAllPendingInMessageLoops();
1813
1814 // The state of the download depends on the observer events that were played
1815 // back to the DownloadItemImpl. Hence we can't establish a single expectation
1816 // here. On Debug builds, the DCHECKs will verify that the state transitions
1817 // were correct. On Release builds, tests are expected to run to completion
1818 // without crashing on success.
1819 EXPECT_TRUE(item_->GetState() == DownloadItem::IN_PROGRESS ||
1820 item_->GetState() == DownloadItem::INTERRUPTED);
1821 if (item_->GetState() == DownloadItem::INTERRUPTED)
1822 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, item_->GetLastReason());
1823
1824 item_->Cancel(true);
1825 RunAllPendingInMessageLoops();
1826 }
1827
1322 TEST(MockDownloadItem, Compiles) { 1828 TEST(MockDownloadItem, Compiles) {
1323 MockDownloadItem mock_item; 1829 MockDownloadItem mock_item;
1324 } 1830 }
1325 1831
1326 } // namespace content 1832 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/download/download_item_impl.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698