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