Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(109)

Side by Side Diff: mojo/edk/embedder/platform_channel_pair_posix_unittest.cc

Issue 814543006: Move //mojo/{public, edk} underneath //third_party (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "mojo/edk/embedder/platform_channel_pair.h"
6
7 #include <errno.h>
8 #include <poll.h>
9 #include <signal.h>
10 #include <stdio.h>
11 #include <sys/socket.h>
12 #include <sys/types.h>
13 #include <sys/uio.h>
14 #include <unistd.h>
15
16 #include <deque>
17
18 #include "base/files/file_path.h"
19 #include "base/files/file_util.h"
20 #include "base/files/scoped_file.h"
21 #include "base/files/scoped_temp_dir.h"
22 #include "base/logging.h"
23 #include "base/macros.h"
24 #include "mojo/edk/embedder/platform_channel_utils_posix.h"
25 #include "mojo/edk/embedder/platform_handle.h"
26 #include "mojo/edk/embedder/platform_handle_vector.h"
27 #include "mojo/edk/embedder/scoped_platform_handle.h"
28 #include "mojo/edk/test/test_utils.h"
29 #include "testing/gtest/include/gtest/gtest.h"
30
31 namespace mojo {
32 namespace embedder {
33 namespace {
34
35 void WaitReadable(PlatformHandle h) {
36 struct pollfd pfds = {};
37 pfds.fd = h.fd;
38 pfds.events = POLLIN;
39 CHECK_EQ(poll(&pfds, 1, -1), 1);
40 }
41
42 class PlatformChannelPairPosixTest : public testing::Test {
43 public:
44 PlatformChannelPairPosixTest() {}
45 ~PlatformChannelPairPosixTest() override {}
46
47 void SetUp() override {
48 // Make sure |SIGPIPE| isn't being ignored.
49 struct sigaction action = {};
50 action.sa_handler = SIG_DFL;
51 ASSERT_EQ(0, sigaction(SIGPIPE, &action, &old_action_));
52 }
53
54 void TearDown() override {
55 // Restore the |SIGPIPE| handler.
56 ASSERT_EQ(0, sigaction(SIGPIPE, &old_action_, nullptr));
57 }
58
59 private:
60 struct sigaction old_action_;
61
62 DISALLOW_COPY_AND_ASSIGN(PlatformChannelPairPosixTest);
63 };
64
65 TEST_F(PlatformChannelPairPosixTest, NoSigPipe) {
66 PlatformChannelPair channel_pair;
67 ScopedPlatformHandle server_handle = channel_pair.PassServerHandle().Pass();
68 ScopedPlatformHandle client_handle = channel_pair.PassClientHandle().Pass();
69
70 // Write to the client.
71 static const char kHello[] = "hello";
72 EXPECT_EQ(static_cast<ssize_t>(sizeof(kHello)),
73 write(client_handle.get().fd, kHello, sizeof(kHello)));
74
75 // Close the client.
76 client_handle.reset();
77
78 // Read from the server; this should be okay.
79 char buffer[100] = {};
80 EXPECT_EQ(static_cast<ssize_t>(sizeof(kHello)),
81 read(server_handle.get().fd, buffer, sizeof(buffer)));
82 EXPECT_STREQ(kHello, buffer);
83
84 // Try reading again.
85 ssize_t result = read(server_handle.get().fd, buffer, sizeof(buffer));
86 // We should probably get zero (for "end of file"), but -1 would also be okay.
87 EXPECT_TRUE(result == 0 || result == -1);
88 if (result == -1)
89 PLOG(WARNING) << "read (expected 0 for EOF)";
90
91 // Test our replacement for |write()|/|send()|.
92 result = PlatformChannelWrite(server_handle.get(), kHello, sizeof(kHello));
93 EXPECT_EQ(-1, result);
94 if (errno != EPIPE)
95 PLOG(WARNING) << "write (expected EPIPE)";
96
97 // Test our replacement for |writev()|/|sendv()|.
98 struct iovec iov[2] = {{const_cast<char*>(kHello), sizeof(kHello)},
99 {const_cast<char*>(kHello), sizeof(kHello)}};
100 result = PlatformChannelWritev(server_handle.get(), iov, 2);
101 EXPECT_EQ(-1, result);
102 if (errno != EPIPE)
103 PLOG(WARNING) << "write (expected EPIPE)";
104 }
105
106 TEST_F(PlatformChannelPairPosixTest, SendReceiveData) {
107 PlatformChannelPair channel_pair;
108 ScopedPlatformHandle server_handle = channel_pair.PassServerHandle().Pass();
109 ScopedPlatformHandle client_handle = channel_pair.PassClientHandle().Pass();
110
111 for (size_t i = 0; i < 10; i++) {
112 std::string send_string(1 << i, 'A' + i);
113
114 EXPECT_EQ(static_cast<ssize_t>(send_string.size()),
115 PlatformChannelWrite(server_handle.get(), send_string.data(),
116 send_string.size()));
117
118 WaitReadable(client_handle.get());
119
120 char buf[10000] = {};
121 std::deque<PlatformHandle> received_handles;
122 ssize_t result = PlatformChannelRecvmsg(client_handle.get(), buf,
123 sizeof(buf), &received_handles);
124 EXPECT_EQ(static_cast<ssize_t>(send_string.size()), result);
125 EXPECT_EQ(send_string, std::string(buf, static_cast<size_t>(result)));
126 EXPECT_TRUE(received_handles.empty());
127 }
128 }
129
130 TEST_F(PlatformChannelPairPosixTest, SendReceiveFDs) {
131 base::ScopedTempDir temp_dir;
132 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
133
134 static const char kHello[] = "hello";
135
136 PlatformChannelPair channel_pair;
137 ScopedPlatformHandle server_handle = channel_pair.PassServerHandle().Pass();
138 ScopedPlatformHandle client_handle = channel_pair.PassClientHandle().Pass();
139
140 for (size_t i = 1; i < kPlatformChannelMaxNumHandles; i++) {
141 // Make |i| files, with the j-th file consisting of j copies of the digit
142 // |c|.
143 const char c = '0' + (i % 10);
144 ScopedPlatformHandleVectorPtr platform_handles(new PlatformHandleVector);
145 for (size_t j = 1; j <= i; j++) {
146 base::FilePath unused;
147 base::ScopedFILE fp(
148 base::CreateAndOpenTemporaryFileInDir(temp_dir.path(), &unused));
149 ASSERT_TRUE(fp);
150 ASSERT_EQ(j, fwrite(std::string(j, c).data(), 1, j, fp.get()));
151 platform_handles->push_back(
152 test::PlatformHandleFromFILE(fp.Pass()).release());
153 ASSERT_TRUE(platform_handles->back().is_valid());
154 }
155
156 // Send the FDs (+ "hello").
157 struct iovec iov = {const_cast<char*>(kHello), sizeof(kHello)};
158 // We assume that the |sendmsg()| actually sends all the data.
159 EXPECT_EQ(static_cast<ssize_t>(sizeof(kHello)),
160 PlatformChannelSendmsgWithHandles(server_handle.get(), &iov, 1,
161 &platform_handles->at(0),
162 platform_handles->size()));
163
164 WaitReadable(client_handle.get());
165
166 char buf[10000] = {};
167 std::deque<PlatformHandle> received_handles;
168 // We assume that the |recvmsg()| actually reads all the data.
169 EXPECT_EQ(static_cast<ssize_t>(sizeof(kHello)),
170 PlatformChannelRecvmsg(client_handle.get(), buf, sizeof(buf),
171 &received_handles));
172 EXPECT_STREQ(kHello, buf);
173 EXPECT_EQ(i, received_handles.size());
174
175 for (size_t j = 0; !received_handles.empty(); j++) {
176 base::ScopedFILE fp(test::FILEFromPlatformHandle(
177 ScopedPlatformHandle(received_handles.front()), "rb"));
178 received_handles.pop_front();
179 ASSERT_TRUE(fp);
180 rewind(fp.get());
181 char read_buf[kPlatformChannelMaxNumHandles];
182 size_t bytes_read = fread(read_buf, 1, sizeof(read_buf), fp.get());
183 EXPECT_EQ(j + 1, bytes_read);
184 EXPECT_EQ(std::string(j + 1, c), std::string(read_buf, bytes_read));
185 }
186 }
187 }
188
189 TEST_F(PlatformChannelPairPosixTest, AppendReceivedFDs) {
190 base::ScopedTempDir temp_dir;
191 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
192
193 static const char kHello[] = "hello";
194
195 PlatformChannelPair channel_pair;
196 ScopedPlatformHandle server_handle = channel_pair.PassServerHandle().Pass();
197 ScopedPlatformHandle client_handle = channel_pair.PassClientHandle().Pass();
198
199 const std::string file_contents("hello world");
200
201 {
202 base::FilePath unused;
203 base::ScopedFILE fp(
204 base::CreateAndOpenTemporaryFileInDir(temp_dir.path(), &unused));
205 ASSERT_TRUE(fp);
206 ASSERT_EQ(file_contents.size(),
207 fwrite(file_contents.data(), 1, file_contents.size(), fp.get()));
208 ScopedPlatformHandleVectorPtr platform_handles(new PlatformHandleVector);
209 platform_handles->push_back(
210 test::PlatformHandleFromFILE(fp.Pass()).release());
211 ASSERT_TRUE(platform_handles->back().is_valid());
212
213 // Send the FD (+ "hello").
214 struct iovec iov = {const_cast<char*>(kHello), sizeof(kHello)};
215 // We assume that the |sendmsg()| actually sends all the data.
216 EXPECT_EQ(static_cast<ssize_t>(sizeof(kHello)),
217 PlatformChannelSendmsgWithHandles(server_handle.get(), &iov, 1,
218 &platform_handles->at(0),
219 platform_handles->size()));
220 }
221
222 WaitReadable(client_handle.get());
223
224 // Start with an invalid handle in the deque.
225 std::deque<PlatformHandle> received_handles;
226 received_handles.push_back(PlatformHandle());
227
228 char buf[100] = {};
229 // We assume that the |recvmsg()| actually reads all the data.
230 EXPECT_EQ(static_cast<ssize_t>(sizeof(kHello)),
231 PlatformChannelRecvmsg(client_handle.get(), buf, sizeof(buf),
232 &received_handles));
233 EXPECT_STREQ(kHello, buf);
234 ASSERT_EQ(2u, received_handles.size());
235 EXPECT_FALSE(received_handles[0].is_valid());
236 EXPECT_TRUE(received_handles[1].is_valid());
237
238 {
239 base::ScopedFILE fp(test::FILEFromPlatformHandle(
240 ScopedPlatformHandle(received_handles[1]), "rb"));
241 received_handles[1] = PlatformHandle();
242 ASSERT_TRUE(fp);
243 rewind(fp.get());
244 char read_buf[100];
245 size_t bytes_read = fread(read_buf, 1, sizeof(read_buf), fp.get());
246 EXPECT_EQ(file_contents.size(), bytes_read);
247 EXPECT_EQ(file_contents, std::string(read_buf, bytes_read));
248 }
249 }
250
251 } // namespace
252 } // namespace embedder
253 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/edk/embedder/platform_channel_pair_posix.cc ('k') | mojo/edk/embedder/platform_channel_pair_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698