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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « services/files/file_impl.cc ('k') | services/files/shared_impl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: services/files/files_apptest.cc
diff --git a/services/files/files_apptest.cc b/services/files/files_apptest.cc
index c5dc5a6b053b3fc82e298083b2a53ee536accedf..5d1b2006aa1b4b82e309655d11a8c1f97af2c699 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,191 @@ 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.
+ 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 that an open file can be moved (by someone else) without
+// operations on it being affected.
+// TODO(vtl): Test delete flags.
+
} // namespace
} // namespace files
} // namespace mojo
« 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