OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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 #include "base/message_loop/message_loop.h" | 7 #include "base/message_loop/message_loop.h" |
8 #include "base/pickle.h" | 8 #include "base/pickle.h" |
9 #include "base/threading/thread.h" | 9 #include "base/threading/thread.h" |
10 #include "ipc/ipc_message.h" | 10 #include "ipc/ipc_message.h" |
11 #include "ipc/ipc_message_macros.h" | |
12 #include "ipc/ipc_test_base.h" | 11 #include "ipc/ipc_test_base.h" |
13 #include "ipc/message_filter.h" | 12 #include "ipc/message_filter.h" |
14 | 13 |
| 14 // Get basic type definitions. |
| 15 #define IPC_MESSAGE_IMPL |
| 16 #include "ipc/ipc_channel_proxy_unittest_messages.h" |
| 17 |
| 18 // Generate constructors. |
| 19 #include "ipc/struct_constructor_macros.h" |
| 20 #include "ipc/ipc_channel_proxy_unittest_messages.h" |
| 21 |
| 22 // Generate destructors. |
| 23 #include "ipc/struct_destructor_macros.h" |
| 24 #include "ipc/ipc_channel_proxy_unittest_messages.h" |
| 25 |
| 26 // Generate param traits write methods. |
| 27 #include "ipc/param_traits_write_macros.h" |
| 28 namespace IPC { |
| 29 #include "ipc/ipc_channel_proxy_unittest_messages.h" |
| 30 } // namespace IPC |
| 31 |
| 32 // Generate param traits read methods. |
| 33 #include "ipc/param_traits_read_macros.h" |
| 34 namespace IPC { |
| 35 #include "ipc/ipc_channel_proxy_unittest_messages.h" |
| 36 } // namespace IPC |
| 37 |
| 38 // Generate param traits log methods. |
| 39 #include "ipc/param_traits_log_macros.h" |
| 40 namespace IPC { |
| 41 #include "ipc/ipc_channel_proxy_unittest_messages.h" |
| 42 } // namespace IPC |
| 43 |
| 44 |
15 namespace { | 45 namespace { |
16 | 46 |
17 #if defined(IPC_MESSAGE_START) | |
18 #undef IPC_MESSAGE_START | |
19 #endif | |
20 | |
21 enum Command { | |
22 SEND, | |
23 QUIT | |
24 }; | |
25 | |
26 static void Send(IPC::Sender* sender, | |
27 int message_class, | |
28 Command command) { | |
29 const int IPC_MESSAGE_START = message_class; | |
30 IPC::Message* message = new IPC::Message(0, | |
31 IPC_MESSAGE_ID(), | |
32 IPC::Message::PRIORITY_NORMAL); | |
33 message->WriteInt(command); | |
34 sender->Send(message); | |
35 } | |
36 | |
37 class QuitListener : public IPC::Listener { | 47 class QuitListener : public IPC::Listener { |
38 public: | 48 public: |
39 QuitListener() {} | 49 QuitListener() : bad_message_received_(false) {} |
40 virtual ~QuitListener() {} | 50 virtual ~QuitListener() {} |
41 | 51 |
42 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { | 52 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { |
43 PickleIterator iter(message); | 53 IPC_BEGIN_MESSAGE_MAP(QuitListener, message) |
44 | 54 IPC_MESSAGE_HANDLER(WorkerMsg_Quit, OnQuit) |
45 int command = SEND; | 55 IPC_MESSAGE_HANDLER(TestMsg_BadMessage, OnBadMessage) |
46 EXPECT_TRUE(iter.ReadInt(&command)); | 56 IPC_END_MESSAGE_MAP() |
47 if (command == QUIT) | |
48 base::MessageLoop::current()->QuitWhenIdle(); | |
49 | |
50 return true; | 57 return true; |
51 } | 58 } |
| 59 |
| 60 virtual void OnBadMessageReceived(const IPC::Message& message) OVERRIDE { |
| 61 bad_message_received_ = true; |
| 62 } |
| 63 |
| 64 void OnQuit() { |
| 65 base::MessageLoop::current()->QuitWhenIdle(); |
| 66 } |
| 67 |
| 68 void OnBadMessage(const BadType& bad_type) { |
| 69 // Should never be called since IPC wouldn't be deserialized correctly. |
| 70 CHECK(false); |
| 71 } |
| 72 |
| 73 bool bad_message_received_; |
52 }; | 74 }; |
53 | 75 |
54 class ChannelReflectorListener : public IPC::Listener { | 76 class ChannelReflectorListener : public IPC::Listener { |
55 public: | 77 public: |
56 ChannelReflectorListener() : channel_(NULL) {} | 78 ChannelReflectorListener() : channel_(NULL) {} |
57 virtual ~ChannelReflectorListener() {} | 79 virtual ~ChannelReflectorListener() {} |
58 | 80 |
59 void Init(IPC::Channel* channel) { | 81 void Init(IPC::Channel* channel) { |
60 DCHECK(!channel_); | 82 DCHECK(!channel_); |
61 channel_ = channel; | 83 channel_ = channel; |
62 } | 84 } |
63 | 85 |
64 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { | 86 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { |
65 CHECK(channel_); | 87 IPC_BEGIN_MESSAGE_MAP(ChannelReflectorListener, message) |
| 88 IPC_MESSAGE_HANDLER(TestMsg_Bounce, OnTestBounce) |
| 89 IPC_MESSAGE_HANDLER(TestMsg_SendBadMessage, OnSendBadMessage) |
| 90 IPC_MESSAGE_HANDLER(UtilityMsg_Bounce, OnUtilityBounce) |
| 91 IPC_MESSAGE_HANDLER(WorkerMsg_Bounce, OnBounce) |
| 92 IPC_MESSAGE_HANDLER(WorkerMsg_Quit, OnQuit) |
| 93 IPC_END_MESSAGE_MAP() |
| 94 return true; |
| 95 } |
66 | 96 |
67 PickleIterator iter(message); | 97 void OnTestBounce() { |
| 98 channel_->Send(new TestMsg_Bounce()); |
| 99 } |
68 | 100 |
69 int command = SEND; | 101 void OnSendBadMessage() { |
70 EXPECT_TRUE(iter.ReadInt(&command)); | 102 channel_->Send(new TestMsg_BadMessage(BadType())); |
71 if (command == QUIT) { | 103 } |
72 channel_->Send(new IPC::Message(message)); | |
73 base::MessageLoop::current()->QuitWhenIdle(); | |
74 return true; | |
75 } | |
76 | 104 |
77 channel_->Send(new IPC::Message(message)); | 105 void OnUtilityBounce() { |
78 return true; | 106 channel_->Send(new UtilityMsg_Bounce()); |
| 107 } |
| 108 |
| 109 void OnBounce() { |
| 110 channel_->Send(new WorkerMsg_Bounce()); |
| 111 } |
| 112 |
| 113 void OnQuit() { |
| 114 channel_->Send(new WorkerMsg_Quit()); |
| 115 base::MessageLoop::current()->QuitWhenIdle(); |
79 } | 116 } |
80 | 117 |
81 private: | 118 private: |
82 IPC::Channel* channel_; | 119 IPC::Channel* channel_; |
83 }; | 120 }; |
84 | 121 |
85 class MessageCountFilter : public IPC::MessageFilter { | 122 class MessageCountFilter : public IPC::MessageFilter { |
86 public: | 123 public: |
87 enum FilterEvent { | 124 enum FilterEvent { |
88 NONE, | 125 NONE, |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 | 179 |
143 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { | 180 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { |
144 // We should always get the OnFilterAdded and OnChannelConnected events | 181 // We should always get the OnFilterAdded and OnChannelConnected events |
145 // prior to any messages. | 182 // prior to any messages. |
146 EXPECT_EQ(CHANNEL_CONNECTED, last_filter_event_); | 183 EXPECT_EQ(CHANNEL_CONNECTED, last_filter_event_); |
147 | 184 |
148 if (!is_global_filter_) { | 185 if (!is_global_filter_) { |
149 EXPECT_EQ(supported_message_class_, IPC_MESSAGE_CLASS(message)); | 186 EXPECT_EQ(supported_message_class_, IPC_MESSAGE_CLASS(message)); |
150 } | 187 } |
151 ++messages_received_; | 188 ++messages_received_; |
152 return message_filtering_enabled_; | 189 |
| 190 if (!message_filtering_enabled_) |
| 191 return false; |
| 192 |
| 193 bool handled = true; |
| 194 IPC_BEGIN_MESSAGE_MAP(MessageCountFilter, message) |
| 195 IPC_MESSAGE_HANDLER(TestMsg_BadMessage, OnBadMessage) |
| 196 IPC_MESSAGE_UNHANDLED(handled = false) |
| 197 IPC_END_MESSAGE_MAP() |
| 198 return handled; |
| 199 } |
| 200 |
| 201 void OnBadMessage(const BadType& bad_type) { |
| 202 // Should never be called since IPC wouldn't be deserialized correctly. |
| 203 CHECK(false); |
153 } | 204 } |
154 | 205 |
155 virtual bool GetSupportedMessageClasses( | 206 virtual bool GetSupportedMessageClasses( |
156 std::vector<uint32>* supported_message_classes) const OVERRIDE { | 207 std::vector<uint32>* supported_message_classes) const OVERRIDE { |
157 if (is_global_filter_) | 208 if (is_global_filter_) |
158 return false; | 209 return false; |
159 supported_message_classes->push_back(supported_message_class_); | 210 supported_message_classes->push_back(supported_message_class_); |
160 return true; | 211 return true; |
161 } | 212 } |
162 | 213 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 } | 251 } |
201 | 252 |
202 virtual void TearDown() { | 253 virtual void TearDown() { |
203 DestroyChannelProxy(); | 254 DestroyChannelProxy(); |
204 thread_.reset(); | 255 thread_.reset(); |
205 listener_.reset(); | 256 listener_.reset(); |
206 IPCTestBase::TearDown(); | 257 IPCTestBase::TearDown(); |
207 } | 258 } |
208 | 259 |
209 void SendQuitMessageAndWaitForIdle() { | 260 void SendQuitMessageAndWaitForIdle() { |
210 Send(sender(), -1, QUIT); | 261 sender()->Send(new WorkerMsg_Quit); |
211 base::MessageLoop::current()->Run(); | 262 base::MessageLoop::current()->Run(); |
212 EXPECT_TRUE(WaitForClientShutdown()); | 263 EXPECT_TRUE(WaitForClientShutdown()); |
213 } | 264 } |
214 | 265 |
| 266 bool DidListenerGetBadMessage() { |
| 267 return listener_->bad_message_received_; |
| 268 } |
| 269 |
215 private: | 270 private: |
216 scoped_ptr<base::Thread> thread_; | 271 scoped_ptr<base::Thread> thread_; |
217 scoped_ptr<QuitListener> listener_; | 272 scoped_ptr<QuitListener> listener_; |
218 }; | 273 }; |
219 | 274 |
220 TEST_F(IPCChannelProxyTest, MessageClassFilters) { | 275 TEST_F(IPCChannelProxyTest, MessageClassFilters) { |
221 // Construct a filter per message class. | 276 // Construct a filter per message class. |
222 std::vector<scoped_refptr<MessageCountFilter> > class_filters; | 277 std::vector<scoped_refptr<MessageCountFilter> > class_filters; |
223 for (uint32 i = 0; i < LastIPCMsgStart; ++i) { | 278 class_filters.push_back(make_scoped_refptr( |
224 class_filters.push_back(make_scoped_refptr( | 279 new MessageCountFilter(TestMsgStart))); |
225 new MessageCountFilter(i))); | 280 class_filters.push_back(make_scoped_refptr( |
226 channel_proxy()->AddFilter(class_filters.back().get()); | 281 new MessageCountFilter(UtilityMsgStart))); |
227 } | 282 for (size_t i = 0; i < class_filters.size(); ++i) |
| 283 channel_proxy()->AddFilter(class_filters[i].get()); |
228 | 284 |
229 // Send a message for each class; each filter should receive just one message. | 285 // Send a message for each class; each filter should receive just one message. |
230 for (uint32 i = 0; i < LastIPCMsgStart; ++i) | 286 sender()->Send(new TestMsg_Bounce()); |
231 Send(sender(), i, SEND); | 287 sender()->Send(new UtilityMsg_Bounce()); |
232 | 288 |
233 // Send some messages not assigned to a specific or valid message class. | 289 // Send some messages not assigned to a specific or valid message class. |
234 Send(sender(), -1, SEND); | 290 sender()->Send(new WorkerMsg_Bounce); |
235 Send(sender(), LastIPCMsgStart, SEND); | |
236 Send(sender(), LastIPCMsgStart + 1, SEND); | |
237 | 291 |
238 // Each filter should have received just the one sent message of the | 292 // Each filter should have received just the one sent message of the |
239 // corresponding class. | 293 // corresponding class. |
240 SendQuitMessageAndWaitForIdle(); | 294 SendQuitMessageAndWaitForIdle(); |
241 for (size_t i = 0; i < class_filters.size(); ++i) | 295 for (size_t i = 0; i < class_filters.size(); ++i) |
242 EXPECT_EQ(1U, class_filters[i]->messages_received()); | 296 EXPECT_EQ(1U, class_filters[i]->messages_received()); |
243 } | 297 } |
244 | 298 |
245 TEST_F(IPCChannelProxyTest, GlobalAndMessageClassFilters) { | 299 TEST_F(IPCChannelProxyTest, GlobalAndMessageClassFilters) { |
246 // Add a class and global filter. | 300 // Add a class and global filter. |
247 const int kMessageClass = 7; | |
248 scoped_refptr<MessageCountFilter> class_filter( | 301 scoped_refptr<MessageCountFilter> class_filter( |
249 new MessageCountFilter(kMessageClass)); | 302 new MessageCountFilter(TestMsgStart)); |
250 class_filter->set_message_filtering_enabled(false); | 303 class_filter->set_message_filtering_enabled(false); |
251 channel_proxy()->AddFilter(class_filter.get()); | 304 channel_proxy()->AddFilter(class_filter.get()); |
252 | 305 |
253 scoped_refptr<MessageCountFilter> global_filter(new MessageCountFilter()); | 306 scoped_refptr<MessageCountFilter> global_filter(new MessageCountFilter()); |
254 global_filter->set_message_filtering_enabled(false); | 307 global_filter->set_message_filtering_enabled(false); |
255 channel_proxy()->AddFilter(global_filter.get()); | 308 channel_proxy()->AddFilter(global_filter.get()); |
256 | 309 |
257 // A message of class |kMessageClass| should be seen by both the global | 310 // A message of class Test should be seen by both the global filter and |
258 // filter and |kMessageClass|-specific filter. | 311 // Test-specific filter. |
259 Send(sender(), kMessageClass, SEND); | 312 sender()->Send(new TestMsg_Bounce); |
260 | 313 |
261 // A message of a different class should be seen only by the global filter. | 314 // A message of a different class should be seen only by the global filter. |
262 Send(sender(), kMessageClass + 1, SEND); | 315 sender()->Send(new UtilityMsg_Bounce); |
263 | 316 |
264 // Flush all messages. | 317 // Flush all messages. |
265 SendQuitMessageAndWaitForIdle(); | 318 SendQuitMessageAndWaitForIdle(); |
266 | 319 |
267 // The class filter should have received only the class-specific message. | 320 // The class filter should have received only the class-specific message. |
268 EXPECT_EQ(1U, class_filter->messages_received()); | 321 EXPECT_EQ(1U, class_filter->messages_received()); |
269 | 322 |
270 // The global filter should have received both SEND messages, as well as the | 323 // The global filter should have received both messages, as well as the final |
271 // final QUIT message. | 324 // QUIT message. |
272 EXPECT_EQ(3U, global_filter->messages_received()); | 325 EXPECT_EQ(3U, global_filter->messages_received()); |
273 } | 326 } |
274 | 327 |
275 TEST_F(IPCChannelProxyTest, FilterRemoval) { | 328 TEST_F(IPCChannelProxyTest, FilterRemoval) { |
276 // Add a class and global filter. | 329 // Add a class and global filter. |
277 const int kMessageClass = 7; | |
278 scoped_refptr<MessageCountFilter> class_filter( | 330 scoped_refptr<MessageCountFilter> class_filter( |
279 new MessageCountFilter(kMessageClass)); | 331 new MessageCountFilter(TestMsgStart)); |
280 scoped_refptr<MessageCountFilter> global_filter(new MessageCountFilter()); | 332 scoped_refptr<MessageCountFilter> global_filter(new MessageCountFilter()); |
281 | 333 |
282 // Add and remove both types of filters. | 334 // Add and remove both types of filters. |
283 channel_proxy()->AddFilter(class_filter.get()); | 335 channel_proxy()->AddFilter(class_filter.get()); |
284 channel_proxy()->AddFilter(global_filter.get()); | 336 channel_proxy()->AddFilter(global_filter.get()); |
285 channel_proxy()->RemoveFilter(global_filter.get()); | 337 channel_proxy()->RemoveFilter(global_filter.get()); |
286 channel_proxy()->RemoveFilter(class_filter.get()); | 338 channel_proxy()->RemoveFilter(class_filter.get()); |
287 | 339 |
288 // Send some messages; they should not be seen by either filter. | 340 // Send some messages; they should not be seen by either filter. |
289 Send(sender(), 0, SEND); | 341 sender()->Send(new TestMsg_Bounce); |
290 Send(sender(), kMessageClass, SEND); | 342 sender()->Send(new UtilityMsg_Bounce); |
291 | 343 |
292 // Ensure that the filters were removed and did not receive any messages. | 344 // Ensure that the filters were removed and did not receive any messages. |
293 SendQuitMessageAndWaitForIdle(); | 345 SendQuitMessageAndWaitForIdle(); |
294 EXPECT_EQ(MessageCountFilter::FILTER_REMOVED, | 346 EXPECT_EQ(MessageCountFilter::FILTER_REMOVED, |
295 global_filter->last_filter_event()); | 347 global_filter->last_filter_event()); |
296 EXPECT_EQ(MessageCountFilter::FILTER_REMOVED, | 348 EXPECT_EQ(MessageCountFilter::FILTER_REMOVED, |
297 class_filter->last_filter_event()); | 349 class_filter->last_filter_event()); |
298 EXPECT_EQ(0U, class_filter->messages_received()); | 350 EXPECT_EQ(0U, class_filter->messages_received()); |
299 EXPECT_EQ(0U, global_filter->messages_received()); | 351 EXPECT_EQ(0U, global_filter->messages_received()); |
300 } | 352 } |
301 | 353 |
| 354 // The test that follow trigger DCHECKS in debug build. |
| 355 #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON) |
| 356 |
| 357 TEST_F(IPCChannelProxyTest, BadMessageOnListenerThread) { |
| 358 scoped_refptr<MessageCountFilter> class_filter( |
| 359 new MessageCountFilter(TestMsgStart)); |
| 360 class_filter->set_message_filtering_enabled(false); |
| 361 channel_proxy()->AddFilter(class_filter.get()); |
| 362 |
| 363 sender()->Send(new TestMsg_SendBadMessage()); |
| 364 |
| 365 SendQuitMessageAndWaitForIdle(); |
| 366 EXPECT_TRUE(DidListenerGetBadMessage()); |
| 367 } |
| 368 |
| 369 TEST_F(IPCChannelProxyTest, BadMessageOnIPCThread) { |
| 370 scoped_refptr<MessageCountFilter> class_filter( |
| 371 new MessageCountFilter(TestMsgStart)); |
| 372 class_filter->set_message_filtering_enabled(true); |
| 373 channel_proxy()->AddFilter(class_filter.get()); |
| 374 |
| 375 sender()->Send(new TestMsg_SendBadMessage()); |
| 376 |
| 377 SendQuitMessageAndWaitForIdle(); |
| 378 EXPECT_TRUE(DidListenerGetBadMessage()); |
| 379 } |
| 380 |
| 381 class IPCChannelBadMessageTest : public IPCTestBase { |
| 382 public: |
| 383 IPCChannelBadMessageTest() {} |
| 384 virtual ~IPCChannelBadMessageTest() {} |
| 385 |
| 386 virtual void SetUp() OVERRIDE { |
| 387 IPCTestBase::SetUp(); |
| 388 |
| 389 Init("ChannelProxyClient"); |
| 390 |
| 391 listener_.reset(new QuitListener()); |
| 392 CreateChannel(listener_.get()); |
| 393 ASSERT_TRUE(ConnectChannel()); |
| 394 |
| 395 ASSERT_TRUE(StartClient()); |
| 396 } |
| 397 |
| 398 virtual void TearDown() { |
| 399 listener_.reset(); |
| 400 IPCTestBase::TearDown(); |
| 401 } |
| 402 |
| 403 void SendQuitMessageAndWaitForIdle() { |
| 404 sender()->Send(new WorkerMsg_Quit); |
| 405 base::MessageLoop::current()->Run(); |
| 406 EXPECT_TRUE(WaitForClientShutdown()); |
| 407 } |
| 408 |
| 409 bool DidListenerGetBadMessage() { |
| 410 return listener_->bad_message_received_; |
| 411 } |
| 412 |
| 413 private: |
| 414 scoped_ptr<QuitListener> listener_; |
| 415 }; |
| 416 |
| 417 TEST_F(IPCChannelBadMessageTest, BadMessage) { |
| 418 sender()->Send(new TestMsg_SendBadMessage()); |
| 419 SendQuitMessageAndWaitForIdle(); |
| 420 EXPECT_TRUE(DidListenerGetBadMessage()); |
| 421 } |
| 422 |
| 423 #endif |
| 424 |
302 MULTIPROCESS_IPC_TEST_CLIENT_MAIN(ChannelProxyClient) { | 425 MULTIPROCESS_IPC_TEST_CLIENT_MAIN(ChannelProxyClient) { |
303 base::MessageLoopForIO main_message_loop; | 426 base::MessageLoopForIO main_message_loop; |
304 ChannelReflectorListener listener; | 427 ChannelReflectorListener listener; |
305 IPC::Channel channel(IPCTestBase::GetChannelName("ChannelProxyClient"), | 428 IPC::Channel channel(IPCTestBase::GetChannelName("ChannelProxyClient"), |
306 IPC::Channel::MODE_CLIENT, | 429 IPC::Channel::MODE_CLIENT, |
307 &listener); | 430 &listener); |
308 CHECK(channel.Connect()); | 431 CHECK(channel.Connect()); |
309 listener.Init(&channel); | 432 listener.Init(&channel); |
310 | 433 |
311 base::MessageLoop::current()->Run(); | 434 base::MessageLoop::current()->Run(); |
312 return 0; | 435 return 0; |
313 } | 436 } |
314 | 437 |
315 } // namespace | 438 } // namespace |
OLD | NEW |