OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 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 <errno.h> | |
6 #include <fcntl.h> | |
7 | |
8 #include <set> | |
9 #include <string> | |
10 | |
11 #include <gmock/gmock.h> | |
12 | |
13 #include "nacl_io/googledrivefs/googledrivefs.h" | |
14 #include "nacl_io/kernel_handle.h" | |
15 #include "nacl_io/osdirent.h" | |
16 #include "nacl_io/pepper_interface_delegate.h" | |
17 #include "sdk_util/scoped_ref.h" | |
18 | |
19 #include "fake_ppapi/fake_pepper_interface_googledrivefs.h" | |
20 #include "fake_ppapi/fake_util.h" | |
21 #include "mock_util.h" | |
22 | |
23 using namespace nacl_io; | |
24 using namespace sdk_util; | |
25 | |
26 using ::testing::_; | |
27 using ::testing::DoAll; | |
28 using ::testing::Invoke; | |
29 using ::testing::Return; | |
30 | |
31 namespace { | |
32 | |
33 class GoogleDriveFsForTesting : public GoogleDriveFs { | |
34 public: | |
35 GoogleDriveFsForTesting(StringMap_t& string_map, PepperInterface* ppapi) { | |
36 FsInitArgs args; | |
37 args.string_map = string_map; | |
38 args.ppapi = ppapi; | |
39 Error error = Init(args); | |
40 EXPECT_EQ(0, error); | |
41 } | |
42 }; | |
43 | |
44 class GoogleDriveFsTest : public ::testing::Test { | |
45 public: | |
46 GoogleDriveFsTest(); | |
47 | |
48 virtual void SetUp() { | |
49 char buffer[33]; | |
50 int char_written = | |
51 sprintf(buffer, "%i", ppapi_googledrivefs_.GetInstance()); | |
52 ASSERT_LE(0, char_written); | |
53 | |
54 map_["instance"] = std::string(buffer); | |
55 map_["token"] = "some token value"; | |
56 } | |
57 | |
58 protected: | |
59 FakePepperInterfaceGoogleDriveFs ppapi_googledrivefs_; | |
60 PepperInterfaceDelegate ppapi_; | |
61 StringMap_t map_; | |
62 }; | |
63 | |
64 GoogleDriveFsTest::GoogleDriveFsTest() | |
65 : ppapi_(ppapi_googledrivefs_.GetInstance()) { | |
66 // Default delegation to the googledrivefs pepper interface. | |
67 ppapi_.SetCoreInterfaceDelegate(ppapi_googledrivefs_.GetCoreInterface()); | |
68 ppapi_.SetURLLoaderInterfaceDelegate( | |
69 ppapi_googledrivefs_.GetURLLoaderInterface()); | |
70 ppapi_.SetURLRequestInfoInterfaceDelegate( | |
71 ppapi_googledrivefs_.GetURLRequestInfoInterface()); | |
72 ppapi_.SetURLResponseInfoInterfaceDelegate( | |
73 ppapi_googledrivefs_.GetURLResponseInfoInterface()); | |
74 ppapi_.SetFileIoInterfaceDelegate(ppapi_googledrivefs_.GetFileIoInterface()); | |
75 ppapi_.SetVarInterfaceDelegate(ppapi_googledrivefs_.GetVarInterface()); | |
76 } | |
77 | |
78 } // namespace | |
79 | |
80 TEST_F(GoogleDriveFsTest, Mkdir) { | |
81 ScopedRef<GoogleDriveFsForTesting> fs( | |
82 new GoogleDriveFsForTesting(map_, &ppapi_)); | |
83 | |
84 // | |
85 // mkdir at the root should return EEXIST, not EACCES. | |
86 // | |
87 EXPECT_EQ(EEXIST, fs->Mkdir(Path("/"), 0644)); | |
88 | |
89 // | |
90 // mkdir on a directory that has not been existed. | |
91 // | |
92 Path path("/foo"); | |
93 | |
94 ASSERT_EQ(0, fs->Mkdir(path, 0644)); | |
95 | |
96 ScopedNode node; | |
97 ASSERT_EQ(0, fs->Open(path, O_RDONLY, &node)); | |
98 | |
99 EXPECT_TRUE(node->IsaDir()); | |
100 | |
101 // | |
102 // mkdir on a directory that has already been existed. | |
103 // | |
104 EXPECT_EQ(EEXIST, fs->Mkdir(path, 0644)); | |
105 | |
106 // | |
107 // mkdir on an existing file. | |
108 // | |
109 ScopedNode file_node; | |
110 Path file_path("/filename"); | |
111 ASSERT_EQ(0, fs->Open(file_path, O_WRONLY | O_CREAT | O_TRUNC, &file_node)); | |
112 | |
113 EXPECT_EQ(EEXIST, fs->Mkdir(file_path, 0644)); | |
114 } | |
115 | |
116 TEST_F(GoogleDriveFsTest, Rmdir) { | |
117 ScopedRef<GoogleDriveFsForTesting> fs( | |
118 new GoogleDriveFsForTesting(map_, &ppapi_)); | |
119 | |
120 // | |
121 // rmdir at the root returns EEXIST, as returned in nacl_io_demo. | |
122 // | |
123 EXPECT_EQ(EEXIST, fs->Rmdir(Path("/"))); | |
124 | |
125 // | |
126 // rmdir on an existing dir. | |
127 // | |
128 Path dir_path("/dir"); | |
129 ASSERT_EQ(0, fs->Mkdir(dir_path, 0644)); | |
130 EXPECT_EQ(0, fs->Rmdir(dir_path)); | |
131 | |
132 // | |
133 // rmdir on a non-existing dir. | |
134 // | |
135 EXPECT_EQ(ENOENT, fs->Rmdir(dir_path)); | |
136 | |
137 // | |
138 // rmdir on an existing file. | |
139 // | |
140 ScopedNode file_node; | |
141 Path file_path("/filename"); | |
142 ASSERT_EQ(0, fs->Open(file_path, O_RDWR | O_CREAT | O_TRUNC, &file_node)); | |
143 | |
144 ASSERT_EQ(ENOTDIR, fs->Rmdir(file_path)); | |
145 | |
146 // | |
147 // rmdir on an existing dir that has a file. | |
148 // | |
149 Path nonempty_dir_path("/nonempty_dir"); | |
150 ASSERT_EQ(0, fs->Mkdir(nonempty_dir_path, 0644)); | |
151 | |
152 ScopedNode file_in_nonempty_dir_node; | |
153 Path file_in_nonempty_dir_path("/nonempty_dir/file"); | |
154 ASSERT_EQ(0, fs->Open(file_in_nonempty_dir_path, O_RDWR | O_CREAT | O_TRUNC, | |
155 &file_in_nonempty_dir_node)); | |
156 | |
157 EXPECT_EQ(ENOTEMPTY, fs->Rmdir(nonempty_dir_path)); | |
158 } | |
159 | |
160 TEST_F(GoogleDriveFsTest, OpenNonExistingFile) { | |
161 ScopedRef<GoogleDriveFsForTesting> fs( | |
162 new GoogleDriveFsForTesting(map_, &ppapi_)); | |
163 | |
164 // | |
165 // open a non-existing file in r mode. | |
chanpatorikku
2016/08/07 02:41:03
nacl_io_demo covers only 6 different flags in file
binji
2016/08/22 19:21:53
Yes, this is fine.
chanpatorikku
2016/08/29 17:14:04
Acknowledged.
| |
166 // | |
167 Path nonexisting_file_path("/file"); | |
168 ScopedNode nonexisting_file_node; | |
169 EXPECT_EQ(ENOENT, | |
170 fs->Open(nonexisting_file_path, O_RDONLY, &nonexisting_file_node)); | |
171 | |
172 // | |
173 // open a non-existing file in r+ mode. | |
174 // | |
175 EXPECT_EQ(ENOENT, | |
176 fs->Open(nonexisting_file_path, O_RDWR, &nonexisting_file_node)); | |
177 | |
178 // | |
179 // open a non-existing file in w mode. | |
180 // | |
181 Path nonexisting_file_w_mode_path("/nonexisting_file_w_mode"); | |
182 ScopedNode nonexisting_file_w_mode_node; | |
183 EXPECT_EQ(0, | |
184 fs->Open(nonexisting_file_w_mode_path, O_WRONLY | O_CREAT | O_TRUNC, | |
185 &nonexisting_file_w_mode_node)); | |
186 | |
187 // | |
188 // open a non-existing file in w+ mode. | |
189 // | |
190 Path nonexisting_file_w_plus_mode_path("/nonexisting_file_w_plus_mode"); | |
191 ScopedNode nonexisting_file_w_plus_mode_node; | |
192 EXPECT_EQ( | |
193 0, fs->Open(nonexisting_file_w_plus_mode_path, O_RDWR | O_CREAT | O_TRUNC, | |
194 &nonexisting_file_w_plus_mode_node)); | |
195 | |
196 // | |
197 // open a non-existing file in a mode. | |
198 // | |
199 Path nonexisting_file_a_mode_path("/nonexisting_file_a_mode"); | |
200 ScopedNode nonexisting_file_a_mode_node; | |
201 EXPECT_EQ( | |
202 0, fs->Open(nonexisting_file_a_mode_path, O_WRONLY | O_CREAT | O_APPEND, | |
203 &nonexisting_file_a_mode_node)); | |
204 | |
205 // | |
206 // open a non-existing file in a+ mode. | |
207 // | |
208 Path nonexisting_file_a_plus_mode_path("/nonexisting_file_a_plus_mode"); | |
209 ScopedNode nonexisting_file_a_plus_mode_node; | |
210 EXPECT_EQ(0, fs->Open(nonexisting_file_a_plus_mode_path, | |
211 O_RDWR | O_CREAT | O_APPEND, | |
212 &nonexisting_file_a_plus_mode_node)); | |
213 } | |
214 | |
215 TEST_F(GoogleDriveFsTest, OpenExistingFile) { | |
216 ScopedRef<GoogleDriveFsForTesting> fs( | |
217 new GoogleDriveFsForTesting(map_, &ppapi_)); | |
218 | |
219 Path existing_file_path("/file"); | |
220 ScopedNode existing_file_node; | |
221 EXPECT_EQ(0, fs->Open(existing_file_path, O_WRONLY | O_CREAT | O_TRUNC, | |
222 &existing_file_node)); | |
223 | |
224 // | |
225 // open an existing file in r mode. | |
226 // | |
227 ScopedNode existing_file_r_mode_node; | |
228 EXPECT_EQ(0, | |
229 fs->Open(existing_file_path, O_RDONLY, &existing_file_r_mode_node)); | |
230 | |
231 // | |
232 // open an existing file in r+ mode. | |
233 // | |
234 ScopedNode existing_file_r_plus_mode_node; | |
235 EXPECT_EQ( | |
236 0, fs->Open(existing_file_path, O_RDWR, &existing_file_r_plus_mode_node)); | |
237 | |
238 // | |
239 // open an existing file in w mode. | |
240 // | |
241 ScopedNode existing_file_w_mode_node; | |
242 EXPECT_EQ(0, fs->Open(existing_file_path, O_WRONLY | O_CREAT | O_TRUNC, | |
243 &existing_file_w_mode_node)); | |
244 | |
245 // | |
246 // open an existing file in w+ mode. | |
247 // | |
248 ScopedNode existing_file_w_plus_mode_node; | |
249 EXPECT_EQ(0, fs->Open(existing_file_path, O_RDWR | O_CREAT | O_TRUNC, | |
250 &existing_file_w_plus_mode_node)); | |
251 | |
252 // | |
253 // open an existing file in a mode. | |
254 // | |
255 ScopedNode existing_file_a_mode_node; | |
256 EXPECT_EQ(0, fs->Open(existing_file_path, O_WRONLY | O_CREAT | O_APPEND, | |
257 &existing_file_a_mode_node)); | |
258 | |
259 // | |
260 // open an existing file in a+ mode. | |
261 // | |
262 ScopedNode existing_file_a_plus_mode_node; | |
263 EXPECT_EQ(0, fs->Open(existing_file_path, O_RDWR | O_CREAT | O_APPEND, | |
264 &existing_file_a_plus_mode_node)); | |
265 } | |
266 | |
267 TEST_F(GoogleDriveFsTest, OpenOtherCases) { | |
268 ScopedRef<GoogleDriveFsForTesting> fs( | |
269 new GoogleDriveFsForTesting(map_, &ppapi_)); | |
270 | |
271 // | |
272 // A file opened without O_TRUNC flag does not truncate data. | |
273 // | |
274 Path file_path("/file"); | |
275 ScopedNode file_node; | |
276 EXPECT_EQ(0, fs->Open(file_path, O_WRONLY | O_CREAT | O_APPEND, &file_node)); | |
277 | |
278 // Write some data. | |
279 const char* contents = "contents"; | |
280 int bytes_written = 0; | |
281 EXPECT_EQ(0, file_node->Write(HandleAttr(), contents, strlen(contents), | |
282 &bytes_written)); | |
283 EXPECT_EQ(strlen(contents), bytes_written); | |
284 | |
285 // Create again. | |
286 EXPECT_EQ(0, fs->Open(file_path, O_WRONLY | O_CREAT | O_APPEND, &file_node)); | |
287 | |
288 // Check that the file still has data. | |
289 off_t size; | |
290 EXPECT_EQ(0, file_node->GetSize(&size)); | |
291 EXPECT_EQ(strlen(contents), size); | |
292 | |
293 // | |
294 // A file opened with O_TRUNC flag truncates data. | |
295 // | |
296 // Create again. | |
297 EXPECT_EQ(0, fs->Open(file_path, O_WRONLY | O_CREAT | O_TRUNC, &file_node)); | |
298 | |
299 // File should be empty. | |
300 EXPECT_EQ(0, file_node->GetSize(&size)); | |
301 EXPECT_EQ(0, size); | |
302 } | |
303 | |
304 TEST_F(GoogleDriveFsTest, ReadContents) { | |
305 ScopedRef<GoogleDriveFsForTesting> fs( | |
306 new GoogleDriveFsForTesting(map_, &ppapi_)); | |
307 | |
308 Path file_path("/file"); | |
309 ScopedNode file_node; | |
310 EXPECT_EQ(0, fs->Open(file_path, O_WRONLY | O_CREAT | O_APPEND, &file_node)); | |
311 | |
312 const char* contents = "contents"; | |
313 int bytes_written = 0; | |
314 EXPECT_EQ(0, file_node->Write(HandleAttr(), contents, strlen(contents), | |
315 &bytes_written)); | |
316 EXPECT_EQ(strlen(contents), bytes_written); | |
317 | |
318 ScopedNode node; | |
319 ASSERT_EQ(0, fs->Open(file_path, O_RDONLY, &node)); | |
320 | |
321 // | |
322 // Read nothing past the end of the file. | |
323 // | |
324 char buffer[10] = {0}; | |
325 int bytes_read = 0; | |
326 HandleAttr attr; | |
327 attr.offs = 100; | |
328 ASSERT_EQ(0, node->Read(attr, &buffer[0], sizeof(buffer), &bytes_read)); | |
329 ASSERT_EQ(0, bytes_read); | |
330 | |
331 // | |
332 // Read from the beginning of the file. Buffer size > file size. | |
333 // | |
334 attr.offs = 0; | |
335 ASSERT_EQ(0, node->Read(attr, &buffer[0], sizeof(buffer), &bytes_read)); | |
336 ASSERT_EQ(strlen(contents), bytes_read); | |
337 ASSERT_STREQ(contents, buffer); | |
338 | |
339 // | |
340 // Read from the middle of the file. Buffer size > file size. | |
341 // | |
342 attr.offs = 4; | |
343 ASSERT_EQ(0, node->Read(attr, &buffer[0], sizeof(buffer), &bytes_read)); | |
344 ASSERT_EQ(strlen(contents) - 4, bytes_read); | |
345 buffer[bytes_read] = 0; | |
346 ASSERT_STREQ("ents", buffer); | |
347 | |
348 // | |
349 // Read from the beginning of the file. Buffer size < file size. | |
350 // | |
351 char buffer_smaller_than_file[5]; | |
352 attr.offs = 0; | |
353 ASSERT_EQ(0, node->Read(attr, &buffer_smaller_than_file[0], | |
354 sizeof(buffer_smaller_than_file), &bytes_read)); | |
355 ASSERT_EQ(sizeof(buffer_smaller_than_file), bytes_read); | |
356 ASSERT_EQ('c', buffer_smaller_than_file[0]); | |
357 ASSERT_EQ('o', buffer_smaller_than_file[1]); | |
358 ASSERT_EQ('n', buffer_smaller_than_file[2]); | |
359 ASSERT_EQ('t', buffer_smaller_than_file[3]); | |
360 ASSERT_EQ('e', buffer_smaller_than_file[4]); | |
361 | |
362 // | |
363 // Read from the middle of the file. Buffer size < file size. | |
364 // | |
365 attr.offs = 1; | |
366 ASSERT_EQ(0, node->Read(attr, &buffer_smaller_than_file[0], | |
367 sizeof(buffer_smaller_than_file), &bytes_read)); | |
368 ASSERT_EQ(sizeof(buffer_smaller_than_file), bytes_read); | |
369 ASSERT_EQ('o', buffer_smaller_than_file[0]); | |
370 ASSERT_EQ('n', buffer_smaller_than_file[1]); | |
371 ASSERT_EQ('t', buffer_smaller_than_file[2]); | |
372 ASSERT_EQ('e', buffer_smaller_than_file[3]); | |
373 ASSERT_EQ('n', buffer_smaller_than_file[4]); | |
374 | |
375 // | |
376 // Read from the beginning of the file. Buffer size == file size. | |
377 // | |
378 char equal_buffer_size[8]; | |
379 attr.offs = 0; | |
380 ASSERT_EQ(0, node->Read(attr, &equal_buffer_size[0], | |
381 sizeof(equal_buffer_size), &bytes_read)); | |
382 ASSERT_EQ(sizeof(equal_buffer_size), bytes_read); | |
383 ASSERT_EQ('c', equal_buffer_size[0]); | |
384 ASSERT_EQ('o', equal_buffer_size[1]); | |
385 ASSERT_EQ('n', equal_buffer_size[2]); | |
386 ASSERT_EQ('t', equal_buffer_size[3]); | |
387 ASSERT_EQ('e', equal_buffer_size[4]); | |
388 ASSERT_EQ('n', equal_buffer_size[5]); | |
389 ASSERT_EQ('t', equal_buffer_size[6]); | |
390 ASSERT_EQ('s', equal_buffer_size[7]); | |
391 } | |
392 | |
393 TEST_F(GoogleDriveFsTest, ReadFailureCases) { | |
394 ScopedRef<GoogleDriveFsForTesting> fs( | |
395 new GoogleDriveFsForTesting(map_, &ppapi_)); | |
396 | |
397 Path file_path("/file"); | |
398 ScopedNode file_node; | |
399 EXPECT_EQ(0, fs->Open(file_path, O_WRONLY | O_CREAT | O_APPEND, &file_node)); | |
400 | |
401 const char* contents = "contents"; | |
402 int bytes_written = 0; | |
403 EXPECT_EQ(0, file_node->Write(HandleAttr(), contents, strlen(contents), | |
404 &bytes_written)); | |
405 EXPECT_EQ(strlen(contents), bytes_written); | |
406 | |
407 ScopedNode node; | |
408 ASSERT_EQ(0, fs->Open(file_path, O_WRONLY | O_CREAT | O_APPEND, &node)); | |
409 | |
410 // | |
411 // Reading from a file opened as write-only should fail. | |
412 // | |
413 char buffer[10]; | |
414 int bytes_read = 1; // Set to a non-zero value. | |
415 HandleAttr attr; | |
416 EXPECT_EQ(EACCES, node->Read(attr, &buffer[0], sizeof(buffer), &bytes_read)); | |
417 EXPECT_EQ(0, bytes_read); | |
418 | |
419 // mkdir on a directory that has not been existed. | |
420 Path dir_path("/dir"); | |
421 ASSERT_EQ(0, fs->Mkdir(dir_path, 0644)); | |
422 | |
423 // | |
424 // Reading from a directory should fail. | |
425 // | |
426 ScopedNode dir_node; | |
427 ASSERT_EQ(0, fs->Open(dir_path, O_RDONLY, &dir_node)); | |
428 ASSERT_EQ(EISDIR, | |
429 dir_node->Read(attr, &buffer[0], sizeof(buffer), &bytes_read)); | |
430 } | |
431 | |
432 TEST_F(GoogleDriveFsTest, WriteContents) { | |
433 ScopedRef<GoogleDriveFsForTesting> fs( | |
434 new GoogleDriveFsForTesting(map_, &ppapi_)); | |
435 | |
436 // | |
437 // Write from the beginning of the file. | |
438 // | |
439 Path file_path("/file"); | |
440 ScopedNode file_node; | |
441 EXPECT_EQ(0, fs->Open(file_path, O_WRONLY | O_CREAT | O_APPEND, &file_node)); | |
442 | |
443 const char* contents = "contents"; | |
444 int bytes_written = 0; | |
445 EXPECT_EQ(0, file_node->Write(HandleAttr(), contents, strlen(contents), | |
446 &bytes_written)); | |
447 ASSERT_EQ(strlen(contents), bytes_written); | |
448 | |
449 // Open as read-write. | |
450 ScopedNode node; | |
451 ASSERT_EQ(0, fs->Open(file_path, O_RDWR, &node)); | |
452 | |
453 // | |
454 // Write from the middle of the file. | |
455 // | |
456 bytes_written = 1; // Set to a non-zero value. | |
457 HandleAttr attr; | |
458 attr.offs = 3; | |
459 EXPECT_EQ(0, node->Write(attr, "struct", 6, &bytes_written)); | |
460 EXPECT_EQ(6, bytes_written); | |
461 | |
462 char buffer[10]; | |
463 attr.offs = 0; | |
464 int bytes_read = 0; | |
465 EXPECT_EQ(0, node->Read(attr, &buffer[0], sizeof(buffer), &bytes_read)); | |
466 EXPECT_EQ(9, bytes_read); | |
467 buffer[bytes_read] = 0; | |
468 EXPECT_STREQ("construct", buffer); | |
469 } | |
470 | |
471 TEST_F(GoogleDriveFsTest, WriteFailureCases) { | |
472 ScopedRef<GoogleDriveFsForTesting> fs( | |
473 new GoogleDriveFsForTesting(map_, &ppapi_)); | |
474 | |
475 Path file_path("/file"); | |
476 ScopedNode file_node; | |
477 EXPECT_EQ(0, fs->Open(file_path, O_WRONLY | O_CREAT | O_APPEND, &file_node)); | |
478 | |
479 const char* contents = "contents"; | |
480 int bytes_written = 0; | |
481 EXPECT_EQ(0, file_node->Write(HandleAttr(), contents, strlen(contents), | |
482 &bytes_written)); | |
483 EXPECT_EQ(strlen(contents), bytes_written); | |
484 | |
485 ScopedNode node; | |
486 ASSERT_EQ(0, fs->Open(file_path, O_RDONLY, &node)); | |
487 | |
488 // | |
489 // Writing from a file opened as read-only should fail. | |
490 // | |
491 bytes_written = 1; // Set to a non-zero value. | |
492 HandleAttr attr; | |
493 attr.offs = 0; | |
494 char buffer[10]; | |
495 ASSERT_EQ(EACCES, | |
496 node->Write(attr, &buffer[0], sizeof(buffer), &bytes_written)); | |
497 ASSERT_EQ(0, bytes_written); | |
498 | |
499 // mkdir on a directory that has not been existed. | |
500 Path dir_path("/dir"); | |
501 ASSERT_EQ(0, fs->Mkdir(dir_path, 0644)); | |
502 | |
503 // | |
504 // Writing to a directory should fail. | |
505 // | |
506 EXPECT_EQ(0, fs->Open(dir_path, O_RDONLY, &node)); | |
507 int bytes_read = 0; | |
508 EXPECT_EQ(EISDIR, node->Write(attr, &buffer[0], sizeof(buffer), &bytes_read)); | |
509 } | |
510 | |
511 TEST_F(GoogleDriveFsTest, GetStat) { | |
512 ScopedRef<GoogleDriveFsForTesting> fs( | |
513 new GoogleDriveFsForTesting(map_, &ppapi_)); | |
514 | |
515 // | |
516 // GetStat on a file. | |
517 // | |
518 ScopedNode node; | |
519 ASSERT_EQ(0, fs->Open(Path("/file"), O_WRONLY | O_CREAT | O_APPEND, &node)); | |
520 | |
521 const char* contents = "contents"; | |
522 int bytes_written = 0; | |
523 EXPECT_EQ( | |
524 0, node->Write(HandleAttr(), contents, strlen(contents), &bytes_written)); | |
525 ASSERT_EQ(strlen(contents), bytes_written); | |
526 | |
527 struct stat statbuf; | |
528 EXPECT_EQ(0, node->GetStat(&statbuf)); | |
529 EXPECT_TRUE(S_ISREG(statbuf.st_mode)); | |
530 EXPECT_EQ(S_IWRITE, statbuf.st_mode & S_MODEBITS); | |
531 EXPECT_EQ(strlen(contents), statbuf.st_size); | |
532 EXPECT_EQ(0, statbuf.st_atime); | |
533 EXPECT_EQ(0, statbuf.st_ctime); | |
534 | |
535 // UTC time "2016-07-24T08:21:28.940Z" specified at each file | |
536 // in FakeGoogleDriveServer is equal to the UNIX timestamp 1469348488 | |
537 // 1300628744, though, is returned by mktime. | |
chanpatorikku
2016/08/07 02:41:03
Test cases of lines 537-538 and lines 564-565 are
binji
2016/08/22 19:21:53
mktime is defined as generating a time in local ti
chanpatorikku
2016/08/29 17:14:03
mktime generates time in local time, but st_mtime
binji
2016/08/30 01:39:34
I'm not seeing this behavior. Using pnacl-clang, I
| |
538 // EXPECT_EQ(1469348488, statbuf.st_mtime); | |
539 | |
540 // Test Get* and Isa* methods. | |
541 off_t size; | |
542 EXPECT_EQ(0, node->GetSize(&size)); | |
543 EXPECT_EQ(strlen(contents), size); | |
544 EXPECT_FALSE(node->IsaDir()); | |
545 EXPECT_TRUE(node->IsaFile()); | |
546 EXPECT_EQ(ENOTTY, node->Isatty()); | |
547 | |
548 Path path("/dir"); | |
549 ASSERT_EQ(0, fs->Mkdir(path, 0644)); | |
550 | |
551 // | |
552 // GetStat on a directory. | |
553 // | |
554 EXPECT_EQ(0, fs->Open(path, O_RDONLY, &node)); | |
555 EXPECT_EQ(0, node->GetStat(&statbuf)); | |
556 EXPECT_TRUE(S_ISDIR(statbuf.st_mode)); | |
557 EXPECT_EQ(S_IREAD, statbuf.st_mode & S_MODEBITS); | |
558 EXPECT_EQ(0, statbuf.st_size); | |
559 EXPECT_EQ(0, statbuf.st_atime); | |
560 EXPECT_EQ(0, statbuf.st_ctime); | |
561 | |
562 // UTC time "2016-07-24T08:21:28.940Z" specified at each directory | |
563 // in FakeGoogleDriveServer is equal to the UNIX timestamp 1469348488; | |
564 // 1300628744, though, is returned by mktime. | |
565 // EXPECT_EQ(1469348488, statbuf.st_mtime); | |
566 | |
567 // Test Get* and Isa* methods. | |
568 EXPECT_EQ(0, node->GetSize(&size)); | |
569 EXPECT_EQ(0, size); | |
570 EXPECT_TRUE(node->IsaDir()); | |
571 EXPECT_FALSE(node->IsaFile()); | |
572 EXPECT_EQ(ENOTTY, node->Isatty()); | |
573 } | |
574 | |
575 TEST_F(GoogleDriveFsTest, FTruncate) { | |
576 ScopedRef<GoogleDriveFsForTesting> fs( | |
577 new GoogleDriveFsForTesting(map_, &ppapi_)); | |
578 | |
579 ScopedNode node; | |
580 ASSERT_EQ(0, fs->Open(Path("/file"), O_RDWR | O_CREAT | O_TRUNC, &node)); | |
581 const char* contents = "contents"; | |
582 int bytes_written = 0; | |
583 EXPECT_EQ( | |
584 0, node->Write(HandleAttr(), contents, strlen(contents), &bytes_written)); | |
585 ASSERT_EQ(strlen(contents), bytes_written); | |
586 | |
587 HandleAttr attr; | |
588 char buffer[10] = {0}; | |
589 int bytes_read = 0; | |
590 | |
591 // | |
592 // First make the file shorter... | |
593 // | |
594 EXPECT_EQ(0, node->FTruncate(4)); | |
595 EXPECT_EQ(0, node->Read(attr, &buffer[0], sizeof(buffer), &bytes_read)); | |
596 EXPECT_EQ(4, bytes_read); | |
597 buffer[bytes_read] = 0; | |
598 EXPECT_STREQ("cont", buffer); | |
599 | |
600 // | |
601 // Now make the file longer... | |
602 // | |
603 EXPECT_EQ(0, node->FTruncate(8)); | |
604 EXPECT_EQ(0, node->Read(attr, &buffer[0], sizeof(buffer), &bytes_read)); | |
605 EXPECT_EQ(8, bytes_read); | |
606 buffer[bytes_read] = 0; | |
607 EXPECT_STREQ("cont\0\0\0\0", buffer); | |
608 | |
609 Path path("/dir"); | |
610 ASSERT_EQ(0, fs->Mkdir(path, 0644)); | |
611 | |
612 // | |
613 // Ftruncate should fail for a directory. | |
614 // | |
615 EXPECT_EQ(0, fs->Open(path, O_RDONLY, &node)); | |
616 EXPECT_EQ(EISDIR, node->FTruncate(4)); | |
617 } | |
618 | |
619 TEST_F(GoogleDriveFsTest, OpenDirectory) { | |
620 ScopedRef<GoogleDriveFsForTesting> fs( | |
621 new GoogleDriveFsForTesting(map_, &ppapi_)); | |
622 | |
623 Path dir_path("/dir"); | |
624 ASSERT_EQ(0, fs->Mkdir(dir_path, 0644)); | |
625 | |
626 // | |
627 // Open a directory with r mode should succeed. | |
628 // | |
629 ScopedNode node; | |
630 ASSERT_EQ(0, fs->Open(dir_path, O_RDONLY, &node)); | |
631 | |
632 // | |
633 // Open a directory with r+, w, w+, a, and a+ mode should fail. | |
634 // | |
635 EXPECT_EQ(EPERM, fs->Open(dir_path, O_RDWR, &node)); | |
636 EXPECT_EQ(EPERM, fs->Open(dir_path, O_WRONLY | O_CREAT | O_TRUNC, &node)); | |
637 EXPECT_EQ(EPERM, fs->Open(dir_path, O_RDWR | O_CREAT | O_TRUNC, &node)); | |
638 EXPECT_EQ(EPERM, fs->Open(dir_path, O_WRONLY | O_CREAT | O_APPEND, &node)); | |
639 EXPECT_EQ(EPERM, fs->Open(dir_path, O_RDWR | O_CREAT | O_APPEND, &node)); | |
640 | |
641 // | |
642 // Opening a non-existing directory should fail. | |
643 // | |
644 EXPECT_EQ(ENOENT, fs->Open(Path("/nonexistingdir"), O_RDONLY, &node)); | |
645 } | |
646 | |
647 TEST_F(GoogleDriveFsTest, GetDents) { | |
648 ScopedRef<GoogleDriveFsForTesting> fs( | |
649 new GoogleDriveFsForTesting(map_, &ppapi_)); | |
650 | |
651 ScopedNode node; | |
652 Path file_path("/file"); | |
653 ASSERT_EQ(0, fs->Open(file_path, O_WRONLY | O_CREAT | O_TRUNC, &node)); | |
654 const char* contents = "contents"; | |
655 int bytes_written = 0; | |
656 EXPECT_EQ( | |
657 0, node->Write(HandleAttr(), contents, strlen(contents), &bytes_written)); | |
658 ASSERT_EQ(strlen(contents), bytes_written); | |
659 | |
660 ScopedNode root; | |
661 ASSERT_EQ(0, fs->Open(Path("/"), O_RDONLY, &root)); | |
662 | |
663 struct stat stat; | |
664 ASSERT_EQ(0, node->GetStat(&stat)); | |
665 | |
666 // | |
667 // Should fail for regular files. | |
668 // | |
669 const size_t kMaxDirents = 5; | |
670 dirent dirents[kMaxDirents]; | |
671 int bytes_read = 1; // Set to a non-zero value. | |
672 | |
673 memset(&dirents[0], 0, sizeof(dirents)); | |
674 EXPECT_EQ(ENOTDIR, | |
675 node->GetDents(0, &dirents[0], sizeof(dirents), &bytes_read)); | |
676 EXPECT_EQ(0, bytes_read); | |
677 | |
678 // | |
679 // Should work with root directory. | |
680 // | |
681 // +2 to test a size that is not a multiple of sizeof(dirent). | |
682 // Expect it to round down. | |
683 memset(&dirents[0], 0, sizeof(dirents)); | |
684 EXPECT_EQ( | |
685 0, root->GetDents(0, &dirents[0], sizeof(dirent) * 3 + 2, &bytes_read)); | |
686 | |
687 { | |
688 size_t num_dirents = bytes_read / sizeof(dirent); | |
689 EXPECT_EQ(3, num_dirents); | |
690 EXPECT_EQ(sizeof(dirent) * num_dirents, bytes_read); | |
691 | |
692 std::multiset<std::string> dirnames; | |
693 for (size_t i = 0; i < num_dirents; ++i) { | |
694 EXPECT_EQ(sizeof(dirent), dirents[i].d_reclen); | |
695 dirnames.insert(dirents[i].d_name); | |
696 } | |
697 | |
698 EXPECT_EQ(1, dirnames.count("file")); | |
699 EXPECT_EQ(1, dirnames.count(".")); | |
700 EXPECT_EQ(1, dirnames.count("..")); | |
701 } | |
702 | |
703 // Add another file... | |
704 ASSERT_EQ(0, fs->Open(Path("/file2"), O_WRONLY | O_CREAT | O_TRUNC, &node)); | |
705 ASSERT_EQ(0, node->GetStat(&stat)); | |
706 | |
707 // | |
708 // Read the root directory again after adding another file. | |
709 // | |
710 memset(&dirents[0], 0, sizeof(dirents)); | |
711 EXPECT_EQ(0, root->GetDents(0, &dirents[0], sizeof(dirents), &bytes_read)); | |
712 | |
713 { | |
714 size_t num_dirents = bytes_read / sizeof(dirent); | |
715 EXPECT_EQ(4, num_dirents); | |
716 EXPECT_EQ(sizeof(dirent) * num_dirents, bytes_read); | |
717 | |
718 std::multiset<std::string> dirnames; | |
719 for (size_t i = 0; i < num_dirents; ++i) { | |
720 EXPECT_EQ(sizeof(dirent), dirents[i].d_reclen); | |
721 dirnames.insert(dirents[i].d_name); | |
722 } | |
723 | |
724 EXPECT_EQ(1, dirnames.count("file")); | |
725 EXPECT_EQ(1, dirnames.count("file2")); | |
726 EXPECT_EQ(1, dirnames.count(".")); | |
727 EXPECT_EQ(1, dirnames.count("..")); | |
728 } | |
729 | |
730 // | |
731 // Read >100 entries. Multiple API requests are sent to request >100 entries. | |
732 // | |
733 const size_t kMaxDirectsMultipleRequests = 105; | |
734 std::vector<dirent> direntsMultipleRequests; | |
735 direntsMultipleRequests.resize(kMaxDirectsMultipleRequests); | |
736 | |
737 // Add 100 files... | |
738 for (size_t i = 0; i < 100; ++i) { | |
739 char buffer[4]; | |
740 int char_written = sprintf(buffer, "%i", i); | |
741 ASSERT_LE(0, char_written); | |
742 | |
743 ASSERT_EQ(0, fs->Open(Path("/anotherfile" + std::string(buffer)), | |
744 O_WRONLY | O_CREAT | O_TRUNC, &node)); | |
745 ASSERT_EQ(0, node->GetStat(&stat)); | |
746 } | |
747 | |
748 EXPECT_EQ(0, root->GetDents(0, &direntsMultipleRequests[0], | |
749 sizeof(dirent) * direntsMultipleRequests.size(), | |
750 &bytes_read)); | |
751 { | |
752 size_t num_dirents = bytes_read / sizeof(dirent); | |
753 EXPECT_EQ(104, num_dirents); | |
754 EXPECT_EQ(sizeof(dirent) * num_dirents, bytes_read); | |
755 | |
756 std::multiset<std::string> dirnames; | |
757 for (size_t i = 0; i < num_dirents; ++i) { | |
758 EXPECT_EQ(sizeof(dirent), direntsMultipleRequests[i].d_reclen); | |
759 dirnames.insert(direntsMultipleRequests[i].d_name); | |
760 } | |
761 | |
762 for (size_t i = 0; i < 100; ++i) { | |
763 char buffer[4]; | |
764 int char_written = sprintf(buffer, "%i", i); | |
765 ASSERT_LE(0, char_written); | |
766 | |
767 EXPECT_EQ(1, dirnames.count("anotherfile" + std::string(buffer))); | |
768 } | |
769 | |
770 EXPECT_EQ(1, dirnames.count("file")); | |
771 EXPECT_EQ(1, dirnames.count("file2")); | |
772 EXPECT_EQ(1, dirnames.count(".")); | |
773 EXPECT_EQ(1, dirnames.count("..")); | |
774 } | |
775 } | |
776 | |
777 // TEST_F(GoogleDriveFsTest, Remove) { | |
778 // TODO: Add tests after Remove becomes supported. | |
779 // } | |
780 | |
781 // TEST_F(GoogleDriveFsTest, Unlink) { | |
782 // TODO: Add tests after Unlink becomes supported. | |
783 // } | |
784 | |
785 // TEST_F(GoogleDriveFsTest, Rename) { | |
786 // TODO: Add tests after Rename becomes supported. | |
787 // } | |
788 | |
789 // TEST_F(GoogleDriveFsTest, Chmod) { | |
790 // Chmod not supported. | |
791 // } | |
OLD | NEW |