Use TargetTransform instead of transform in ConvertPointFor/FromAncestor
[chromium-blink-merge.git] / ipc / sync_socket_unittest.cc
blob69a2dca59dd0497855742c3329d801f90085c1a3
1 // Copyright (c) 2012 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.
5 #include "base/sync_socket.h"
7 #include <stdio.h>
8 #include <string>
9 #include <sstream>
11 #include "base/bind.h"
12 #include "base/message_loop.h"
13 #include "base/process_util.h"
14 #include "base/threading/thread.h"
15 #include "ipc/ipc_channel_proxy.h"
16 #include "ipc/ipc_multiprocess_test.h"
17 #include "ipc/ipc_tests.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "testing/multiprocess_func_list.h"
21 #if defined(OS_POSIX)
22 #include "base/file_descriptor_posix.h"
23 #endif
25 // IPC messages for testing ---------------------------------------------------
27 #define IPC_MESSAGE_IMPL
28 #include "ipc/ipc_message_macros.h"
30 #define IPC_MESSAGE_START TestMsgStart
32 // Message class to pass a base::SyncSocket::Handle to another process. This
33 // is not as easy as it sounds, because of the differences in transferring
34 // Windows HANDLEs versus posix file descriptors.
35 #if defined(OS_WIN)
36 IPC_MESSAGE_CONTROL1(MsgClassSetHandle, base::SyncSocket::Handle)
37 #elif defined(OS_POSIX)
38 IPC_MESSAGE_CONTROL1(MsgClassSetHandle, base::FileDescriptor)
39 #endif
41 // Message class to pass a response to the server.
42 IPC_MESSAGE_CONTROL1(MsgClassResponse, std::string)
44 // Message class to tell the server to shut down.
45 IPC_MESSAGE_CONTROL0(MsgClassShutdown)
47 // ----------------------------------------------------------------------------
49 namespace {
50 const char kHelloString[] = "Hello, SyncSocket Client";
51 const size_t kHelloStringLength = arraysize(kHelloString);
52 } // namespace
54 // The SyncSocket server listener class processes two sorts of
55 // messages from the client.
56 class SyncSocketServerListener : public IPC::Listener {
57 public:
58 SyncSocketServerListener() : chan_(NULL) {
61 void Init(IPC::Channel* chan) {
62 chan_ = chan;
65 virtual bool OnMessageReceived(const IPC::Message& msg) {
66 if (msg.routing_id() == MSG_ROUTING_CONTROL) {
67 IPC_BEGIN_MESSAGE_MAP(SyncSocketServerListener, msg)
68 IPC_MESSAGE_HANDLER(MsgClassSetHandle, OnMsgClassSetHandle)
69 IPC_MESSAGE_HANDLER(MsgClassShutdown, OnMsgClassShutdown)
70 IPC_END_MESSAGE_MAP()
72 return true;
75 private:
76 // This sort of message is sent first, causing the transfer of
77 // the handle for the SyncSocket. This message sends a buffer
78 // on the SyncSocket and then sends a response to the client.
79 #if defined(OS_WIN)
80 void OnMsgClassSetHandle(const base::SyncSocket::Handle handle) {
81 SetHandle(handle);
83 #elif defined(OS_POSIX)
84 void OnMsgClassSetHandle(const base::FileDescriptor& fd_struct) {
85 SetHandle(fd_struct.fd);
87 #else
88 # error "What platform?"
89 #endif // defined(OS_WIN)
91 void SetHandle(base::SyncSocket::Handle handle) {
92 base::SyncSocket sync_socket(handle);
93 EXPECT_EQ(sync_socket.Send(kHelloString, kHelloStringLength),
94 kHelloStringLength);
95 IPC::Message* msg = new MsgClassResponse(kHelloString);
96 EXPECT_TRUE(chan_->Send(msg));
99 // When the client responds, it sends back a shutdown message,
100 // which causes the message loop to exit.
101 void OnMsgClassShutdown() {
102 MessageLoop::current()->Quit();
105 IPC::Channel* chan_;
107 DISALLOW_COPY_AND_ASSIGN(SyncSocketServerListener);
110 // Runs the fuzzing server child mode. Returns when the preset number
111 // of messages have been received.
112 MULTIPROCESS_IPC_TEST_MAIN(RunSyncSocketServer) {
113 MessageLoopForIO main_message_loop;
114 SyncSocketServerListener listener;
115 IPC::Channel chan(kSyncSocketChannel, IPC::Channel::MODE_CLIENT, &listener);
116 EXPECT_TRUE(chan.Connect());
117 listener.Init(&chan);
118 MessageLoop::current()->Run();
119 return 0;
122 // The SyncSocket client listener only processes one sort of message,
123 // a response from the server.
124 class SyncSocketClientListener : public IPC::Listener {
125 public:
126 SyncSocketClientListener() {
129 void Init(base::SyncSocket* socket, IPC::Channel* chan) {
130 socket_ = socket;
131 chan_ = chan;
134 virtual bool OnMessageReceived(const IPC::Message& msg) {
135 if (msg.routing_id() == MSG_ROUTING_CONTROL) {
136 IPC_BEGIN_MESSAGE_MAP(SyncSocketClientListener, msg)
137 IPC_MESSAGE_HANDLER(MsgClassResponse, OnMsgClassResponse)
138 IPC_END_MESSAGE_MAP()
140 return true;
143 private:
144 // When a response is received from the server, it sends the same
145 // string as was written on the SyncSocket. These are compared
146 // and a shutdown message is sent back to the server.
147 void OnMsgClassResponse(const std::string& str) {
148 // We rely on the order of sync_socket.Send() and chan_->Send() in
149 // the SyncSocketServerListener object.
150 EXPECT_EQ(kHelloStringLength, socket_->Peek());
151 char buf[kHelloStringLength];
152 socket_->Receive(static_cast<void*>(buf), kHelloStringLength);
153 EXPECT_EQ(strcmp(str.c_str(), buf), 0);
154 // After receiving from the socket there should be no bytes left.
155 EXPECT_EQ(0U, socket_->Peek());
156 IPC::Message* msg = new MsgClassShutdown();
157 EXPECT_TRUE(chan_->Send(msg));
158 MessageLoop::current()->Quit();
161 base::SyncSocket* socket_;
162 IPC::Channel* chan_;
164 DISALLOW_COPY_AND_ASSIGN(SyncSocketClientListener);
167 class SyncSocketTest : public IPCChannelTest {
170 TEST_F(SyncSocketTest, SanityTest) {
171 SyncSocketClientListener listener;
172 IPC::Channel chan(kSyncSocketChannel, IPC::Channel::MODE_SERVER,
173 &listener);
174 base::ProcessHandle server_process = SpawnChild(SYNC_SOCKET_SERVER, &chan);
175 ASSERT_TRUE(server_process);
176 // Create a pair of SyncSockets.
177 base::SyncSocket pair[2];
178 base::SyncSocket::CreatePair(&pair[0], &pair[1]);
179 // Immediately after creation there should be no pending bytes.
180 EXPECT_EQ(0U, pair[0].Peek());
181 EXPECT_EQ(0U, pair[1].Peek());
182 base::SyncSocket::Handle target_handle;
183 // Connect the channel and listener.
184 ASSERT_TRUE(chan.Connect());
185 listener.Init(&pair[0], &chan);
186 #if defined(OS_WIN)
187 // On windows we need to duplicate the handle into the server process.
188 BOOL retval = DuplicateHandle(GetCurrentProcess(), pair[1].handle(),
189 server_process, &target_handle,
190 0, FALSE, DUPLICATE_SAME_ACCESS);
191 EXPECT_TRUE(retval);
192 // Set up a message to pass the handle to the server.
193 IPC::Message* msg = new MsgClassSetHandle(target_handle);
194 #else
195 target_handle = pair[1].handle();
196 // Set up a message to pass the handle to the server.
197 base::FileDescriptor filedesc(target_handle, false);
198 IPC::Message* msg = new MsgClassSetHandle(filedesc);
199 #endif // defined(OS_WIN)
200 EXPECT_TRUE(chan.Send(msg));
201 // Use the current thread as the I/O thread.
202 MessageLoop::current()->Run();
203 // Shut down.
204 pair[0].Close();
205 pair[1].Close();
206 EXPECT_TRUE(base::WaitForSingleProcess(
207 server_process, base::TimeDelta::FromSeconds(5)));
208 base::CloseProcessHandle(server_process);
212 // A blocking read operation that will block the thread until it receives
213 // |length| bytes of packets or Shutdown() is called on another thread.
214 static void BlockingRead(base::SyncSocket* socket, char* buf,
215 size_t length, size_t* received) {
216 DCHECK(buf != NULL);
217 // Notify the parent thread that we're up and running.
218 socket->Send(kHelloString, kHelloStringLength);
219 *received = socket->Receive(buf, length);
222 // Tests that we can safely end a blocking Receive operation on one thread
223 // from another thread by disconnecting (but not closing) the socket.
224 TEST_F(SyncSocketTest, DisconnectTest) {
225 base::CancelableSyncSocket pair[2];
226 ASSERT_TRUE(base::CancelableSyncSocket::CreatePair(&pair[0], &pair[1]));
228 base::Thread worker("BlockingThread");
229 worker.Start();
231 // Try to do a blocking read from one of the sockets on the worker thread.
232 char buf[0xff];
233 size_t received = 1U; // Initialize to an unexpected value.
234 worker.message_loop()->PostTask(FROM_HERE,
235 base::Bind(&BlockingRead, &pair[0], &buf[0], arraysize(buf), &received));
237 // Wait for the worker thread to say hello.
238 char hello[kHelloStringLength] = {0};
239 pair[1].Receive(&hello[0], sizeof(hello));
240 EXPECT_EQ(0, strcmp(hello, kHelloString));
241 // Give the worker a chance to start Receive().
242 base::PlatformThread::YieldCurrentThread();
244 // Now shut down the socket that the thread is issuing a blocking read on
245 // which should cause Receive to return with an error.
246 pair[0].Shutdown();
248 worker.Stop();
250 EXPECT_EQ(0U, received);
253 // Tests that read is a blocking operation.
254 TEST_F(SyncSocketTest, BlockingReceiveTest) {
255 base::CancelableSyncSocket pair[2];
256 ASSERT_TRUE(base::CancelableSyncSocket::CreatePair(&pair[0], &pair[1]));
258 base::Thread worker("BlockingThread");
259 worker.Start();
261 // Try to do a blocking read from one of the sockets on the worker thread.
262 char buf[kHelloStringLength] = {0};
263 size_t received = 1U; // Initialize to an unexpected value.
264 worker.message_loop()->PostTask(FROM_HERE,
265 base::Bind(&BlockingRead, &pair[0], &buf[0],
266 kHelloStringLength, &received));
268 // Wait for the worker thread to say hello.
269 char hello[kHelloStringLength] = {0};
270 pair[1].Receive(&hello[0], sizeof(hello));
271 EXPECT_EQ(0, strcmp(hello, kHelloString));
272 // Give the worker a chance to start Receive().
273 base::PlatformThread::YieldCurrentThread();
275 // Send a message to the socket on the blocking thead, it should free the
276 // socket from Receive().
277 pair[1].Send(kHelloString, kHelloStringLength);
278 worker.Stop();
280 // Verify the socket has received the message.
281 EXPECT_TRUE(strcmp(buf, kHelloString) == 0);
282 EXPECT_EQ(kHelloStringLength, received);
285 // Tests that the write operation is non-blocking and returns immediately
286 // when there is insufficient space in the socket's buffer.
287 TEST_F(SyncSocketTest, NonBlockingWriteTest) {
288 base::CancelableSyncSocket pair[2];
289 ASSERT_TRUE(base::CancelableSyncSocket::CreatePair(&pair[0], &pair[1]));
291 // Fill up the buffer for one of the socket, Send() should not block the
292 // thread even when the buffer is full.
293 while (pair[0].Send(kHelloString, kHelloStringLength) != 0) {}
295 // Data should be avialble on another socket.
296 size_t bytes_in_buffer = pair[1].Peek();
297 EXPECT_NE(bytes_in_buffer, 0U);
299 // No more data can be written to the buffer since socket has been full,
300 // verify that the amount of avialble data on another socket is unchanged.
301 EXPECT_EQ(0U, pair[0].Send(kHelloString, kHelloStringLength));
302 EXPECT_EQ(bytes_in_buffer, pair[1].Peek());
304 // Read from another socket to free some space for a new write.
305 char hello[kHelloStringLength] = {0};
306 pair[1].Receive(&hello[0], sizeof(hello));
308 // Should be able to write more data to the buffer now.
309 EXPECT_EQ(kHelloStringLength, pair[0].Send(kHelloString, kHelloStringLength));