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 <memory> |
| 9 |
8 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
9 #include "base/files/file_util.h" | 11 #include "base/files/file_util.h" |
10 #include "base/files/scoped_temp_dir.h" | 12 #include "base/files/scoped_temp_dir.h" |
11 #include "base/memory/weak_ptr.h" | 13 #include "base/memory/weak_ptr.h" |
12 #include "base/message_loop/message_loop.h" | 14 #include "base/message_loop/message_loop.h" |
13 #include "base/observer_list.h" | 15 #include "base/observer_list.h" |
14 #include "base/run_loop.h" | 16 #include "base/run_loop.h" |
15 #include "base/strings/stringprintf.h" | 17 #include "base/strings/stringprintf.h" |
16 #include "base/test/test_file_util.h" | 18 #include "base/test/test_file_util.h" |
17 #include "build/build_config.h" | 19 #include "build/build_config.h" |
18 #include "chrome/browser/download/download_path_reservation_tracker.h" | 20 #include "chrome/browser/download/download_path_reservation_tracker.h" |
19 #include "chrome/browser/download/download_target_determiner.h" | 21 #include "chrome/browser/download/download_target_determiner.h" |
20 #include "content/public/test/mock_download_item.h" | 22 #include "content/public/test/mock_download_item.h" |
21 #include "content/public/test/test_browser_thread.h" | 23 #include "content/public/test/test_browser_thread.h" |
| 24 #include "net/base/filename_util.h" |
22 #include "testing/gmock/include/gmock/gmock.h" | 25 #include "testing/gmock/include/gmock/gmock.h" |
23 #include "testing/gtest/include/gtest/gtest.h" | 26 #include "testing/gtest/include/gtest/gtest.h" |
24 | 27 |
25 using content::BrowserThread; | 28 using content::BrowserThread; |
26 using content::DownloadItem; | 29 using content::DownloadItem; |
27 using content::MockDownloadItem; | 30 using content::MockDownloadItem; |
28 using testing::AnyNumber; | 31 using testing::AnyNumber; |
29 using testing::Return; | 32 using testing::Return; |
30 using testing::ReturnRef; | 33 using testing::ReturnRef; |
31 using testing::ReturnRefOfCopy; | 34 using testing::ReturnRefOfCopy; |
(...skipping 11 matching lines...) Expand all Loading... |
43 MockDownloadItem* CreateDownloadItem(int32_t id); | 46 MockDownloadItem* CreateDownloadItem(int32_t id); |
44 base::FilePath GetPathInDownloadsDirectory( | 47 base::FilePath GetPathInDownloadsDirectory( |
45 const base::FilePath::CharType* suffix); | 48 const base::FilePath::CharType* suffix); |
46 bool IsPathInUse(const base::FilePath& path); | 49 bool IsPathInUse(const base::FilePath& path); |
47 void CallGetReservedPath( | 50 void CallGetReservedPath( |
48 DownloadItem* download_item, | 51 DownloadItem* download_item, |
49 const base::FilePath& target_path, | 52 const base::FilePath& target_path, |
50 bool create_directory, | 53 bool create_directory, |
51 DownloadPathReservationTracker::FilenameConflictAction conflict_action, | 54 DownloadPathReservationTracker::FilenameConflictAction conflict_action, |
52 base::FilePath* return_path, | 55 base::FilePath* return_path, |
53 bool* return_verified); | 56 PathValidationResult* return_result); |
54 | 57 |
55 const base::FilePath& default_download_path() const { | 58 const base::FilePath& default_download_path() const { |
56 return default_download_path_; | 59 return default_download_path_; |
57 } | 60 } |
58 void set_default_download_path(const base::FilePath& path) { | 61 void set_default_download_path(const base::FilePath& path) { |
59 default_download_path_ = path; | 62 default_download_path_ = path; |
60 } | 63 } |
61 // Creates a name of form 'a'*repeat + suffix | 64 // Creates a name of form 'a'*repeat + suffix |
62 base::FilePath GetLongNamePathInDownloadsDirectory( | 65 base::FilePath GetLongNamePathInDownloadsDirectory( |
63 size_t repeat, const base::FilePath::CharType* suffix); | 66 size_t repeat, |
| 67 const base::FilePath::CharType* suffix); |
64 | 68 |
65 protected: | 69 protected: |
66 base::ScopedTempDir test_download_dir_; | 70 base::ScopedTempDir test_download_dir_; |
67 base::FilePath default_download_path_; | 71 base::FilePath default_download_path_; |
68 base::MessageLoopForUI message_loop_; | 72 base::MessageLoopForUI message_loop_; |
69 content::TestBrowserThread ui_thread_; | 73 content::TestBrowserThread ui_thread_; |
70 content::TestBrowserThread file_thread_; | 74 content::TestBrowserThread file_thread_; |
71 | 75 |
72 private: | 76 private: |
73 void TestReservedPathCallback(base::FilePath* return_path, | 77 void TestReservedPathCallback(base::FilePath* return_path, |
74 bool* return_verified, bool* did_run_callback, | 78 PathValidationResult* return_result, |
75 const base::FilePath& path, bool verified); | 79 const base::Closure& quit_closure, |
| 80 PathValidationResult result, |
| 81 const base::FilePath& path); |
76 }; | 82 }; |
77 | 83 |
78 DownloadPathReservationTrackerTest::DownloadPathReservationTrackerTest() | 84 DownloadPathReservationTrackerTest::DownloadPathReservationTrackerTest() |
79 : ui_thread_(BrowserThread::UI, &message_loop_), | 85 : ui_thread_(BrowserThread::UI, &message_loop_), |
80 file_thread_(BrowserThread::FILE, &message_loop_) { | 86 file_thread_(BrowserThread::FILE, &message_loop_) { |
81 } | 87 } |
82 | 88 |
83 void DownloadPathReservationTrackerTest::SetUp() { | 89 void DownloadPathReservationTrackerTest::SetUp() { |
84 ASSERT_TRUE(test_download_dir_.CreateUniqueTempDir()); | 90 ASSERT_TRUE(test_download_dir_.CreateUniqueTempDir()); |
85 set_default_download_path(test_download_dir_.GetPath()); | 91 set_default_download_path(test_download_dir_.GetPath()); |
86 } | 92 } |
87 | 93 |
88 void DownloadPathReservationTrackerTest::TearDown() { | 94 void DownloadPathReservationTrackerTest::TearDown() { |
89 base::RunLoop().RunUntilIdle(); | 95 base::RunLoop().RunUntilIdle(); |
90 } | 96 } |
91 | 97 |
92 MockDownloadItem* DownloadPathReservationTrackerTest::CreateDownloadItem( | 98 MockDownloadItem* DownloadPathReservationTrackerTest::CreateDownloadItem( |
93 int32_t id) { | 99 int32_t id) { |
94 MockDownloadItem* item = new ::testing::StrictMock<MockDownloadItem>; | 100 MockDownloadItem* item = new ::testing::StrictMock<MockDownloadItem>; |
95 EXPECT_CALL(*item, GetId()) | 101 EXPECT_CALL(*item, GetId()) |
96 .WillRepeatedly(Return(id)); | 102 .WillRepeatedly(Return(id)); |
97 EXPECT_CALL(*item, GetTargetFilePath()) | 103 EXPECT_CALL(*item, GetTargetFilePath()) |
98 .WillRepeatedly(ReturnRefOfCopy(base::FilePath())); | 104 .WillRepeatedly(ReturnRefOfCopy(base::FilePath())); |
99 EXPECT_CALL(*item, GetState()) | 105 EXPECT_CALL(*item, GetState()) |
100 .WillRepeatedly(Return(DownloadItem::IN_PROGRESS)); | 106 .WillRepeatedly(Return(DownloadItem::IN_PROGRESS)); |
| 107 EXPECT_CALL(*item, GetURL()).WillRepeatedly(ReturnRefOfCopy(GURL())); |
101 return item; | 108 return item; |
102 } | 109 } |
103 | 110 |
104 base::FilePath DownloadPathReservationTrackerTest::GetPathInDownloadsDirectory( | 111 base::FilePath DownloadPathReservationTrackerTest::GetPathInDownloadsDirectory( |
105 const base::FilePath::CharType* suffix) { | 112 const base::FilePath::CharType* suffix) { |
106 return default_download_path().Append(suffix).NormalizePathSeparators(); | 113 return default_download_path().Append(suffix).NormalizePathSeparators(); |
107 } | 114 } |
108 | 115 |
109 bool DownloadPathReservationTrackerTest::IsPathInUse( | 116 bool DownloadPathReservationTrackerTest::IsPathInUse( |
110 const base::FilePath& path) { | 117 const base::FilePath& path) { |
111 return DownloadPathReservationTracker::IsPathInUseForTesting(path); | 118 return DownloadPathReservationTracker::IsPathInUseForTesting(path); |
112 } | 119 } |
113 | 120 |
114 void DownloadPathReservationTrackerTest::CallGetReservedPath( | 121 void DownloadPathReservationTrackerTest::CallGetReservedPath( |
115 DownloadItem* download_item, | 122 DownloadItem* download_item, |
116 const base::FilePath& target_path, | 123 const base::FilePath& target_path, |
117 bool create_directory, | 124 bool create_directory, |
118 DownloadPathReservationTracker::FilenameConflictAction conflict_action, | 125 DownloadPathReservationTracker::FilenameConflictAction conflict_action, |
119 base::FilePath* return_path, | 126 base::FilePath* return_path, |
120 bool* return_verified) { | 127 PathValidationResult* return_result) { |
121 // Weak pointer factory to prevent the callback from running after this | 128 // Weak pointer factory to prevent the callback from running after this |
122 // function has returned. | 129 // function has returned. |
123 base::WeakPtrFactory<DownloadPathReservationTrackerTest> weak_ptr_factory( | 130 base::WeakPtrFactory<DownloadPathReservationTrackerTest> weak_ptr_factory( |
124 this); | 131 this); |
125 bool did_run_callback = false; | 132 base::RunLoop run_loop; |
126 DownloadPathReservationTracker::GetReservedPath( | 133 DownloadPathReservationTracker::GetReservedPath( |
127 download_item, | 134 download_item, target_path, default_download_path(), create_directory, |
128 target_path, | |
129 default_download_path(), | |
130 create_directory, | |
131 conflict_action, | 135 conflict_action, |
132 base::Bind(&DownloadPathReservationTrackerTest::TestReservedPathCallback, | 136 base::Bind(&DownloadPathReservationTrackerTest::TestReservedPathCallback, |
133 weak_ptr_factory.GetWeakPtr(), return_path, return_verified, | 137 weak_ptr_factory.GetWeakPtr(), return_path, return_result, |
134 &did_run_callback)); | 138 run_loop.QuitClosure())); |
135 base::RunLoop().RunUntilIdle(); | 139 run_loop.Run(); |
136 EXPECT_TRUE(did_run_callback); | |
137 } | 140 } |
138 | 141 |
139 void DownloadPathReservationTrackerTest::TestReservedPathCallback( | 142 void DownloadPathReservationTrackerTest::TestReservedPathCallback( |
140 base::FilePath* return_path, bool* return_verified, bool* did_run_callback, | 143 base::FilePath* return_path, |
141 const base::FilePath& path, bool verified) { | 144 PathValidationResult* return_result, |
142 *did_run_callback = true; | 145 const base::Closure& quit_closure, |
| 146 PathValidationResult result, |
| 147 const base::FilePath& path) { |
143 *return_path = path; | 148 *return_path = path; |
144 *return_verified = verified; | 149 *return_result = result; |
| 150 quit_closure.Run(); |
145 } | 151 } |
146 | 152 |
147 base::FilePath | 153 base::FilePath |
148 DownloadPathReservationTrackerTest::GetLongNamePathInDownloadsDirectory( | 154 DownloadPathReservationTrackerTest::GetLongNamePathInDownloadsDirectory( |
149 size_t repeat, const base::FilePath::CharType* suffix) { | 155 size_t repeat, const base::FilePath::CharType* suffix) { |
150 return GetPathInDownloadsDirectory( | 156 return GetPathInDownloadsDirectory( |
151 (base::FilePath::StringType(repeat, FILE_PATH_LITERAL('a')) | 157 (base::FilePath::StringType(repeat, FILE_PATH_LITERAL('a')) |
152 + suffix).c_str()); | 158 + suffix).c_str()); |
153 } | 159 } |
154 | 160 |
155 void SetDownloadItemState(content::MockDownloadItem* download_item, | 161 void SetDownloadItemState(content::MockDownloadItem* download_item, |
156 content::DownloadItem::DownloadState state) { | 162 content::DownloadItem::DownloadState state) { |
157 EXPECT_CALL(*download_item, GetState()) | 163 EXPECT_CALL(*download_item, GetState()) |
158 .WillRepeatedly(Return(state)); | 164 .WillRepeatedly(Return(state)); |
159 download_item->NotifyObserversDownloadUpdated(); | 165 download_item->NotifyObserversDownloadUpdated(); |
160 } | 166 } |
161 | 167 |
162 } // namespace | 168 } // namespace |
163 | 169 |
164 // A basic reservation is acquired and committed. | 170 // A basic reservation is acquired and committed. |
165 TEST_F(DownloadPathReservationTrackerTest, BasicReservation) { | 171 TEST_F(DownloadPathReservationTrackerTest, BasicReservation) { |
166 std::unique_ptr<MockDownloadItem> item(CreateDownloadItem(1)); | 172 std::unique_ptr<MockDownloadItem> item(CreateDownloadItem(1)); |
167 base::FilePath path( | 173 base::FilePath path( |
168 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt"))); | 174 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt"))); |
169 ASSERT_FALSE(IsPathInUse(path)); | 175 ASSERT_FALSE(IsPathInUse(path)); |
170 | 176 |
171 base::FilePath reserved_path; | 177 base::FilePath reserved_path; |
172 bool verified = false; | 178 PathValidationResult result = PathValidationResult::NAME_TOO_LONG; |
173 DownloadPathReservationTracker::FilenameConflictAction conflict_action = | 179 DownloadPathReservationTracker::FilenameConflictAction conflict_action = |
174 DownloadPathReservationTracker::OVERWRITE; | 180 DownloadPathReservationTracker::OVERWRITE; |
175 bool create_directory = false; | 181 bool create_directory = false; |
176 CallGetReservedPath( | 182 CallGetReservedPath(item.get(), path, create_directory, conflict_action, |
177 item.get(), | 183 &reserved_path, &result); |
178 path, | |
179 create_directory, | |
180 conflict_action, | |
181 &reserved_path, | |
182 &verified); | |
183 EXPECT_TRUE(IsPathInUse(path)); | 184 EXPECT_TRUE(IsPathInUse(path)); |
184 EXPECT_TRUE(verified); | 185 EXPECT_EQ(PathValidationResult::SUCCESS, result); |
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 base::RunLoop().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 PathValidationResult result = PathValidationResult::NAME_TOO_LONG; |
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(item.get(), path, create_directory, conflict_action, |
207 item.get(), | 208 &reserved_path, &result); |
208 path, | |
209 create_directory, | |
210 conflict_action, | |
211 &reserved_path, | |
212 &verified); | |
213 EXPECT_TRUE(IsPathInUse(path)); | 209 EXPECT_TRUE(IsPathInUse(path)); |
214 EXPECT_TRUE(verified); | 210 EXPECT_EQ(PathValidationResult::SUCCESS, result); |
215 EXPECT_EQ(path.value(), reserved_path.value()); | 211 EXPECT_EQ(path.value(), reserved_path.value()); |
216 | 212 |
217 // Once the download is interrupted, the path should become available again. | 213 // Once the download is interrupted, the path should become available again. |
218 SetDownloadItemState(item.get(), DownloadItem::INTERRUPTED); | 214 SetDownloadItemState(item.get(), DownloadItem::INTERRUPTED); |
219 base::RunLoop().RunUntilIdle(); | 215 base::RunLoop().RunUntilIdle(); |
220 EXPECT_FALSE(IsPathInUse(path)); | 216 EXPECT_FALSE(IsPathInUse(path)); |
221 } | 217 } |
222 | 218 |
223 // A completed download should also lose its reservation. | 219 // A completed download should also lose its reservation. |
224 TEST_F(DownloadPathReservationTrackerTest, CompleteDownload) { | 220 TEST_F(DownloadPathReservationTrackerTest, CompleteDownload) { |
225 std::unique_ptr<MockDownloadItem> item(CreateDownloadItem(1)); | 221 std::unique_ptr<MockDownloadItem> item(CreateDownloadItem(1)); |
226 base::FilePath path( | 222 base::FilePath path( |
227 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt"))); | 223 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt"))); |
228 ASSERT_FALSE(IsPathInUse(path)); | 224 ASSERT_FALSE(IsPathInUse(path)); |
229 | 225 |
230 base::FilePath reserved_path; | 226 base::FilePath reserved_path; |
231 bool verified = false; | 227 PathValidationResult result = PathValidationResult::NAME_TOO_LONG; |
232 DownloadPathReservationTracker::FilenameConflictAction conflict_action = | 228 DownloadPathReservationTracker::FilenameConflictAction conflict_action = |
233 DownloadPathReservationTracker::OVERWRITE; | 229 DownloadPathReservationTracker::OVERWRITE; |
234 bool create_directory = false; | 230 bool create_directory = false; |
235 CallGetReservedPath( | 231 CallGetReservedPath(item.get(), path, create_directory, conflict_action, |
236 item.get(), | 232 &reserved_path, &result); |
237 path, | |
238 create_directory, | |
239 conflict_action, | |
240 &reserved_path, | |
241 &verified); | |
242 EXPECT_TRUE(IsPathInUse(path)); | 233 EXPECT_TRUE(IsPathInUse(path)); |
243 EXPECT_TRUE(verified); | 234 EXPECT_EQ(PathValidationResult::SUCCESS, result); |
244 EXPECT_EQ(path.value(), reserved_path.value()); | 235 EXPECT_EQ(path.value(), reserved_path.value()); |
245 | 236 |
246 // Once the download completes, the path should become available again. For a | 237 // 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. | 238 // 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 | 239 // The path wouldn't be available since it is occupied on disk by the |
249 // completed download. | 240 // completed download. |
250 SetDownloadItemState(item.get(), DownloadItem::COMPLETE); | 241 SetDownloadItemState(item.get(), DownloadItem::COMPLETE); |
251 base::RunLoop().RunUntilIdle(); | 242 base::RunLoop().RunUntilIdle(); |
252 EXPECT_FALSE(IsPathInUse(path)); | 243 EXPECT_FALSE(IsPathInUse(path)); |
253 } | 244 } |
254 | 245 |
255 // If there are files on the file system, a unique reservation should uniquify | 246 // If there are files on the file system, a unique reservation should uniquify |
256 // around it. | 247 // around it. |
257 TEST_F(DownloadPathReservationTrackerTest, ConflictingFiles) { | 248 TEST_F(DownloadPathReservationTrackerTest, ConflictingFiles) { |
258 std::unique_ptr<MockDownloadItem> item(CreateDownloadItem(1)); | 249 std::unique_ptr<MockDownloadItem> item(CreateDownloadItem(1)); |
259 base::FilePath path( | 250 base::FilePath path( |
260 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt"))); | 251 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt"))); |
261 base::FilePath path1( | 252 base::FilePath path1( |
262 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo (1).txt"))); | 253 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo (1).txt"))); |
263 // Create a file at |path|, and a .crdownload file at |path1|. | 254 // Create a file at |path|, and a .crdownload file at |path1|. |
264 ASSERT_EQ(0, base::WriteFile(path, "", 0)); | 255 ASSERT_EQ(0, base::WriteFile(path, "", 0)); |
265 ASSERT_EQ(0, | 256 ASSERT_EQ(0, |
266 base::WriteFile( | 257 base::WriteFile( |
267 DownloadTargetDeterminer::GetCrDownloadPath(path1), "", 0)); | 258 DownloadTargetDeterminer::GetCrDownloadPath(path1), "", 0)); |
268 ASSERT_TRUE(IsPathInUse(path)); | 259 ASSERT_TRUE(IsPathInUse(path)); |
269 | 260 |
270 base::FilePath reserved_path; | 261 base::FilePath reserved_path; |
271 bool verified = false; | 262 PathValidationResult result = PathValidationResult::NAME_TOO_LONG; |
272 bool create_directory = false; | 263 bool create_directory = false; |
273 DownloadPathReservationTracker::FilenameConflictAction conflict_action = | 264 DownloadPathReservationTracker::FilenameConflictAction conflict_action = |
274 DownloadPathReservationTracker::UNIQUIFY; | 265 DownloadPathReservationTracker::UNIQUIFY; |
275 CallGetReservedPath( | 266 CallGetReservedPath(item.get(), path, create_directory, conflict_action, |
276 item.get(), | 267 &reserved_path, &result); |
277 path, | |
278 create_directory, | |
279 conflict_action, | |
280 &reserved_path, | |
281 &verified); | |
282 EXPECT_TRUE(IsPathInUse(path)); | 268 EXPECT_TRUE(IsPathInUse(path)); |
283 EXPECT_TRUE(IsPathInUse(reserved_path)); | 269 EXPECT_TRUE(IsPathInUse(reserved_path)); |
284 EXPECT_TRUE(verified); | 270 EXPECT_EQ(PathValidationResult::SUCCESS, result); |
285 // The path should be uniquified, skipping over foo.txt but not over | 271 // The path should be uniquified, skipping over foo.txt but not over |
286 // "foo (1).txt.crdownload" | 272 // "foo (1).txt.crdownload" |
287 EXPECT_EQ( | 273 EXPECT_EQ( |
288 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo (1).txt")).value(), | 274 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo (1).txt")).value(), |
289 reserved_path.value()); | 275 reserved_path.value()); |
290 | 276 |
291 SetDownloadItemState(item.get(), DownloadItem::COMPLETE); | 277 SetDownloadItemState(item.get(), DownloadItem::COMPLETE); |
292 item.reset(); | 278 item.reset(); |
293 base::RunLoop().RunUntilIdle(); | 279 base::RunLoop().RunUntilIdle(); |
294 EXPECT_TRUE(IsPathInUse(path)); | 280 EXPECT_TRUE(IsPathInUse(path)); |
295 EXPECT_FALSE(IsPathInUse(reserved_path)); | 281 EXPECT_FALSE(IsPathInUse(reserved_path)); |
296 } | 282 } |
297 | 283 |
| 284 // If there are conflicting files on the file system, an overwriting reservation |
| 285 // should succeed without altering the target path. |
| 286 TEST_F(DownloadPathReservationTrackerTest, ConflictingFiles_Overwrite) { |
| 287 std::unique_ptr<MockDownloadItem> item(CreateDownloadItem(1)); |
| 288 base::FilePath path( |
| 289 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt"))); |
| 290 // Create a file at |path|. |
| 291 ASSERT_EQ(0, base::WriteFile(path, "", 0)); |
| 292 ASSERT_TRUE(IsPathInUse(path)); |
| 293 |
| 294 base::FilePath reserved_path; |
| 295 PathValidationResult result = PathValidationResult::NAME_TOO_LONG; |
| 296 bool create_directory = false; |
| 297 DownloadPathReservationTracker::FilenameConflictAction conflict_action = |
| 298 DownloadPathReservationTracker::OVERWRITE; |
| 299 CallGetReservedPath(item.get(), path, create_directory, conflict_action, |
| 300 &reserved_path, &result); |
| 301 EXPECT_TRUE(IsPathInUse(path)); |
| 302 EXPECT_TRUE(IsPathInUse(reserved_path)); |
| 303 EXPECT_EQ(PathValidationResult::SUCCESS, result); |
| 304 EXPECT_EQ(path.value(), reserved_path.value()); |
| 305 |
| 306 SetDownloadItemState(item.get(), DownloadItem::COMPLETE); |
| 307 item.reset(); |
| 308 base::RunLoop().RunUntilIdle(); |
| 309 } |
| 310 |
298 // Multiple reservations for the same path should uniquify around each other. | 311 // Multiple reservations for the same path should uniquify around each other. |
299 TEST_F(DownloadPathReservationTrackerTest, ConflictingReservations) { | 312 TEST_F(DownloadPathReservationTrackerTest, ConflictingReservations) { |
300 std::unique_ptr<MockDownloadItem> item1(CreateDownloadItem(1)); | 313 std::unique_ptr<MockDownloadItem> item1(CreateDownloadItem(1)); |
301 base::FilePath path( | 314 base::FilePath path( |
302 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt"))); | 315 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt"))); |
303 base::FilePath uniquified_path( | 316 base::FilePath uniquified_path( |
304 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo (1).txt"))); | 317 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo (1).txt"))); |
305 ASSERT_FALSE(IsPathInUse(path)); | 318 ASSERT_FALSE(IsPathInUse(path)); |
306 ASSERT_FALSE(IsPathInUse(uniquified_path)); | 319 ASSERT_FALSE(IsPathInUse(uniquified_path)); |
307 | 320 |
308 base::FilePath reserved_path1; | 321 base::FilePath reserved_path1; |
309 bool verified = false; | 322 PathValidationResult result = PathValidationResult::NAME_TOO_LONG; |
310 bool create_directory = false; | 323 bool create_directory = false; |
311 | 324 |
312 DownloadPathReservationTracker::FilenameConflictAction conflict_action = | 325 DownloadPathReservationTracker::FilenameConflictAction conflict_action = |
313 DownloadPathReservationTracker::UNIQUIFY; | 326 DownloadPathReservationTracker::UNIQUIFY; |
314 CallGetReservedPath( | 327 CallGetReservedPath(item1.get(), path, create_directory, conflict_action, |
315 item1.get(), | 328 &reserved_path1, &result); |
316 path, | |
317 create_directory, | |
318 conflict_action, | |
319 &reserved_path1, | |
320 &verified); | |
321 EXPECT_TRUE(IsPathInUse(path)); | 329 EXPECT_TRUE(IsPathInUse(path)); |
322 EXPECT_TRUE(verified); | 330 EXPECT_EQ(PathValidationResult::SUCCESS, result); |
323 | |
324 | 331 |
325 { | 332 { |
326 // Requesting a reservation for the same path with uniquification results in | 333 // Requesting a reservation for the same path with uniquification results in |
327 // a uniquified path. | 334 // a uniquified path. |
328 std::unique_ptr<MockDownloadItem> item2(CreateDownloadItem(2)); | 335 std::unique_ptr<MockDownloadItem> item2(CreateDownloadItem(2)); |
329 base::FilePath reserved_path2; | 336 base::FilePath reserved_path2; |
330 CallGetReservedPath( | 337 CallGetReservedPath(item2.get(), path, create_directory, conflict_action, |
331 item2.get(), | 338 &reserved_path2, &result); |
332 path, | |
333 create_directory, | |
334 conflict_action, | |
335 &reserved_path2, | |
336 &verified); | |
337 EXPECT_TRUE(IsPathInUse(path)); | 339 EXPECT_TRUE(IsPathInUse(path)); |
338 EXPECT_TRUE(IsPathInUse(uniquified_path)); | 340 EXPECT_TRUE(IsPathInUse(uniquified_path)); |
339 EXPECT_EQ(uniquified_path.value(), reserved_path2.value()); | 341 EXPECT_EQ(uniquified_path.value(), reserved_path2.value()); |
340 SetDownloadItemState(item2.get(), DownloadItem::COMPLETE); | 342 SetDownloadItemState(item2.get(), DownloadItem::COMPLETE); |
341 } | 343 } |
342 base::RunLoop().RunUntilIdle(); | 344 base::RunLoop().RunUntilIdle(); |
343 EXPECT_TRUE(IsPathInUse(path)); | 345 EXPECT_TRUE(IsPathInUse(path)); |
344 EXPECT_FALSE(IsPathInUse(uniquified_path)); | 346 EXPECT_FALSE(IsPathInUse(uniquified_path)); |
345 | 347 |
346 { | 348 { |
347 // Since the previous download item was removed, requesting a reservation | 349 // Since the previous download item was removed, requesting a reservation |
348 // for the same path should result in the same uniquified path. | 350 // for the same path should result in the same uniquified path. |
349 std::unique_ptr<MockDownloadItem> item2(CreateDownloadItem(2)); | 351 std::unique_ptr<MockDownloadItem> item2(CreateDownloadItem(2)); |
350 base::FilePath reserved_path2; | 352 base::FilePath reserved_path2; |
351 CallGetReservedPath( | 353 CallGetReservedPath(item2.get(), path, create_directory, conflict_action, |
352 item2.get(), | 354 &reserved_path2, &result); |
353 path, | |
354 create_directory, | |
355 conflict_action, | |
356 &reserved_path2, | |
357 &verified); | |
358 EXPECT_TRUE(IsPathInUse(path)); | 355 EXPECT_TRUE(IsPathInUse(path)); |
359 EXPECT_TRUE(IsPathInUse(uniquified_path)); | 356 EXPECT_TRUE(IsPathInUse(uniquified_path)); |
360 EXPECT_EQ(uniquified_path.value(), reserved_path2.value()); | 357 EXPECT_EQ(uniquified_path.value(), reserved_path2.value()); |
361 SetDownloadItemState(item2.get(), DownloadItem::COMPLETE); | 358 SetDownloadItemState(item2.get(), DownloadItem::COMPLETE); |
362 } | 359 } |
363 base::RunLoop().RunUntilIdle(); | 360 base::RunLoop().RunUntilIdle(); |
364 | 361 |
365 // Now acquire an overwriting reservation. We should end up with the same | 362 // Now acquire an overwriting reservation. We should end up with the same |
366 // non-uniquified path for both reservations. | 363 // non-uniquified path for both reservations. |
367 std::unique_ptr<MockDownloadItem> item3(CreateDownloadItem(2)); | 364 std::unique_ptr<MockDownloadItem> item3(CreateDownloadItem(2)); |
368 base::FilePath reserved_path3; | 365 base::FilePath reserved_path3; |
369 conflict_action = DownloadPathReservationTracker::OVERWRITE; | 366 conflict_action = DownloadPathReservationTracker::OVERWRITE; |
370 CallGetReservedPath( | 367 CallGetReservedPath(item3.get(), path, create_directory, conflict_action, |
371 item3.get(), | 368 &reserved_path3, &result); |
372 path, | |
373 create_directory, | |
374 conflict_action, | |
375 &reserved_path3, | |
376 &verified); | |
377 EXPECT_TRUE(IsPathInUse(path)); | 369 EXPECT_TRUE(IsPathInUse(path)); |
378 EXPECT_FALSE(IsPathInUse(uniquified_path)); | 370 EXPECT_FALSE(IsPathInUse(uniquified_path)); |
379 | 371 |
380 EXPECT_EQ(path.value(), reserved_path1.value()); | 372 EXPECT_EQ(path.value(), reserved_path1.value()); |
381 EXPECT_EQ(path.value(), reserved_path3.value()); | 373 EXPECT_EQ(path.value(), reserved_path3.value()); |
382 | 374 |
383 SetDownloadItemState(item1.get(), DownloadItem::COMPLETE); | 375 SetDownloadItemState(item1.get(), DownloadItem::COMPLETE); |
384 SetDownloadItemState(item3.get(), DownloadItem::COMPLETE); | 376 SetDownloadItemState(item3.get(), DownloadItem::COMPLETE); |
385 } | 377 } |
386 | 378 |
387 // Two active downloads shouldn't be able to reserve paths that only differ by | 379 // Two active downloads shouldn't be able to reserve paths that only differ by |
388 // case. | 380 // case. |
389 TEST_F(DownloadPathReservationTrackerTest, ConflictingCaseReservations) { | 381 TEST_F(DownloadPathReservationTrackerTest, ConflictingCaseReservations) { |
390 std::unique_ptr<MockDownloadItem> item1(CreateDownloadItem(1)); | 382 std::unique_ptr<MockDownloadItem> item1(CreateDownloadItem(1)); |
391 std::unique_ptr<MockDownloadItem> item2(CreateDownloadItem(2)); | 383 std::unique_ptr<MockDownloadItem> item2(CreateDownloadItem(2)); |
392 | 384 |
393 base::FilePath path_foo = | 385 base::FilePath path_foo = |
394 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt")); | 386 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt")); |
395 base::FilePath path_Foo = | 387 base::FilePath path_Foo = |
396 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("Foo.txt")); | 388 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("Foo.txt")); |
397 | 389 |
398 base::FilePath first_reservation; | 390 base::FilePath first_reservation; |
399 bool verified = false; | 391 PathValidationResult result = PathValidationResult::PATH_NOT_WRITABLE; |
400 CallGetReservedPath(item1.get(), path_foo, false, | 392 CallGetReservedPath(item1.get(), path_foo, false, |
401 DownloadPathReservationTracker::UNIQUIFY, | 393 DownloadPathReservationTracker::UNIQUIFY, |
402 &first_reservation, &verified); | 394 &first_reservation, &result); |
403 EXPECT_TRUE(IsPathInUse(path_foo)); | 395 EXPECT_TRUE(IsPathInUse(path_foo)); |
404 EXPECT_TRUE(verified); | 396 EXPECT_EQ(PathValidationResult::SUCCESS, result); |
405 EXPECT_EQ(path_foo, first_reservation); | 397 EXPECT_EQ(path_foo, first_reservation); |
406 | 398 |
407 // Foo should also be in use at this point. | 399 // Foo should also be in use at this point. |
408 EXPECT_TRUE(IsPathInUse(path_Foo)); | 400 EXPECT_TRUE(IsPathInUse(path_Foo)); |
409 | 401 |
410 base::FilePath second_reservation; | 402 base::FilePath second_reservation; |
411 CallGetReservedPath(item2.get(), path_Foo, false, | 403 CallGetReservedPath(item2.get(), path_Foo, false, |
412 DownloadPathReservationTracker::UNIQUIFY, | 404 DownloadPathReservationTracker::UNIQUIFY, |
413 &second_reservation, &verified); | 405 &second_reservation, &result); |
414 EXPECT_TRUE(verified); | 406 EXPECT_EQ(PathValidationResult::SUCCESS, result); |
415 EXPECT_EQ(GetPathInDownloadsDirectory(FILE_PATH_LITERAL("Foo (1).txt")), | 407 EXPECT_EQ(GetPathInDownloadsDirectory(FILE_PATH_LITERAL("Foo (1).txt")), |
416 second_reservation); | 408 second_reservation); |
417 SetDownloadItemState(item1.get(), DownloadItem::COMPLETE); | 409 SetDownloadItemState(item1.get(), DownloadItem::COMPLETE); |
418 SetDownloadItemState(item2.get(), DownloadItem::COMPLETE); | 410 SetDownloadItemState(item2.get(), DownloadItem::COMPLETE); |
419 } | 411 } |
420 | 412 |
421 // If a unique path cannot be determined after trying kMaxUniqueFiles | 413 // If a unique path cannot be determined after trying kMaxUniqueFiles |
422 // uniquifiers, then the callback should notified that verification failed, and | 414 // uniquifiers, then the callback should notified that verification failed, and |
423 // the returned path should be set to the original requested path. | 415 // the returned path should be set to the original requested path. |
424 TEST_F(DownloadPathReservationTrackerTest, UnresolvedConflicts) { | 416 TEST_F(DownloadPathReservationTrackerTest, UnresolvedConflicts) { |
425 base::FilePath path( | 417 base::FilePath path( |
426 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt"))); | 418 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt"))); |
427 std::unique_ptr<MockDownloadItem> | 419 std::unique_ptr<MockDownloadItem> |
428 items[DownloadPathReservationTracker::kMaxUniqueFiles + 1]; | 420 items[DownloadPathReservationTracker::kMaxUniqueFiles + 1]; |
429 DownloadPathReservationTracker::FilenameConflictAction conflict_action = | 421 DownloadPathReservationTracker::FilenameConflictAction conflict_action = |
430 DownloadPathReservationTracker::UNIQUIFY; | 422 DownloadPathReservationTracker::UNIQUIFY; |
431 bool create_directory = false; | 423 bool create_directory = false; |
432 | 424 |
433 // Create |kMaxUniqueFiles + 1| reservations for |path|. The first reservation | 425 // Create |kMaxUniqueFiles + 1| reservations for |path|. The first reservation |
434 // will have no uniquifier. The |kMaxUniqueFiles| remaining reservations do. | 426 // will have no uniquifier. The |kMaxUniqueFiles| remaining reservations do. |
435 for (int i = 0; i <= DownloadPathReservationTracker::kMaxUniqueFiles; i++) { | 427 for (int i = 0; i <= DownloadPathReservationTracker::kMaxUniqueFiles; i++) { |
436 base::FilePath reserved_path; | 428 base::FilePath reserved_path; |
437 base::FilePath expected_path; | 429 base::FilePath expected_path; |
438 bool verified = false; | 430 PathValidationResult result = PathValidationResult::NAME_TOO_LONG; |
439 if (i > 0) { | 431 if (i > 0) { |
440 expected_path = | 432 expected_path = |
441 path.InsertBeforeExtensionASCII(base::StringPrintf(" (%d)", i)); | 433 path.InsertBeforeExtensionASCII(base::StringPrintf(" (%d)", i)); |
442 } else { | 434 } else { |
443 expected_path = path; | 435 expected_path = path; |
444 } | 436 } |
445 items[i].reset(CreateDownloadItem(i)); | 437 items[i].reset(CreateDownloadItem(i)); |
446 EXPECT_FALSE(IsPathInUse(expected_path)); | 438 EXPECT_FALSE(IsPathInUse(expected_path)); |
447 CallGetReservedPath( | 439 CallGetReservedPath(items[i].get(), path, create_directory, conflict_action, |
448 items[i].get(), | 440 &reserved_path, &result); |
449 path, | |
450 create_directory, | |
451 conflict_action, | |
452 &reserved_path, | |
453 &verified); | |
454 EXPECT_TRUE(IsPathInUse(expected_path)); | 441 EXPECT_TRUE(IsPathInUse(expected_path)); |
455 EXPECT_EQ(expected_path.value(), reserved_path.value()); | 442 EXPECT_EQ(expected_path.value(), reserved_path.value()); |
456 EXPECT_TRUE(verified); | 443 EXPECT_EQ(PathValidationResult::SUCCESS, result); |
457 } | 444 } |
458 // The next reservation for |path| will fail to be unique. | 445 // The next reservation for |path| will fail to be unique. |
459 std::unique_ptr<MockDownloadItem> item( | 446 std::unique_ptr<MockDownloadItem> item( |
460 CreateDownloadItem(DownloadPathReservationTracker::kMaxUniqueFiles + 1)); | 447 CreateDownloadItem(DownloadPathReservationTracker::kMaxUniqueFiles + 1)); |
461 base::FilePath reserved_path; | 448 base::FilePath reserved_path; |
462 bool verified = true; | 449 PathValidationResult result = PathValidationResult::NAME_TOO_LONG; |
463 CallGetReservedPath( | 450 CallGetReservedPath(item.get(), path, create_directory, conflict_action, |
464 item.get(), | 451 &reserved_path, &result); |
465 path, | 452 EXPECT_EQ(PathValidationResult::CONFLICT, result); |
466 create_directory, | |
467 conflict_action, | |
468 &reserved_path, | |
469 &verified); | |
470 EXPECT_FALSE(verified); | |
471 EXPECT_EQ(path.value(), reserved_path.value()); | 453 EXPECT_EQ(path.value(), reserved_path.value()); |
472 | 454 |
473 SetDownloadItemState(item.get(), DownloadItem::COMPLETE); | 455 SetDownloadItemState(item.get(), DownloadItem::COMPLETE); |
474 for (int i = 0; i <= DownloadPathReservationTracker::kMaxUniqueFiles; i++) | 456 for (int i = 0; i <= DownloadPathReservationTracker::kMaxUniqueFiles; i++) |
475 SetDownloadItemState(items[i].get(), DownloadItem::COMPLETE); | 457 SetDownloadItemState(items[i].get(), DownloadItem::COMPLETE); |
476 } | 458 } |
477 | 459 |
478 // If the target directory is unwriteable, then callback should be notified that | 460 // If the target directory is unwriteable, then callback should be notified that |
479 // verification failed. | 461 // verification failed. |
480 TEST_F(DownloadPathReservationTrackerTest, UnwriteableDirectory) { | 462 TEST_F(DownloadPathReservationTrackerTest, UnwriteableDirectory) { |
481 std::unique_ptr<MockDownloadItem> item(CreateDownloadItem(1)); | 463 std::unique_ptr<MockDownloadItem> item(CreateDownloadItem(1)); |
482 base::FilePath path( | 464 base::FilePath path( |
483 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt"))); | 465 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt"))); |
484 base::FilePath dir(path.DirName()); | 466 base::FilePath dir(path.DirName()); |
485 ASSERT_FALSE(IsPathInUse(path)); | 467 ASSERT_FALSE(IsPathInUse(path)); |
486 | 468 |
487 { | 469 { |
488 // Scope for FilePermissionRestorer | 470 // Scope for FilePermissionRestorer |
489 base::FilePermissionRestorer restorer(dir); | 471 base::FilePermissionRestorer restorer(dir); |
490 EXPECT_TRUE(base::MakeFileUnwritable(dir)); | 472 EXPECT_TRUE(base::MakeFileUnwritable(dir)); |
491 base::FilePath reserved_path; | 473 base::FilePath reserved_path; |
492 bool verified = true; | 474 PathValidationResult result = PathValidationResult::NAME_TOO_LONG; |
493 DownloadPathReservationTracker::FilenameConflictAction conflict_action = | 475 DownloadPathReservationTracker::FilenameConflictAction conflict_action = |
494 DownloadPathReservationTracker::OVERWRITE; | 476 DownloadPathReservationTracker::OVERWRITE; |
495 bool create_directory = false; | 477 bool create_directory = false; |
496 CallGetReservedPath( | 478 CallGetReservedPath(item.get(), path, create_directory, conflict_action, |
497 item.get(), | 479 &reserved_path, &result); |
498 path, | |
499 create_directory, | |
500 conflict_action, | |
501 &reserved_path, | |
502 &verified); | |
503 // Verification fails. | 480 // Verification fails. |
504 EXPECT_FALSE(verified); | 481 EXPECT_EQ(PathValidationResult::PATH_NOT_WRITABLE, result); |
505 #if defined(OS_ANDROID) | 482 #if defined(OS_ANDROID) |
506 EXPECT_TRUE(reserved_path.empty()); | 483 EXPECT_TRUE(reserved_path.empty()); |
507 #else | 484 #else |
508 EXPECT_EQ(path.BaseName().value(), reserved_path.BaseName().value()); | 485 EXPECT_EQ(path.BaseName().value(), reserved_path.BaseName().value()); |
509 #endif | 486 #endif |
510 } | 487 } |
511 SetDownloadItemState(item.get(), DownloadItem::COMPLETE); | 488 SetDownloadItemState(item.get(), DownloadItem::COMPLETE); |
512 } | 489 } |
513 | 490 |
514 // If the default download directory doesn't exist, then it should be | 491 // If the default download directory doesn't exist, then it should be |
515 // created. But only if we are actually going to create the download path there. | 492 // created. But only if we are actually going to create the download path there. |
516 TEST_F(DownloadPathReservationTrackerTest, CreateDefaultDownloadPath) { | 493 TEST_F(DownloadPathReservationTrackerTest, CreateDefaultDownloadPath) { |
517 base::FilePath path( | 494 base::FilePath path( |
518 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo/foo.txt"))); | 495 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo/foo.txt"))); |
519 base::FilePath dir(path.DirName()); | 496 base::FilePath dir(path.DirName()); |
520 ASSERT_FALSE(base::DirectoryExists(dir)); | 497 ASSERT_FALSE(base::DirectoryExists(dir)); |
521 DownloadPathReservationTracker::FilenameConflictAction conflict_action = | 498 DownloadPathReservationTracker::FilenameConflictAction conflict_action = |
522 DownloadPathReservationTracker::OVERWRITE; | 499 DownloadPathReservationTracker::OVERWRITE; |
523 bool create_directory = false; | 500 bool create_directory = false; |
524 | 501 |
525 { | 502 { |
526 std::unique_ptr<MockDownloadItem> item(CreateDownloadItem(1)); | 503 std::unique_ptr<MockDownloadItem> item(CreateDownloadItem(1)); |
527 base::FilePath reserved_path; | 504 base::FilePath reserved_path; |
528 bool verified = true; | 505 PathValidationResult result = PathValidationResult::NAME_TOO_LONG; |
529 CallGetReservedPath( | 506 CallGetReservedPath(item.get(), path, create_directory, conflict_action, |
530 item.get(), | 507 &reserved_path, &result); |
531 path, | |
532 create_directory, | |
533 conflict_action, | |
534 &reserved_path, | |
535 &verified); | |
536 // Verification fails because the directory doesn't exist. | 508 // Verification fails because the directory doesn't exist. |
537 EXPECT_FALSE(verified); | 509 EXPECT_EQ(PathValidationResult::PATH_NOT_WRITABLE, result); |
538 SetDownloadItemState(item.get(), DownloadItem::COMPLETE); | 510 SetDownloadItemState(item.get(), DownloadItem::COMPLETE); |
539 } | 511 } |
540 ASSERT_FALSE(IsPathInUse(path)); | 512 ASSERT_FALSE(IsPathInUse(path)); |
541 { | 513 { |
542 std::unique_ptr<MockDownloadItem> item(CreateDownloadItem(1)); | 514 std::unique_ptr<MockDownloadItem> item(CreateDownloadItem(1)); |
543 base::FilePath reserved_path; | 515 base::FilePath reserved_path; |
544 bool verified = true; | 516 PathValidationResult result = PathValidationResult::NAME_TOO_LONG; |
545 set_default_download_path(dir); | 517 set_default_download_path(dir); |
546 CallGetReservedPath( | 518 CallGetReservedPath(item.get(), path, create_directory, conflict_action, |
547 item.get(), | 519 &reserved_path, &result); |
548 path, | |
549 create_directory, | |
550 conflict_action, | |
551 &reserved_path, | |
552 &verified); | |
553 // Verification succeeds because the directory is created. | 520 // Verification succeeds because the directory is created. |
554 EXPECT_TRUE(verified); | 521 EXPECT_EQ(PathValidationResult::SUCCESS, result); |
555 EXPECT_TRUE(base::DirectoryExists(dir)); | 522 EXPECT_TRUE(base::DirectoryExists(dir)); |
556 SetDownloadItemState(item.get(), DownloadItem::COMPLETE); | 523 SetDownloadItemState(item.get(), DownloadItem::COMPLETE); |
557 } | 524 } |
558 } | 525 } |
559 | 526 |
560 // If the target path of the download item changes, the reservation should be | 527 // If the target path of the download item changes, the reservation should be |
561 // updated to match. | 528 // updated to match. |
562 TEST_F(DownloadPathReservationTrackerTest, UpdatesToTargetPath) { | 529 TEST_F(DownloadPathReservationTrackerTest, UpdatesToTargetPath) { |
563 std::unique_ptr<MockDownloadItem> item(CreateDownloadItem(1)); | 530 std::unique_ptr<MockDownloadItem> item(CreateDownloadItem(1)); |
564 base::FilePath path( | 531 base::FilePath path( |
565 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt"))); | 532 GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt"))); |
566 ASSERT_FALSE(IsPathInUse(path)); | 533 ASSERT_FALSE(IsPathInUse(path)); |
567 | 534 |
568 base::FilePath reserved_path; | 535 base::FilePath reserved_path; |
569 bool verified = false; | 536 PathValidationResult result = PathValidationResult::NAME_TOO_LONG; |
570 DownloadPathReservationTracker::FilenameConflictAction conflict_action = | 537 DownloadPathReservationTracker::FilenameConflictAction conflict_action = |
571 DownloadPathReservationTracker::OVERWRITE; | 538 DownloadPathReservationTracker::OVERWRITE; |
572 bool create_directory = false; | 539 bool create_directory = false; |
573 CallGetReservedPath( | 540 CallGetReservedPath(item.get(), path, create_directory, conflict_action, |
574 item.get(), | 541 &reserved_path, &result); |
575 path, | |
576 create_directory, | |
577 conflict_action, | |
578 &reserved_path, | |
579 &verified); | |
580 EXPECT_TRUE(IsPathInUse(path)); | 542 EXPECT_TRUE(IsPathInUse(path)); |
581 EXPECT_TRUE(verified); | 543 EXPECT_EQ(PathValidationResult::SUCCESS, result); |
582 EXPECT_EQ(path.value(), reserved_path.value()); | 544 EXPECT_EQ(path.value(), reserved_path.value()); |
583 | 545 |
584 // The target path is initially empty. If an OnDownloadUpdated() is issued in | 546 // The target path is initially empty. If an OnDownloadUpdated() is issued in |
585 // this state, we shouldn't lose the reservation. | 547 // this state, we shouldn't lose the reservation. |
586 ASSERT_EQ(base::FilePath::StringType(), item->GetTargetFilePath().value()); | 548 ASSERT_EQ(base::FilePath::StringType(), item->GetTargetFilePath().value()); |
587 item->NotifyObserversDownloadUpdated(); | 549 item->NotifyObserversDownloadUpdated(); |
588 base::RunLoop().RunUntilIdle(); | 550 base::RunLoop().RunUntilIdle(); |
589 EXPECT_TRUE(IsPathInUse(path)); | 551 EXPECT_TRUE(IsPathInUse(path)); |
590 | 552 |
591 // If the target path changes, we should update the reservation to match. | 553 // If the target path changes, we should update the reservation to match. |
(...skipping 26 matching lines...) Expand all Loading... |
618 // TODO(kinaba): the current implementation leaves spaces for appending | 580 // TODO(kinaba): the current implementation leaves spaces for appending |
619 // ".crdownload". So take it into account. Should be removed in the future. | 581 // ".crdownload". So take it into account. Should be removed in the future. |
620 const size_t max_length = real_max_length - 11; | 582 const size_t max_length = real_max_length - 11; |
621 | 583 |
622 std::unique_ptr<MockDownloadItem> item(CreateDownloadItem(1)); | 584 std::unique_ptr<MockDownloadItem> item(CreateDownloadItem(1)); |
623 base::FilePath path(GetLongNamePathInDownloadsDirectory( | 585 base::FilePath path(GetLongNamePathInDownloadsDirectory( |
624 max_length, FILE_PATH_LITERAL(".txt"))); | 586 max_length, FILE_PATH_LITERAL(".txt"))); |
625 ASSERT_FALSE(IsPathInUse(path)); | 587 ASSERT_FALSE(IsPathInUse(path)); |
626 | 588 |
627 base::FilePath reserved_path; | 589 base::FilePath reserved_path; |
628 bool verified = false; | 590 PathValidationResult result = PathValidationResult::NAME_TOO_LONG; |
629 DownloadPathReservationTracker::FilenameConflictAction conflict_action = | 591 DownloadPathReservationTracker::FilenameConflictAction conflict_action = |
630 DownloadPathReservationTracker::OVERWRITE; | 592 DownloadPathReservationTracker::OVERWRITE; |
631 bool create_directory = false; | 593 bool create_directory = false; |
632 CallGetReservedPath( | 594 CallGetReservedPath(item.get(), path, create_directory, conflict_action, |
633 item.get(), | 595 &reserved_path, &result); |
634 path, | |
635 create_directory, | |
636 conflict_action, | |
637 &reserved_path, | |
638 &verified); | |
639 EXPECT_TRUE(IsPathInUse(reserved_path)); | 596 EXPECT_TRUE(IsPathInUse(reserved_path)); |
640 EXPECT_TRUE(verified); | 597 EXPECT_EQ(PathValidationResult::SUCCESS, result); |
641 // The file name length is truncated to max_length. | 598 // The file name length is truncated to max_length. |
642 EXPECT_EQ(max_length, reserved_path.BaseName().value().size()); | 599 EXPECT_EQ(max_length, reserved_path.BaseName().value().size()); |
643 // But the extension is kept unchanged. | 600 // But the extension is kept unchanged. |
644 EXPECT_EQ(path.Extension(), reserved_path.Extension()); | 601 EXPECT_EQ(path.Extension(), reserved_path.Extension()); |
645 SetDownloadItemState(item.get(), DownloadItem::COMPLETE); | 602 SetDownloadItemState(item.get(), DownloadItem::COMPLETE); |
646 } | 603 } |
647 | 604 |
648 TEST_F(DownloadPathReservationTrackerTest, TruncationConflict) { | 605 TEST_F(DownloadPathReservationTrackerTest, TruncationConflict) { |
649 int real_max_length = | 606 int real_max_length = |
650 base::GetMaximumPathComponentLength(default_download_path()); | 607 base::GetMaximumPathComponentLength(default_download_path()); |
(...skipping 10 matching lines...) Expand all Loading... |
661 base::FilePath path2(GetLongNamePathInDownloadsDirectory( | 618 base::FilePath path2(GetLongNamePathInDownloadsDirectory( |
662 max_length - 8, FILE_PATH_LITERAL(" (2).txt"))); | 619 max_length - 8, FILE_PATH_LITERAL(" (2).txt"))); |
663 ASSERT_FALSE(IsPathInUse(path)); | 620 ASSERT_FALSE(IsPathInUse(path)); |
664 // "aaa...aaaaaaa.txt" (truncated path) and | 621 // "aaa...aaaaaaa.txt" (truncated path) and |
665 // "aaa...aaa (1).txt" (truncated and first uniquification try) exists. | 622 // "aaa...aaa (1).txt" (truncated and first uniquification try) exists. |
666 // "aaa...aaa (2).txt" should be used. | 623 // "aaa...aaa (2).txt" should be used. |
667 ASSERT_EQ(0, base::WriteFile(path0, "", 0)); | 624 ASSERT_EQ(0, base::WriteFile(path0, "", 0)); |
668 ASSERT_EQ(0, base::WriteFile(path1, "", 0)); | 625 ASSERT_EQ(0, base::WriteFile(path1, "", 0)); |
669 | 626 |
670 base::FilePath reserved_path; | 627 base::FilePath reserved_path; |
671 bool verified = false; | 628 PathValidationResult result = PathValidationResult::NAME_TOO_LONG; |
672 DownloadPathReservationTracker::FilenameConflictAction conflict_action = | 629 DownloadPathReservationTracker::FilenameConflictAction conflict_action = |
673 DownloadPathReservationTracker::UNIQUIFY; | 630 DownloadPathReservationTracker::UNIQUIFY; |
674 bool create_directory = false; | 631 bool create_directory = false; |
675 CallGetReservedPath( | 632 CallGetReservedPath(item.get(), path, create_directory, conflict_action, |
676 item.get(), | 633 &reserved_path, &result); |
677 path, | |
678 create_directory, | |
679 conflict_action, | |
680 &reserved_path, | |
681 &verified); | |
682 EXPECT_TRUE(IsPathInUse(reserved_path)); | 634 EXPECT_TRUE(IsPathInUse(reserved_path)); |
683 EXPECT_TRUE(verified); | 635 EXPECT_EQ(PathValidationResult::SUCCESS, result); |
684 EXPECT_EQ(path2, reserved_path); | 636 EXPECT_EQ(path2, reserved_path); |
685 SetDownloadItemState(item.get(), DownloadItem::COMPLETE); | 637 SetDownloadItemState(item.get(), DownloadItem::COMPLETE); |
686 } | 638 } |
687 | 639 |
688 TEST_F(DownloadPathReservationTrackerTest, TruncationFail) { | 640 TEST_F(DownloadPathReservationTrackerTest, TruncationFail) { |
689 int real_max_length = | 641 int real_max_length = |
690 base::GetMaximumPathComponentLength(default_download_path()); | 642 base::GetMaximumPathComponentLength(default_download_path()); |
691 ASSERT_NE(-1, real_max_length); | 643 ASSERT_NE(-1, real_max_length); |
692 const size_t max_length = real_max_length - 11; | 644 const size_t max_length = real_max_length - 11; |
693 | 645 |
694 std::unique_ptr<MockDownloadItem> item(CreateDownloadItem(1)); | 646 std::unique_ptr<MockDownloadItem> item(CreateDownloadItem(1)); |
695 base::FilePath path(GetPathInDownloadsDirectory( | 647 base::FilePath path(GetPathInDownloadsDirectory( |
696 (FILE_PATH_LITERAL("a.") + | 648 (FILE_PATH_LITERAL("a.") + |
697 base::FilePath::StringType(max_length, 'b')).c_str())); | 649 base::FilePath::StringType(max_length, 'b')).c_str())); |
698 ASSERT_FALSE(IsPathInUse(path)); | 650 ASSERT_FALSE(IsPathInUse(path)); |
699 | 651 |
700 base::FilePath reserved_path; | 652 base::FilePath reserved_path; |
701 bool verified = false; | 653 PathValidationResult result = PathValidationResult::SUCCESS; |
702 DownloadPathReservationTracker::FilenameConflictAction conflict_action = | 654 DownloadPathReservationTracker::FilenameConflictAction conflict_action = |
703 DownloadPathReservationTracker::OVERWRITE; | 655 DownloadPathReservationTracker::OVERWRITE; |
704 bool create_directory = false; | 656 bool create_directory = false; |
705 CallGetReservedPath( | 657 CallGetReservedPath(item.get(), path, create_directory, conflict_action, |
706 item.get(), | 658 &reserved_path, &result); |
707 path, | |
708 create_directory, | |
709 conflict_action, | |
710 &reserved_path, | |
711 &verified); | |
712 // We cannot truncate a path with very long extension. | 659 // We cannot truncate a path with very long extension. |
713 EXPECT_FALSE(verified); | 660 EXPECT_EQ(PathValidationResult::NAME_TOO_LONG, result); |
714 SetDownloadItemState(item.get(), DownloadItem::COMPLETE); | 661 SetDownloadItemState(item.get(), DownloadItem::COMPLETE); |
715 } | 662 } |
716 | 663 |
717 #endif // Platforms that support filename truncation. | 664 #endif // Platforms that support filename truncation. |
OLD | NEW |