Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(278)

Side by Side Diff: native_client_sdk/src/tests/nacl_io_test/googledrivefs_test.cc

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

Powered by Google App Engine
This is Rietveld 408576698