Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / download / download_path_reservation_tracker_unittest.cc
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.
4
5 #include "base/file_util.h"
6 #include "base/files/file_path.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"
19
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;
27
28 namespace {
29
30 class DownloadPathReservationTrackerTest : public testing::Test {
31  public:
32   DownloadPathReservationTrackerTest();
33
34   // testing::Test
35   virtual void SetUp() OVERRIDE;
36   virtual void TearDown() OVERRIDE;
37
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);
49
50   const base::FilePath& default_download_path() const {
51     return default_download_path_;
52   }
53   void set_default_download_path(const base::FilePath& path) {
54     default_download_path_ = path;
55   }
56   // Creates a name of form 'a'*repeat + suffix
57   base::FilePath GetLongNamePathInDownloadsDirectory(
58       size_t repeat, const base::FilePath::CharType* suffix);
59
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_;
66
67  private:
68   void TestReservedPathCallback(base::FilePath* return_path,
69                                 bool* return_verified, bool* did_run_callback,
70                                 const base::FilePath& path, bool verified);
71 };
72
73 DownloadPathReservationTrackerTest::DownloadPathReservationTrackerTest()
74     : ui_thread_(BrowserThread::UI, &message_loop_),
75       file_thread_(BrowserThread::FILE, &message_loop_) {
76 }
77
78 void DownloadPathReservationTrackerTest::SetUp() {
79   ASSERT_TRUE(test_download_dir_.CreateUniqueTempDir());
80   set_default_download_path(test_download_dir_.path());
81 }
82
83 void DownloadPathReservationTrackerTest::TearDown() {
84   message_loop_.RunUntilIdle();
85 }
86
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;
97 }
98
99 base::FilePath DownloadPathReservationTrackerTest::GetPathInDownloadsDirectory(
100     const base::FilePath::CharType* suffix) {
101   return default_download_path().Append(suffix).NormalizePathSeparators();
102 }
103
104 bool DownloadPathReservationTrackerTest::IsPathInUse(
105     const base::FilePath& path) {
106   return DownloadPathReservationTracker::IsPathInUseForTesting(path);
107 }
108
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);
132 }
133
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;
140 }
141
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());
148 }
149
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();
155 }
156
157 }  // namespace
158
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));
165
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());
181
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));
187 }
188
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));
195
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());
211
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));
216 }
217
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));
224
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());
240
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));
248 }
249
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));
264
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());
285
286   SetDownloadItemState(item.get(), DownloadItem::COMPLETE);
287   item.reset();
288   message_loop_.RunUntilIdle();
289   EXPECT_TRUE(IsPathInUse(path));
290   EXPECT_FALSE(IsPathInUse(reserved_path));
291 }
292
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));
302
303   base::FilePath reserved_path1;
304   bool verified = false;
305   bool create_directory = false;
306
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);
318
319
320   {
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);
336   }
337   message_loop_.RunUntilIdle();
338   EXPECT_TRUE(IsPathInUse(path));
339   EXPECT_FALSE(IsPathInUse(uniquified_path));
340
341   {
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);
357   }
358   message_loop_.RunUntilIdle();
359
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));
374
375   EXPECT_EQ(path.value(), reserved_path1.value());
376   EXPECT_EQ(path.value(), reserved_path3.value());
377
378   SetDownloadItemState(item1.get(), DownloadItem::COMPLETE);
379   SetDownloadItemState(item3.get(), DownloadItem::COMPLETE);
380 }
381
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;
393
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;
405     }
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);
418   }
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());
433
434   SetDownloadItemState(item.get(), DownloadItem::COMPLETE);
435   for (int i = 0; i <= DownloadPathReservationTracker::kMaxUniqueFiles; i++)
436     SetDownloadItemState(items[i].get(), DownloadItem::COMPLETE);
437 }
438
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));
447
448   {
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());
467   }
468   SetDownloadItemState(item.get(), DownloadItem::COMPLETE);
469 }
470
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;
481
482   {
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);
496   }
497   ASSERT_FALSE(IsPathInUse(path));
498   {
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);
514   }
515 }
516
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));
524
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());
540
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));
547
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));
558
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));
564 }
565
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)
569
570 TEST_F(DownloadPathReservationTrackerTest, BasicTruncation) {
571   int real_max_length =
572       base::GetMaximumPathComponentLength(default_download_path());
573   ASSERT_NE(-1, real_max_length);
574
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;
578
579   scoped_ptr<MockDownloadItem> item(CreateDownloadItem(1));
580   base::FilePath path(GetLongNamePathInDownloadsDirectory(
581       max_length, FILE_PATH_LITERAL(".txt")));
582   ASSERT_FALSE(IsPathInUse(path));
583
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);
603 }
604
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;
610
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));
626
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);
643 }
644
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;
650
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));
656
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);
672 }
673
674 #endif