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