Add myself to the browser compositor watch list.
[chromium-blink-merge.git] / ipc / sync_socket_unittest.cc
blob79cf6c3c33d1cbcc56d97d22616c443623e05a06
1 // Copyright (c) 2011 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/message_loop.h"
12 #include "base/process_util.h"
13 #include "ipc/ipc_channel_proxy.h"
14 #include "ipc/ipc_tests.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "testing/multiprocess_func_list.h"
18 #if defined(OS_POSIX)
19 #include "base/file_descriptor_posix.h"
20 #endif
22 // IPC messages for testing ---------------------------------------------------
24 #define IPC_MESSAGE_IMPL
25 #include "ipc/ipc_message_macros.h"
27 #define IPC_MESSAGE_START TestMsgStart
29 // Message class to pass a base::SyncSocket::Handle to another process. This
30 // is not as easy as it sounds, because of the differences in transferring
31 // Windows HANDLEs versus posix file descriptors.
32 #if defined(OS_WIN)
33 IPC_MESSAGE_CONTROL1(MsgClassSetHandle, base::SyncSocket::Handle)
34 #elif defined(OS_POSIX)
35 IPC_MESSAGE_CONTROL1(MsgClassSetHandle, base::FileDescriptor)
36 #endif
38 // Message class to pass a response to the server.
39 IPC_MESSAGE_CONTROL1(MsgClassResponse, std::string)
41 // Message class to tell the server to shut down.
42 IPC_MESSAGE_CONTROL0(MsgClassShutdown)
44 // ----------------------------------------------------------------------------
46 namespace {
47 const char kHelloString[] = "Hello, SyncSocket Client";
48 const size_t kHelloStringLength = arraysize(kHelloString);
49 } // namespace
51 // The SyncSocket server listener class processes two sorts of
52 // messages from the client.
53 class SyncSocketServerListener : public IPC::Channel::Listener {
54 public:
55 SyncSocketServerListener() : chan_(NULL) {
58 void Init(IPC::Channel* chan) {
59 chan_ = chan;
62 virtual bool OnMessageReceived(const IPC::Message& msg) {
63 if (msg.routing_id() == MSG_ROUTING_CONTROL) {
64 IPC_BEGIN_MESSAGE_MAP(SyncSocketServerListener, msg)
65 IPC_MESSAGE_HANDLER(MsgClassSetHandle, OnMsgClassSetHandle)
66 IPC_MESSAGE_HANDLER(MsgClassShutdown, OnMsgClassShutdown)
67 IPC_END_MESSAGE_MAP()
69 return true;
72 private:
73 // This sort of message is sent first, causing the transfer of
74 // the handle for the SyncSocket. This message sends a buffer
75 // on the SyncSocket and then sends a response to the client.
76 #if defined(OS_WIN)
77 void OnMsgClassSetHandle(const base::SyncSocket::Handle handle) {
78 SetHandle(handle);
80 #elif defined(OS_POSIX)
81 void OnMsgClassSetHandle(const base::FileDescriptor& fd_struct) {
82 SetHandle(fd_struct.fd);
84 #else
85 # error "What platform?"
86 #endif // defined(OS_WIN)
88 void SetHandle(base::SyncSocket::Handle handle) {
89 base::SyncSocket sync_socket(handle);
90 EXPECT_EQ(sync_socket.Send(static_cast<const void*>(kHelloString),
91 kHelloStringLength), kHelloStringLength);
92 IPC::Message* msg = new MsgClassResponse(kHelloString);
93 EXPECT_TRUE(chan_->Send(msg));
96 // When the client responds, it sends back a shutdown message,
97 // which causes the message loop to exit.
98 void OnMsgClassShutdown() {
99 MessageLoop::current()->Quit();
102 IPC::Channel* chan_;
104 DISALLOW_COPY_AND_ASSIGN(SyncSocketServerListener);
107 // Runs the fuzzing server child mode. Returns when the preset number
108 // of messages have been received.
109 MULTIPROCESS_TEST_MAIN(RunSyncSocketServer) {
110 MessageLoopForIO main_message_loop;
111 SyncSocketServerListener listener;
112 IPC::Channel chan(kSyncSocketChannel, IPC::Channel::MODE_CLIENT, &listener);
113 EXPECT_TRUE(chan.Connect());
114 listener.Init(&chan);
115 MessageLoop::current()->Run();
116 return 0;
119 // The SyncSocket client listener only processes one sort of message,
120 // a response from the server.
121 class SyncSocketClientListener : public IPC::Channel::Listener {
122 public:
123 SyncSocketClientListener() {
126 void Init(base::SyncSocket* socket, IPC::Channel* chan) {
127 socket_ = socket;
128 chan_ = chan;
131 virtual bool OnMessageReceived(const IPC::Message& msg) {
132 if (msg.routing_id() == MSG_ROUTING_CONTROL) {
133 IPC_BEGIN_MESSAGE_MAP(SyncSocketClientListener, msg)
134 IPC_MESSAGE_HANDLER(MsgClassResponse, OnMsgClassResponse)
135 IPC_END_MESSAGE_MAP()
137 return true;
140 private:
141 // When a response is received from the server, it sends the same
142 // string as was written on the SyncSocket. These are compared
143 // and a shutdown message is sent back to the server.
144 void OnMsgClassResponse(const std::string& str) {
145 // We rely on the order of sync_socket.Send() and chan_->Send() in
146 // the SyncSocketServerListener object.
147 EXPECT_EQ(kHelloStringLength, socket_->Peek());
148 char buf[kHelloStringLength];
149 socket_->Receive(static_cast<void*>(buf), kHelloStringLength);
150 EXPECT_EQ(strcmp(str.c_str(), buf), 0);
151 // After receiving from the socket there should be no bytes left.
152 EXPECT_EQ(0U, socket_->Peek());
153 IPC::Message* msg = new MsgClassShutdown();
154 EXPECT_TRUE(chan_->Send(msg));
155 MessageLoop::current()->Quit();
158 base::SyncSocket* socket_;
159 IPC::Channel* chan_;
161 DISALLOW_COPY_AND_ASSIGN(SyncSocketClientListener);
164 class SyncSocketTest : public IPCChannelTest {
167 TEST_F(SyncSocketTest, SanityTest) {
168 SyncSocketClientListener listener;
169 IPC::Channel chan(kSyncSocketChannel, IPC::Channel::MODE_SERVER,
170 &listener);
171 base::ProcessHandle server_process = SpawnChild(SYNC_SOCKET_SERVER, &chan);
172 ASSERT_TRUE(server_process);
173 // Create a pair of SyncSockets.
174 base::SyncSocket* pair[2];
175 base::SyncSocket::CreatePair(pair);
176 // Immediately after creation there should be no pending bytes.
177 EXPECT_EQ(0U, pair[0]->Peek());
178 EXPECT_EQ(0U, pair[1]->Peek());
179 base::SyncSocket::Handle target_handle;
180 // Connect the channel and listener.
181 ASSERT_TRUE(chan.Connect());
182 listener.Init(pair[0], &chan);
183 #if defined(OS_WIN)
184 // On windows we need to duplicate the handle into the server process.
185 BOOL retval = DuplicateHandle(GetCurrentProcess(), pair[1]->handle(),
186 server_process, &target_handle,
187 0, FALSE, DUPLICATE_SAME_ACCESS);
188 EXPECT_TRUE(retval);
189 // Set up a message to pass the handle to the server.
190 IPC::Message* msg = new MsgClassSetHandle(target_handle);
191 #else
192 target_handle = pair[1]->handle();
193 // Set up a message to pass the handle to the server.
194 base::FileDescriptor filedesc(target_handle, false);
195 IPC::Message* msg = new MsgClassSetHandle(filedesc);
196 #endif // defined(OS_WIN)
197 EXPECT_TRUE(chan.Send(msg));
198 // Use the current thread as the I/O thread.
199 MessageLoop::current()->Run();
200 // Shut down.
201 delete pair[0];
202 delete pair[1];
203 EXPECT_TRUE(base::WaitForSingleProcess(server_process, 5000));
204 base::CloseProcessHandle(server_process);