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

Side by Side Diff: ipc/ipc_channel_unittest.cc

Issue 12051048: Refactor (many) IPC tests, notably most of the multiprocess tests. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix win Created 7 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 | Annotate | Revision Log
« no previous file with comments | « ipc/ipc.gyp ('k') | ipc/ipc_fuzzing_tests.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 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 "build/build_config.h" 5 #include "build/build_config.h"
6 6
7 #if defined(OS_WIN) 7 #if defined(OS_WIN)
8 #include <windows.h> 8 #include <windows.h>
9 #elif defined(OS_POSIX)
10 #include <sys/types.h>
11 #include <unistd.h>
12 #endif 9 #endif
13 10
14 #include <stdio.h>
15 #include <string> 11 #include <string>
16 #include <utility>
17 12
18 #include "base/command_line.h" 13 #include "base/message_loop.h"
19 #include "base/pickle.h" 14 #include "base/pickle.h"
20 #include "base/threading/thread.h" 15 #include "base/threading/thread.h"
21 #include "base/time.h" 16 #include "ipc/ipc_message.h"
22 #include "ipc/ipc_descriptors.h"
23 #include "ipc/ipc_channel.h"
24 #include "ipc/ipc_channel_proxy.h"
25 #include "ipc/ipc_message_utils.h"
26 #include "ipc/ipc_multiprocess_test.h"
27 #include "ipc/ipc_sender.h"
28 #include "ipc/ipc_switches.h"
29 #include "ipc/ipc_test_base.h" 17 #include "ipc/ipc_test_base.h"
30 18
31 namespace { 19 namespace {
32 20
33 const size_t kLongMessageStringNumBytes = 50000; 21 const size_t kLongMessageStringNumBytes = 50000;
34 22
35 class IPCChannelTest : public IPCTestBase {
36 };
37
38 TEST_F(IPCChannelTest, BasicMessageTest) {
39 int v1 = 10;
40 std::string v2("foobar");
41 std::wstring v3(L"hello world");
42
43 IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL);
44 EXPECT_TRUE(m.WriteInt(v1));
45 EXPECT_TRUE(m.WriteString(v2));
46 EXPECT_TRUE(m.WriteWString(v3));
47
48 PickleIterator iter(m);
49
50 int vi;
51 std::string vs;
52 std::wstring vw;
53
54 EXPECT_TRUE(m.ReadInt(&iter, &vi));
55 EXPECT_EQ(v1, vi);
56
57 EXPECT_TRUE(m.ReadString(&iter, &vs));
58 EXPECT_EQ(v2, vs);
59
60 EXPECT_TRUE(m.ReadWString(&iter, &vw));
61 EXPECT_EQ(v3, vw);
62
63 // should fail
64 EXPECT_FALSE(m.ReadInt(&iter, &vi));
65 EXPECT_FALSE(m.ReadString(&iter, &vs));
66 EXPECT_FALSE(m.ReadWString(&iter, &vw));
67 }
68
69 static void Send(IPC::Sender* sender, const char* text) { 23 static void Send(IPC::Sender* sender, const char* text) {
70 static int message_index = 0; 24 static int message_index = 0;
71 25
72 IPC::Message* message = new IPC::Message(0, 26 IPC::Message* message = new IPC::Message(0,
73 2, 27 2,
74 IPC::Message::PRIORITY_NORMAL); 28 IPC::Message::PRIORITY_NORMAL);
75 message->WriteInt(message_index++); 29 message->WriteInt(message_index++);
76 message->WriteString(std::string(text)); 30 message->WriteString(std::string(text));
77 31
78 // Make sure we can handle large messages. 32 // Make sure we can handle large messages.
79 char junk[kLongMessageStringNumBytes]; 33 char junk[kLongMessageStringNumBytes];
80 memset(junk, 'a', sizeof(junk)-1); 34 memset(junk, 'a', sizeof(junk)-1);
81 junk[sizeof(junk)-1] = 0; 35 junk[sizeof(junk)-1] = 0;
82 message->WriteString(std::string(junk)); 36 message->WriteString(std::string(junk));
83 37
84 // DEBUG: printf("[%u] sending message [%s]\n", GetCurrentProcessId(), text); 38 // DEBUG: printf("[%u] sending message [%s]\n", GetCurrentProcessId(), text);
85 sender->Send(message); 39 sender->Send(message);
86 } 40 }
87 41
88 class MyChannelListener : public IPC::Listener { 42 // A generic listener that expects messages of a certain type (see
43 // OnMessageReceived()), and either sends a generic response or quits after the
44 // 50th message (or on channel error).
45 class GenericChannelListener : public IPC::Listener {
89 public: 46 public:
90 virtual bool OnMessageReceived(const IPC::Message& message) { 47 GenericChannelListener() : sender_(NULL), messages_left_(50) {}
48 virtual ~GenericChannelListener() {}
49
50 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
91 PickleIterator iter(message); 51 PickleIterator iter(message);
92 52
93 int ignored; 53 int ignored;
94 EXPECT_TRUE(iter.ReadInt(&ignored)); 54 EXPECT_TRUE(iter.ReadInt(&ignored));
95 std::string data; 55 std::string data;
96 EXPECT_TRUE(iter.ReadString(&data)); 56 EXPECT_TRUE(iter.ReadString(&data));
97 std::string big_string; 57 std::string big_string;
98 EXPECT_TRUE(iter.ReadString(&big_string)); 58 EXPECT_TRUE(iter.ReadString(&big_string));
99 EXPECT_EQ(kLongMessageStringNumBytes - 1, big_string.length()); 59 EXPECT_EQ(kLongMessageStringNumBytes - 1, big_string.length());
100 60
101 61 SendNextMessage();
102 if (--messages_left_ == 0) {
103 MessageLoop::current()->Quit();
104 } else {
105 Send(sender_, "Foo");
106 }
107 return true; 62 return true;
108 } 63 }
109 64
110 virtual void OnChannelError() { 65 virtual void OnChannelError() OVERRIDE {
111 // There is a race when closing the channel so the last message may be lost. 66 // There is a race when closing the channel so the last message may be lost.
112 EXPECT_LE(messages_left_, 1); 67 EXPECT_LE(messages_left_, 1);
113 MessageLoop::current()->Quit(); 68 MessageLoop::current()->Quit();
114 } 69 }
115 70
116 void Init(IPC::Sender* s) { 71 void Init(IPC::Sender* s) {
117 sender_ = s; 72 sender_ = s;
118 messages_left_ = 50; 73 }
74
75 protected:
76 void SendNextMessage() {
77 if (--messages_left_ <= 0)
78 MessageLoop::current()->Quit();
79 else
80 Send(sender_, "Foo");
119 } 81 }
120 82
121 private: 83 private:
122 IPC::Sender* sender_; 84 IPC::Sender* sender_;
123 int messages_left_; 85 int messages_left_;
124 }; 86 };
125 87
88 class IPCChannelTest : public IPCTestBase {
89 };
90
91 // TODO(viettrungluu): Move to a separate IPCMessageTest.
92 TEST_F(IPCChannelTest, BasicMessageTest) {
93 int v1 = 10;
94 std::string v2("foobar");
95 std::wstring v3(L"hello world");
96
97 IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL);
98 EXPECT_TRUE(m.WriteInt(v1));
99 EXPECT_TRUE(m.WriteString(v2));
100 EXPECT_TRUE(m.WriteWString(v3));
101
102 PickleIterator iter(m);
103
104 int vi;
105 std::string vs;
106 std::wstring vw;
107
108 EXPECT_TRUE(m.ReadInt(&iter, &vi));
109 EXPECT_EQ(v1, vi);
110
111 EXPECT_TRUE(m.ReadString(&iter, &vs));
112 EXPECT_EQ(v2, vs);
113
114 EXPECT_TRUE(m.ReadWString(&iter, &vw));
115 EXPECT_EQ(v3, vw);
116
117 // should fail
118 EXPECT_FALSE(m.ReadInt(&iter, &vi));
119 EXPECT_FALSE(m.ReadString(&iter, &vs));
120 EXPECT_FALSE(m.ReadWString(&iter, &vw));
121 }
122
126 TEST_F(IPCChannelTest, ChannelTest) { 123 TEST_F(IPCChannelTest, ChannelTest) {
127 MyChannelListener channel_listener; 124 Init("GenericClient");
128 // Setup IPC channel.
129 IPC::Channel chan(kTestClientChannel, IPC::Channel::MODE_SERVER,
130 &channel_listener);
131 ASSERT_TRUE(chan.Connect());
132 125
133 channel_listener.Init(&chan); 126 // Set up IPC channel and start client.
127 GenericChannelListener listener;
128 CreateChannel(&listener);
129 listener.Init(sender());
130 ASSERT_TRUE(ConnectChannel());
131 ASSERT_TRUE(StartClient());
134 132
135 base::ProcessHandle process_handle = SpawnChild(TEST_CLIENT, &chan); 133 Send(sender(), "hello from parent");
136 ASSERT_TRUE(process_handle);
137
138 Send(&chan, "hello from parent");
139 134
140 // Run message loop. 135 // Run message loop.
141 MessageLoop::current()->Run(); 136 MessageLoop::current()->Run();
142 137
143 // Close Channel so client gets its OnChannelError() callback fired. 138 // Close the channel so the client's OnChannelError() gets fired.
144 chan.Close(); 139 channel()->Close();
145 140
146 // Cleanup child process. 141 EXPECT_TRUE(WaitForClientShutdown());
147 EXPECT_TRUE(base::WaitForSingleProcess( 142 DestroyChannel();
148 process_handle, base::TimeDelta::FromSeconds(5)));
149 base::CloseProcessHandle(process_handle);
150 } 143 }
151 144
145 // TODO(viettrungluu): Move to a separate IPCChannelWinTest.
152 #if defined(OS_WIN) 146 #if defined(OS_WIN)
153 TEST_F(IPCChannelTest, ChannelTestExistingPipe) { 147 TEST_F(IPCChannelTest, ChannelTestExistingPipe) {
154 MyChannelListener channel_listener; 148 Init("GenericClient");
155 // Setup IPC channel with existing pipe. Specify name in Chrome format. 149
150 // Create pipe manually using the standard Chromium name and set up IPC
151 // channel.
152 GenericChannelListener listener;
156 std::string name("\\\\.\\pipe\\chrome."); 153 std::string name("\\\\.\\pipe\\chrome.");
157 name.append(kTestClientChannel); 154 name.append(GetChannelName("GenericClient"));
158 const DWORD open_mode = PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED |
159 FILE_FLAG_FIRST_PIPE_INSTANCE;
160 HANDLE pipe = CreateNamedPipeA(name.c_str(), 155 HANDLE pipe = CreateNamedPipeA(name.c_str(),
161 open_mode, 156 PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED |
157 FILE_FLAG_FIRST_PIPE_INSTANCE,
162 PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, 158 PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
163 1, 159 1,
164 4096, 160 4096,
165 4096, 161 4096,
166 5000, 162 5000,
167 NULL); 163 NULL);
168 IPC::Channel chan(IPC::ChannelHandle(pipe), IPC::Channel::MODE_SERVER, 164 CreateChannelFromChannelHandle(IPC::ChannelHandle(pipe), &listener);
169 &channel_listener); 165 CloseHandle(pipe); // The channel duplicates the handle.
170 // Channel will duplicate the handle. 166 listener.Init(sender());
171 CloseHandle(pipe);
172 ASSERT_TRUE(chan.Connect());
173 167
174 channel_listener.Init(&chan); 168 // Connect to channel and start client.
169 ASSERT_TRUE(ConnectChannel());
170 ASSERT_TRUE(StartClient());
175 171
176 base::ProcessHandle process_handle = SpawnChild(TEST_CLIENT, &chan); 172 Send(sender(), "hello from parent");
177 ASSERT_TRUE(process_handle);
178
179 Send(&chan, "hello from parent");
180 173
181 // Run message loop. 174 // Run message loop.
182 MessageLoop::current()->Run(); 175 MessageLoop::current()->Run();
183 176
184 // Close Channel so client gets its OnChannelError() callback fired. 177 // Close the channel so the client's OnChannelError() gets fired.
185 chan.Close(); 178 channel()->Close();
186 179
187 // Cleanup child process. 180 EXPECT_TRUE(WaitForClientShutdown());
188 EXPECT_TRUE(base::WaitForSingleProcess( 181 DestroyChannel();
189 process_handle, base::TimeDelta::FromSeconds(5)));
190 base::CloseProcessHandle(process_handle);
191 } 182 }
192 #endif // defined (OS_WIN) 183 #endif // defined (OS_WIN)
193 184
194 TEST_F(IPCChannelTest, ChannelProxyTest) { 185 TEST_F(IPCChannelTest, ChannelProxyTest) {
195 MyChannelListener channel_listener; 186 Init("GenericClient");
196 187
197 // The thread needs to out-live the ChannelProxy.
198 base::Thread thread("ChannelProxyTestServer"); 188 base::Thread thread("ChannelProxyTestServer");
199 base::Thread::Options options; 189 base::Thread::Options options;
200 options.message_loop_type = MessageLoop::TYPE_IO; 190 options.message_loop_type = MessageLoop::TYPE_IO;
201 thread.StartWithOptions(options); 191 thread.StartWithOptions(options);
202 {
203 // setup IPC channel proxy
204 IPC::ChannelProxy chan(kTestClientChannel, IPC::Channel::MODE_SERVER,
205 &channel_listener, thread.message_loop_proxy());
206 192
207 channel_listener.Init(&chan); 193 // Set up IPC channel proxy.
194 GenericChannelListener listener;
195 CreateChannelProxy(&listener, thread.message_loop_proxy());
196 listener.Init(sender());
208 197
209 #if defined(OS_WIN) 198 ASSERT_TRUE(StartClient());
210 base::ProcessHandle process_handle = SpawnChild(TEST_CLIENT, NULL);
211 #elif defined(OS_POSIX)
212 bool debug_on_start = CommandLine::ForCurrentProcess()->HasSwitch(
213 switches::kDebugChildren);
214 base::FileHandleMappingVector fds_to_map;
215 const int ipcfd = chan.GetClientFileDescriptor();
216 if (ipcfd > -1) {
217 fds_to_map.push_back(std::pair<int, int>(ipcfd, kPrimaryIPCChannel + 3));
218 }
219 199
220 base::ProcessHandle process_handle = MultiProcessTest::SpawnChild( 200 Send(sender(), "hello from parent");
221 "RunTestClient",
222 fds_to_map,
223 debug_on_start);
224 #endif // defined(OS_POSIX)
225 201
226 ASSERT_TRUE(process_handle); 202 // Run message loop.
203 MessageLoop::current()->Run();
227 204
228 Send(&chan, "hello from parent"); 205 EXPECT_TRUE(WaitForClientShutdown());
229 206
230 // run message loop 207 // Destroy the channel proxy before shutting down the thread.
231 MessageLoop::current()->Run(); 208 DestroyChannelProxy();
232
233 // cleanup child process
234 EXPECT_TRUE(base::WaitForSingleProcess(
235 process_handle, base::TimeDelta::FromSeconds(5)));
236 base::CloseProcessHandle(process_handle);
237 }
238 thread.Stop(); 209 thread.Stop();
239 } 210 }
240 211
241 class ChannelListenerWithOnConnectedSend : public IPC::Listener { 212 class ChannelListenerWithOnConnectedSend : public GenericChannelListener {
242 public: 213 public:
214 ChannelListenerWithOnConnectedSend() {}
215 virtual ~ChannelListenerWithOnConnectedSend() {}
216
243 virtual void OnChannelConnected(int32 peer_pid) OVERRIDE { 217 virtual void OnChannelConnected(int32 peer_pid) OVERRIDE {
244 SendNextMessage(); 218 SendNextMessage();
245 } 219 }
246
247 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
248 PickleIterator iter(message);
249
250 int ignored;
251 EXPECT_TRUE(iter.ReadInt(&ignored));
252 std::string data;
253 EXPECT_TRUE(iter.ReadString(&data));
254 std::string big_string;
255 EXPECT_TRUE(iter.ReadString(&big_string));
256 EXPECT_EQ(kLongMessageStringNumBytes - 1, big_string.length());
257 SendNextMessage();
258 return true;
259 }
260
261 virtual void OnChannelError() OVERRIDE {
262 // There is a race when closing the channel so the last message may be lost.
263 EXPECT_LE(messages_left_, 1);
264 MessageLoop::current()->Quit();
265 }
266
267 void Init(IPC::Sender* s) {
268 sender_ = s;
269 messages_left_ = 50;
270 }
271
272 private:
273 void SendNextMessage() {
274 if (--messages_left_ == 0) {
275 MessageLoop::current()->Quit();
276 } else {
277 Send(sender_, "Foo");
278 }
279 }
280
281 IPC::Sender* sender_;
282 int messages_left_;
283 }; 220 };
284 221
285 #if defined(OS_WIN) 222 #if defined(OS_WIN)
286 // Acting flakey in Windows. http://crbug.com/129595 223 // Acting flakey in Windows. http://crbug.com/129595
287 #define MAYBE_SendMessageInChannelConnected DISABLED_SendMessageInChannelConnect ed 224 #define MAYBE_SendMessageInChannelConnected DISABLED_SendMessageInChannelConnect ed
288 #else 225 #else
289 #define MAYBE_SendMessageInChannelConnected SendMessageInChannelConnected 226 #define MAYBE_SendMessageInChannelConnected SendMessageInChannelConnected
290 #endif 227 #endif
228 // This tests the case of a listener sending back an event in its
229 // OnChannelConnected handler.
291 TEST_F(IPCChannelTest, MAYBE_SendMessageInChannelConnected) { 230 TEST_F(IPCChannelTest, MAYBE_SendMessageInChannelConnected) {
292 // This tests the case of a listener sending back an event in it's 231 Init("GenericClient");
293 // OnChannelConnected handler.
294 232
295 ChannelListenerWithOnConnectedSend channel_listener; 233 // Set up IPC channel and start client.
296 // Setup IPC channel. 234 ChannelListenerWithOnConnectedSend listener;
297 IPC::Channel channel(kTestClientChannel, IPC::Channel::MODE_SERVER, 235 CreateChannel(&listener);
298 &channel_listener); 236 listener.Init(sender());
299 channel_listener.Init(&channel); 237 ASSERT_TRUE(ConnectChannel());
300 ASSERT_TRUE(channel.Connect()); 238 ASSERT_TRUE(StartClient());
301 239
302 base::ProcessHandle process_handle = SpawnChild(TEST_CLIENT, &channel); 240 Send(sender(), "hello from parent");
303 ASSERT_TRUE(process_handle);
304
305 Send(&channel, "hello from parent");
306 241
307 // Run message loop. 242 // Run message loop.
308 MessageLoop::current()->Run(); 243 MessageLoop::current()->Run();
309 244
310 // Close Channel so client gets its OnChannelError() callback fired. 245 // Close the channel so the client's OnChannelError() gets fired.
311 channel.Close(); 246 channel()->Close();
312 247
313 // Cleanup child process. 248 EXPECT_TRUE(WaitForClientShutdown());
314 EXPECT_TRUE(base::WaitForSingleProcess( 249 DestroyChannel();
315 process_handle, base::TimeDelta::FromSeconds(5)));
316 base::CloseProcessHandle(process_handle);
317 } 250 }
318 251
319 MULTIPROCESS_IPC_TEST_MAIN(RunTestClient) { 252 MULTIPROCESS_IPC_TEST_CLIENT_MAIN(GenericClient) {
320 MessageLoopForIO main_message_loop; 253 MessageLoopForIO main_message_loop;
321 MyChannelListener channel_listener; 254 GenericChannelListener listener;
322 255
323 // setup IPC channel 256 // Set up IPC channel.
324 IPC::Channel chan(kTestClientChannel, IPC::Channel::MODE_CLIENT, 257 IPC::Channel channel(IPCTestBase::GetChannelName("GenericClient"),
325 &channel_listener); 258 IPC::Channel::MODE_CLIENT,
326 CHECK(chan.Connect()); 259 &listener);
327 channel_listener.Init(&chan); 260 CHECK(channel.Connect());
328 Send(&chan, "hello from child"); 261 listener.Init(&channel);
329 // run message loop 262 Send(&channel, "hello from child");
263
330 MessageLoop::current()->Run(); 264 MessageLoop::current()->Run();
331 return 0; 265 return 0;
332 } 266 }
333 267
334 } // namespace 268 } // namespace
OLDNEW
« no previous file with comments | « ipc/ipc.gyp ('k') | ipc/ipc_fuzzing_tests.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698