OLD | NEW |
(Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include <map> |
| 6 #include <string> |
| 7 |
| 8 #include "components/filesystem/files_test_base.h" |
| 9 |
| 10 namespace mojo { |
| 11 namespace files { |
| 12 namespace { |
| 13 |
| 14 using DirectoryImplTest = FilesTestBase; |
| 15 |
| 16 TEST_F(DirectoryImplTest, Read) { |
| 17 DirectoryPtr directory; |
| 18 GetTemporaryRoot(&directory); |
| 19 Error error; |
| 20 |
| 21 // Make some files. |
| 22 const struct { |
| 23 const char* name; |
| 24 uint32_t open_flags; |
| 25 } files_to_create[] = { |
| 26 {"my_file1", kOpenFlagRead | kOpenFlagWrite | kOpenFlagCreate}, |
| 27 {"my_file2", kOpenFlagWrite | kOpenFlagCreate | kOpenFlagExclusive}, |
| 28 {"my_file3", kOpenFlagWrite | kOpenFlagCreate | kOpenFlagAppend}, |
| 29 {"my_file4", kOpenFlagWrite | kOpenFlagCreate | kOpenFlagTruncate}}; |
| 30 for (size_t i = 0; i < arraysize(files_to_create); i++) { |
| 31 error = ERROR_INTERNAL; |
| 32 directory->OpenFile(files_to_create[i].name, nullptr, |
| 33 files_to_create[i].open_flags, Capture(&error)); |
| 34 ASSERT_TRUE(directory.WaitForIncomingMethodCall()); |
| 35 EXPECT_EQ(ERROR_OK, error); |
| 36 } |
| 37 // Make a directory. |
| 38 error = ERROR_INTERNAL; |
| 39 directory->OpenDirectory("my_dir", nullptr, |
| 40 kOpenFlagRead | kOpenFlagWrite | kOpenFlagCreate, |
| 41 Capture(&error)); |
| 42 ASSERT_TRUE(directory.WaitForIncomingMethodCall()); |
| 43 EXPECT_EQ(ERROR_OK, error); |
| 44 |
| 45 error = ERROR_INTERNAL; |
| 46 Array<DirectoryEntryPtr> directory_contents; |
| 47 directory->Read(Capture(&error, &directory_contents)); |
| 48 ASSERT_TRUE(directory.WaitForIncomingMethodCall()); |
| 49 EXPECT_EQ(ERROR_OK, error); |
| 50 |
| 51 // Expected contents of the directory. |
| 52 std::map<std::string, FileType> expected_contents; |
| 53 expected_contents["my_file1"] = FILE_TYPE_REGULAR_FILE; |
| 54 expected_contents["my_file2"] = FILE_TYPE_REGULAR_FILE; |
| 55 expected_contents["my_file3"] = FILE_TYPE_REGULAR_FILE; |
| 56 expected_contents["my_file4"] = FILE_TYPE_REGULAR_FILE; |
| 57 expected_contents["my_dir"] = FILE_TYPE_DIRECTORY; |
| 58 expected_contents["."] = FILE_TYPE_DIRECTORY; |
| 59 expected_contents[".."] = FILE_TYPE_DIRECTORY; |
| 60 |
| 61 EXPECT_EQ(expected_contents.size(), directory_contents.size()); |
| 62 for (size_t i = 0; i < directory_contents.size(); i++) { |
| 63 ASSERT_TRUE(directory_contents[i]); |
| 64 ASSERT_TRUE(directory_contents[i]->name); |
| 65 auto it = expected_contents.find(directory_contents[i]->name.get()); |
| 66 ASSERT_TRUE(it != expected_contents.end()); |
| 67 EXPECT_EQ(it->second, directory_contents[i]->type); |
| 68 expected_contents.erase(it); |
| 69 } |
| 70 } |
| 71 |
| 72 // Note: Ignore nanoseconds, since it may not always be supported. We expect at |
| 73 // least second-resolution support though. |
| 74 // TODO(vtl): Maybe share this with |FileImplTest.StatTouch| ... but then it'd |
| 75 // be harder to split this file. |
| 76 TEST_F(DirectoryImplTest, StatTouch) { |
| 77 DirectoryPtr directory; |
| 78 GetTemporaryRoot(&directory); |
| 79 Error error; |
| 80 |
| 81 // Stat it. |
| 82 error = ERROR_INTERNAL; |
| 83 FileInformationPtr file_info; |
| 84 directory->Stat(Capture(&error, &file_info)); |
| 85 ASSERT_TRUE(directory.WaitForIncomingMethodCall()); |
| 86 EXPECT_EQ(ERROR_OK, error); |
| 87 ASSERT_FALSE(file_info.is_null()); |
| 88 EXPECT_EQ(FILE_TYPE_DIRECTORY, file_info->type); |
| 89 EXPECT_EQ(0, file_info->size); |
| 90 ASSERT_FALSE(file_info->atime.is_null()); |
| 91 EXPECT_GT(file_info->atime->seconds, 0); // Expect that it's not 1970-01-01. |
| 92 ASSERT_FALSE(file_info->mtime.is_null()); |
| 93 EXPECT_GT(file_info->mtime->seconds, 0); |
| 94 int64_t first_mtime = file_info->mtime->seconds; |
| 95 |
| 96 // Touch only the atime. |
| 97 error = ERROR_INTERNAL; |
| 98 TimespecOrNowPtr t(TimespecOrNow::New()); |
| 99 t->now = false; |
| 100 t->timespec = Timespec::New(); |
| 101 const int64_t kPartyTime1 = 1234567890; // Party like it's 2009-02-13. |
| 102 t->timespec->seconds = kPartyTime1; |
| 103 directory->Touch(t.Pass(), nullptr, Capture(&error)); |
| 104 ASSERT_TRUE(directory.WaitForIncomingMethodCall()); |
| 105 EXPECT_EQ(ERROR_OK, error); |
| 106 |
| 107 // Stat again. |
| 108 error = ERROR_INTERNAL; |
| 109 file_info.reset(); |
| 110 directory->Stat(Capture(&error, &file_info)); |
| 111 ASSERT_TRUE(directory.WaitForIncomingMethodCall()); |
| 112 EXPECT_EQ(ERROR_OK, error); |
| 113 ASSERT_FALSE(file_info.is_null()); |
| 114 ASSERT_FALSE(file_info->atime.is_null()); |
| 115 EXPECT_EQ(kPartyTime1, file_info->atime->seconds); |
| 116 ASSERT_FALSE(file_info->mtime.is_null()); |
| 117 EXPECT_EQ(first_mtime, file_info->mtime->seconds); |
| 118 |
| 119 // Touch only the mtime. |
| 120 t = TimespecOrNow::New(); |
| 121 t->now = false; |
| 122 t->timespec = Timespec::New(); |
| 123 const int64_t kPartyTime2 = 1425059525; // No time like the present. |
| 124 t->timespec->seconds = kPartyTime2; |
| 125 directory->Touch(nullptr, t.Pass(), Capture(&error)); |
| 126 ASSERT_TRUE(directory.WaitForIncomingMethodCall()); |
| 127 EXPECT_EQ(ERROR_OK, error); |
| 128 |
| 129 // Stat again. |
| 130 error = ERROR_INTERNAL; |
| 131 file_info.reset(); |
| 132 directory->Stat(Capture(&error, &file_info)); |
| 133 ASSERT_TRUE(directory.WaitForIncomingMethodCall()); |
| 134 EXPECT_EQ(ERROR_OK, error); |
| 135 ASSERT_FALSE(file_info.is_null()); |
| 136 ASSERT_FALSE(file_info->atime.is_null()); |
| 137 EXPECT_EQ(kPartyTime1, file_info->atime->seconds); |
| 138 ASSERT_FALSE(file_info->mtime.is_null()); |
| 139 EXPECT_EQ(kPartyTime2, file_info->mtime->seconds); |
| 140 |
| 141 // TODO(vtl): Also test Touch() "now" options. |
| 142 // TODO(vtl): Also test touching both atime and mtime. |
| 143 } |
| 144 |
| 145 // TODO(vtl): Properly test OpenFile() and OpenDirectory() (including flags). |
| 146 |
| 147 TEST_F(DirectoryImplTest, BasicRenameDelete) { |
| 148 DirectoryPtr directory; |
| 149 GetTemporaryRoot(&directory); |
| 150 Error error; |
| 151 |
| 152 // Create my_file. |
| 153 error = ERROR_INTERNAL; |
| 154 directory->OpenFile("my_file", nullptr, kOpenFlagWrite | kOpenFlagCreate, |
| 155 Capture(&error)); |
| 156 ASSERT_TRUE(directory.WaitForIncomingMethodCall()); |
| 157 EXPECT_EQ(ERROR_OK, error); |
| 158 |
| 159 // Opening my_file should succeed. |
| 160 error = ERROR_INTERNAL; |
| 161 directory->OpenFile("my_file", nullptr, kOpenFlagRead, Capture(&error)); |
| 162 ASSERT_TRUE(directory.WaitForIncomingMethodCall()); |
| 163 EXPECT_EQ(ERROR_OK, error); |
| 164 |
| 165 // Rename my_file to my_new_file. |
| 166 directory->Rename("my_file", "my_new_file", Capture(&error)); |
| 167 ASSERT_TRUE(directory.WaitForIncomingMethodCall()); |
| 168 EXPECT_EQ(ERROR_OK, error); |
| 169 |
| 170 // Opening my_file should fail. |
| 171 error = ERROR_INTERNAL; |
| 172 directory->OpenFile("my_file", nullptr, kOpenFlagRead, Capture(&error)); |
| 173 ASSERT_TRUE(directory.WaitForIncomingMethodCall()); |
| 174 EXPECT_EQ(ERROR_UNKNOWN, error); |
| 175 |
| 176 // Opening my_new_file should succeed. |
| 177 error = ERROR_INTERNAL; |
| 178 directory->OpenFile("my_new_file", nullptr, kOpenFlagRead, Capture(&error)); |
| 179 ASSERT_TRUE(directory.WaitForIncomingMethodCall()); |
| 180 EXPECT_EQ(ERROR_OK, error); |
| 181 |
| 182 // Delete my_new_file (no flags). |
| 183 directory->Delete("my_new_file", 0, Capture(&error)); |
| 184 ASSERT_TRUE(directory.WaitForIncomingMethodCall()); |
| 185 EXPECT_EQ(ERROR_OK, error); |
| 186 |
| 187 // Opening my_new_file should fail. |
| 188 error = ERROR_INTERNAL; |
| 189 directory->OpenFile("my_new_file", nullptr, kOpenFlagRead, Capture(&error)); |
| 190 ASSERT_TRUE(directory.WaitForIncomingMethodCall()); |
| 191 EXPECT_EQ(ERROR_UNKNOWN, error); |
| 192 } |
| 193 |
| 194 // TODO(vtl): Test that an open file can be moved (by someone else) without |
| 195 // operations on it being affected. |
| 196 // TODO(vtl): Test delete flags. |
| 197 |
| 198 } // namespace |
| 199 } // namespace files |
| 200 } // namespace mojo |
OLD | NEW |