OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "mojo/embedder/platform_channel_pair.h" | 5 #include "mojo/embedder/platform_channel_pair.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <poll.h> | 8 #include <poll.h> |
9 #include <signal.h> | 9 #include <signal.h> |
10 #include <stdio.h> | 10 #include <stdio.h> |
11 #include <sys/socket.h> | 11 #include <sys/socket.h> |
12 #include <sys/types.h> | 12 #include <sys/types.h> |
13 #include <sys/uio.h> | 13 #include <sys/uio.h> |
14 #include <unistd.h> | 14 #include <unistd.h> |
15 | 15 |
16 #include <vector> | 16 #include <vector> |
17 | 17 |
18 #include "base/file_util.h" | 18 #include "base/file_util.h" |
19 #include "base/files/file_path.h" | 19 #include "base/files/file_path.h" |
| 20 #include "base/files/scoped_file.h" |
20 #include "base/logging.h" | 21 #include "base/logging.h" |
21 #include "base/macros.h" | 22 #include "base/macros.h" |
| 23 #include "mojo/common/test/test_utils.h" |
22 #include "mojo/embedder/platform_channel_utils_posix.h" | 24 #include "mojo/embedder/platform_channel_utils_posix.h" |
23 #include "mojo/embedder/scoped_platform_handle.h" | 25 #include "mojo/embedder/scoped_platform_handle.h" |
24 #include "testing/gtest/include/gtest/gtest.h" | 26 #include "testing/gtest/include/gtest/gtest.h" |
25 | 27 |
26 namespace mojo { | 28 namespace mojo { |
27 namespace embedder { | 29 namespace embedder { |
28 namespace { | 30 namespace { |
29 | 31 |
30 ScopedPlatformHandle PlatformHandleFromFILE(FILE* fp) { | |
31 CHECK(fp); | |
32 return ScopedPlatformHandle(PlatformHandle(dup(fileno(fp)))); | |
33 } | |
34 | |
35 FILE* FILEFromPlatformHandle(ScopedPlatformHandle h, const char* mode) { | |
36 CHECK(h.is_valid()); | |
37 return fdopen(h.release().fd, mode); | |
38 } | |
39 | |
40 void WaitReadable(PlatformHandle h) { | 32 void WaitReadable(PlatformHandle h) { |
41 struct pollfd pfds = {}; | 33 struct pollfd pfds = {}; |
42 pfds.fd = h.fd; | 34 pfds.fd = h.fd; |
43 pfds.events = POLLIN; | 35 pfds.events = POLLIN; |
44 CHECK_EQ(poll(&pfds, 1, -1), 1); | 36 CHECK_EQ(poll(&pfds, 1, -1), 1); |
45 } | 37 } |
46 | 38 |
47 class PlatformChannelPairPosixTest : public testing::Test { | 39 class PlatformChannelPairPosixTest : public testing::Test { |
48 public: | 40 public: |
49 PlatformChannelPairPosixTest() {} | 41 PlatformChannelPairPosixTest() {} |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
137 TEST_F(PlatformChannelPairPosixTest, SendReceiveFDs) { | 129 TEST_F(PlatformChannelPairPosixTest, SendReceiveFDs) { |
138 PlatformChannelPair channel_pair; | 130 PlatformChannelPair channel_pair; |
139 ScopedPlatformHandle server_handle = channel_pair.PassServerHandle().Pass(); | 131 ScopedPlatformHandle server_handle = channel_pair.PassServerHandle().Pass(); |
140 ScopedPlatformHandle client_handle = channel_pair.PassClientHandle().Pass(); | 132 ScopedPlatformHandle client_handle = channel_pair.PassClientHandle().Pass(); |
141 | 133 |
142 for (size_t i = 1; i < kPlatformChannelMaxNumHandles; i++) { | 134 for (size_t i = 1; i < kPlatformChannelMaxNumHandles; i++) { |
143 // Make |i| files, with the j-th file consisting of j copies of the digit i. | 135 // Make |i| files, with the j-th file consisting of j copies of the digit i. |
144 PlatformHandleVector platform_handles; | 136 PlatformHandleVector platform_handles; |
145 for (size_t j = 1; j <= i; j++) { | 137 for (size_t j = 1; j <= i; j++) { |
146 base::FilePath ignored; | 138 base::FilePath ignored; |
147 FILE* fp = base::CreateAndOpenTemporaryFile(&ignored); | 139 base::ScopedFILE fp(base::CreateAndOpenTemporaryFile(&ignored)); |
148 ASSERT_TRUE(fp); | 140 ASSERT_TRUE(fp); |
149 platform_handles.push_back(PlatformHandleFromFILE(fp).release()); | 141 fwrite(std::string(j, '0' + i).data(), 1, j, fp.get()); |
| 142 platform_handles.push_back( |
| 143 test::PlatformHandleFromFILE(fp.Pass()).release()); |
150 ASSERT_TRUE(platform_handles.back().is_valid()); | 144 ASSERT_TRUE(platform_handles.back().is_valid()); |
151 fwrite(std::string(j, '0' + i).data(), 1, j, fp); | |
152 fclose(fp); | |
153 } | 145 } |
154 | 146 |
155 // Send the FDs. | 147 // Send the FDs. |
156 EXPECT_TRUE(PlatformChannelSendHandles(server_handle.get(), | 148 EXPECT_TRUE(PlatformChannelSendHandles(server_handle.get(), |
157 &platform_handles[0], | 149 &platform_handles[0], |
158 platform_handles.size())); | 150 platform_handles.size())); |
159 | 151 |
160 WaitReadable(client_handle.get()); | 152 WaitReadable(client_handle.get()); |
161 | 153 |
162 char buf[100] = { 'a' }; | 154 char buf[100] = { 'a' }; |
163 scoped_ptr<PlatformHandleVector> received_handles; | 155 scoped_ptr<PlatformHandleVector> received_handles; |
164 EXPECT_EQ(1, PlatformChannelRecvmsg(client_handle.get(), buf, sizeof(buf), | 156 EXPECT_EQ(1, PlatformChannelRecvmsg(client_handle.get(), buf, sizeof(buf), |
165 &received_handles)); | 157 &received_handles)); |
166 EXPECT_EQ('\0', buf[0]); | 158 EXPECT_EQ('\0', buf[0]); |
167 ASSERT_TRUE(received_handles); | 159 ASSERT_TRUE(received_handles); |
168 EXPECT_EQ(i, received_handles->size()); | 160 EXPECT_EQ(i, received_handles->size()); |
169 | 161 |
170 for (size_t j = 0; j < received_handles->size(); j++) { | 162 for (size_t j = 0; j < received_handles->size(); j++) { |
171 FILE* fp = FILEFromPlatformHandle( | 163 base::ScopedFILE fp(test::FILEFromPlatformHandle( |
172 ScopedPlatformHandle((*received_handles)[j]), "rb"); | 164 ScopedPlatformHandle((*received_handles)[j]), "rb")); |
173 (*received_handles)[j] = PlatformHandle(); | 165 (*received_handles)[j] = PlatformHandle(); |
174 ASSERT_TRUE(fp); | 166 ASSERT_TRUE(fp); |
175 rewind(fp); | 167 rewind(fp.get()); |
176 char read_buf[100]; | 168 char read_buf[100]; |
177 size_t bytes_read = fread(read_buf, 1, sizeof(read_buf), fp); | 169 size_t bytes_read = fread(read_buf, 1, sizeof(read_buf), fp.get()); |
178 fclose(fp); | |
179 EXPECT_EQ(j + 1, bytes_read); | 170 EXPECT_EQ(j + 1, bytes_read); |
180 EXPECT_EQ(std::string(j + 1, '0' + i), std::string(read_buf, bytes_read)); | 171 EXPECT_EQ(std::string(j + 1, '0' + i), std::string(read_buf, bytes_read)); |
181 } | 172 } |
182 } | 173 } |
183 } | 174 } |
184 | 175 |
185 TEST_F(PlatformChannelPairPosixTest, AppendReceivedFDs) { | 176 TEST_F(PlatformChannelPairPosixTest, AppendReceivedFDs) { |
186 PlatformChannelPair channel_pair; | 177 PlatformChannelPair channel_pair; |
187 ScopedPlatformHandle server_handle = channel_pair.PassServerHandle().Pass(); | 178 ScopedPlatformHandle server_handle = channel_pair.PassServerHandle().Pass(); |
188 ScopedPlatformHandle client_handle = channel_pair.PassClientHandle().Pass(); | 179 ScopedPlatformHandle client_handle = channel_pair.PassClientHandle().Pass(); |
189 | 180 |
190 const std::string file_contents("hello world"); | 181 const std::string file_contents("hello world"); |
191 | 182 |
192 { | 183 { |
193 base::FilePath ignored; | 184 base::FilePath ignored; |
194 FILE* fp = base::CreateAndOpenTemporaryFile(&ignored); | 185 base::ScopedFILE fp(base::CreateAndOpenTemporaryFile(&ignored)); |
195 ASSERT_TRUE(fp); | 186 ASSERT_TRUE(fp); |
| 187 fwrite(file_contents.data(), 1, file_contents.size(), fp.get()); |
196 PlatformHandleVector platform_handles; | 188 PlatformHandleVector platform_handles; |
197 platform_handles.push_back(PlatformHandleFromFILE(fp).release()); | 189 platform_handles.push_back( |
| 190 test::PlatformHandleFromFILE(fp.Pass()).release()); |
198 ASSERT_TRUE(platform_handles.back().is_valid()); | 191 ASSERT_TRUE(platform_handles.back().is_valid()); |
199 fwrite(file_contents.data(), 1, file_contents.size(), fp); | |
200 fclose(fp); | |
201 | 192 |
202 // Send the FD. | 193 // Send the FD. |
203 EXPECT_TRUE(PlatformChannelSendHandles(server_handle.get(), | 194 EXPECT_TRUE(PlatformChannelSendHandles(server_handle.get(), |
204 &platform_handles[0], | 195 &platform_handles[0], |
205 platform_handles.size())); | 196 platform_handles.size())); |
206 } | 197 } |
207 | 198 |
208 WaitReadable(client_handle.get()); | 199 WaitReadable(client_handle.get()); |
209 | 200 |
210 // Start with an invalid handle in the vector. | 201 // Start with an invalid handle in the vector. |
211 scoped_ptr<PlatformHandleVector> handles(new PlatformHandleVector()); | 202 scoped_ptr<PlatformHandleVector> handles(new PlatformHandleVector()); |
212 handles->push_back(PlatformHandle()); | 203 handles->push_back(PlatformHandle()); |
213 | 204 |
214 char buf[100] = { 'a' }; | 205 char buf[100] = { 'a' }; |
215 EXPECT_EQ(1, PlatformChannelRecvmsg(client_handle.get(), buf, sizeof(buf), | 206 EXPECT_EQ(1, PlatformChannelRecvmsg(client_handle.get(), buf, sizeof(buf), |
216 &handles)); | 207 &handles)); |
217 EXPECT_EQ('\0', buf[0]); | 208 EXPECT_EQ('\0', buf[0]); |
218 ASSERT_TRUE(handles); | 209 ASSERT_TRUE(handles); |
219 ASSERT_EQ(2u, handles->size()); | 210 ASSERT_EQ(2u, handles->size()); |
220 EXPECT_FALSE((*handles)[0].is_valid()); | 211 EXPECT_FALSE((*handles)[0].is_valid()); |
221 EXPECT_TRUE((*handles)[1].is_valid()); | 212 EXPECT_TRUE((*handles)[1].is_valid()); |
222 | 213 |
223 { | 214 { |
224 FILE* fp = FILEFromPlatformHandle(ScopedPlatformHandle((*handles)[1]), | 215 base::ScopedFILE fp(test::FILEFromPlatformHandle( |
225 "rb"); | 216 ScopedPlatformHandle((*handles)[1]), "rb")); |
226 (*handles)[1] = PlatformHandle(); | 217 (*handles)[1] = PlatformHandle(); |
227 ASSERT_TRUE(fp); | 218 ASSERT_TRUE(fp); |
228 rewind(fp); | 219 rewind(fp.get()); |
229 char read_buf[100]; | 220 char read_buf[100]; |
230 size_t bytes_read = fread(read_buf, 1, sizeof(read_buf), fp); | 221 size_t bytes_read = fread(read_buf, 1, sizeof(read_buf), fp.get()); |
231 fclose(fp); | |
232 EXPECT_EQ(file_contents.size(), bytes_read); | 222 EXPECT_EQ(file_contents.size(), bytes_read); |
233 EXPECT_EQ(file_contents, std::string(read_buf, bytes_read)); | 223 EXPECT_EQ(file_contents, std::string(read_buf, bytes_read)); |
234 } | 224 } |
235 } | 225 } |
236 | 226 |
237 } // namespace | 227 } // namespace |
238 } // namespace embedder | 228 } // namespace embedder |
239 } // namespace mojo | 229 } // namespace mojo |
OLD | NEW |