blob: 7c5c8a70fca2c15dd01d151ee08c88b7e3d28348 [file] [log] [blame]
[email protected]b51352a2014-02-26 05:18:041// Copyright 2014 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 "build/build_config.h"
6
[email protected]b51352a2014-02-26 05:18:047#include "base/pickle.h"
8#include "base/threading/thread.h"
9#include "ipc/ipc_message.h"
[email protected]b51352a2014-02-26 05:18:0410#include "ipc/ipc_test_base.h"
[email protected]74122042014-04-25 00:07:3011#include "ipc/message_filter.h"
[email protected]b51352a2014-02-26 05:18:0412
[email protected]8e9ba762014-05-21 16:39:1813// Get basic type definitions.
14#define IPC_MESSAGE_IMPL
15#include "ipc/ipc_channel_proxy_unittest_messages.h"
16
17// Generate constructors.
18#include "ipc/struct_constructor_macros.h"
19#include "ipc/ipc_channel_proxy_unittest_messages.h"
20
21// Generate destructors.
22#include "ipc/struct_destructor_macros.h"
23#include "ipc/ipc_channel_proxy_unittest_messages.h"
24
25// Generate param traits write methods.
26#include "ipc/param_traits_write_macros.h"
27namespace IPC {
28#include "ipc/ipc_channel_proxy_unittest_messages.h"
29} // namespace IPC
30
31// Generate param traits read methods.
32#include "ipc/param_traits_read_macros.h"
33namespace IPC {
34#include "ipc/ipc_channel_proxy_unittest_messages.h"
35} // namespace IPC
36
37// Generate param traits log methods.
38#include "ipc/param_traits_log_macros.h"
39namespace IPC {
40#include "ipc/ipc_channel_proxy_unittest_messages.h"
41} // namespace IPC
42
43
[email protected]b51352a2014-02-26 05:18:0444namespace {
45
[email protected]b51352a2014-02-26 05:18:0446class QuitListener : public IPC::Listener {
47 public:
[email protected]8e9ba762014-05-21 16:39:1848 QuitListener() : bad_message_received_(false) {}
[email protected]b51352a2014-02-26 05:18:0449
dchengfe61fca2014-10-22 02:29:5250 bool OnMessageReceived(const IPC::Message& message) override {
[email protected]8e9ba762014-05-21 16:39:1851 IPC_BEGIN_MESSAGE_MAP(QuitListener, message)
52 IPC_MESSAGE_HANDLER(WorkerMsg_Quit, OnQuit)
53 IPC_MESSAGE_HANDLER(TestMsg_BadMessage, OnBadMessage)
54 IPC_END_MESSAGE_MAP()
[email protected]b51352a2014-02-26 05:18:0455 return true;
56 }
[email protected]8e9ba762014-05-21 16:39:1857
dchengfe61fca2014-10-22 02:29:5258 void OnBadMessageReceived(const IPC::Message& message) override {
[email protected]8e9ba762014-05-21 16:39:1859 bad_message_received_ = true;
60 }
61
62 void OnQuit() {
63 base::MessageLoop::current()->QuitWhenIdle();
64 }
65
66 void OnBadMessage(const BadType& bad_type) {
67 // Should never be called since IPC wouldn't be deserialized correctly.
68 CHECK(false);
69 }
70
71 bool bad_message_received_;
[email protected]b51352a2014-02-26 05:18:0472};
73
74class ChannelReflectorListener : public IPC::Listener {
75 public:
76 ChannelReflectorListener() : channel_(NULL) {}
[email protected]b51352a2014-02-26 05:18:0477
78 void Init(IPC::Channel* channel) {
79 DCHECK(!channel_);
80 channel_ = channel;
81 }
82
dchengfe61fca2014-10-22 02:29:5283 bool OnMessageReceived(const IPC::Message& message) override {
[email protected]8e9ba762014-05-21 16:39:1884 IPC_BEGIN_MESSAGE_MAP(ChannelReflectorListener, message)
85 IPC_MESSAGE_HANDLER(TestMsg_Bounce, OnTestBounce)
86 IPC_MESSAGE_HANDLER(TestMsg_SendBadMessage, OnSendBadMessage)
87 IPC_MESSAGE_HANDLER(UtilityMsg_Bounce, OnUtilityBounce)
88 IPC_MESSAGE_HANDLER(WorkerMsg_Bounce, OnBounce)
89 IPC_MESSAGE_HANDLER(WorkerMsg_Quit, OnQuit)
90 IPC_END_MESSAGE_MAP()
[email protected]b51352a2014-02-26 05:18:0491 return true;
92 }
93
[email protected]8e9ba762014-05-21 16:39:1894 void OnTestBounce() {
95 channel_->Send(new TestMsg_Bounce());
96 }
97
98 void OnSendBadMessage() {
99 channel_->Send(new TestMsg_BadMessage(BadType()));
100 }
101
102 void OnUtilityBounce() {
103 channel_->Send(new UtilityMsg_Bounce());
104 }
105
106 void OnBounce() {
107 channel_->Send(new WorkerMsg_Bounce());
108 }
109
110 void OnQuit() {
111 channel_->Send(new WorkerMsg_Quit());
112 base::MessageLoop::current()->QuitWhenIdle();
113 }
114
[email protected]b51352a2014-02-26 05:18:04115 private:
116 IPC::Channel* channel_;
117};
118
[email protected]74122042014-04-25 00:07:30119class MessageCountFilter : public IPC::MessageFilter {
[email protected]b51352a2014-02-26 05:18:04120 public:
[email protected]21bb77b2014-04-23 23:54:53121 enum FilterEvent {
122 NONE,
123 FILTER_ADDED,
124 CHANNEL_CONNECTED,
125 CHANNEL_ERROR,
126 CHANNEL_CLOSING,
127 FILTER_REMOVED
128 };
[email protected]b51352a2014-02-26 05:18:04129 MessageCountFilter()
130 : messages_received_(0),
131 supported_message_class_(0),
132 is_global_filter_(true),
[email protected]21bb77b2014-04-23 23:54:53133 last_filter_event_(NONE),
[email protected]b51352a2014-02-26 05:18:04134 message_filtering_enabled_(false) {}
135
tfarina10a5c062015-09-04 18:47:57136 MessageCountFilter(uint32_t supported_message_class)
[email protected]b51352a2014-02-26 05:18:04137 : messages_received_(0),
138 supported_message_class_(supported_message_class),
139 is_global_filter_(false),
[email protected]21bb77b2014-04-23 23:54:53140 last_filter_event_(NONE),
[email protected]b51352a2014-02-26 05:18:04141 message_filtering_enabled_(false) {}
142
dchengfe61fca2014-10-22 02:29:52143 void OnFilterAdded(IPC::Sender* sender) override {
[email protected]d1549b82014-06-13 06:07:14144 EXPECT_TRUE(sender);
[email protected]21bb77b2014-04-23 23:54:53145 EXPECT_EQ(NONE, last_filter_event_);
146 last_filter_event_ = FILTER_ADDED;
147 }
148
dchengfe61fca2014-10-22 02:29:52149 void OnChannelConnected(int32_t peer_pid) override {
[email protected]21bb77b2014-04-23 23:54:53150 EXPECT_EQ(FILTER_ADDED, last_filter_event_);
151 EXPECT_NE(static_cast<int32_t>(base::kNullProcessId), peer_pid);
152 last_filter_event_ = CHANNEL_CONNECTED;
153 }
154
dchengfe61fca2014-10-22 02:29:52155 void OnChannelError() override {
[email protected]21bb77b2014-04-23 23:54:53156 EXPECT_EQ(CHANNEL_CONNECTED, last_filter_event_);
157 last_filter_event_ = CHANNEL_ERROR;
158 }
159
dchengfe61fca2014-10-22 02:29:52160 void OnChannelClosing() override {
[email protected]21bb77b2014-04-23 23:54:53161 // We may or may not have gotten OnChannelError; if not, the last event has
162 // to be OnChannelConnected.
163 if (last_filter_event_ != CHANNEL_ERROR)
164 EXPECT_EQ(CHANNEL_CONNECTED, last_filter_event_);
165 last_filter_event_ = CHANNEL_CLOSING;
166 }
167
dchengfe61fca2014-10-22 02:29:52168 void OnFilterRemoved() override {
[email protected]21bb77b2014-04-23 23:54:53169 // If the channel didn't get a chance to connect, we might see the
170 // OnFilterRemoved event with no other events preceding it. We still want
171 // OnFilterRemoved to be called to allow for deleting the Filter.
172 if (last_filter_event_ != NONE)
173 EXPECT_EQ(CHANNEL_CLOSING, last_filter_event_);
174 last_filter_event_ = FILTER_REMOVED;
[email protected]b51352a2014-02-26 05:18:04175 }
176
dchengfe61fca2014-10-22 02:29:52177 bool OnMessageReceived(const IPC::Message& message) override {
[email protected]21bb77b2014-04-23 23:54:53178 // We should always get the OnFilterAdded and OnChannelConnected events
179 // prior to any messages.
180 EXPECT_EQ(CHANNEL_CONNECTED, last_filter_event_);
181
[email protected]b51352a2014-02-26 05:18:04182 if (!is_global_filter_) {
183 EXPECT_EQ(supported_message_class_, IPC_MESSAGE_CLASS(message));
184 }
185 ++messages_received_;
[email protected]8e9ba762014-05-21 16:39:18186
187 if (!message_filtering_enabled_)
188 return false;
189
190 bool handled = true;
191 IPC_BEGIN_MESSAGE_MAP(MessageCountFilter, message)
192 IPC_MESSAGE_HANDLER(TestMsg_BadMessage, OnBadMessage)
193 IPC_MESSAGE_UNHANDLED(handled = false)
194 IPC_END_MESSAGE_MAP()
195 return handled;
196 }
197
198 void OnBadMessage(const BadType& bad_type) {
199 // Should never be called since IPC wouldn't be deserialized correctly.
200 CHECK(false);
[email protected]b51352a2014-02-26 05:18:04201 }
202
dchengfe61fca2014-10-22 02:29:52203 bool GetSupportedMessageClasses(
tfarina10a5c062015-09-04 18:47:57204 std::vector<uint32_t>* supported_message_classes) const override {
[email protected]b51352a2014-02-26 05:18:04205 if (is_global_filter_)
206 return false;
207 supported_message_classes->push_back(supported_message_class_);
208 return true;
209 }
210
211 void set_message_filtering_enabled(bool enabled) {
212 message_filtering_enabled_ = enabled;
213 }
214
215 size_t messages_received() const { return messages_received_; }
[email protected]21bb77b2014-04-23 23:54:53216 FilterEvent last_filter_event() const { return last_filter_event_; }
[email protected]b51352a2014-02-26 05:18:04217
218 private:
dchengfe61fca2014-10-22 02:29:52219 ~MessageCountFilter() override {}
[email protected]b51352a2014-02-26 05:18:04220
221 size_t messages_received_;
tfarina10a5c062015-09-04 18:47:57222 uint32_t supported_message_class_;
[email protected]b51352a2014-02-26 05:18:04223 bool is_global_filter_;
[email protected]21bb77b2014-04-23 23:54:53224
225 FilterEvent last_filter_event_;
[email protected]b51352a2014-02-26 05:18:04226 bool message_filtering_enabled_;
227};
228
229class IPCChannelProxyTest : public IPCTestBase {
230 public:
231 IPCChannelProxyTest() {}
dcheng1c3d9ac2014-12-23 19:59:59232 ~IPCChannelProxyTest() override {}
[email protected]b51352a2014-02-26 05:18:04233
dcheng1c3d9ac2014-12-23 19:59:59234 void SetUp() override {
[email protected]b51352a2014-02-26 05:18:04235 IPCTestBase::SetUp();
236
237 Init("ChannelProxyClient");
238
239 thread_.reset(new base::Thread("ChannelProxyTestServerThread"));
240 base::Thread::Options options;
241 options.message_loop_type = base::MessageLoop::TYPE_IO;
242 thread_->StartWithOptions(options);
243
244 listener_.reset(new QuitListener());
skyostile687bdff2015-05-12 11:29:21245 CreateChannelProxy(listener_.get(), thread_->task_runner().get());
[email protected]b51352a2014-02-26 05:18:04246
247 ASSERT_TRUE(StartClient());
248 }
249
dcheng1c3d9ac2014-12-23 19:59:59250 void TearDown() override {
[email protected]b51352a2014-02-26 05:18:04251 DestroyChannelProxy();
252 thread_.reset();
253 listener_.reset();
254 IPCTestBase::TearDown();
255 }
256
257 void SendQuitMessageAndWaitForIdle() {
[email protected]8e9ba762014-05-21 16:39:18258 sender()->Send(new WorkerMsg_Quit);
[email protected]b51352a2014-02-26 05:18:04259 base::MessageLoop::current()->Run();
260 EXPECT_TRUE(WaitForClientShutdown());
261 }
262
[email protected]8e9ba762014-05-21 16:39:18263 bool DidListenerGetBadMessage() {
264 return listener_->bad_message_received_;
265 }
266
[email protected]b51352a2014-02-26 05:18:04267 private:
268 scoped_ptr<base::Thread> thread_;
269 scoped_ptr<QuitListener> listener_;
270};
271
tfarina8514f0d2015-07-28 14:41:47272#if defined(OS_ANDROID)
273#define MAYBE_MessageClassFilters DISABLED_MessageClassFilters
274#else
275#define MAYBE_MessageClassFilters MessageClassFilters
276#endif
277TEST_F(IPCChannelProxyTest, MAYBE_MessageClassFilters) {
[email protected]b51352a2014-02-26 05:18:04278 // Construct a filter per message class.
279 std::vector<scoped_refptr<MessageCountFilter> > class_filters;
[email protected]8e9ba762014-05-21 16:39:18280 class_filters.push_back(make_scoped_refptr(
281 new MessageCountFilter(TestMsgStart)));
282 class_filters.push_back(make_scoped_refptr(
283 new MessageCountFilter(UtilityMsgStart)));
284 for (size_t i = 0; i < class_filters.size(); ++i)
285 channel_proxy()->AddFilter(class_filters[i].get());
[email protected]b51352a2014-02-26 05:18:04286
287 // Send a message for each class; each filter should receive just one message.
[email protected]8e9ba762014-05-21 16:39:18288 sender()->Send(new TestMsg_Bounce());
289 sender()->Send(new UtilityMsg_Bounce());
[email protected]b51352a2014-02-26 05:18:04290
291 // Send some messages not assigned to a specific or valid message class.
[email protected]8e9ba762014-05-21 16:39:18292 sender()->Send(new WorkerMsg_Bounce);
[email protected]b51352a2014-02-26 05:18:04293
294 // Each filter should have received just the one sent message of the
295 // corresponding class.
296 SendQuitMessageAndWaitForIdle();
297 for (size_t i = 0; i < class_filters.size(); ++i)
298 EXPECT_EQ(1U, class_filters[i]->messages_received());
299}
300
tfarina8514f0d2015-07-28 14:41:47301#if defined(OS_ANDROID)
302#define MAYBE_GlobalAndMessageClassFilters DISABLED_GlobalAndMessageClassFilters
303#else
304#define MAYBE_GlobalAndMessageClassFilters GlobalAndMessageClassFilters
305#endif
306TEST_F(IPCChannelProxyTest, MAYBE_GlobalAndMessageClassFilters) {
[email protected]b51352a2014-02-26 05:18:04307 // Add a class and global filter.
[email protected]b51352a2014-02-26 05:18:04308 scoped_refptr<MessageCountFilter> class_filter(
[email protected]8e9ba762014-05-21 16:39:18309 new MessageCountFilter(TestMsgStart));
[email protected]b51352a2014-02-26 05:18:04310 class_filter->set_message_filtering_enabled(false);
311 channel_proxy()->AddFilter(class_filter.get());
312
313 scoped_refptr<MessageCountFilter> global_filter(new MessageCountFilter());
314 global_filter->set_message_filtering_enabled(false);
315 channel_proxy()->AddFilter(global_filter.get());
316
[email protected]8e9ba762014-05-21 16:39:18317 // A message of class Test should be seen by both the global filter and
318 // Test-specific filter.
319 sender()->Send(new TestMsg_Bounce);
[email protected]b51352a2014-02-26 05:18:04320
321 // A message of a different class should be seen only by the global filter.
[email protected]8e9ba762014-05-21 16:39:18322 sender()->Send(new UtilityMsg_Bounce);
[email protected]b51352a2014-02-26 05:18:04323
324 // Flush all messages.
325 SendQuitMessageAndWaitForIdle();
326
327 // The class filter should have received only the class-specific message.
328 EXPECT_EQ(1U, class_filter->messages_received());
329
[email protected]8e9ba762014-05-21 16:39:18330 // The global filter should have received both messages, as well as the final
331 // QUIT message.
[email protected]b51352a2014-02-26 05:18:04332 EXPECT_EQ(3U, global_filter->messages_received());
333}
334
tfarina8514f0d2015-07-28 14:41:47335#if defined(OS_ANDROID)
336#define MAYBE_FilterRemoval DISABLED_FilterRemoval
337#else
338#define MAYBE_FilterRemoval FilterRemoval
339#endif
340TEST_F(IPCChannelProxyTest, MAYBE_FilterRemoval) {
[email protected]b51352a2014-02-26 05:18:04341 // Add a class and global filter.
[email protected]b51352a2014-02-26 05:18:04342 scoped_refptr<MessageCountFilter> class_filter(
[email protected]8e9ba762014-05-21 16:39:18343 new MessageCountFilter(TestMsgStart));
[email protected]b51352a2014-02-26 05:18:04344 scoped_refptr<MessageCountFilter> global_filter(new MessageCountFilter());
345
346 // Add and remove both types of filters.
347 channel_proxy()->AddFilter(class_filter.get());
348 channel_proxy()->AddFilter(global_filter.get());
349 channel_proxy()->RemoveFilter(global_filter.get());
350 channel_proxy()->RemoveFilter(class_filter.get());
351
352 // Send some messages; they should not be seen by either filter.
[email protected]8e9ba762014-05-21 16:39:18353 sender()->Send(new TestMsg_Bounce);
354 sender()->Send(new UtilityMsg_Bounce);
[email protected]b51352a2014-02-26 05:18:04355
356 // Ensure that the filters were removed and did not receive any messages.
357 SendQuitMessageAndWaitForIdle();
[email protected]21bb77b2014-04-23 23:54:53358 EXPECT_EQ(MessageCountFilter::FILTER_REMOVED,
359 global_filter->last_filter_event());
360 EXPECT_EQ(MessageCountFilter::FILTER_REMOVED,
361 class_filter->last_filter_event());
[email protected]b51352a2014-02-26 05:18:04362 EXPECT_EQ(0U, class_filter->messages_received());
363 EXPECT_EQ(0U, global_filter->messages_received());
364}
365
[email protected]8e9ba762014-05-21 16:39:18366// The test that follow trigger DCHECKS in debug build.
367#if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
368
369TEST_F(IPCChannelProxyTest, BadMessageOnListenerThread) {
370 scoped_refptr<MessageCountFilter> class_filter(
371 new MessageCountFilter(TestMsgStart));
372 class_filter->set_message_filtering_enabled(false);
373 channel_proxy()->AddFilter(class_filter.get());
374
375 sender()->Send(new TestMsg_SendBadMessage());
376
377 SendQuitMessageAndWaitForIdle();
378 EXPECT_TRUE(DidListenerGetBadMessage());
379}
380
381TEST_F(IPCChannelProxyTest, BadMessageOnIPCThread) {
382 scoped_refptr<MessageCountFilter> class_filter(
383 new MessageCountFilter(TestMsgStart));
384 class_filter->set_message_filtering_enabled(true);
385 channel_proxy()->AddFilter(class_filter.get());
386
387 sender()->Send(new TestMsg_SendBadMessage());
388
389 SendQuitMessageAndWaitForIdle();
390 EXPECT_TRUE(DidListenerGetBadMessage());
391}
392
393class IPCChannelBadMessageTest : public IPCTestBase {
394 public:
Daniel Cheng3e6beaa72014-12-31 03:48:36395 void SetUp() override {
[email protected]8e9ba762014-05-21 16:39:18396 IPCTestBase::SetUp();
397
398 Init("ChannelProxyClient");
399
400 listener_.reset(new QuitListener());
401 CreateChannel(listener_.get());
402 ASSERT_TRUE(ConnectChannel());
403
404 ASSERT_TRUE(StartClient());
405 }
406
Daniel Cheng3e6beaa72014-12-31 03:48:36407 void TearDown() override {
[email protected]8e9ba762014-05-21 16:39:18408 listener_.reset();
409 IPCTestBase::TearDown();
410 }
411
412 void SendQuitMessageAndWaitForIdle() {
413 sender()->Send(new WorkerMsg_Quit);
414 base::MessageLoop::current()->Run();
415 EXPECT_TRUE(WaitForClientShutdown());
416 }
417
418 bool DidListenerGetBadMessage() {
419 return listener_->bad_message_received_;
420 }
421
422 private:
423 scoped_ptr<QuitListener> listener_;
424};
425
[email protected]0f415a82014-05-27 01:54:53426#if !defined(OS_WIN)
427 // TODO(jam): for some reason this is flaky on win buildbots.
[email protected]8e9ba762014-05-21 16:39:18428TEST_F(IPCChannelBadMessageTest, BadMessage) {
429 sender()->Send(new TestMsg_SendBadMessage());
430 SendQuitMessageAndWaitForIdle();
431 EXPECT_TRUE(DidListenerGetBadMessage());
432}
[email protected]0f415a82014-05-27 01:54:53433#endif
[email protected]8e9ba762014-05-21 16:39:18434
435#endif
436
[email protected]b51352a2014-02-26 05:18:04437MULTIPROCESS_IPC_TEST_CLIENT_MAIN(ChannelProxyClient) {
438 base::MessageLoopForIO main_message_loop;
439 ChannelReflectorListener listener;
[email protected]e482111a82014-05-30 03:58:59440 scoped_ptr<IPC::Channel> channel(IPC::Channel::CreateClient(
erikchen30dc2812015-09-24 03:26:38441 IPCTestBase::GetChannelName("ChannelProxyClient"), &listener));
[email protected]e482111a82014-05-30 03:58:59442 CHECK(channel->Connect());
443 listener.Init(channel.get());
[email protected]b51352a2014-02-26 05:18:04444
445 base::MessageLoop::current()->Run();
446 return 0;
447}
448
449} // namespace