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