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

Side by Side Diff: ipc/sync_socket_unittest.cc

Issue 418004: This adds the first version of SyncSocket to base, along with a trivial unitt... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 1 month 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 | Annotate | Revision Log
« base/sync_socket.h ('K') | « ipc/ipc_tests.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2009 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 <stdio.h>
6 #include <iostream>
7 #include <string>
8 #include <sstream>
9
10 #include "base/message_loop.h"
11 #include "base/platform_thread.h"
12 #include "base/process_util.h"
13 #include "base/sync_socket.h"
14 #include "ipc/ipc_channel.h"
15 #include "ipc/ipc_channel_proxy.h"
16 #include "ipc/ipc_message_utils.h"
17 #include "ipc/ipc_tests.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "testing/multiprocess_func_list.h"
20
21
22 // We don't actually use the messages defined in this file, but we do this
23 // to get to the IPC macros.
24 #define MESSAGES_INTERNAL_FILE "ipc/ipc_sync_message_unittest.h"
25 #include "ipc/ipc_message_macros.h"
26
27 enum IPCMessageIds {
28 UNUSED_IPC_TYPE,
29 SERVER_FIRST_IPC_TYPE, // SetHandle message sent to server.
30 SERVER_SECOND_IPC_TYPE, // Shutdown message sent to server.
31 CLIENT_FIRST_IPC_TYPE // Response message sent to client.
32 };
33
34 namespace {
35 const char kHelloString[] = "Hello, SyncSocket Client";
36 const size_t kHelloStringLength = arraysize(kHelloString);
37 } // namespace
38
39 // Message class to pass a HANDLE to another process.
40 class MsgClassSetHandle
41 : public IPC::MessageWithTuple< Tuple1<base::SyncSocket::Handle> > {
42 public:
43 enum { ID = SERVER_FIRST_IPC_TYPE };
44 explicit MsgClassSetHandle(const base::SyncSocket::Handle arg1)
45 : IPC::MessageWithTuple< Tuple1<base::SyncSocket::Handle> >(
46 MSG_ROUTING_CONTROL, ID, MakeRefTuple(arg1)) {}
47
48 private:
49 DISALLOW_COPY_AND_ASSIGN(MsgClassSetHandle);
50 };
51
52 // Message class to pass a response to the server.
53 class MsgClassResponse
54 : public IPC::MessageWithTuple< Tuple1<std::string> > {
55 public:
56 enum { ID = CLIENT_FIRST_IPC_TYPE };
57 explicit MsgClassResponse(const std::string& arg1)
58 : IPC::MessageWithTuple< Tuple1<std::string> >(
59 MSG_ROUTING_CONTROL, ID, MakeRefTuple(arg1)) {}
60
61 private:
62 DISALLOW_COPY_AND_ASSIGN(MsgClassResponse);
63 };
64
65 // Message class to tell the server to shut down.
66 class MsgClassShutdown
67 : public IPC::MessageWithTuple< Tuple0 > {
68 public:
69 enum { ID = SERVER_SECOND_IPC_TYPE };
70 MsgClassShutdown()
71 : IPC::MessageWithTuple< Tuple0 >(
72 MSG_ROUTING_CONTROL, ID, MakeTuple()) {}
73
74 private:
75 DISALLOW_COPY_AND_ASSIGN(MsgClassShutdown);
76 };
77
78 // The SyncSocket server listener class processes two sorts of
79 // messages from the client.
80 class SyncSocketServerListener : public IPC::Channel::Listener {
81 public:
82 SyncSocketServerListener() : chan_(NULL) {
83 }
84
85 void Init(IPC::Channel* chan) {
86 chan_ = chan;
87 }
88
89 virtual void OnMessageReceived(const IPC::Message& msg) {
90 if (msg.routing_id() == MSG_ROUTING_CONTROL) {
91 IPC_BEGIN_MESSAGE_MAP(SyncSocketServerListener, msg)
92 IPC_MESSAGE_HANDLER(MsgClassSetHandle, OnMsgClassSetHandle)
93 IPC_MESSAGE_HANDLER(MsgClassShutdown, OnMsgClassShutdown)
94 IPC_END_MESSAGE_MAP()
95 }
96 }
97
98 private:
99 // This sort of message is sent first, causing the transfer of
100 // the handle for the SyncSocket. This message sends a buffer
101 // on the SyncSocket and then sends a response to the client.
102 void OnMsgClassSetHandle(const base::SyncSocket::Handle handle) {
103 base::SyncSocket sync_socket(handle);
104 EXPECT_EQ(sync_socket.Send(static_cast<const void*>(kHelloString),
105 kHelloStringLength), kHelloStringLength);
106 IPC::Message* msg = new MsgClassResponse(kHelloString);
107 EXPECT_NE(msg, reinterpret_cast<IPC::Message*>(NULL));
108 EXPECT_TRUE(chan_->Send(msg));
109 }
110
111 // When the client responds, it sends back a shutdown message,
112 // which causes the message loop to exit.
113 void OnMsgClassShutdown() {
114 MessageLoop::current()->Quit();
115 }
116
117 IPC::Channel* chan_;
118
119 DISALLOW_COPY_AND_ASSIGN(SyncSocketServerListener);
120 };
121
122 // Runs the fuzzing server child mode. Returns when the preset number
123 // of messages have been received.
124 MULTIPROCESS_TEST_MAIN(RunSyncSocketServer) {
125 MessageLoopForIO main_message_loop;
126 SyncSocketServerListener listener;
127 IPC::Channel chan(kSyncSocketChannel, IPC::Channel::MODE_CLIENT, &listener);
128 EXPECT_TRUE(chan.Connect());
129 listener.Init(&chan);
130 MessageLoop::current()->Run();
131 return 0;
132 }
133
134 // The SyncSocket client listener only processes one sort of message,
135 // a response from the server.
136 class SyncSocketClientListener : public IPC::Channel::Listener {
137 public:
138 SyncSocketClientListener() {
139 }
140
141 void Init(base::SyncSocket* socket, IPC::Channel* chan) {
142 socket_ = socket;
143 chan_ = chan;
144 }
145
146 virtual void OnMessageReceived(const IPC::Message& msg) {
147 if (msg.routing_id() == MSG_ROUTING_CONTROL) {
148 IPC_BEGIN_MESSAGE_MAP(SyncSocketClientListener, msg)
149 IPC_MESSAGE_HANDLER(MsgClassResponse, OnMsgClassResponse)
150 IPC_END_MESSAGE_MAP()
151 }
152 }
153
154 private:
155 // When a response is received from the server, it sends the same
156 // string as was written on the SyncSocket. These are compared
157 // and a shutdown message is sent back to the server.
158 void OnMsgClassResponse(const std::string& str) {
159 char buf[kHelloStringLength];
160 socket_->Receive(static_cast<void*>(buf), kHelloStringLength);
161 EXPECT_EQ(strcmp(str.c_str(), buf), 0);
162 IPC::Message* msg = new MsgClassShutdown();
163 EXPECT_NE(msg, reinterpret_cast<IPC::Message*>(NULL));
164 EXPECT_TRUE(chan_->Send(msg));
165 MessageLoop::current()->Quit();
166 }
167
168 base::SyncSocket* socket_;
169 IPC::Channel* chan_;
170
171 DISALLOW_COPY_AND_ASSIGN(SyncSocketClientListener);
172 };
173
174 class SyncSocketTest : public IPCChannelTest {
175 };
176
177 TEST_F(SyncSocketTest, SanityTest) {
178 SyncSocketClientListener listener;
179 IPC::Channel chan(kSyncSocketChannel, IPC::Channel::MODE_SERVER,
180 &listener);
181 base::ProcessHandle server_process = SpawnChild(SYNC_SOCKET_SERVER, &chan);
182 ASSERT_TRUE(server_process);
183 // Create a pair of SyncSockets.
184 base::SyncSocket* pair[2];
185 base::SyncSocket::CreatePair(pair);
186 base::SyncSocket::Handle target_handle;
187 #if defined(OS_WIN)
188 // On windows we need to duplicate the handle into the server process.
189 BOOL retval = DuplicateHandle(GetCurrentProcess(), pair[1]->handle(),
190 server_process, &target_handle,
191 0, FALSE, DUPLICATE_SAME_ACCESS);
192 EXPECT_TRUE(retval);
193 #else
194 target_handle = pair[1]->handle();
195 #endif // defined(OS_WIN)
196 // Connect the channel and listener.
197 ASSERT_TRUE(chan.Connect());
198 listener.Init(pair[0], &chan);
199 // Set up a message to pass the handle to the server.
200 IPC::Message* msg = new MsgClassSetHandle(target_handle);
201 EXPECT_NE(msg, reinterpret_cast<IPC::Message*>(NULL));
202 EXPECT_TRUE(chan.Send(msg));
203 // Use the current thread as the I/O thread.
204 MessageLoop::current()->Run();
205 // Shut down.
206 delete pair[0];
207 delete pair[1];
208 EXPECT_TRUE(base::WaitForSingleProcess(server_process, 5000));
209 base::CloseProcessHandle(server_process);
210 }
211
OLDNEW
« base/sync_socket.h ('K') | « ipc/ipc_tests.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698