No dual_mode on Win10+ shortcuts.
[chromium-blink-merge.git] / chrome / browser / download / download_path_reservation_tracker_unittest.cc
blob902efcbc308d2f15b5786e2c2f2084d4a7325009
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/files/file_path.h"
6 #include "base/files/file_util.h"
7 #include "base/files/scoped_temp_dir.h"
8 #include "base/memory/weak_ptr.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/observer_list.h"
11 #include "base/strings/stringprintf.h"
12 #include "base/test/test_file_util.h"
13 #include "chrome/browser/download/download_path_reservation_tracker.h"
14 #include "chrome/browser/download/download_target_determiner.h"
15 #include "content/public/test/mock_download_item.h"
16 #include "content/public/test/test_browser_thread.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gtest/include/gtest/gtest.h"
20 using content::BrowserThread;
21 using content::DownloadItem;
22 using content::MockDownloadItem;
23 using testing::AnyNumber;
24 using testing::Return;
25 using testing::ReturnRef;
26 using testing::ReturnRefOfCopy;
28 namespace {
30 class DownloadPathReservationTrackerTest : public testing::Test {
31 public:
32 DownloadPathReservationTrackerTest();
34 // testing::Test
35 void SetUp() override;
36 void TearDown() override;
38 MockDownloadItem* CreateDownloadItem(int32 id);
39 base::FilePath GetPathInDownloadsDirectory(
40 const base::FilePath::CharType* suffix);
41 bool IsPathInUse(const base::FilePath& path);
42 void CallGetReservedPath(
43 DownloadItem* download_item,
44 const base::FilePath& target_path,
45 bool create_directory,
46 DownloadPathReservationTracker::FilenameConflictAction conflict_action,
47 base::FilePath* return_path,
48 bool* return_verified);
50 const base::FilePath& default_download_path() const {
51 return default_download_path_;
53 void set_default_download_path(const base::FilePath& path) {
54 default_download_path_ = path;
56 // Creates a name of form 'a'*repeat + suffix
57 base::FilePath GetLongNamePathInDownloadsDirectory(
58 size_t repeat, const base::FilePath::CharType* suffix);
60 protected:
61 base::ScopedTempDir test_download_dir_;
62 base::FilePath default_download_path_;
63 base::MessageLoopForUI message_loop_;
64 content::TestBrowserThread ui_thread_;
65 content::TestBrowserThread file_thread_;
67 private:
68 void TestReservedPathCallback(base::FilePath* return_path,
69 bool* return_verified, bool* did_run_callback,
70 const base::FilePath& path, bool verified);
73 DownloadPathReservationTrackerTest::DownloadPathReservationTrackerTest()
74 : ui_thread_(BrowserThread::UI, &message_loop_),
75 file_thread_(BrowserThread::FILE, &message_loop_) {
78 void DownloadPathReservationTrackerTest::SetUp() {
79 ASSERT_TRUE(test_download_dir_.CreateUniqueTempDir());
80 set_default_download_path(test_download_dir_.path());
83 void DownloadPathReservationTrackerTest::TearDown() {
84 message_loop_.RunUntilIdle();
87 MockDownloadItem* DownloadPathReservationTrackerTest::CreateDownloadItem(
88 int32 id) {
89 MockDownloadItem* item = new ::testing::StrictMock<MockDownloadItem>;
90 EXPECT_CALL(*item, GetId())
91 .WillRepeatedly(Return(id));
92 EXPECT_CALL(*item, GetTargetFilePath())
93 .WillRepeatedly(ReturnRefOfCopy(base::FilePath()));
94 EXPECT_CALL(*item, GetState())
95 .WillRepeatedly(Return(DownloadItem::IN_PROGRESS));
96 return item;
99 base::FilePath DownloadPathReservationTrackerTest::GetPathInDownloadsDirectory(
100 const base::FilePath::CharType* suffix) {
101 return default_download_path().Append(suffix).NormalizePathSeparators();
104 bool DownloadPathReservationTrackerTest::IsPathInUse(
105 const base::FilePath& path) {
106 return DownloadPathReservationTracker::IsPathInUseForTesting(path);
109 void DownloadPathReservationTrackerTest::CallGetReservedPath(
110 DownloadItem* download_item,
111 const base::FilePath& target_path,
112 bool create_directory,
113 DownloadPathReservationTracker::FilenameConflictAction conflict_action,
114 base::FilePath* return_path,
115 bool* return_verified) {
116 // Weak pointer factory to prevent the callback from running after this
117 // function has returned.
118 base::WeakPtrFactory<DownloadPathReservationTrackerTest> weak_ptr_factory(
119 this);
120 bool did_run_callback = false;
121 DownloadPathReservationTracker::GetReservedPath(
122 download_item,
123 target_path,
124 default_download_path(),
125 create_directory,
126 conflict_action,
127 base::Bind(&DownloadPathReservationTrackerTest::TestReservedPathCallback,
128 weak_ptr_factory.GetWeakPtr(), return_path, return_verified,
129 &did_run_callback));
130 message_loop_.RunUntilIdle();
131 EXPECT_TRUE(did_run_callback);
134 void DownloadPathReservationTrackerTest::TestReservedPathCallback(
135 base::FilePath* return_path, bool* return_verified, bool* did_run_callback,
136 const base::FilePath& path, bool verified) {
137 *did_run_callback = true;
138 *return_path = path;
139 *return_verified = verified;
142 base::FilePath
143 DownloadPathReservationTrackerTest::GetLongNamePathInDownloadsDirectory(
144 size_t repeat, const base::FilePath::CharType* suffix) {
145 return GetPathInDownloadsDirectory(
146 (base::FilePath::StringType(repeat, FILE_PATH_LITERAL('a'))
147 + suffix).c_str());
150 void SetDownloadItemState(content::MockDownloadItem* download_item,
151 content::DownloadItem::DownloadState state) {
152 EXPECT_CALL(*download_item, GetState())
153 .WillRepeatedly(Return(state));
154 download_item->NotifyObserversDownloadUpdated();
157 } // namespace
159 // A basic reservation is acquired and committed.
160 TEST_F(DownloadPathReservationTrackerTest, BasicReservation) {
161 scoped_ptr<MockDownloadItem> item(CreateDownloadItem(1));
162 base::FilePath path(
163 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt")));
164 ASSERT_FALSE(IsPathInUse(path));
166 base::FilePath reserved_path;
167 bool verified = false;
168 DownloadPathReservationTracker::FilenameConflictAction conflict_action =
169 DownloadPathReservationTracker::OVERWRITE;
170 bool create_directory = false;
171 CallGetReservedPath(
172 item.get(),
173 path,
174 create_directory,
175 conflict_action,
176 &reserved_path,
177 &verified);
178 EXPECT_TRUE(IsPathInUse(path));
179 EXPECT_TRUE(verified);
180 EXPECT_EQ(path.value(), reserved_path.value());
182 // Destroying the item should release the reservation.
183 SetDownloadItemState(item.get(), DownloadItem::COMPLETE);
184 item.reset();
185 message_loop_.RunUntilIdle();
186 EXPECT_FALSE(IsPathInUse(path));
189 // A download that is interrupted should lose its reservation.
190 TEST_F(DownloadPathReservationTrackerTest, InterruptedDownload) {
191 scoped_ptr<MockDownloadItem> item(CreateDownloadItem(1));
192 base::FilePath path(
193 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt")));
194 ASSERT_FALSE(IsPathInUse(path));
196 base::FilePath reserved_path;
197 bool verified = false;
198 DownloadPathReservationTracker::FilenameConflictAction conflict_action =
199 DownloadPathReservationTracker::OVERWRITE;
200 bool create_directory = false;
201 CallGetReservedPath(
202 item.get(),
203 path,
204 create_directory,
205 conflict_action,
206 &reserved_path,
207 &verified);
208 EXPECT_TRUE(IsPathInUse(path));
209 EXPECT_TRUE(verified);
210 EXPECT_EQ(path.value(), reserved_path.value());
212 // Once the download is interrupted, the path should become available again.
213 SetDownloadItemState(item.get(), DownloadItem::INTERRUPTED);
214 message_loop_.RunUntilIdle();
215 EXPECT_FALSE(IsPathInUse(path));
218 // A completed download should also lose its reservation.
219 TEST_F(DownloadPathReservationTrackerTest, CompleteDownload) {
220 scoped_ptr<MockDownloadItem> item(CreateDownloadItem(1));
221 base::FilePath path(
222 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt")));
223 ASSERT_FALSE(IsPathInUse(path));
225 base::FilePath reserved_path;
226 bool verified = false;
227 DownloadPathReservationTracker::FilenameConflictAction conflict_action =
228 DownloadPathReservationTracker::OVERWRITE;
229 bool create_directory = false;
230 CallGetReservedPath(
231 item.get(),
232 path,
233 create_directory,
234 conflict_action,
235 &reserved_path,
236 &verified);
237 EXPECT_TRUE(IsPathInUse(path));
238 EXPECT_TRUE(verified);
239 EXPECT_EQ(path.value(), reserved_path.value());
241 // Once the download completes, the path should become available again. For a
242 // real download, at this point only the path reservation will be released.
243 // The path wouldn't be available since it is occupied on disk by the
244 // completed download.
245 SetDownloadItemState(item.get(), DownloadItem::COMPLETE);
246 message_loop_.RunUntilIdle();
247 EXPECT_FALSE(IsPathInUse(path));
250 // If there are files on the file system, a unique reservation should uniquify
251 // around it.
252 TEST_F(DownloadPathReservationTrackerTest, ConflictingFiles) {
253 scoped_ptr<MockDownloadItem> item(CreateDownloadItem(1));
254 base::FilePath path(
255 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt")));
256 base::FilePath path1(
257 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo (1).txt")));
258 // Create a file at |path|, and a .crdownload file at |path1|.
259 ASSERT_EQ(0, base::WriteFile(path, "", 0));
260 ASSERT_EQ(0,
261 base::WriteFile(
262 DownloadTargetDeterminer::GetCrDownloadPath(path1), "", 0));
263 ASSERT_TRUE(IsPathInUse(path));
265 base::FilePath reserved_path;
266 bool verified = false;
267 bool create_directory = false;
268 DownloadPathReservationTracker::FilenameConflictAction conflict_action =
269 DownloadPathReservationTracker::UNIQUIFY;
270 CallGetReservedPath(
271 item.get(),
272 path,
273 create_directory,
274 conflict_action,
275 &reserved_path,
276 &verified);
277 EXPECT_TRUE(IsPathInUse(path));
278 EXPECT_TRUE(IsPathInUse(reserved_path));
279 EXPECT_TRUE(verified);
280 // The path should be uniquified, skipping over foo.txt but not over
281 // "foo (1).txt.crdownload"
282 EXPECT_EQ(
283 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo (1).txt")).value(),
284 reserved_path.value());
286 SetDownloadItemState(item.get(), DownloadItem::COMPLETE);
287 item.reset();
288 message_loop_.RunUntilIdle();
289 EXPECT_TRUE(IsPathInUse(path));
290 EXPECT_FALSE(IsPathInUse(reserved_path));
293 // Multiple reservations for the same path should uniquify around each other.
294 TEST_F(DownloadPathReservationTrackerTest, ConflictingReservations) {
295 scoped_ptr<MockDownloadItem> item1(CreateDownloadItem(1));
296 base::FilePath path(
297 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt")));
298 base::FilePath uniquified_path(
299 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo (1).txt")));
300 ASSERT_FALSE(IsPathInUse(path));
301 ASSERT_FALSE(IsPathInUse(uniquified_path));
303 base::FilePath reserved_path1;
304 bool verified = false;
305 bool create_directory = false;
307 DownloadPathReservationTracker::FilenameConflictAction conflict_action =
308 DownloadPathReservationTracker::UNIQUIFY;
309 CallGetReservedPath(
310 item1.get(),
311 path,
312 create_directory,
313 conflict_action,
314 &reserved_path1,
315 &verified);
316 EXPECT_TRUE(IsPathInUse(path));
317 EXPECT_TRUE(verified);
321 // Requesting a reservation for the same path with uniquification results in
322 // a uniquified path.
323 scoped_ptr<MockDownloadItem> item2(CreateDownloadItem(2));
324 base::FilePath reserved_path2;
325 CallGetReservedPath(
326 item2.get(),
327 path,
328 create_directory,
329 conflict_action,
330 &reserved_path2,
331 &verified);
332 EXPECT_TRUE(IsPathInUse(path));
333 EXPECT_TRUE(IsPathInUse(uniquified_path));
334 EXPECT_EQ(uniquified_path.value(), reserved_path2.value());
335 SetDownloadItemState(item2.get(), DownloadItem::COMPLETE);
337 message_loop_.RunUntilIdle();
338 EXPECT_TRUE(IsPathInUse(path));
339 EXPECT_FALSE(IsPathInUse(uniquified_path));
342 // Since the previous download item was removed, requesting a reservation
343 // for the same path should result in the same uniquified path.
344 scoped_ptr<MockDownloadItem> item2(CreateDownloadItem(2));
345 base::FilePath reserved_path2;
346 CallGetReservedPath(
347 item2.get(),
348 path,
349 create_directory,
350 conflict_action,
351 &reserved_path2,
352 &verified);
353 EXPECT_TRUE(IsPathInUse(path));
354 EXPECT_TRUE(IsPathInUse(uniquified_path));
355 EXPECT_EQ(uniquified_path.value(), reserved_path2.value());
356 SetDownloadItemState(item2.get(), DownloadItem::COMPLETE);
358 message_loop_.RunUntilIdle();
360 // Now acquire an overwriting reservation. We should end up with the same
361 // non-uniquified path for both reservations.
362 scoped_ptr<MockDownloadItem> item3(CreateDownloadItem(2));
363 base::FilePath reserved_path3;
364 conflict_action = DownloadPathReservationTracker::OVERWRITE;
365 CallGetReservedPath(
366 item3.get(),
367 path,
368 create_directory,
369 conflict_action,
370 &reserved_path3,
371 &verified);
372 EXPECT_TRUE(IsPathInUse(path));
373 EXPECT_FALSE(IsPathInUse(uniquified_path));
375 EXPECT_EQ(path.value(), reserved_path1.value());
376 EXPECT_EQ(path.value(), reserved_path3.value());
378 SetDownloadItemState(item1.get(), DownloadItem::COMPLETE);
379 SetDownloadItemState(item3.get(), DownloadItem::COMPLETE);
382 // If a unique path cannot be determined after trying kMaxUniqueFiles
383 // uniquifiers, then the callback should notified that verification failed, and
384 // the returned path should be set to the original requested path.
385 TEST_F(DownloadPathReservationTrackerTest, UnresolvedConflicts) {
386 base::FilePath path(
387 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt")));
388 scoped_ptr<MockDownloadItem>
389 items[DownloadPathReservationTracker::kMaxUniqueFiles + 1];
390 DownloadPathReservationTracker::FilenameConflictAction conflict_action =
391 DownloadPathReservationTracker::UNIQUIFY;
392 bool create_directory = false;
394 // Create |kMaxUniqueFiles + 1| reservations for |path|. The first reservation
395 // will have no uniquifier. The |kMaxUniqueFiles| remaining reservations do.
396 for (int i = 0; i <= DownloadPathReservationTracker::kMaxUniqueFiles; i++) {
397 base::FilePath reserved_path;
398 base::FilePath expected_path;
399 bool verified = false;
400 if (i > 0) {
401 expected_path =
402 path.InsertBeforeExtensionASCII(base::StringPrintf(" (%d)", i));
403 } else {
404 expected_path = path;
406 items[i].reset(CreateDownloadItem(i));
407 EXPECT_FALSE(IsPathInUse(expected_path));
408 CallGetReservedPath(
409 items[i].get(),
410 path,
411 create_directory,
412 conflict_action,
413 &reserved_path,
414 &verified);
415 EXPECT_TRUE(IsPathInUse(expected_path));
416 EXPECT_EQ(expected_path.value(), reserved_path.value());
417 EXPECT_TRUE(verified);
419 // The next reservation for |path| will fail to be unique.
420 scoped_ptr<MockDownloadItem> item(
421 CreateDownloadItem(DownloadPathReservationTracker::kMaxUniqueFiles + 1));
422 base::FilePath reserved_path;
423 bool verified = true;
424 CallGetReservedPath(
425 item.get(),
426 path,
427 create_directory,
428 conflict_action,
429 &reserved_path,
430 &verified);
431 EXPECT_FALSE(verified);
432 EXPECT_EQ(path.value(), reserved_path.value());
434 SetDownloadItemState(item.get(), DownloadItem::COMPLETE);
435 for (int i = 0; i <= DownloadPathReservationTracker::kMaxUniqueFiles; i++)
436 SetDownloadItemState(items[i].get(), DownloadItem::COMPLETE);
439 // If the target directory is unwriteable, then callback should be notified that
440 // verification failed.
441 TEST_F(DownloadPathReservationTrackerTest, UnwriteableDirectory) {
442 scoped_ptr<MockDownloadItem> item(CreateDownloadItem(1));
443 base::FilePath path(
444 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt")));
445 base::FilePath dir(path.DirName());
446 ASSERT_FALSE(IsPathInUse(path));
449 // Scope for FilePermissionRestorer
450 base::FilePermissionRestorer restorer(dir);
451 EXPECT_TRUE(base::MakeFileUnwritable(dir));
452 base::FilePath reserved_path;
453 bool verified = true;
454 DownloadPathReservationTracker::FilenameConflictAction conflict_action =
455 DownloadPathReservationTracker::OVERWRITE;
456 bool create_directory = false;
457 CallGetReservedPath(
458 item.get(),
459 path,
460 create_directory,
461 conflict_action,
462 &reserved_path,
463 &verified);
464 // Verification fails.
465 EXPECT_FALSE(verified);
466 EXPECT_EQ(path.BaseName().value(), reserved_path.BaseName().value());
468 SetDownloadItemState(item.get(), DownloadItem::COMPLETE);
471 // If the default download directory doesn't exist, then it should be
472 // created. But only if we are actually going to create the download path there.
473 TEST_F(DownloadPathReservationTrackerTest, CreateDefaultDownloadPath) {
474 base::FilePath path(
475 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo/foo.txt")));
476 base::FilePath dir(path.DirName());
477 ASSERT_FALSE(base::DirectoryExists(dir));
478 DownloadPathReservationTracker::FilenameConflictAction conflict_action =
479 DownloadPathReservationTracker::OVERWRITE;
480 bool create_directory = false;
483 scoped_ptr<MockDownloadItem> item(CreateDownloadItem(1));
484 base::FilePath reserved_path;
485 bool verified = true;
486 CallGetReservedPath(
487 item.get(),
488 path,
489 create_directory,
490 conflict_action,
491 &reserved_path,
492 &verified);
493 // Verification fails because the directory doesn't exist.
494 EXPECT_FALSE(verified);
495 SetDownloadItemState(item.get(), DownloadItem::COMPLETE);
497 ASSERT_FALSE(IsPathInUse(path));
499 scoped_ptr<MockDownloadItem> item(CreateDownloadItem(1));
500 base::FilePath reserved_path;
501 bool verified = true;
502 set_default_download_path(dir);
503 CallGetReservedPath(
504 item.get(),
505 path,
506 create_directory,
507 conflict_action,
508 &reserved_path,
509 &verified);
510 // Verification succeeds because the directory is created.
511 EXPECT_TRUE(verified);
512 EXPECT_TRUE(base::DirectoryExists(dir));
513 SetDownloadItemState(item.get(), DownloadItem::COMPLETE);
517 // If the target path of the download item changes, the reservation should be
518 // updated to match.
519 TEST_F(DownloadPathReservationTrackerTest, UpdatesToTargetPath) {
520 scoped_ptr<MockDownloadItem> item(CreateDownloadItem(1));
521 base::FilePath path(
522 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt")));
523 ASSERT_FALSE(IsPathInUse(path));
525 base::FilePath reserved_path;
526 bool verified = false;
527 DownloadPathReservationTracker::FilenameConflictAction conflict_action =
528 DownloadPathReservationTracker::OVERWRITE;
529 bool create_directory = false;
530 CallGetReservedPath(
531 item.get(),
532 path,
533 create_directory,
534 conflict_action,
535 &reserved_path,
536 &verified);
537 EXPECT_TRUE(IsPathInUse(path));
538 EXPECT_TRUE(verified);
539 EXPECT_EQ(path.value(), reserved_path.value());
541 // The target path is initially empty. If an OnDownloadUpdated() is issued in
542 // this state, we shouldn't lose the reservation.
543 ASSERT_EQ(base::FilePath::StringType(), item->GetTargetFilePath().value());
544 item->NotifyObserversDownloadUpdated();
545 message_loop_.RunUntilIdle();
546 EXPECT_TRUE(IsPathInUse(path));
548 // If the target path changes, we should update the reservation to match.
549 base::FilePath new_target_path(
550 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("bar.txt")));
551 ASSERT_FALSE(IsPathInUse(new_target_path));
552 EXPECT_CALL(*item, GetTargetFilePath())
553 .WillRepeatedly(ReturnRef(new_target_path));
554 item->NotifyObserversDownloadUpdated();
555 message_loop_.RunUntilIdle();
556 EXPECT_FALSE(IsPathInUse(path));
557 EXPECT_TRUE(IsPathInUse(new_target_path));
559 // Destroying the item should release the reservation.
560 SetDownloadItemState(item.get(), DownloadItem::COMPLETE);
561 item.reset();
562 message_loop_.RunUntilIdle();
563 EXPECT_FALSE(IsPathInUse(new_target_path));
566 // Tests for long name truncation. On other platforms automatic truncation
567 // is not performed (yet).
568 #if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS)
570 TEST_F(DownloadPathReservationTrackerTest, BasicTruncation) {
571 int real_max_length =
572 base::GetMaximumPathComponentLength(default_download_path());
573 ASSERT_NE(-1, real_max_length);
575 // TODO(kinaba): the current implementation leaves spaces for appending
576 // ".crdownload". So take it into account. Should be removed in the future.
577 const size_t max_length = real_max_length - 11;
579 scoped_ptr<MockDownloadItem> item(CreateDownloadItem(1));
580 base::FilePath path(GetLongNamePathInDownloadsDirectory(
581 max_length, FILE_PATH_LITERAL(".txt")));
582 ASSERT_FALSE(IsPathInUse(path));
584 base::FilePath reserved_path;
585 bool verified = false;
586 DownloadPathReservationTracker::FilenameConflictAction conflict_action =
587 DownloadPathReservationTracker::OVERWRITE;
588 bool create_directory = false;
589 CallGetReservedPath(
590 item.get(),
591 path,
592 create_directory,
593 conflict_action,
594 &reserved_path,
595 &verified);
596 EXPECT_TRUE(IsPathInUse(reserved_path));
597 EXPECT_TRUE(verified);
598 // The file name length is truncated to max_length.
599 EXPECT_EQ(max_length, reserved_path.BaseName().value().size());
600 // But the extension is kept unchanged.
601 EXPECT_EQ(path.Extension(), reserved_path.Extension());
602 SetDownloadItemState(item.get(), DownloadItem::COMPLETE);
605 TEST_F(DownloadPathReservationTrackerTest, TruncationConflict) {
606 int real_max_length =
607 base::GetMaximumPathComponentLength(default_download_path());
608 ASSERT_NE(-1, real_max_length);
609 const size_t max_length = real_max_length - 11;
611 scoped_ptr<MockDownloadItem> item(CreateDownloadItem(1));
612 base::FilePath path(GetLongNamePathInDownloadsDirectory(
613 max_length, FILE_PATH_LITERAL(".txt")));
614 base::FilePath path0(GetLongNamePathInDownloadsDirectory(
615 max_length - 4, FILE_PATH_LITERAL(".txt")));
616 base::FilePath path1(GetLongNamePathInDownloadsDirectory(
617 max_length - 8, FILE_PATH_LITERAL(" (1).txt")));
618 base::FilePath path2(GetLongNamePathInDownloadsDirectory(
619 max_length - 8, FILE_PATH_LITERAL(" (2).txt")));
620 ASSERT_FALSE(IsPathInUse(path));
621 // "aaa...aaaaaaa.txt" (truncated path) and
622 // "aaa...aaa (1).txt" (truncated and first uniquification try) exists.
623 // "aaa...aaa (2).txt" should be used.
624 ASSERT_EQ(0, base::WriteFile(path0, "", 0));
625 ASSERT_EQ(0, base::WriteFile(path1, "", 0));
627 base::FilePath reserved_path;
628 bool verified = false;
629 DownloadPathReservationTracker::FilenameConflictAction conflict_action =
630 DownloadPathReservationTracker::UNIQUIFY;
631 bool create_directory = false;
632 CallGetReservedPath(
633 item.get(),
634 path,
635 create_directory,
636 conflict_action,
637 &reserved_path,
638 &verified);
639 EXPECT_TRUE(IsPathInUse(reserved_path));
640 EXPECT_TRUE(verified);
641 EXPECT_EQ(path2, reserved_path);
642 SetDownloadItemState(item.get(), DownloadItem::COMPLETE);
645 TEST_F(DownloadPathReservationTrackerTest, TruncationFail) {
646 int real_max_length =
647 base::GetMaximumPathComponentLength(default_download_path());
648 ASSERT_NE(-1, real_max_length);
649 const size_t max_length = real_max_length - 11;
651 scoped_ptr<MockDownloadItem> item(CreateDownloadItem(1));
652 base::FilePath path(GetPathInDownloadsDirectory(
653 (FILE_PATH_LITERAL("a.") +
654 base::FilePath::StringType(max_length, 'b')).c_str()));
655 ASSERT_FALSE(IsPathInUse(path));
657 base::FilePath reserved_path;
658 bool verified = false;
659 DownloadPathReservationTracker::FilenameConflictAction conflict_action =
660 DownloadPathReservationTracker::OVERWRITE;
661 bool create_directory = false;
662 CallGetReservedPath(
663 item.get(),
664 path,
665 create_directory,
666 conflict_action,
667 &reserved_path,
668 &verified);
669 // We cannot truncate a path with very long extension.
670 EXPECT_FALSE(verified);
671 SetDownloadItemState(item.get(), DownloadItem::COMPLETE);
674 #endif