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 |