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 <stddef.h> | 5 #include <stddef.h> |
6 #include <stdint.h> | 6 #include <stdint.h> |
7 | 7 |
8 #include "base/files/file_path.h" | 8 #include "base/files/file_path.h" |
9 #include "base/files/file_util.h" | 9 #include "base/files/file_util.h" |
10 #include "base/files/scoped_temp_dir.h" | 10 #include "base/files/scoped_temp_dir.h" |
11 #include "base/memory/weak_ptr.h" | 11 #include "base/memory/weak_ptr.h" |
12 #include "base/message_loop/message_loop.h" | 12 #include "base/message_loop/message_loop.h" |
13 #include "base/observer_list.h" | 13 #include "base/observer_list.h" |
| 14 #include "base/run_loop.h" |
14 #include "base/strings/stringprintf.h" | 15 #include "base/strings/stringprintf.h" |
15 #include "base/test/test_file_util.h" | 16 #include "base/test/test_file_util.h" |
16 #include "build/build_config.h" | 17 #include "build/build_config.h" |
17 #include "chrome/browser/download/download_path_reservation_tracker.h" | 18 #include "chrome/browser/download/download_path_reservation_tracker.h" |
18 #include "chrome/browser/download/download_target_determiner.h" | 19 #include "chrome/browser/download/download_target_determiner.h" |
19 #include "chrome/common/features.h" | 20 #include "chrome/common/features.h" |
20 #include "content/public/test/mock_download_item.h" | 21 #include "content/public/test/mock_download_item.h" |
21 #include "content/public/test/test_browser_thread.h" | 22 #include "content/public/test/test_browser_thread.h" |
22 #include "testing/gmock/include/gmock/gmock.h" | 23 #include "testing/gmock/include/gmock/gmock.h" |
23 #include "testing/gtest/include/gtest/gtest.h" | 24 #include "testing/gtest/include/gtest/gtest.h" |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 : ui_thread_(BrowserThread::UI, &message_loop_), | 80 : ui_thread_(BrowserThread::UI, &message_loop_), |
80 file_thread_(BrowserThread::FILE, &message_loop_) { | 81 file_thread_(BrowserThread::FILE, &message_loop_) { |
81 } | 82 } |
82 | 83 |
83 void DownloadPathReservationTrackerTest::SetUp() { | 84 void DownloadPathReservationTrackerTest::SetUp() { |
84 ASSERT_TRUE(test_download_dir_.CreateUniqueTempDir()); | 85 ASSERT_TRUE(test_download_dir_.CreateUniqueTempDir()); |
85 set_default_download_path(test_download_dir_.path()); | 86 set_default_download_path(test_download_dir_.path()); |
86 } | 87 } |
87 | 88 |
88 void DownloadPathReservationTrackerTest::TearDown() { | 89 void DownloadPathReservationTrackerTest::TearDown() { |
89 message_loop_.RunUntilIdle(); | 90 base::RunLoop().RunUntilIdle(); |
90 } | 91 } |
91 | 92 |
92 MockDownloadItem* DownloadPathReservationTrackerTest::CreateDownloadItem( | 93 MockDownloadItem* DownloadPathReservationTrackerTest::CreateDownloadItem( |
93 int32_t id) { | 94 int32_t id) { |
94 MockDownloadItem* item = new ::testing::StrictMock<MockDownloadItem>; | 95 MockDownloadItem* item = new ::testing::StrictMock<MockDownloadItem>; |
95 EXPECT_CALL(*item, GetId()) | 96 EXPECT_CALL(*item, GetId()) |
96 .WillRepeatedly(Return(id)); | 97 .WillRepeatedly(Return(id)); |
97 EXPECT_CALL(*item, GetTargetFilePath()) | 98 EXPECT_CALL(*item, GetTargetFilePath()) |
98 .WillRepeatedly(ReturnRefOfCopy(base::FilePath())); | 99 .WillRepeatedly(ReturnRefOfCopy(base::FilePath())); |
99 EXPECT_CALL(*item, GetState()) | 100 EXPECT_CALL(*item, GetState()) |
(...skipping 25 matching lines...) Expand all Loading... |
125 bool did_run_callback = false; | 126 bool did_run_callback = false; |
126 DownloadPathReservationTracker::GetReservedPath( | 127 DownloadPathReservationTracker::GetReservedPath( |
127 download_item, | 128 download_item, |
128 target_path, | 129 target_path, |
129 default_download_path(), | 130 default_download_path(), |
130 create_directory, | 131 create_directory, |
131 conflict_action, | 132 conflict_action, |
132 base::Bind(&DownloadPathReservationTrackerTest::TestReservedPathCallback, | 133 base::Bind(&DownloadPathReservationTrackerTest::TestReservedPathCallback, |
133 weak_ptr_factory.GetWeakPtr(), return_path, return_verified, | 134 weak_ptr_factory.GetWeakPtr(), return_path, return_verified, |
134 &did_run_callback)); | 135 &did_run_callback)); |
135 message_loop_.RunUntilIdle(); | 136 base::RunLoop().RunUntilIdle(); |
136 EXPECT_TRUE(did_run_callback); | 137 EXPECT_TRUE(did_run_callback); |
137 } | 138 } |
138 | 139 |
139 void DownloadPathReservationTrackerTest::TestReservedPathCallback( | 140 void DownloadPathReservationTrackerTest::TestReservedPathCallback( |
140 base::FilePath* return_path, bool* return_verified, bool* did_run_callback, | 141 base::FilePath* return_path, bool* return_verified, bool* did_run_callback, |
141 const base::FilePath& path, bool verified) { | 142 const base::FilePath& path, bool verified) { |
142 *did_run_callback = true; | 143 *did_run_callback = true; |
143 *return_path = path; | 144 *return_path = path; |
144 *return_verified = verified; | 145 *return_verified = verified; |
145 } | 146 } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
180 conflict_action, | 181 conflict_action, |
181 &reserved_path, | 182 &reserved_path, |
182 &verified); | 183 &verified); |
183 EXPECT_TRUE(IsPathInUse(path)); | 184 EXPECT_TRUE(IsPathInUse(path)); |
184 EXPECT_TRUE(verified); | 185 EXPECT_TRUE(verified); |
185 EXPECT_EQ(path.value(), reserved_path.value()); | 186 EXPECT_EQ(path.value(), reserved_path.value()); |
186 | 187 |
187 // Destroying the item should release the reservation. | 188 // Destroying the item should release the reservation. |
188 SetDownloadItemState(item.get(), DownloadItem::COMPLETE); | 189 SetDownloadItemState(item.get(), DownloadItem::COMPLETE); |
189 item.reset(); | 190 item.reset(); |
190 message_loop_.RunUntilIdle(); | 191 base::RunLoop().RunUntilIdle(); |
191 EXPECT_FALSE(IsPathInUse(path)); | 192 EXPECT_FALSE(IsPathInUse(path)); |
192 } | 193 } |
193 | 194 |
194 // A download that is interrupted should lose its reservation. | 195 // A download that is interrupted should lose its reservation. |
195 TEST_F(DownloadPathReservationTrackerTest, InterruptedDownload) { | 196 TEST_F(DownloadPathReservationTrackerTest, InterruptedDownload) { |
196 std::unique_ptr<MockDownloadItem> item(CreateDownloadItem(1)); | 197 std::unique_ptr<MockDownloadItem> item(CreateDownloadItem(1)); |
197 base::FilePath path( | 198 base::FilePath path( |
198 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt"))); | 199 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt"))); |
199 ASSERT_FALSE(IsPathInUse(path)); | 200 ASSERT_FALSE(IsPathInUse(path)); |
200 | 201 |
201 base::FilePath reserved_path; | 202 base::FilePath reserved_path; |
202 bool verified = false; | 203 bool verified = false; |
203 DownloadPathReservationTracker::FilenameConflictAction conflict_action = | 204 DownloadPathReservationTracker::FilenameConflictAction conflict_action = |
204 DownloadPathReservationTracker::OVERWRITE; | 205 DownloadPathReservationTracker::OVERWRITE; |
205 bool create_directory = false; | 206 bool create_directory = false; |
206 CallGetReservedPath( | 207 CallGetReservedPath( |
207 item.get(), | 208 item.get(), |
208 path, | 209 path, |
209 create_directory, | 210 create_directory, |
210 conflict_action, | 211 conflict_action, |
211 &reserved_path, | 212 &reserved_path, |
212 &verified); | 213 &verified); |
213 EXPECT_TRUE(IsPathInUse(path)); | 214 EXPECT_TRUE(IsPathInUse(path)); |
214 EXPECT_TRUE(verified); | 215 EXPECT_TRUE(verified); |
215 EXPECT_EQ(path.value(), reserved_path.value()); | 216 EXPECT_EQ(path.value(), reserved_path.value()); |
216 | 217 |
217 // Once the download is interrupted, the path should become available again. | 218 // Once the download is interrupted, the path should become available again. |
218 SetDownloadItemState(item.get(), DownloadItem::INTERRUPTED); | 219 SetDownloadItemState(item.get(), DownloadItem::INTERRUPTED); |
219 message_loop_.RunUntilIdle(); | 220 base::RunLoop().RunUntilIdle(); |
220 EXPECT_FALSE(IsPathInUse(path)); | 221 EXPECT_FALSE(IsPathInUse(path)); |
221 } | 222 } |
222 | 223 |
223 // A completed download should also lose its reservation. | 224 // A completed download should also lose its reservation. |
224 TEST_F(DownloadPathReservationTrackerTest, CompleteDownload) { | 225 TEST_F(DownloadPathReservationTrackerTest, CompleteDownload) { |
225 std::unique_ptr<MockDownloadItem> item(CreateDownloadItem(1)); | 226 std::unique_ptr<MockDownloadItem> item(CreateDownloadItem(1)); |
226 base::FilePath path( | 227 base::FilePath path( |
227 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt"))); | 228 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt"))); |
228 ASSERT_FALSE(IsPathInUse(path)); | 229 ASSERT_FALSE(IsPathInUse(path)); |
229 | 230 |
(...skipping 11 matching lines...) Expand all Loading... |
241 &verified); | 242 &verified); |
242 EXPECT_TRUE(IsPathInUse(path)); | 243 EXPECT_TRUE(IsPathInUse(path)); |
243 EXPECT_TRUE(verified); | 244 EXPECT_TRUE(verified); |
244 EXPECT_EQ(path.value(), reserved_path.value()); | 245 EXPECT_EQ(path.value(), reserved_path.value()); |
245 | 246 |
246 // Once the download completes, the path should become available again. For a | 247 // Once the download completes, the path should become available again. For a |
247 // real download, at this point only the path reservation will be released. | 248 // real download, at this point only the path reservation will be released. |
248 // The path wouldn't be available since it is occupied on disk by the | 249 // The path wouldn't be available since it is occupied on disk by the |
249 // completed download. | 250 // completed download. |
250 SetDownloadItemState(item.get(), DownloadItem::COMPLETE); | 251 SetDownloadItemState(item.get(), DownloadItem::COMPLETE); |
251 message_loop_.RunUntilIdle(); | 252 base::RunLoop().RunUntilIdle(); |
252 EXPECT_FALSE(IsPathInUse(path)); | 253 EXPECT_FALSE(IsPathInUse(path)); |
253 } | 254 } |
254 | 255 |
255 // If there are files on the file system, a unique reservation should uniquify | 256 // If there are files on the file system, a unique reservation should uniquify |
256 // around it. | 257 // around it. |
257 TEST_F(DownloadPathReservationTrackerTest, ConflictingFiles) { | 258 TEST_F(DownloadPathReservationTrackerTest, ConflictingFiles) { |
258 std::unique_ptr<MockDownloadItem> item(CreateDownloadItem(1)); | 259 std::unique_ptr<MockDownloadItem> item(CreateDownloadItem(1)); |
259 base::FilePath path( | 260 base::FilePath path( |
260 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt"))); | 261 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt"))); |
261 base::FilePath path1( | 262 base::FilePath path1( |
(...skipping 21 matching lines...) Expand all Loading... |
283 EXPECT_TRUE(IsPathInUse(reserved_path)); | 284 EXPECT_TRUE(IsPathInUse(reserved_path)); |
284 EXPECT_TRUE(verified); | 285 EXPECT_TRUE(verified); |
285 // The path should be uniquified, skipping over foo.txt but not over | 286 // The path should be uniquified, skipping over foo.txt but not over |
286 // "foo (1).txt.crdownload" | 287 // "foo (1).txt.crdownload" |
287 EXPECT_EQ( | 288 EXPECT_EQ( |
288 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo (1).txt")).value(), | 289 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo (1).txt")).value(), |
289 reserved_path.value()); | 290 reserved_path.value()); |
290 | 291 |
291 SetDownloadItemState(item.get(), DownloadItem::COMPLETE); | 292 SetDownloadItemState(item.get(), DownloadItem::COMPLETE); |
292 item.reset(); | 293 item.reset(); |
293 message_loop_.RunUntilIdle(); | 294 base::RunLoop().RunUntilIdle(); |
294 EXPECT_TRUE(IsPathInUse(path)); | 295 EXPECT_TRUE(IsPathInUse(path)); |
295 EXPECT_FALSE(IsPathInUse(reserved_path)); | 296 EXPECT_FALSE(IsPathInUse(reserved_path)); |
296 } | 297 } |
297 | 298 |
298 // Multiple reservations for the same path should uniquify around each other. | 299 // Multiple reservations for the same path should uniquify around each other. |
299 TEST_F(DownloadPathReservationTrackerTest, ConflictingReservations) { | 300 TEST_F(DownloadPathReservationTrackerTest, ConflictingReservations) { |
300 std::unique_ptr<MockDownloadItem> item1(CreateDownloadItem(1)); | 301 std::unique_ptr<MockDownloadItem> item1(CreateDownloadItem(1)); |
301 base::FilePath path( | 302 base::FilePath path( |
302 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt"))); | 303 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt"))); |
303 base::FilePath uniquified_path( | 304 base::FilePath uniquified_path( |
(...skipping 28 matching lines...) Expand all Loading... |
332 path, | 333 path, |
333 create_directory, | 334 create_directory, |
334 conflict_action, | 335 conflict_action, |
335 &reserved_path2, | 336 &reserved_path2, |
336 &verified); | 337 &verified); |
337 EXPECT_TRUE(IsPathInUse(path)); | 338 EXPECT_TRUE(IsPathInUse(path)); |
338 EXPECT_TRUE(IsPathInUse(uniquified_path)); | 339 EXPECT_TRUE(IsPathInUse(uniquified_path)); |
339 EXPECT_EQ(uniquified_path.value(), reserved_path2.value()); | 340 EXPECT_EQ(uniquified_path.value(), reserved_path2.value()); |
340 SetDownloadItemState(item2.get(), DownloadItem::COMPLETE); | 341 SetDownloadItemState(item2.get(), DownloadItem::COMPLETE); |
341 } | 342 } |
342 message_loop_.RunUntilIdle(); | 343 base::RunLoop().RunUntilIdle(); |
343 EXPECT_TRUE(IsPathInUse(path)); | 344 EXPECT_TRUE(IsPathInUse(path)); |
344 EXPECT_FALSE(IsPathInUse(uniquified_path)); | 345 EXPECT_FALSE(IsPathInUse(uniquified_path)); |
345 | 346 |
346 { | 347 { |
347 // Since the previous download item was removed, requesting a reservation | 348 // Since the previous download item was removed, requesting a reservation |
348 // for the same path should result in the same uniquified path. | 349 // for the same path should result in the same uniquified path. |
349 std::unique_ptr<MockDownloadItem> item2(CreateDownloadItem(2)); | 350 std::unique_ptr<MockDownloadItem> item2(CreateDownloadItem(2)); |
350 base::FilePath reserved_path2; | 351 base::FilePath reserved_path2; |
351 CallGetReservedPath( | 352 CallGetReservedPath( |
352 item2.get(), | 353 item2.get(), |
353 path, | 354 path, |
354 create_directory, | 355 create_directory, |
355 conflict_action, | 356 conflict_action, |
356 &reserved_path2, | 357 &reserved_path2, |
357 &verified); | 358 &verified); |
358 EXPECT_TRUE(IsPathInUse(path)); | 359 EXPECT_TRUE(IsPathInUse(path)); |
359 EXPECT_TRUE(IsPathInUse(uniquified_path)); | 360 EXPECT_TRUE(IsPathInUse(uniquified_path)); |
360 EXPECT_EQ(uniquified_path.value(), reserved_path2.value()); | 361 EXPECT_EQ(uniquified_path.value(), reserved_path2.value()); |
361 SetDownloadItemState(item2.get(), DownloadItem::COMPLETE); | 362 SetDownloadItemState(item2.get(), DownloadItem::COMPLETE); |
362 } | 363 } |
363 message_loop_.RunUntilIdle(); | 364 base::RunLoop().RunUntilIdle(); |
364 | 365 |
365 // Now acquire an overwriting reservation. We should end up with the same | 366 // Now acquire an overwriting reservation. We should end up with the same |
366 // non-uniquified path for both reservations. | 367 // non-uniquified path for both reservations. |
367 std::unique_ptr<MockDownloadItem> item3(CreateDownloadItem(2)); | 368 std::unique_ptr<MockDownloadItem> item3(CreateDownloadItem(2)); |
368 base::FilePath reserved_path3; | 369 base::FilePath reserved_path3; |
369 conflict_action = DownloadPathReservationTracker::OVERWRITE; | 370 conflict_action = DownloadPathReservationTracker::OVERWRITE; |
370 CallGetReservedPath( | 371 CallGetReservedPath( |
371 item3.get(), | 372 item3.get(), |
372 path, | 373 path, |
373 create_directory, | 374 create_directory, |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
578 &reserved_path, | 579 &reserved_path, |
579 &verified); | 580 &verified); |
580 EXPECT_TRUE(IsPathInUse(path)); | 581 EXPECT_TRUE(IsPathInUse(path)); |
581 EXPECT_TRUE(verified); | 582 EXPECT_TRUE(verified); |
582 EXPECT_EQ(path.value(), reserved_path.value()); | 583 EXPECT_EQ(path.value(), reserved_path.value()); |
583 | 584 |
584 // The target path is initially empty. If an OnDownloadUpdated() is issued in | 585 // The target path is initially empty. If an OnDownloadUpdated() is issued in |
585 // this state, we shouldn't lose the reservation. | 586 // this state, we shouldn't lose the reservation. |
586 ASSERT_EQ(base::FilePath::StringType(), item->GetTargetFilePath().value()); | 587 ASSERT_EQ(base::FilePath::StringType(), item->GetTargetFilePath().value()); |
587 item->NotifyObserversDownloadUpdated(); | 588 item->NotifyObserversDownloadUpdated(); |
588 message_loop_.RunUntilIdle(); | 589 base::RunLoop().RunUntilIdle(); |
589 EXPECT_TRUE(IsPathInUse(path)); | 590 EXPECT_TRUE(IsPathInUse(path)); |
590 | 591 |
591 // If the target path changes, we should update the reservation to match. | 592 // If the target path changes, we should update the reservation to match. |
592 base::FilePath new_target_path( | 593 base::FilePath new_target_path( |
593 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("bar.txt"))); | 594 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("bar.txt"))); |
594 ASSERT_FALSE(IsPathInUse(new_target_path)); | 595 ASSERT_FALSE(IsPathInUse(new_target_path)); |
595 EXPECT_CALL(*item, GetTargetFilePath()) | 596 EXPECT_CALL(*item, GetTargetFilePath()) |
596 .WillRepeatedly(ReturnRef(new_target_path)); | 597 .WillRepeatedly(ReturnRef(new_target_path)); |
597 item->NotifyObserversDownloadUpdated(); | 598 item->NotifyObserversDownloadUpdated(); |
598 message_loop_.RunUntilIdle(); | 599 base::RunLoop().RunUntilIdle(); |
599 EXPECT_FALSE(IsPathInUse(path)); | 600 EXPECT_FALSE(IsPathInUse(path)); |
600 EXPECT_TRUE(IsPathInUse(new_target_path)); | 601 EXPECT_TRUE(IsPathInUse(new_target_path)); |
601 | 602 |
602 // Destroying the item should release the reservation. | 603 // Destroying the item should release the reservation. |
603 SetDownloadItemState(item.get(), DownloadItem::COMPLETE); | 604 SetDownloadItemState(item.get(), DownloadItem::COMPLETE); |
604 item.reset(); | 605 item.reset(); |
605 message_loop_.RunUntilIdle(); | 606 base::RunLoop().RunUntilIdle(); |
606 EXPECT_FALSE(IsPathInUse(new_target_path)); | 607 EXPECT_FALSE(IsPathInUse(new_target_path)); |
607 } | 608 } |
608 | 609 |
609 // Tests for long name truncation. On other platforms automatic truncation | 610 // Tests for long name truncation. On other platforms automatic truncation |
610 // is not performed (yet). | 611 // is not performed (yet). |
611 #if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS) | 612 #if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS) |
612 | 613 |
613 TEST_F(DownloadPathReservationTrackerTest, BasicTruncation) { | 614 TEST_F(DownloadPathReservationTrackerTest, BasicTruncation) { |
614 int real_max_length = | 615 int real_max_length = |
615 base::GetMaximumPathComponentLength(default_download_path()); | 616 base::GetMaximumPathComponentLength(default_download_path()); |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
708 create_directory, | 709 create_directory, |
709 conflict_action, | 710 conflict_action, |
710 &reserved_path, | 711 &reserved_path, |
711 &verified); | 712 &verified); |
712 // We cannot truncate a path with very long extension. | 713 // We cannot truncate a path with very long extension. |
713 EXPECT_FALSE(verified); | 714 EXPECT_FALSE(verified); |
714 SetDownloadItemState(item.get(), DownloadItem::COMPLETE); | 715 SetDownloadItemState(item.get(), DownloadItem::COMPLETE); |
715 } | 716 } |
716 | 717 |
717 #endif // Platforms that support filename truncation. | 718 #endif // Platforms that support filename truncation. |
OLD | NEW |