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

Side by Side Diff: services/files/files_apptest.cc

Issue 963093004: Files: Add basic implementation of Directory and some basic tests. (Closed) Base URL: https://github.com/domokit/mojo.git@file_man
Patch Set: oops Created 5 years, 9 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
« no previous file with comments | « services/files/file_impl.cc ('k') | services/files/shared_impl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // TODO(vtl): Split this file.
6
7 #include <map>
8 #include <string>
5 #include <vector> 9 #include <vector>
6 10
7 #include "base/macros.h" 11 #include "base/macros.h"
8 #include "mojo/public/cpp/application/application_impl.h" 12 #include "mojo/public/cpp/application/application_impl.h"
9 #include "mojo/public/cpp/application/application_test_base.h" 13 #include "mojo/public/cpp/application/application_test_base.h"
10 #include "mojo/public/cpp/bindings/interface_request.h" 14 #include "mojo/public/cpp/bindings/interface_request.h"
11 #include "mojo/public/cpp/bindings/type_converter.h" 15 #include "mojo/public/cpp/bindings/type_converter.h"
12 #include "services/files/directory.mojom.h" 16 #include "services/files/directory.mojom.h"
13 #include "services/files/file.mojom.h" 17 #include "services/files/file.mojom.h"
14 #include "services/files/files.mojom.h" 18 #include "services/files/files.mojom.h"
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 class FilesAppTest : public test::ApplicationTestBase { 91 class FilesAppTest : public test::ApplicationTestBase {
88 public: 92 public:
89 FilesAppTest() {} 93 FilesAppTest() {}
90 ~FilesAppTest() override {} 94 ~FilesAppTest() override {}
91 95
92 void SetUp() override { 96 void SetUp() override {
93 test::ApplicationTestBase::SetUp(); 97 test::ApplicationTestBase::SetUp();
94 application_impl()->ConnectToService("mojo:files", &files_); 98 application_impl()->ConnectToService("mojo:files", &files_);
95 } 99 }
96 100
101 protected:
102 void GetTemporaryRoot(DirectoryPtr* directory) {
103 Error error = ERROR_INTERNAL;
104 files()->OpenFileSystem(FILE_SYSTEM_TEMPORARY, GetProxy(directory),
105 Capture(&error));
106 ASSERT_TRUE(files().WaitForIncomingMethodCall());
107 ASSERT_EQ(ERROR_OK, error);
108 }
109
97 FilesPtr& files() { return files_; } 110 FilesPtr& files() { return files_; }
98 111
99 private: 112 private:
100 FilesPtr files_; 113 FilesPtr files_;
101 114
102 DISALLOW_COPY_AND_ASSIGN(FilesAppTest); 115 DISALLOW_COPY_AND_ASSIGN(FilesAppTest);
103 }; 116 };
104 117
105 TEST_F(FilesAppTest, CreateWriteCloseRenameOpenRead) { 118 // FileImpl --------------------------------------------------------------------
106 // Get a temporary root directory. 119
120 typedef FilesAppTest FileImplTest;
121
122 TEST_F(FileImplTest, CreateWriteCloseRenameOpenRead) {
107 DirectoryPtr directory; 123 DirectoryPtr directory;
108 Error error = ERROR_INTERNAL; 124 GetTemporaryRoot(&directory);
109 files()->OpenFileSystem(FILE_SYSTEM_TEMPORARY, GetProxy(&directory), 125 Error error;
110 Capture(&error));
111 ASSERT_TRUE(files().WaitForIncomingMethodCall());
112 EXPECT_EQ(ERROR_OK, error);
113 126
114 { 127 {
115 // Create my_file. 128 // Create my_file.
116 FilePtr file; 129 FilePtr file;
117 error = ERROR_INTERNAL; 130 error = ERROR_INTERNAL;
118 directory->OpenFile("my_file", GetProxy(&file), 131 directory->OpenFile("my_file", GetProxy(&file),
119 kOpenFlagWrite | kOpenFlagCreate, Capture(&error)); 132 kOpenFlagWrite | kOpenFlagCreate, Capture(&error));
120 ASSERT_TRUE(directory.WaitForIncomingMethodCall()); 133 ASSERT_TRUE(directory.WaitForIncomingMethodCall());
121 EXPECT_EQ(ERROR_OK, error); 134 EXPECT_EQ(ERROR_OK, error);
122 135
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 EXPECT_EQ(static_cast<uint8_t>('l'), bytes_read[1]); 181 EXPECT_EQ(static_cast<uint8_t>('l'), bytes_read[1]);
169 EXPECT_EQ(static_cast<uint8_t>('l'), bytes_read[2]); 182 EXPECT_EQ(static_cast<uint8_t>('l'), bytes_read[2]);
170 } 183 }
171 184
172 // TODO(vtl): Test various open options. 185 // TODO(vtl): Test various open options.
173 // TODO(vtl): Test read/write offset options. 186 // TODO(vtl): Test read/write offset options.
174 } 187 }
175 188
176 // Note: Ignore nanoseconds, since it may not always be supported. We expect at 189 // Note: Ignore nanoseconds, since it may not always be supported. We expect at
177 // least second-resolution support though. 190 // least second-resolution support though.
178 TEST_F(FilesAppTest, StatTouch) { 191 TEST_F(FileImplTest, StatTouch) {
179 // Get a temporary root directory.
180 DirectoryPtr directory; 192 DirectoryPtr directory;
181 Error error = ERROR_INTERNAL; 193 GetTemporaryRoot(&directory);
182 files()->OpenFileSystem(FILE_SYSTEM_TEMPORARY, GetProxy(&directory), 194 Error error;
183 Capture(&error));
184 ASSERT_TRUE(files().WaitForIncomingMethodCall());
185 EXPECT_EQ(ERROR_OK, error);
186 195
187 // Create my_file. 196 // Create my_file.
188 FilePtr file; 197 FilePtr file;
189 error = ERROR_INTERNAL; 198 error = ERROR_INTERNAL;
190 directory->OpenFile("my_file", GetProxy(&file), 199 directory->OpenFile("my_file", GetProxy(&file),
191 kOpenFlagWrite | kOpenFlagCreate, Capture(&error)); 200 kOpenFlagWrite | kOpenFlagCreate, Capture(&error));
192 ASSERT_TRUE(directory.WaitForIncomingMethodCall()); 201 ASSERT_TRUE(directory.WaitForIncomingMethodCall());
193 EXPECT_EQ(ERROR_OK, error); 202 EXPECT_EQ(ERROR_OK, error);
194 203
195 // Stat it. 204 // Stat it.
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 // TODO(vtl): Also test Touch() "now" options. 264 // TODO(vtl): Also test Touch() "now" options.
256 // TODO(vtl): Also test touching both atime and mtime. 265 // TODO(vtl): Also test touching both atime and mtime.
257 266
258 // Close it. 267 // Close it.
259 error = ERROR_INTERNAL; 268 error = ERROR_INTERNAL;
260 file->Close(Capture(&error)); 269 file->Close(Capture(&error));
261 ASSERT_TRUE(file.WaitForIncomingMethodCall()); 270 ASSERT_TRUE(file.WaitForIncomingMethodCall());
262 EXPECT_EQ(ERROR_OK, error); 271 EXPECT_EQ(ERROR_OK, error);
263 } 272 }
264 273
265 TEST_F(FilesAppTest, TellSeek) { 274 TEST_F(FileImplTest, TellSeek) {
266 // Get a temporary root directory.
267 DirectoryPtr directory; 275 DirectoryPtr directory;
268 Error error = ERROR_INTERNAL; 276 GetTemporaryRoot(&directory);
269 files()->OpenFileSystem(FILE_SYSTEM_TEMPORARY, GetProxy(&directory), 277 Error error;
270 Capture(&error));
271 ASSERT_TRUE(files().WaitForIncomingMethodCall());
272 EXPECT_EQ(ERROR_OK, error);
273 278
274 // Create my_file. 279 // Create my_file.
275 FilePtr file; 280 FilePtr file;
276 error = ERROR_INTERNAL; 281 error = ERROR_INTERNAL;
277 directory->OpenFile("my_file", GetProxy(&file), 282 directory->OpenFile("my_file", GetProxy(&file),
278 kOpenFlagWrite | kOpenFlagCreate, Capture(&error)); 283 kOpenFlagWrite | kOpenFlagCreate, Capture(&error));
279 ASSERT_TRUE(directory.WaitForIncomingMethodCall()); 284 ASSERT_TRUE(directory.WaitForIncomingMethodCall());
280 EXPECT_EQ(ERROR_OK, error); 285 EXPECT_EQ(ERROR_OK, error);
281 286
282 // Write to it. 287 // Write to it.
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
350 // TODO(vtl): Check that seeking actually affects reading/writing. 355 // TODO(vtl): Check that seeking actually affects reading/writing.
351 // TODO(vtl): Check that seeking can extend the file? 356 // TODO(vtl): Check that seeking can extend the file?
352 357
353 // Close it. 358 // Close it.
354 error = ERROR_INTERNAL; 359 error = ERROR_INTERNAL;
355 file->Close(Capture(&error)); 360 file->Close(Capture(&error));
356 ASSERT_TRUE(file.WaitForIncomingMethodCall()); 361 ASSERT_TRUE(file.WaitForIncomingMethodCall());
357 EXPECT_EQ(ERROR_OK, error); 362 EXPECT_EQ(ERROR_OK, error);
358 } 363 }
359 364
360 TEST_F(FilesAppTest, Dup) { 365 TEST_F(FileImplTest, Dup) {
361 // Get a temporary root directory.
362 DirectoryPtr directory; 366 DirectoryPtr directory;
363 Error error = ERROR_INTERNAL; 367 GetTemporaryRoot(&directory);
364 files()->OpenFileSystem(FILE_SYSTEM_TEMPORARY, GetProxy(&directory), 368 Error error;
365 Capture(&error));
366 ASSERT_TRUE(files().WaitForIncomingMethodCall());
367 EXPECT_EQ(ERROR_OK, error);
368 369
369 // Create my_file. 370 // Create my_file.
370 FilePtr file1; 371 FilePtr file1;
371 error = ERROR_INTERNAL; 372 error = ERROR_INTERNAL;
372 directory->OpenFile("my_file", GetProxy(&file1), 373 directory->OpenFile("my_file", GetProxy(&file1),
373 kOpenFlagRead | kOpenFlagWrite | kOpenFlagCreate, 374 kOpenFlagRead | kOpenFlagWrite | kOpenFlagCreate,
374 Capture(&error)); 375 Capture(&error));
375 ASSERT_TRUE(directory.WaitForIncomingMethodCall()); 376 ASSERT_TRUE(directory.WaitForIncomingMethodCall());
376 EXPECT_EQ(ERROR_OK, error); 377 EXPECT_EQ(ERROR_OK, error);
377 378
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
449 450
450 // Close |file2|. 451 // Close |file2|.
451 error = ERROR_INTERNAL; 452 error = ERROR_INTERNAL;
452 file2->Close(Capture(&error)); 453 file2->Close(Capture(&error));
453 ASSERT_TRUE(file2.WaitForIncomingMethodCall()); 454 ASSERT_TRUE(file2.WaitForIncomingMethodCall());
454 EXPECT_EQ(ERROR_OK, error); 455 EXPECT_EQ(ERROR_OK, error);
455 456
456 // TODO(vtl): Test that |file2| has the same open options as |file1|. 457 // TODO(vtl): Test that |file2| has the same open options as |file1|.
457 } 458 }
458 459
460 // DirectoryImpl ---------------------------------------------------------------
461
462 typedef FilesAppTest DirectoryImplTest;
463
464 TEST_F(FileImplTest, Read) {
465 DirectoryPtr directory;
466 GetTemporaryRoot(&directory);
467 Error error;
468
469 // Make some files.
470 const struct {
471 const char* name;
472 uint32_t open_flags;
473 } files_to_create[] = {
474 {"my_file1", kOpenFlagRead | kOpenFlagWrite | kOpenFlagCreate},
475 {"my_file2", kOpenFlagWrite | kOpenFlagCreate | kOpenFlagExclusive},
476 {"my_file3", kOpenFlagWrite | kOpenFlagCreate | kOpenFlagAppend},
477 {"my_file4", kOpenFlagWrite | kOpenFlagCreate | kOpenFlagTruncate}};
478 for (size_t i = 0; i < arraysize(files_to_create); i++) {
479 error = ERROR_INTERNAL;
480 directory->OpenFile(files_to_create[i].name, nullptr,
481 files_to_create[i].open_flags, Capture(&error));
482 ASSERT_TRUE(directory.WaitForIncomingMethodCall());
483 EXPECT_EQ(ERROR_OK, error);
484 }
485 // Make a directory.
486 error = ERROR_INTERNAL;
487 directory->OpenDirectory("my_dir", nullptr,
488 kOpenFlagRead | kOpenFlagWrite | kOpenFlagCreate,
489 Capture(&error));
490 ASSERT_TRUE(directory.WaitForIncomingMethodCall());
491 EXPECT_EQ(ERROR_OK, error);
492
493 error = ERROR_INTERNAL;
494 Array<DirectoryEntryPtr> directory_contents;
495 directory->Read(Capture(&error, &directory_contents));
496 ASSERT_TRUE(directory.WaitForIncomingMethodCall());
497 EXPECT_EQ(ERROR_OK, error);
498
499 // Expected contents of the directory.
500 std::map<std::string, FileType> expected_contents;
501 expected_contents["my_file1"] = FILE_TYPE_REGULAR_FILE;
502 expected_contents["my_file2"] = FILE_TYPE_REGULAR_FILE;
503 expected_contents["my_file3"] = FILE_TYPE_REGULAR_FILE;
504 expected_contents["my_file4"] = FILE_TYPE_REGULAR_FILE;
505 expected_contents["my_dir"] = FILE_TYPE_DIRECTORY;
506 expected_contents["."] = FILE_TYPE_DIRECTORY;
507 expected_contents[".."] = FILE_TYPE_DIRECTORY;
508
509 EXPECT_EQ(expected_contents.size(), directory_contents.size());
510 for (size_t i = 0; i < directory_contents.size(); i++) {
511 ASSERT_TRUE(directory_contents[i]);
512 ASSERT_TRUE(directory_contents[i]->name);
513 auto it = expected_contents.find(directory_contents[i]->name.get());
514 ASSERT_TRUE(it != expected_contents.end());
515 EXPECT_EQ(it->second, directory_contents[i]->type);
516 expected_contents.erase(it);
517 }
518 }
519
520 // Note: Ignore nanoseconds, since it may not always be supported. We expect at
521 // least second-resolution support though.
522 // TODO(vtl): Maybe share this with |FileImplTest.StatTouch| ... but then it'd
523 // be harder to split this file.
524 TEST_F(DirectoryImplTest, StatTouch) {
525 DirectoryPtr directory;
526 GetTemporaryRoot(&directory);
527 Error error;
528
529 // Stat it.
530 error = ERROR_INTERNAL;
531 FileInformationPtr file_info;
532 directory->Stat(Capture(&error, &file_info));
533 ASSERT_TRUE(directory.WaitForIncomingMethodCall());
534 EXPECT_EQ(ERROR_OK, error);
535 ASSERT_FALSE(file_info.is_null());
536 EXPECT_EQ(0, file_info->size);
537 ASSERT_FALSE(file_info->atime.is_null());
538 EXPECT_GT(file_info->atime->seconds, 0); // Expect that it's not 1970-01-01.
539 ASSERT_FALSE(file_info->mtime.is_null());
540 EXPECT_GT(file_info->mtime->seconds, 0);
541 int64_t first_mtime = file_info->mtime->seconds;
542
543 // Touch only the atime.
544 error = ERROR_INTERNAL;
545 TimespecOrNowPtr t(TimespecOrNow::New());
546 t->now = false;
547 t->timespec = Timespec::New();
548 const int64_t kPartyTime1 = 1234567890; // Party like it's 2009-02-13.
549 t->timespec->seconds = kPartyTime1;
550 directory->Touch(t.Pass(), nullptr, Capture(&error));
551 ASSERT_TRUE(directory.WaitForIncomingMethodCall());
552 EXPECT_EQ(ERROR_OK, error);
553
554 // Stat again.
555 error = ERROR_INTERNAL;
556 file_info.reset();
557 directory->Stat(Capture(&error, &file_info));
558 ASSERT_TRUE(directory.WaitForIncomingMethodCall());
559 EXPECT_EQ(ERROR_OK, error);
560 ASSERT_FALSE(file_info.is_null());
561 ASSERT_FALSE(file_info->atime.is_null());
562 EXPECT_EQ(kPartyTime1, file_info->atime->seconds);
563 ASSERT_FALSE(file_info->mtime.is_null());
564 EXPECT_EQ(first_mtime, file_info->mtime->seconds);
565
566 // Touch only the mtime.
567 t = TimespecOrNow::New();
568 t->now = false;
569 t->timespec = Timespec::New();
570 const int64_t kPartyTime2 = 1425059525; // No time like the present.
571 t->timespec->seconds = kPartyTime2;
572 directory->Touch(nullptr, t.Pass(), Capture(&error));
573 ASSERT_TRUE(directory.WaitForIncomingMethodCall());
574 EXPECT_EQ(ERROR_OK, error);
575
576 // Stat again.
577 error = ERROR_INTERNAL;
578 file_info.reset();
579 directory->Stat(Capture(&error, &file_info));
580 ASSERT_TRUE(directory.WaitForIncomingMethodCall());
581 EXPECT_EQ(ERROR_OK, error);
582 ASSERT_FALSE(file_info.is_null());
583 ASSERT_FALSE(file_info->atime.is_null());
584 EXPECT_EQ(kPartyTime1, file_info->atime->seconds);
585 ASSERT_FALSE(file_info->mtime.is_null());
586 EXPECT_EQ(kPartyTime2, file_info->mtime->seconds);
587
588 // TODO(vtl): Also test Touch() "now" options.
589 // TODO(vtl): Also test touching both atime and mtime.
590 }
591
592 // TODO(vtl): Properly test OpenFile() and OpenDirectory() (including flags).
593
594 TEST_F(DirectoryImplTest, BasicRenameDelete) {
595 DirectoryPtr directory;
596 GetTemporaryRoot(&directory);
597 Error error;
598
599 // Create my_file.
600 error = ERROR_INTERNAL;
601 directory->OpenFile("my_file", nullptr, kOpenFlagWrite | kOpenFlagCreate,
602 Capture(&error));
603 ASSERT_TRUE(directory.WaitForIncomingMethodCall());
604 EXPECT_EQ(ERROR_OK, error);
605
606 // Opening my_file should succeed.
607 error = ERROR_INTERNAL;
608 directory->OpenFile("my_file", nullptr, kOpenFlagRead, Capture(&error));
609 ASSERT_TRUE(directory.WaitForIncomingMethodCall());
610 EXPECT_EQ(ERROR_OK, error);
611
612 // Rename my_file to my_new_file.
613 directory->Rename("my_file", "my_new_file", Capture(&error));
614 ASSERT_TRUE(directory.WaitForIncomingMethodCall());
615 EXPECT_EQ(ERROR_OK, error);
616
617 // Opening my_file should fail.
618 error = ERROR_INTERNAL;
619 directory->OpenFile("my_file", nullptr, kOpenFlagRead, Capture(&error));
620 ASSERT_TRUE(directory.WaitForIncomingMethodCall());
621 EXPECT_EQ(ERROR_UNKNOWN, error);
622
623 // Opening my_new_file should succeed.
624 error = ERROR_INTERNAL;
625 directory->OpenFile("my_new_file", nullptr, kOpenFlagRead, Capture(&error));
626 ASSERT_TRUE(directory.WaitForIncomingMethodCall());
627 EXPECT_EQ(ERROR_OK, error);
628
629 // Delete my_new_file (no flags).
630 directory->Delete("my_new_file", 0, Capture(&error));
631 ASSERT_TRUE(directory.WaitForIncomingMethodCall());
632 EXPECT_EQ(ERROR_OK, error);
633
634 // Opening my_new_file should fail.
635 error = ERROR_INTERNAL;
636 directory->OpenFile("my_new_file", nullptr, kOpenFlagRead, Capture(&error));
637 ASSERT_TRUE(directory.WaitForIncomingMethodCall());
638 EXPECT_EQ(ERROR_UNKNOWN, error);
639 }
640
641 // TODO(vtl): Test that an open file can be moved (by someone else) without
642 // operations on it being affected.
643 // TODO(vtl): Test delete flags.
644
459 } // namespace 645 } // namespace
460 } // namespace files 646 } // namespace files
461 } // namespace mojo 647 } // namespace mojo
OLDNEW
« no previous file with comments | « services/files/file_impl.cc ('k') | services/files/shared_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698