Chromium Code Reviews| Index: services/files/files_apptest.cc |
| diff --git a/services/files/files_apptest.cc b/services/files/files_apptest.cc |
| index c5dc5a6b053b3fc82e298083b2a53ee536accedf..d752cbfdd5abbab39cc5f193db14a21c7a23f82e 100644 |
| --- a/services/files/files_apptest.cc |
| +++ b/services/files/files_apptest.cc |
| @@ -2,6 +2,10 @@ |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| +// TODO(vtl): Split this file. |
| + |
| +#include <map> |
| +#include <string> |
| #include <vector> |
| #include "base/macros.h" |
| @@ -94,6 +98,15 @@ class FilesAppTest : public test::ApplicationTestBase { |
| application_impl()->ConnectToService("mojo:files", &files_); |
| } |
| + protected: |
| + void GetTemporaryRoot(DirectoryPtr* directory) { |
| + Error error = ERROR_INTERNAL; |
| + files()->OpenFileSystem(FILE_SYSTEM_TEMPORARY, GetProxy(directory), |
| + Capture(&error)); |
| + ASSERT_TRUE(files().WaitForIncomingMethodCall()); |
| + ASSERT_EQ(ERROR_OK, error); |
| + } |
| + |
| FilesPtr& files() { return files_; } |
| private: |
| @@ -102,14 +115,14 @@ class FilesAppTest : public test::ApplicationTestBase { |
| DISALLOW_COPY_AND_ASSIGN(FilesAppTest); |
| }; |
| -TEST_F(FilesAppTest, CreateWriteCloseRenameOpenRead) { |
| - // Get a temporary root directory. |
| +// FileImpl -------------------------------------------------------------------- |
| + |
| +typedef FilesAppTest FileImplTest; |
| + |
| +TEST_F(FileImplTest, CreateWriteCloseRenameOpenRead) { |
| DirectoryPtr directory; |
| - Error error = ERROR_INTERNAL; |
| - files()->OpenFileSystem(FILE_SYSTEM_TEMPORARY, GetProxy(&directory), |
| - Capture(&error)); |
| - ASSERT_TRUE(files().WaitForIncomingMethodCall()); |
| - EXPECT_EQ(ERROR_OK, error); |
| + GetTemporaryRoot(&directory); |
| + Error error; |
| { |
| // Create my_file. |
| @@ -175,14 +188,10 @@ TEST_F(FilesAppTest, CreateWriteCloseRenameOpenRead) { |
| // Note: Ignore nanoseconds, since it may not always be supported. We expect at |
| // least second-resolution support though. |
| -TEST_F(FilesAppTest, StatTouch) { |
| - // Get a temporary root directory. |
| +TEST_F(FileImplTest, StatTouch) { |
| DirectoryPtr directory; |
| - Error error = ERROR_INTERNAL; |
| - files()->OpenFileSystem(FILE_SYSTEM_TEMPORARY, GetProxy(&directory), |
| - Capture(&error)); |
| - ASSERT_TRUE(files().WaitForIncomingMethodCall()); |
| - EXPECT_EQ(ERROR_OK, error); |
| + GetTemporaryRoot(&directory); |
| + Error error; |
| // Create my_file. |
| FilePtr file; |
| @@ -262,14 +271,10 @@ TEST_F(FilesAppTest, StatTouch) { |
| EXPECT_EQ(ERROR_OK, error); |
| } |
| -TEST_F(FilesAppTest, TellSeek) { |
| - // Get a temporary root directory. |
| +TEST_F(FileImplTest, TellSeek) { |
| DirectoryPtr directory; |
| - Error error = ERROR_INTERNAL; |
| - files()->OpenFileSystem(FILE_SYSTEM_TEMPORARY, GetProxy(&directory), |
| - Capture(&error)); |
| - ASSERT_TRUE(files().WaitForIncomingMethodCall()); |
| - EXPECT_EQ(ERROR_OK, error); |
| + GetTemporaryRoot(&directory); |
| + Error error; |
| // Create my_file. |
| FilePtr file; |
| @@ -357,14 +362,10 @@ TEST_F(FilesAppTest, TellSeek) { |
| EXPECT_EQ(ERROR_OK, error); |
| } |
| -TEST_F(FilesAppTest, Dup) { |
| - // Get a temporary root directory. |
| +TEST_F(FileImplTest, Dup) { |
| DirectoryPtr directory; |
| - Error error = ERROR_INTERNAL; |
| - files()->OpenFileSystem(FILE_SYSTEM_TEMPORARY, GetProxy(&directory), |
| - Capture(&error)); |
| - ASSERT_TRUE(files().WaitForIncomingMethodCall()); |
| - EXPECT_EQ(ERROR_OK, error); |
| + GetTemporaryRoot(&directory); |
| + Error error; |
| // Create my_file. |
| FilePtr file1; |
| @@ -456,6 +457,189 @@ TEST_F(FilesAppTest, Dup) { |
| // TODO(vtl): Test that |file2| has the same open options as |file1|. |
| } |
| +// DirectoryImpl --------------------------------------------------------------- |
| + |
| +typedef FilesAppTest DirectoryImplTest; |
| + |
| +TEST_F(FileImplTest, Read) { |
| + DirectoryPtr directory; |
| + GetTemporaryRoot(&directory); |
| + Error error; |
| + |
| + // Make some files. |
| + const struct { |
| + const char* name; |
| + uint32_t open_flags; |
| + } files_to_create[] = { |
| + {"my_file1", kOpenFlagRead | kOpenFlagWrite | kOpenFlagCreate}, |
| + {"my_file2", kOpenFlagWrite | kOpenFlagCreate | kOpenFlagExclusive}, |
| + {"my_file3", kOpenFlagWrite | kOpenFlagCreate | kOpenFlagAppend}, |
| + {"my_file4", kOpenFlagWrite | kOpenFlagCreate | kOpenFlagTruncate}}; |
| + for (size_t i = 0; i < arraysize(files_to_create); i++) { |
| + error = ERROR_INTERNAL; |
| + directory->OpenFile(files_to_create[i].name, nullptr, |
| + files_to_create[i].open_flags, Capture(&error)); |
| + ASSERT_TRUE(directory.WaitForIncomingMethodCall()); |
| + EXPECT_EQ(ERROR_OK, error); |
| + } |
| + // Make a directory. |
| + error = ERROR_INTERNAL; |
| + directory->OpenDirectory("my_dir", nullptr, |
| + kOpenFlagRead | kOpenFlagWrite | kOpenFlagCreate, |
| + Capture(&error)); |
| + ASSERT_TRUE(directory.WaitForIncomingMethodCall()); |
| + EXPECT_EQ(ERROR_OK, error); |
| + |
| + error = ERROR_INTERNAL; |
| + Array<DirectoryEntryPtr> directory_contents; |
| + directory->Read(Capture(&error, &directory_contents)); |
| + ASSERT_TRUE(directory.WaitForIncomingMethodCall()); |
| + EXPECT_EQ(ERROR_OK, error); |
| + |
| + // Expected contents of the directory. |
| + std::map<std::string, FileType> expected_contents; |
| + expected_contents["my_file1"] = FILE_TYPE_REGULAR_FILE; |
| + expected_contents["my_file2"] = FILE_TYPE_REGULAR_FILE; |
| + expected_contents["my_file3"] = FILE_TYPE_REGULAR_FILE; |
| + expected_contents["my_file4"] = FILE_TYPE_REGULAR_FILE; |
| + expected_contents["my_dir"] = FILE_TYPE_DIRECTORY; |
| + expected_contents["."] = FILE_TYPE_DIRECTORY; |
| + expected_contents[".."] = FILE_TYPE_DIRECTORY; |
| + |
| + EXPECT_EQ(expected_contents.size(), directory_contents.size()); |
| + for (size_t i = 0; i < directory_contents.size(); i++) { |
| + ASSERT_TRUE(directory_contents[i]); |
| + ASSERT_TRUE(directory_contents[i]->name); |
| + auto it = expected_contents.find(directory_contents[i]->name.get()); |
| + ASSERT_TRUE(it != expected_contents.end()); |
| + EXPECT_EQ(it->second, directory_contents[i]->type); |
| + expected_contents.erase(it); |
| + } |
| +} |
| + |
| +// Note: Ignore nanoseconds, since it may not always be supported. We expect at |
| +// least second-resolution support though. |
| +// TODO(vtl): Maybe share this with |FileImplTest.StatTouch| ... but then it'd |
| +// be harder to split this file. |
| +TEST_F(DirectoryImplTest, StatTouch) { |
| + DirectoryPtr directory; |
| + GetTemporaryRoot(&directory); |
| + Error error; |
| + |
| + // Stat it. |
| + error = ERROR_INTERNAL; |
| + FileInformationPtr file_info; |
| + directory->Stat(Capture(&error, &file_info)); |
| + ASSERT_TRUE(directory.WaitForIncomingMethodCall()); |
| + EXPECT_EQ(ERROR_OK, error); |
| + ASSERT_FALSE(file_info.is_null()); |
| + EXPECT_EQ(0, file_info->size); |
| + ASSERT_FALSE(file_info->atime.is_null()); |
| + EXPECT_GT(file_info->atime->seconds, 0); // Expect that it's not 1970-01-01. |
| + ASSERT_FALSE(file_info->mtime.is_null()); |
| + EXPECT_GT(file_info->mtime->seconds, 0); |
| + int64_t first_mtime = file_info->mtime->seconds; |
| + |
| + // Touch only the atime. |
| + error = ERROR_INTERNAL; |
| + TimespecOrNowPtr t(TimespecOrNow::New()); |
| + t->now = false; |
| + t->timespec = Timespec::New(); |
| + const int64_t kPartyTime1 = 1234567890; // Party like it's 2009-02-13. |
| + t->timespec->seconds = kPartyTime1; |
| + directory->Touch(t.Pass(), nullptr, Capture(&error)); |
| + ASSERT_TRUE(directory.WaitForIncomingMethodCall()); |
| + EXPECT_EQ(ERROR_OK, error); |
| + |
| + // Stat again. |
| + error = ERROR_INTERNAL; |
| + file_info.reset(); |
| + directory->Stat(Capture(&error, &file_info)); |
| + ASSERT_TRUE(directory.WaitForIncomingMethodCall()); |
| + EXPECT_EQ(ERROR_OK, error); |
| + ASSERT_FALSE(file_info.is_null()); |
| + ASSERT_FALSE(file_info->atime.is_null()); |
| + EXPECT_EQ(kPartyTime1, file_info->atime->seconds); |
| + ASSERT_FALSE(file_info->mtime.is_null()); |
| + EXPECT_EQ(first_mtime, file_info->mtime->seconds); |
| + |
| + // Touch only the mtime. |
| + t = TimespecOrNow::New(); |
| + t->now = false; |
| + t->timespec = Timespec::New(); |
| + const int64_t kPartyTime2 = 1425059525; // No time like the present. |
| + t->timespec->seconds = kPartyTime2; |
| + directory->Touch(nullptr, t.Pass(), Capture(&error)); |
| + ASSERT_TRUE(directory.WaitForIncomingMethodCall()); |
| + EXPECT_EQ(ERROR_OK, error); |
| + |
| + // Stat again. |
| + error = ERROR_INTERNAL; |
| + file_info.reset(); |
| + directory->Stat(Capture(&error, &file_info)); |
| + ASSERT_TRUE(directory.WaitForIncomingMethodCall()); |
| + EXPECT_EQ(ERROR_OK, error); |
| + ASSERT_FALSE(file_info.is_null()); |
| + ASSERT_FALSE(file_info->atime.is_null()); |
| + EXPECT_EQ(kPartyTime1, file_info->atime->seconds); |
| + ASSERT_FALSE(file_info->mtime.is_null()); |
| + EXPECT_EQ(kPartyTime2, file_info->mtime->seconds); |
| + |
| + // TODO(vtl): Also test Touch() "now" options. |
| + // TODO(vtl): Also test touching both atime and mtime. |
| +} |
| + |
| +// TODO(vtl): Properly test OpenFile() and OpenDirectory() (including flags). |
| + |
| +TEST_F(DirectoryImplTest, BasicRenameDelete) { |
| + DirectoryPtr directory; |
| + GetTemporaryRoot(&directory); |
| + Error error; |
| + |
| + // Create my_file. |
| + error = ERROR_INTERNAL; |
| + directory->OpenFile("my_file", nullptr, kOpenFlagWrite | kOpenFlagCreate, |
| + Capture(&error)); |
| + ASSERT_TRUE(directory.WaitForIncomingMethodCall()); |
| + EXPECT_EQ(ERROR_OK, error); |
| + |
| + // Opening my_file should succeed. |
| + error = ERROR_INTERNAL; |
| + directory->OpenFile("my_file", nullptr, kOpenFlagRead, Capture(&error)); |
| + ASSERT_TRUE(directory.WaitForIncomingMethodCall()); |
| + EXPECT_EQ(ERROR_OK, error); |
| + |
| + // 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. :)
|
| + directory->Rename("my_file", "my_new_file", Capture(&error)); |
| + ASSERT_TRUE(directory.WaitForIncomingMethodCall()); |
| + EXPECT_EQ(ERROR_OK, error); |
| + |
| + // Opening my_file should fail. |
| + error = ERROR_INTERNAL; |
| + directory->OpenFile("my_file", nullptr, kOpenFlagRead, Capture(&error)); |
| + ASSERT_TRUE(directory.WaitForIncomingMethodCall()); |
| + EXPECT_EQ(ERROR_UNKNOWN, error); |
| + |
| + // Opening my_new_file should succeed. |
| + error = ERROR_INTERNAL; |
| + directory->OpenFile("my_new_file", nullptr, kOpenFlagRead, Capture(&error)); |
| + ASSERT_TRUE(directory.WaitForIncomingMethodCall()); |
| + EXPECT_EQ(ERROR_OK, error); |
| + |
| + // Delete my_new_file (no flags). |
| + directory->Delete("my_new_file", 0, Capture(&error)); |
| + ASSERT_TRUE(directory.WaitForIncomingMethodCall()); |
| + EXPECT_EQ(ERROR_OK, error); |
| + |
| + // Opening my_new_file should fail. |
| + error = ERROR_INTERNAL; |
| + directory->OpenFile("my_new_file", nullptr, kOpenFlagRead, Capture(&error)); |
| + ASSERT_TRUE(directory.WaitForIncomingMethodCall()); |
| + EXPECT_EQ(ERROR_UNKNOWN, error); |
| +} |
| + |
| +// TODO(vtl): Test delete flags. |
| + |
| } // namespace |
| } // namespace files |
| } // namespace mojo |