| OLD | NEW |
| (Empty) |
| 1 // Copyright 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 "chrome/browser/chromeos/drive/fileapi_worker.h" | |
| 6 | |
| 7 #include "base/bind.h" | |
| 8 #include "base/bind_helpers.h" | |
| 9 #include "base/file_util.h" | |
| 10 #include "base/memory/scoped_ptr.h" | |
| 11 #include "chrome/browser/chromeos/drive/dummy_file_system.h" | |
| 12 #include "chrome/browser/chromeos/drive/test_util.h" | |
| 13 #include "content/public/test/test_browser_thread_bundle.h" | |
| 14 #include "google_apis/drive/test_util.h" | |
| 15 #include "testing/gtest/include/gtest/gtest.h" | |
| 16 | |
| 17 namespace drive { | |
| 18 namespace fileapi_internal { | |
| 19 namespace { | |
| 20 | |
| 21 // Increments |num_called| for checking how many times the closure is called. | |
| 22 void Increment(int* num_called) { | |
| 23 ++*num_called; | |
| 24 } | |
| 25 | |
| 26 // Returns the |instance| as is. | |
| 27 FileSystemInterface* GetFileSystem(FileSystemInterface* instance) { | |
| 28 return instance; | |
| 29 } | |
| 30 | |
| 31 // A test file system that always returns |local_file_path|. For testing | |
| 32 // purpose, it checks if |open_mode| is the expected value, and record if the | |
| 33 // close callback is called. | |
| 34 class TestFileSystemForOpenFile : public DummyFileSystem { | |
| 35 public: | |
| 36 TestFileSystemForOpenFile(const base::FilePath& local_file_path, | |
| 37 OpenMode expected_open_mode) | |
| 38 : local_file_path_(local_file_path), | |
| 39 expected_open_mode_(expected_open_mode), | |
| 40 closed_(false) { | |
| 41 } | |
| 42 | |
| 43 virtual void OpenFile(const base::FilePath& file_path, | |
| 44 OpenMode open_mode, | |
| 45 const std::string& mime_type, | |
| 46 const drive::OpenFileCallback& callback) OVERRIDE { | |
| 47 EXPECT_EQ(expected_open_mode_, open_mode); | |
| 48 | |
| 49 callback.Run( | |
| 50 FILE_ERROR_OK, | |
| 51 local_file_path_, | |
| 52 base::Bind(&TestFileSystemForOpenFile::Close, base::Unretained(this))); | |
| 53 } | |
| 54 | |
| 55 void Close() { | |
| 56 closed_ = true; | |
| 57 } | |
| 58 | |
| 59 bool closed() const { return closed_; } | |
| 60 | |
| 61 private: | |
| 62 const base::FilePath local_file_path_; | |
| 63 const OpenMode expected_open_mode_; | |
| 64 bool closed_; | |
| 65 }; | |
| 66 | |
| 67 // Helper function of testing OpenFile() for write access. It checks that the | |
| 68 // file handle correctly writes to the expected file. | |
| 69 void VerifyWrite( | |
| 70 int64 expected_size, | |
| 71 const base::FilePath& expected_written_path, | |
| 72 const std::string& write_data, | |
| 73 base::File::Error result, | |
| 74 base::PlatformFile platform_file, | |
| 75 const base::Closure& close_callback) { | |
| 76 // Check that the file is properly opened. | |
| 77 EXPECT_EQ(base::File::FILE_OK, result); | |
| 78 EXPECT_NE(base::kInvalidPlatformFileValue, platform_file); | |
| 79 EXPECT_FALSE(close_callback.is_null()); | |
| 80 | |
| 81 // Check that the file has the expected length (i.e., truncated or not) | |
| 82 base::PlatformFileInfo info; | |
| 83 EXPECT_TRUE(base::GetPlatformFileInfo(platform_file, &info)); | |
| 84 EXPECT_EQ(expected_size, info.size); | |
| 85 | |
| 86 // Write some data. | |
| 87 const int data_size = static_cast<int>(write_data.size()); | |
| 88 EXPECT_EQ(data_size, | |
| 89 base::WritePlatformFile(platform_file, 0, write_data.c_str(), | |
| 90 data_size)); | |
| 91 EXPECT_TRUE(base::TruncatePlatformFile(platform_file, data_size)); | |
| 92 | |
| 93 // Close. | |
| 94 base::ClosePlatformFile(platform_file); | |
| 95 close_callback.Run(); | |
| 96 | |
| 97 // Checks that the written content goes to |expected_written_path|. I.e., | |
| 98 // the |platform_file| handle is pointing to the file. | |
| 99 std::string written; | |
| 100 EXPECT_TRUE(base::ReadFileToString(expected_written_path, &written)); | |
| 101 EXPECT_EQ(write_data, written); | |
| 102 } | |
| 103 | |
| 104 // Helper function of testing OpenFile() for read access. It checks that the | |
| 105 // file is readable and contains |expected_data|. | |
| 106 void VerifyRead(const std::string& expected_data, | |
| 107 base::File::Error result, | |
| 108 base::PlatformFile platform_file, | |
| 109 const base::Closure& close_callback) { | |
| 110 // Check that the file is properly opened. | |
| 111 EXPECT_EQ(base::File::FILE_OK, result); | |
| 112 EXPECT_NE(base::kInvalidPlatformFileValue, platform_file); | |
| 113 EXPECT_FALSE(close_callback.is_null()); | |
| 114 | |
| 115 // Check that the file has the expected content. | |
| 116 const int data_size = static_cast<int>(expected_data.size()); | |
| 117 base::PlatformFileInfo info; | |
| 118 EXPECT_TRUE(base::GetPlatformFileInfo(platform_file, &info)); | |
| 119 EXPECT_EQ(data_size, info.size); | |
| 120 | |
| 121 std::vector<char> buffer(data_size); | |
| 122 EXPECT_EQ(data_size, | |
| 123 base::ReadPlatformFile(platform_file, 0, buffer.data(), data_size)); | |
| 124 EXPECT_EQ(expected_data, std::string(buffer.begin(), buffer.end())); | |
| 125 | |
| 126 // Close. | |
| 127 base::ClosePlatformFile(platform_file); | |
| 128 close_callback.Run(); | |
| 129 } | |
| 130 | |
| 131 } // namespace | |
| 132 | |
| 133 class FileApiWorkerTest : public testing::Test { | |
| 134 private: | |
| 135 content::TestBrowserThreadBundle thread_bundle_; | |
| 136 }; | |
| 137 | |
| 138 TEST_F(FileApiWorkerTest, RunFileSystemCallbackSuccess) { | |
| 139 DummyFileSystem dummy_file_system; | |
| 140 | |
| 141 FileSystemInterface* file_system = NULL; | |
| 142 RunFileSystemCallback( | |
| 143 base::Bind(&GetFileSystem, &dummy_file_system), | |
| 144 google_apis::test_util::CreateCopyResultCallback(&file_system), | |
| 145 base::Closure()); | |
| 146 | |
| 147 EXPECT_EQ(&dummy_file_system, file_system); | |
| 148 } | |
| 149 | |
| 150 TEST_F(FileApiWorkerTest, RunFileSystemCallbackFail) { | |
| 151 FileSystemInterface* file_system = NULL; | |
| 152 | |
| 153 // Make sure on_error_callback is called if file_system_getter returns NULL. | |
| 154 int num_called = 0; | |
| 155 RunFileSystemCallback( | |
| 156 base::Bind(&GetFileSystem, static_cast<FileSystemInterface*>(NULL)), | |
| 157 google_apis::test_util::CreateCopyResultCallback(&file_system), | |
| 158 base::Bind(&Increment, &num_called)); | |
| 159 EXPECT_EQ(1, num_called); | |
| 160 | |
| 161 // Just make sure this null |on_error_callback| doesn't cause a crash. | |
| 162 RunFileSystemCallback( | |
| 163 base::Bind(&GetFileSystem, static_cast<FileSystemInterface*>(NULL)), | |
| 164 google_apis::test_util::CreateCopyResultCallback(&file_system), | |
| 165 base::Closure()); | |
| 166 } | |
| 167 | |
| 168 TEST_F(FileApiWorkerTest, OpenFileForCreateWrite) { | |
| 169 const base::FilePath kDummyPath = base::FilePath::FromUTF8Unsafe("whatever"); | |
| 170 const std::string kWriteData = "byebye"; | |
| 171 | |
| 172 base::FilePath temp_path; | |
| 173 base::CreateTemporaryFile(&temp_path); | |
| 174 | |
| 175 // CREATE => CREATE (fails if file existed.) | |
| 176 TestFileSystemForOpenFile file_system(temp_path, CREATE_FILE); | |
| 177 const int64 kExpectedSize = 0; | |
| 178 | |
| 179 OpenFile(kDummyPath, | |
| 180 base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_WRITE, | |
| 181 base::Bind(&VerifyWrite, kExpectedSize, temp_path, kWriteData), | |
| 182 &file_system); | |
| 183 test_util::RunBlockingPoolTask(); | |
| 184 EXPECT_TRUE(file_system.closed()); | |
| 185 } | |
| 186 | |
| 187 TEST_F(FileApiWorkerTest, OpenFileForOpenAlwaysWrite) { | |
| 188 const base::FilePath kDummyPath = base::FilePath::FromUTF8Unsafe("whatever"); | |
| 189 const std::string kWriteData = "byebye"; | |
| 190 const std::string kInitialData = "hello"; | |
| 191 | |
| 192 base::FilePath temp_path; | |
| 193 base::CreateTemporaryFile(&temp_path); | |
| 194 google_apis::test_util::WriteStringToFile(temp_path, kInitialData); | |
| 195 | |
| 196 // OPEN_ALWAYS => OPEN_OR_CREATE (success whether file exists or not.) | |
| 197 // No truncation should take place. | |
| 198 TestFileSystemForOpenFile file_system(temp_path, OPEN_OR_CREATE_FILE); | |
| 199 const int64 kExpectedSize = static_cast<int64>(kInitialData.size()); | |
| 200 | |
| 201 OpenFile(kDummyPath, | |
| 202 base::PLATFORM_FILE_OPEN_ALWAYS | base::PLATFORM_FILE_WRITE, | |
| 203 base::Bind(&VerifyWrite, kExpectedSize, temp_path, kWriteData), | |
| 204 &file_system); | |
| 205 test_util::RunBlockingPoolTask(); | |
| 206 EXPECT_TRUE(file_system.closed()); | |
| 207 } | |
| 208 | |
| 209 TEST_F(FileApiWorkerTest, OpenFileForOpenTruncatedWrite) { | |
| 210 const base::FilePath kDummyPath = base::FilePath::FromUTF8Unsafe("whatever"); | |
| 211 const std::string kInitialData = "hello"; | |
| 212 const std::string kWriteData = "byebye"; | |
| 213 | |
| 214 base::FilePath temp_path; | |
| 215 base::CreateTemporaryFile(&temp_path); | |
| 216 google_apis::test_util::WriteStringToFile(temp_path, kInitialData); | |
| 217 | |
| 218 // OPEN_TRUNCATED => OPEN (failure when the file did not exist.) | |
| 219 // It should truncate the file before passing to the callback. | |
| 220 TestFileSystemForOpenFile file_system(temp_path, OPEN_FILE); | |
| 221 const int64 kExpectedSize = 0; | |
| 222 | |
| 223 OpenFile(kDummyPath, | |
| 224 base::PLATFORM_FILE_OPEN_TRUNCATED | base::PLATFORM_FILE_WRITE, | |
| 225 base::Bind(&VerifyWrite, kExpectedSize, temp_path, kWriteData), | |
| 226 &file_system); | |
| 227 test_util::RunBlockingPoolTask(); | |
| 228 EXPECT_TRUE(file_system.closed()); | |
| 229 } | |
| 230 | |
| 231 TEST_F(FileApiWorkerTest, OpenFileForOpenCreateAlwaysWrite) { | |
| 232 const base::FilePath kDummyPath = base::FilePath::FromUTF8Unsafe("whatever"); | |
| 233 const std::string kInitialData = "hello"; | |
| 234 const std::string kWriteData = "byebye"; | |
| 235 | |
| 236 base::FilePath temp_path; | |
| 237 base::CreateTemporaryFile(&temp_path); | |
| 238 google_apis::test_util::WriteStringToFile(temp_path, kInitialData); | |
| 239 | |
| 240 // CREATE_ALWAYS => OPEN_OR_CREATE (success whether file exists or not.) | |
| 241 // It should truncate the file before passing to the callback. | |
| 242 TestFileSystemForOpenFile file_system(temp_path, OPEN_OR_CREATE_FILE); | |
| 243 const int64 kExpectedSize = 0; | |
| 244 | |
| 245 OpenFile(kDummyPath, | |
| 246 base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_WRITE, | |
| 247 base::Bind(&VerifyWrite, kExpectedSize, temp_path, kWriteData), | |
| 248 &file_system); | |
| 249 test_util::RunBlockingPoolTask(); | |
| 250 EXPECT_TRUE(file_system.closed()); | |
| 251 } | |
| 252 | |
| 253 TEST_F(FileApiWorkerTest, OpenFileForOpenRead) { | |
| 254 const base::FilePath kDummyPath = base::FilePath::FromUTF8Unsafe("whatever"); | |
| 255 const std::string kInitialData = "hello"; | |
| 256 | |
| 257 base::FilePath temp_path; | |
| 258 base::CreateTemporaryFile(&temp_path); | |
| 259 google_apis::test_util::WriteStringToFile(temp_path, kInitialData); | |
| 260 | |
| 261 // OPEN => OPEN (failure when the file did not exist.) | |
| 262 TestFileSystemForOpenFile file_system(temp_path, OPEN_FILE); | |
| 263 | |
| 264 OpenFile(kDummyPath, | |
| 265 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ, | |
| 266 base::Bind(&VerifyRead, kInitialData), | |
| 267 &file_system); | |
| 268 test_util::RunBlockingPoolTask(); | |
| 269 EXPECT_TRUE(file_system.closed()); | |
| 270 } | |
| 271 | |
| 272 } // namespace fileapi_internal | |
| 273 } // namespace drive | |
| OLD | NEW |