| 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 "files/public/c/lib/directory_wrapper.h" |  | 
| 6 |  | 
| 7 #include <errno.h> |  | 
| 8 |  | 
| 9 #include <memory> |  | 
| 10 |  | 
| 11 #include "files/public/c/lib/fd_impl.h" |  | 
| 12 #include "files/public/c/mojio_fcntl.h" |  | 
| 13 #include "files/public/c/mojio_sys_stat.h" |  | 
| 14 #include "files/public/c/tests/mock_errno_impl.h" |  | 
| 15 #include "files/public/c/tests/mojio_impl_test_base.h" |  | 
| 16 #include "files/public/c/tests/test_utils.h" |  | 
| 17 |  | 
| 18 namespace mojio { |  | 
| 19 namespace { |  | 
| 20 |  | 
| 21 using DirectoryWrapperTest = mojio::test::MojioImplTestBase; |  | 
| 22 |  | 
| 23 const int kLastErrorSentinel = -12345; |  | 
| 24 |  | 
| 25 // Note: |Open()|'s |mode| is currently basically ignored, so there's nothing to |  | 
| 26 // test yet. If this ever changes, we'll have to test it. |  | 
| 27 |  | 
| 28 // TODO(vtl): Currently, the Files service/interface doesn't report |  | 
| 29 // complete/thorough errors, hence our errno checks are bit wacky. |  | 
| 30 TEST_F(DirectoryWrapperTest, OpenCreate) { |  | 
| 31   test::MockErrnoImpl errno_impl(kLastErrorSentinel); |  | 
| 32   DirectoryWrapper dw(&errno_impl, directory().Pass()); |  | 
| 33 |  | 
| 34   // Opening a nonexistent file without MOJIO_O_CREAT should fail. |  | 
| 35   EXPECT_FALSE(dw.Open("my_file", MOJIO_O_RDWR, MOJIO_S_IRWXU)); |  | 
| 36   EXPECT_EQ(EIO, errno_impl.Get()); |  | 
| 37 |  | 
| 38   // Opening it with MOJIO_O_CREAT should work though. |  | 
| 39   errno_impl.Reset(kLastErrorSentinel); |  | 
| 40   EXPECT_TRUE(dw.Open("my_file", MOJIO_O_RDWR | MOJIO_O_CREAT, MOJIO_S_IRWXU)); |  | 
| 41   EXPECT_EQ(kLastErrorSentinel, errno_impl.Get());  // No error. |  | 
| 42   EXPECT_EQ(0, test::GetFileSize(&dw.directory(), "my_file")); |  | 
| 43 |  | 
| 44   // And again. |  | 
| 45   errno_impl.Reset(kLastErrorSentinel); |  | 
| 46   EXPECT_TRUE( |  | 
| 47       dw.Open("my_file", MOJIO_O_WRONLY | MOJIO_O_CREAT, MOJIO_S_IRWXU)); |  | 
| 48   EXPECT_EQ(kLastErrorSentinel, errno_impl.Get());  // No error. |  | 
| 49 |  | 
| 50   // But not with MOJIO_O_EXCL. |  | 
| 51   errno_impl.Reset(kLastErrorSentinel); |  | 
| 52   EXPECT_FALSE(dw.Open("my_file", MOJIO_O_WRONLY | MOJIO_O_CREAT | MOJIO_O_EXCL, |  | 
| 53                        MOJIO_S_IRWXU)); |  | 
| 54   EXPECT_EQ(EIO, errno_impl.Get()); |  | 
| 55 |  | 
| 56   // Make a subdirectory. |  | 
| 57   test::MakeDirAt(&dw.directory(), "my_dir"); |  | 
| 58 |  | 
| 59   // Can't create a file of that name, even with MOJIO_O_CREAT. |  | 
| 60   errno_impl.Reset(kLastErrorSentinel); |  | 
| 61   EXPECT_FALSE( |  | 
| 62       dw.Open("my_dir", MOJIO_O_WRONLY | MOJIO_O_CREAT, MOJIO_S_IRWXU)); |  | 
| 63   EXPECT_EQ(EIO, errno_impl.Get()); |  | 
| 64 |  | 
| 65   // Create a file in that subdirectory, let's say with MOJIO_O_EXCL. |  | 
| 66   errno_impl.Reset(kLastErrorSentinel); |  | 
| 67   EXPECT_TRUE(dw.Open("my_dir/foo", |  | 
| 68                       MOJIO_O_WRONLY | MOJIO_O_CREAT | MOJIO_O_EXCL, |  | 
| 69                       MOJIO_S_IRWXU)); |  | 
| 70   EXPECT_EQ(kLastErrorSentinel, errno_impl.Get());  // No error. |  | 
| 71   EXPECT_EQ(0, test::GetFileSize(&dw.directory(), "my_dir/foo")); |  | 
| 72 } |  | 
| 73 |  | 
| 74 TEST_F(DirectoryWrapperTest, OpenTruncate) { |  | 
| 75   test::MockErrnoImpl errno_impl(kLastErrorSentinel); |  | 
| 76   DirectoryWrapper dw(&errno_impl, directory().Pass()); |  | 
| 77 |  | 
| 78   // Can't open a nonexistent file with only MOJIO_O_TRUNC. |  | 
| 79   EXPECT_FALSE( |  | 
| 80       dw.Open("nonexistent", MOJIO_O_WRONLY | MOJIO_O_TRUNC, MOJIO_S_IRWXU)); |  | 
| 81   EXPECT_EQ(EIO, errno_impl.Get()); |  | 
| 82 |  | 
| 83   // But can with MOJIO_O_CREAT. |  | 
| 84   errno_impl.Reset(kLastErrorSentinel); |  | 
| 85   EXPECT_TRUE(dw.Open("to_create", |  | 
| 86                       MOJIO_O_WRONLY | MOJIO_O_CREAT | MOJIO_O_TRUNC, |  | 
| 87                       MOJIO_S_IRWXU)); |  | 
| 88   EXPECT_EQ(kLastErrorSentinel, errno_impl.Get());  // No error. |  | 
| 89   EXPECT_EQ(0, test::GetFileSize(&dw.directory(), "to_create")); |  | 
| 90 |  | 
| 91   test::CreateTestFileAt(&dw.directory(), "my_file", 123); |  | 
| 92 |  | 
| 93   // Opening without MOJIO_O_TRUNC doesn't change the file size, with or without |  | 
| 94   // MOJIO_O_CREAT. |  | 
| 95   errno_impl.Reset(kLastErrorSentinel); |  | 
| 96   EXPECT_TRUE( |  | 
| 97       dw.Open("my_file", MOJIO_O_WRONLY | MOJIO_O_CREAT, MOJIO_S_IRWXU)); |  | 
| 98   EXPECT_EQ(kLastErrorSentinel, errno_impl.Get());  // No error. |  | 
| 99   EXPECT_EQ(123, test::GetFileSize(&dw.directory(), "my_file")); |  | 
| 100 |  | 
| 101   errno_impl.Reset(kLastErrorSentinel); |  | 
| 102   EXPECT_TRUE( |  | 
| 103       dw.Open("my_file", MOJIO_O_WRONLY | MOJIO_O_CREAT, MOJIO_S_IRWXU)); |  | 
| 104   EXPECT_EQ(kLastErrorSentinel, errno_impl.Get());  // No error. |  | 
| 105   EXPECT_EQ(123, test::GetFileSize(&dw.directory(), "my_file")); |  | 
| 106 |  | 
| 107   // But with MOJIO_O_TRUNC, it truncates (only test without MOJIO_O_CREAT). |  | 
| 108   errno_impl.Reset(kLastErrorSentinel); |  | 
| 109   EXPECT_TRUE( |  | 
| 110       dw.Open("my_file", MOJIO_O_WRONLY | MOJIO_O_TRUNC, MOJIO_S_IRWXU)); |  | 
| 111   EXPECT_EQ(kLastErrorSentinel, errno_impl.Get());  // No error. |  | 
| 112   EXPECT_EQ(0, test::GetFileSize(&dw.directory(), "my_file")); |  | 
| 113 } |  | 
| 114 |  | 
| 115 TEST_F(DirectoryWrapperTest, OpenExisting) { |  | 
| 116   test::CreateTestFileAt(&directory(), "my_file", 123); |  | 
| 117 |  | 
| 118   test::MockErrnoImpl errno_impl(kLastErrorSentinel); |  | 
| 119   DirectoryWrapper dw(&errno_impl, directory().Pass()); |  | 
| 120 |  | 
| 121   // Test various flags: |  | 
| 122   EXPECT_TRUE(dw.Open("my_file", MOJIO_O_RDONLY, MOJIO_S_IRWXU)); |  | 
| 123   EXPECT_EQ(kLastErrorSentinel, errno_impl.Get());  // No error. |  | 
| 124   EXPECT_EQ(123, test::GetFileSize(&dw.directory(), "my_file")); |  | 
| 125 |  | 
| 126   errno_impl.Reset(kLastErrorSentinel); |  | 
| 127   EXPECT_TRUE(dw.Open("my_file", MOJIO_O_RDWR, MOJIO_S_IRWXU)); |  | 
| 128   EXPECT_EQ(kLastErrorSentinel, errno_impl.Get());  // No error. |  | 
| 129   EXPECT_EQ(123, test::GetFileSize(&dw.directory(), "my_file")); |  | 
| 130 |  | 
| 131   errno_impl.Reset(kLastErrorSentinel); |  | 
| 132   EXPECT_TRUE(dw.Open("my_file", MOJIO_O_WRONLY, MOJIO_S_IRWXU)); |  | 
| 133   EXPECT_EQ(kLastErrorSentinel, errno_impl.Get());  // No error. |  | 
| 134   EXPECT_EQ(123, test::GetFileSize(&dw.directory(), "my_file")); |  | 
| 135 |  | 
| 136   errno_impl.Reset(kLastErrorSentinel); |  | 
| 137   EXPECT_TRUE( |  | 
| 138       dw.Open("my_file", MOJIO_O_WRONLY | MOJIO_O_CREAT, MOJIO_S_IRWXU)); |  | 
| 139   EXPECT_EQ(kLastErrorSentinel, errno_impl.Get());  // No error. |  | 
| 140   EXPECT_EQ(123, test::GetFileSize(&dw.directory(), "my_file")); |  | 
| 141 |  | 
| 142   errno_impl.Reset(kLastErrorSentinel); |  | 
| 143   EXPECT_TRUE( |  | 
| 144       dw.Open("my_file", MOJIO_O_WRONLY | MOJIO_O_APPEND, MOJIO_S_IRWXU)); |  | 
| 145   EXPECT_EQ(kLastErrorSentinel, errno_impl.Get());  // No error. |  | 
| 146   EXPECT_EQ(123, test::GetFileSize(&dw.directory(), "my_file")); |  | 
| 147 } |  | 
| 148 |  | 
| 149 // Note: This necessarily also involves the returned |FDImpl|'s |Write()|. |  | 
| 150 TEST_F(DirectoryWrapperTest, OpenAppend) { |  | 
| 151   test::CreateTestFileAt(&directory(), "my_file", 123); |  | 
| 152 |  | 
| 153   test::MockErrnoImpl errno_impl(kLastErrorSentinel); |  | 
| 154   DirectoryWrapper dw(&errno_impl, directory().Pass()); |  | 
| 155 |  | 
| 156   std::unique_ptr<FDImpl> fdi = |  | 
| 157       dw.Open("my_file", MOJIO_O_WRONLY | MOJIO_O_APPEND, MOJIO_S_IRWXU); |  | 
| 158   EXPECT_TRUE(fdi); |  | 
| 159   EXPECT_EQ(kLastErrorSentinel, errno_impl.Get());  // No error. |  | 
| 160 |  | 
| 161   // Write some stuff to it. |  | 
| 162   errno_impl.Reset(kLastErrorSentinel); |  | 
| 163   const char kWriteBuffer[45] = {'x', 'y', 'z'}; |  | 
| 164   EXPECT_EQ(45, fdi->Write(kWriteBuffer, sizeof(kWriteBuffer))); |  | 
| 165   EXPECT_EQ(kLastErrorSentinel, errno_impl.Get());  // No error. |  | 
| 166 |  | 
| 167   EXPECT_EQ(123 + 45, test::GetFileSize(&dw.directory(), "my_file")); |  | 
| 168 } |  | 
| 169 |  | 
| 170 TEST_F(DirectoryWrapperTest, OpenInvalidFlags) { |  | 
| 171   test::MockErrnoImpl errno_impl(kLastErrorSentinel); |  | 
| 172   DirectoryWrapper dw(&errno_impl, directory().Pass()); |  | 
| 173 |  | 
| 174   // Invalid access mode (masked by MOJIO_O_ACCMODE). |  | 
| 175   // |  | 
| 176   // Note: POSIX "requires" that exactly one of MOJIO_O_RDONLY, MOJIO_O_RDWR, or |  | 
| 177   // MOJIO_O_WRONLY be included. However, we follow Linux and let MOJIO_O_RDONLY |  | 
| 178   // have value 0, so this can't be detected (POSIX allows this by saying that |  | 
| 179   // missing one of these flags *may* result in EINVAL). |  | 
| 180   // |  | 
| 181   // However, the or of all three isn't valid, and we do give EINVAL for that. |  | 
| 182   EXPECT_FALSE(dw.Open("my_file", |  | 
| 183                        MOJIO_O_RDONLY | MOJIO_O_RDWR | MOJIO_O_WRONLY, |  | 
| 184                        MOJIO_S_IRWXU)); |  | 
| 185   EXPECT_EQ(EINVAL, errno_impl.Get()); |  | 
| 186 } |  | 
| 187 |  | 
| 188 TEST_F(DirectoryWrapperTest, Efault) { |  | 
| 189   test::MockErrnoImpl errno_impl(kLastErrorSentinel); |  | 
| 190   DirectoryWrapper dw(&errno_impl, directory().Pass()); |  | 
| 191 |  | 
| 192   EXPECT_FALSE(dw.Open(nullptr, MOJIO_O_WRONLY | MOJIO_O_CREAT, MOJIO_S_IRWXU)); |  | 
| 193   EXPECT_EQ(EFAULT, errno_impl.Get()); |  | 
| 194 |  | 
| 195   errno_impl.Reset(kLastErrorSentinel); |  | 
| 196   EXPECT_FALSE(dw.Chdir(nullptr)); |  | 
| 197   EXPECT_EQ(EFAULT, errno_impl.Get()); |  | 
| 198 } |  | 
| 199 |  | 
| 200 }  // namespace |  | 
| 201 }  // namespace mojio |  | 
| OLD | NEW | 
|---|