1 // Copyright 2014 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 <set> 6 7 #include "base/files/file.h" 8 #include "base/files/file_path.h" 9 #include "base/files/file_util.h" 10 #include "base/files/scoped_temp_dir.h" 11 #include "storage/browser/fileapi/native_file_util.h" 12 #include "testing/gtest/include/gtest/gtest.h" 13 14 using storage::FileSystemFileUtil; 15 using storage::FileSystemOperation; 16 using storage::NativeFileUtil; 17 18 namespace content { 19 20 class NativeFileUtilTest : public testing::Test { 21 public: 22 NativeFileUtilTest() {} 23 24 virtual void SetUp() { 25 ASSERT_TRUE(data_dir_.CreateUniqueTempDir()); 26 } 27 28 protected: 29 base::FilePath Path() { 30 return data_dir_.path(); 31 } 32 33 base::FilePath Path(const char* file_name) { 34 return data_dir_.path().AppendASCII(file_name); 35 } 36 37 bool FileExists(const base::FilePath& path) { 38 return base::PathExists(path) && 39 !base::DirectoryExists(path); 40 } 41 42 int64 GetSize(const base::FilePath& path) { 43 base::File::Info info; 44 base::GetFileInfo(path, &info); 45 return info.size; 46 } 47 48 private: 49 base::ScopedTempDir data_dir_; 50 51 DISALLOW_COPY_AND_ASSIGN(NativeFileUtilTest); 52 }; 53 54 TEST_F(NativeFileUtilTest, CreateCloseAndDeleteFile) { 55 base::FilePath file_name = Path("test_file"); 56 int flags = base::File::FLAG_WRITE | base::File::FLAG_ASYNC; 57 base::File file = 58 NativeFileUtil::CreateOrOpen(file_name, base::File::FLAG_CREATE | flags); 59 ASSERT_TRUE(file.IsValid()); 60 ASSERT_TRUE(file.created()); 61 62 EXPECT_TRUE(base::PathExists(file_name)); 63 EXPECT_TRUE(NativeFileUtil::PathExists(file_name)); 64 EXPECT_EQ(0, GetSize(file_name)); 65 file.Close(); 66 67 file = NativeFileUtil::CreateOrOpen(file_name, base::File::FLAG_OPEN | flags); 68 ASSERT_TRUE(file.IsValid()); 69 ASSERT_FALSE(file.created()); 70 file.Close(); 71 72 ASSERT_EQ(base::File::FILE_OK, 73 NativeFileUtil::DeleteFile(file_name)); 74 EXPECT_FALSE(base::PathExists(file_name)); 75 EXPECT_FALSE(NativeFileUtil::PathExists(file_name)); 76 } 77 78 TEST_F(NativeFileUtilTest, EnsureFileExists) { 79 base::FilePath file_name = Path("foobar"); 80 bool created = false; 81 ASSERT_EQ(base::File::FILE_OK, 82 NativeFileUtil::EnsureFileExists(file_name, &created)); 83 ASSERT_TRUE(created); 84 85 EXPECT_TRUE(FileExists(file_name)); 86 EXPECT_EQ(0, GetSize(file_name)); 87 88 ASSERT_EQ(base::File::FILE_OK, 89 NativeFileUtil::EnsureFileExists(file_name, &created)); 90 EXPECT_FALSE(created); 91 } 92 93 TEST_F(NativeFileUtilTest, CreateAndDeleteDirectory) { 94 base::FilePath dir_name = Path("test_dir"); 95 ASSERT_EQ(base::File::FILE_OK, 96 NativeFileUtil::CreateDirectory(dir_name, 97 false /* exclusive */, 98 false /* recursive */)); 99 100 EXPECT_TRUE(NativeFileUtil::DirectoryExists(dir_name)); 101 EXPECT_TRUE(base::DirectoryExists(dir_name)); 102 103 ASSERT_EQ(base::File::FILE_ERROR_EXISTS, 104 NativeFileUtil::CreateDirectory(dir_name, 105 true /* exclusive */, 106 false /* recursive */)); 107 108 ASSERT_EQ(base::File::FILE_OK, 109 NativeFileUtil::DeleteDirectory(dir_name)); 110 EXPECT_FALSE(base::DirectoryExists(dir_name)); 111 EXPECT_FALSE(NativeFileUtil::DirectoryExists(dir_name)); 112 } 113 114 TEST_F(NativeFileUtilTest, TouchFileAndGetFileInfo) { 115 base::FilePath file_name = Path("test_file"); 116 base::File::Info native_info; 117 ASSERT_EQ(base::File::FILE_ERROR_NOT_FOUND, 118 NativeFileUtil::GetFileInfo(file_name, &native_info)); 119 120 bool created = false; 121 ASSERT_EQ(base::File::FILE_OK, 122 NativeFileUtil::EnsureFileExists(file_name, &created)); 123 ASSERT_TRUE(created); 124 125 base::File::Info info; 126 ASSERT_TRUE(base::GetFileInfo(file_name, &info)); 127 ASSERT_EQ(base::File::FILE_OK, 128 NativeFileUtil::GetFileInfo(file_name, &native_info)); 129 ASSERT_EQ(info.size, native_info.size); 130 ASSERT_EQ(info.is_directory, native_info.is_directory); 131 ASSERT_EQ(info.is_symbolic_link, native_info.is_symbolic_link); 132 ASSERT_EQ(info.last_modified, native_info.last_modified); 133 ASSERT_EQ(info.last_accessed, native_info.last_accessed); 134 ASSERT_EQ(info.creation_time, native_info.creation_time); 135 136 const base::Time new_accessed = 137 info.last_accessed + base::TimeDelta::FromHours(10); 138 const base::Time new_modified = 139 info.last_modified + base::TimeDelta::FromHours(5); 140 141 EXPECT_EQ(base::File::FILE_OK, 142 NativeFileUtil::Touch(file_name, 143 new_accessed, new_modified)); 144 145 ASSERT_TRUE(base::GetFileInfo(file_name, &info)); 146 EXPECT_EQ(new_accessed, info.last_accessed); 147 EXPECT_EQ(new_modified, info.last_modified); 148 } 149 150 TEST_F(NativeFileUtilTest, CreateFileEnumerator) { 151 base::FilePath path_1 = Path("dir1"); 152 base::FilePath path_2 = Path("file1"); 153 base::FilePath path_11 = Path("dir1").AppendASCII("file11"); 154 base::FilePath path_12 = Path("dir1").AppendASCII("dir12"); 155 base::FilePath path_121 = 156 Path("dir1").AppendASCII("dir12").AppendASCII("file121"); 157 ASSERT_EQ(base::File::FILE_OK, 158 NativeFileUtil::CreateDirectory(path_1, false, false)); 159 bool created = false; 160 ASSERT_EQ(base::File::FILE_OK, 161 NativeFileUtil::EnsureFileExists(path_2, &created)); 162 ASSERT_EQ(base::File::FILE_OK, 163 NativeFileUtil::EnsureFileExists(path_11, &created)); 164 ASSERT_EQ(base::File::FILE_OK, 165 NativeFileUtil::CreateDirectory(path_12, false, false)); 166 ASSERT_EQ(base::File::FILE_OK, 167 NativeFileUtil::EnsureFileExists(path_121, &created)); 168 169 { 170 scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> enumerator = 171 NativeFileUtil::CreateFileEnumerator(Path(), false); 172 std::set<base::FilePath> set; 173 set.insert(path_1); 174 set.insert(path_2); 175 for (base::FilePath path = enumerator->Next(); !path.empty(); 176 path = enumerator->Next()) 177 EXPECT_EQ(1U, set.erase(path)); 178 EXPECT_TRUE(set.empty()); 179 } 180 181 { 182 scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> enumerator = 183 NativeFileUtil::CreateFileEnumerator(Path(), true); 184 std::set<base::FilePath> set; 185 set.insert(path_1); 186 set.insert(path_2); 187 set.insert(path_11); 188 set.insert(path_12); 189 set.insert(path_121); 190 for (base::FilePath path = enumerator->Next(); !path.empty(); 191 path = enumerator->Next()) 192 EXPECT_EQ(1U, set.erase(path)); 193 EXPECT_TRUE(set.empty()); 194 } 195 } 196 197 TEST_F(NativeFileUtilTest, Truncate) { 198 base::FilePath file_name = Path("truncated"); 199 bool created = false; 200 ASSERT_EQ(base::File::FILE_OK, 201 NativeFileUtil::EnsureFileExists(file_name, &created)); 202 ASSERT_TRUE(created); 203 204 ASSERT_EQ(base::File::FILE_OK, 205 NativeFileUtil::Truncate(file_name, 1020)); 206 207 EXPECT_TRUE(FileExists(file_name)); 208 EXPECT_EQ(1020, GetSize(file_name)); 209 } 210 211 TEST_F(NativeFileUtilTest, CopyFile) { 212 base::FilePath from_file = Path("fromfile"); 213 base::FilePath to_file1 = Path("tofile1"); 214 base::FilePath to_file2 = Path("tofile2"); 215 const NativeFileUtil::CopyOrMoveMode nosync = NativeFileUtil::COPY_NOSYNC; 216 const NativeFileUtil::CopyOrMoveMode sync = NativeFileUtil::COPY_SYNC; 217 bool created = false; 218 ASSERT_EQ(base::File::FILE_OK, 219 NativeFileUtil::EnsureFileExists(from_file, &created)); 220 ASSERT_TRUE(created); 221 222 ASSERT_EQ(base::File::FILE_OK, 223 NativeFileUtil::Truncate(from_file, 1020)); 224 225 EXPECT_TRUE(FileExists(from_file)); 226 EXPECT_EQ(1020, GetSize(from_file)); 227 228 ASSERT_EQ(base::File::FILE_OK, 229 NativeFileUtil::CopyOrMoveFile( 230 from_file, to_file1, FileSystemOperation::OPTION_NONE, nosync)); 231 232 ASSERT_EQ(base::File::FILE_OK, 233 NativeFileUtil::CopyOrMoveFile( 234 from_file, to_file2, FileSystemOperation::OPTION_NONE, sync)); 235 236 EXPECT_TRUE(FileExists(from_file)); 237 EXPECT_EQ(1020, GetSize(from_file)); 238 EXPECT_TRUE(FileExists(to_file1)); 239 EXPECT_EQ(1020, GetSize(to_file1)); 240 EXPECT_TRUE(FileExists(to_file2)); 241 EXPECT_EQ(1020, GetSize(to_file2)); 242 243 base::FilePath dir = Path("dir"); 244 ASSERT_EQ(base::File::FILE_OK, 245 NativeFileUtil::CreateDirectory(dir, false, false)); 246 ASSERT_TRUE(base::DirectoryExists(dir)); 247 base::FilePath to_dir_file = dir.AppendASCII("file"); 248 ASSERT_EQ(base::File::FILE_OK, 249 NativeFileUtil::CopyOrMoveFile( 250 from_file, to_dir_file, 251 FileSystemOperation::OPTION_NONE, nosync)); 252 EXPECT_TRUE(FileExists(to_dir_file)); 253 EXPECT_EQ(1020, GetSize(to_dir_file)); 254 255 // Following tests are error checking. 256 // Source doesn't exist. 257 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND, 258 NativeFileUtil::CopyOrMoveFile( 259 Path("nonexists"), Path("file"), 260 FileSystemOperation::OPTION_NONE, nosync)); 261 262 // Source is not a file. 263 EXPECT_EQ(base::File::FILE_ERROR_NOT_A_FILE, 264 NativeFileUtil::CopyOrMoveFile( 265 dir, Path("file"), FileSystemOperation::OPTION_NONE, nosync)); 266 // Destination is not a file. 267 EXPECT_EQ(base::File::FILE_ERROR_INVALID_OPERATION, 268 NativeFileUtil::CopyOrMoveFile( 269 from_file, dir, FileSystemOperation::OPTION_NONE, nosync)); 270 // Destination's parent doesn't exist. 271 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND, 272 NativeFileUtil::CopyOrMoveFile( 273 from_file, Path("nodir").AppendASCII("file"), 274 FileSystemOperation::OPTION_NONE, nosync)); 275 // Destination's parent is a file. 276 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND, 277 NativeFileUtil::CopyOrMoveFile( 278 from_file, Path("tofile1").AppendASCII("file"), 279 FileSystemOperation::OPTION_NONE, nosync)); 280 } 281 282 TEST_F(NativeFileUtilTest, MoveFile) { 283 base::FilePath from_file = Path("fromfile"); 284 base::FilePath to_file = Path("tofile"); 285 const NativeFileUtil::CopyOrMoveMode move = NativeFileUtil::MOVE; 286 bool created = false; 287 ASSERT_EQ(base::File::FILE_OK, 288 NativeFileUtil::EnsureFileExists(from_file, &created)); 289 ASSERT_TRUE(created); 290 291 ASSERT_EQ(base::File::FILE_OK, NativeFileUtil::Truncate(from_file, 1020)); 292 293 EXPECT_TRUE(FileExists(from_file)); 294 EXPECT_EQ(1020, GetSize(from_file)); 295 296 ASSERT_EQ(base::File::FILE_OK, 297 NativeFileUtil::CopyOrMoveFile( 298 from_file, to_file, FileSystemOperation::OPTION_NONE, move)); 299 300 EXPECT_FALSE(FileExists(from_file)); 301 EXPECT_TRUE(FileExists(to_file)); 302 EXPECT_EQ(1020, GetSize(to_file)); 303 304 ASSERT_EQ(base::File::FILE_OK, 305 NativeFileUtil::EnsureFileExists(from_file, &created)); 306 ASSERT_TRUE(FileExists(from_file)); 307 ASSERT_EQ(base::File::FILE_OK, NativeFileUtil::Truncate(from_file, 1020)); 308 309 base::FilePath dir = Path("dir"); 310 ASSERT_EQ(base::File::FILE_OK, 311 NativeFileUtil::CreateDirectory(dir, false, false)); 312 ASSERT_TRUE(base::DirectoryExists(dir)); 313 base::FilePath to_dir_file = dir.AppendASCII("file"); 314 ASSERT_EQ(base::File::FILE_OK, 315 NativeFileUtil::CopyOrMoveFile( 316 from_file, to_dir_file, 317 FileSystemOperation::OPTION_NONE, move)); 318 EXPECT_FALSE(FileExists(from_file)); 319 EXPECT_TRUE(FileExists(to_dir_file)); 320 EXPECT_EQ(1020, GetSize(to_dir_file)); 321 322 // Following is error checking. 323 // Source doesn't exist. 324 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND, 325 NativeFileUtil::CopyOrMoveFile( 326 Path("nonexists"), Path("file"), 327 FileSystemOperation::OPTION_NONE, move)); 328 329 // Source is not a file. 330 EXPECT_EQ(base::File::FILE_ERROR_NOT_A_FILE, 331 NativeFileUtil::CopyOrMoveFile( 332 dir, Path("file"), FileSystemOperation::OPTION_NONE, move)); 333 ASSERT_EQ(base::File::FILE_OK, 334 NativeFileUtil::EnsureFileExists(from_file, &created)); 335 ASSERT_TRUE(FileExists(from_file)); 336 // Destination is not a file. 337 EXPECT_EQ(base::File::FILE_ERROR_INVALID_OPERATION, 338 NativeFileUtil::CopyOrMoveFile( 339 from_file, dir, FileSystemOperation::OPTION_NONE, move)); 340 341 ASSERT_EQ(base::File::FILE_OK, 342 NativeFileUtil::EnsureFileExists(from_file, &created)); 343 ASSERT_TRUE(FileExists(from_file)); 344 // Destination's parent doesn't exist. 345 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND, 346 NativeFileUtil::CopyOrMoveFile( 347 from_file, Path("nodir").AppendASCII("file"), 348 FileSystemOperation::OPTION_NONE, move)); 349 // Destination's parent is a file. 350 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND, 351 NativeFileUtil::CopyOrMoveFile( 352 from_file, Path("tofile1").AppendASCII("file"), 353 FileSystemOperation::OPTION_NONE, move)); 354 } 355 356 TEST_F(NativeFileUtilTest, PreserveLastModified) { 357 base::FilePath from_file = Path("fromfile"); 358 base::FilePath to_file1 = Path("tofile1"); 359 base::FilePath to_file2 = Path("tofile2"); 360 base::FilePath to_file3 = Path("tofile3"); 361 bool created = false; 362 ASSERT_EQ(base::File::FILE_OK, 363 NativeFileUtil::EnsureFileExists(from_file, &created)); 364 ASSERT_TRUE(created); 365 EXPECT_TRUE(FileExists(from_file)); 366 367 base::File::Info file_info1; 368 ASSERT_EQ(base::File::FILE_OK, 369 NativeFileUtil::GetFileInfo(from_file, &file_info1)); 370 371 // Test for copy (nosync). 372 ASSERT_EQ(base::File::FILE_OK, 373 NativeFileUtil::CopyOrMoveFile( 374 from_file, to_file1, 375 FileSystemOperation::OPTION_PRESERVE_LAST_MODIFIED, 376 NativeFileUtil::COPY_NOSYNC)); 377 378 base::File::Info file_info2; 379 ASSERT_TRUE(FileExists(to_file1)); 380 ASSERT_EQ(base::File::FILE_OK, 381 NativeFileUtil::GetFileInfo(to_file1, &file_info2)); 382 EXPECT_EQ(file_info1.last_modified, file_info2.last_modified); 383 384 // Test for copy (sync). 385 ASSERT_EQ(base::File::FILE_OK, 386 NativeFileUtil::CopyOrMoveFile( 387 from_file, to_file2, 388 FileSystemOperation::OPTION_PRESERVE_LAST_MODIFIED, 389 NativeFileUtil::COPY_SYNC)); 390 391 ASSERT_TRUE(FileExists(to_file2)); 392 ASSERT_EQ(base::File::FILE_OK, 393 NativeFileUtil::GetFileInfo(to_file1, &file_info2)); 394 EXPECT_EQ(file_info1.last_modified, file_info2.last_modified); 395 396 // Test for move. 397 ASSERT_EQ(base::File::FILE_OK, 398 NativeFileUtil::CopyOrMoveFile( 399 from_file, to_file3, 400 FileSystemOperation::OPTION_PRESERVE_LAST_MODIFIED, 401 NativeFileUtil::MOVE)); 402 403 ASSERT_TRUE(FileExists(to_file3)); 404 ASSERT_EQ(base::File::FILE_OK, 405 NativeFileUtil::GetFileInfo(to_file2, &file_info2)); 406 EXPECT_EQ(file_info1.last_modified, file_info2.last_modified); 407 } 408 409 } // namespace content 410