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 |