OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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. | |
qsr
2015/03/06 13:01:04
Not certain you want to test this, but you could p
viettrungluu
2015/03/09 17:59:29
I'll add that to the TODO list. :)
| |
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 delete flags. | |
642 | |
459 } // namespace | 643 } // namespace |
460 } // namespace files | 644 } // namespace files |
461 } // namespace mojo | 645 } // namespace mojo |
OLD | NEW |