blob: 01b895582cbbde35d5b842e5d5def56ee0c0a7f9 [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
avi246998d82015-12-22 02:39:047#include <stddef.h>
8#include <stdint.h>
danakj03de39b22016-04-23 04:21:099#include <memory>
avi246998d82015-12-22 02:39:0410
gabf64a25e2017-05-12 19:42:5611#include "base/message_loop/message_loop.h"
[email protected]b51352a2014-02-26 05:18:0412#include "base/pickle.h"
fdoray8e32586852016-06-22 19:56:1613#include "base/run_loop.h"
[email protected]b51352a2014-02-26 05:18:0414#include "base/threading/thread.h"
15#include "ipc/ipc_message.h"
[email protected]b51352a2014-02-26 05:18:0416#include "ipc/ipc_test_base.h"
[email protected]74122042014-04-25 00:07:3017#include "ipc/message_filter.h"
[email protected]b51352a2014-02-26 05:18:0418
[email protected]8e9ba762014-05-21 16:39:1819// Get basic type definitions.
20#define IPC_MESSAGE_IMPL
21#include "ipc/ipc_channel_proxy_unittest_messages.h"
22
23// Generate constructors.
24#include "ipc/struct_constructor_macros.h"
25#include "ipc/ipc_channel_proxy_unittest_messages.h"
26
27// Generate destructors.
28#include "ipc/struct_destructor_macros.h"
29#include "ipc/ipc_channel_proxy_unittest_messages.h"
30
31// Generate param traits write methods.
32#include "ipc/param_traits_write_macros.h"
33namespace IPC {
34#include "ipc/ipc_channel_proxy_unittest_messages.h"
35} // namespace IPC
36
37// Generate param traits read methods.
38#include "ipc/param_traits_read_macros.h"
39namespace IPC {
40#include "ipc/ipc_channel_proxy_unittest_messages.h"
41} // namespace IPC
42
43// Generate param traits log methods.
44#include "ipc/param_traits_log_macros.h"
45namespace IPC {
46#include "ipc/ipc_channel_proxy_unittest_messages.h"
47} // namespace IPC
48
49
[email protected]b51352a2014-02-26 05:18:0450namespace {
51
[email protected]b51352a2014-02-26 05:18:0452class QuitListener : public IPC::Listener {
53 public:
[email protected]8e9ba762014-05-21 16:39:1854 QuitListener() : bad_message_received_(false) {}
[email protected]b51352a2014-02-26 05:18:0455
dchengfe61fca2014-10-22 02:29:5256 bool OnMessageReceived(const IPC::Message& message) override {
[email protected]8e9ba762014-05-21 16:39:1857 IPC_BEGIN_MESSAGE_MAP(QuitListener, message)
58 IPC_MESSAGE_HANDLER(WorkerMsg_Quit, OnQuit)
59 IPC_MESSAGE_HANDLER(TestMsg_BadMessage, OnBadMessage)
60 IPC_END_MESSAGE_MAP()
[email protected]b51352a2014-02-26 05:18:0461 return true;
62 }
[email protected]8e9ba762014-05-21 16:39:1863
dchengfe61fca2014-10-22 02:29:5264 void OnBadMessageReceived(const IPC::Message& message) override {
[email protected]8e9ba762014-05-21 16:39:1865 bad_message_received_ = true;
66 }
67
68 void OnQuit() {
69 base::MessageLoop::current()->QuitWhenIdle();
70 }
71
72 void OnBadMessage(const BadType& bad_type) {
73 // Should never be called since IPC wouldn't be deserialized correctly.
74 CHECK(false);
75 }
76
77 bool bad_message_received_;
[email protected]b51352a2014-02-26 05:18:0478};
79
80class ChannelReflectorListener : public IPC::Listener {
81 public:
82 ChannelReflectorListener() : channel_(NULL) {}
[email protected]b51352a2014-02-26 05:18:0483
84 void Init(IPC::Channel* channel) {
85 DCHECK(!channel_);
86 channel_ = channel;
87 }
88
dchengfe61fca2014-10-22 02:29:5289 bool OnMessageReceived(const IPC::Message& message) override {
[email protected]8e9ba762014-05-21 16:39:1890 IPC_BEGIN_MESSAGE_MAP(ChannelReflectorListener, message)
91 IPC_MESSAGE_HANDLER(TestMsg_Bounce, OnTestBounce)
92 IPC_MESSAGE_HANDLER(TestMsg_SendBadMessage, OnSendBadMessage)
Noel Gordon93d53af2017-07-06 12:48:0893 IPC_MESSAGE_HANDLER(AutomationMsg_Bounce, OnAutomationBounce)
[email protected]8e9ba762014-05-21 16:39:1894 IPC_MESSAGE_HANDLER(WorkerMsg_Bounce, OnBounce)
95 IPC_MESSAGE_HANDLER(WorkerMsg_Quit, OnQuit)
96 IPC_END_MESSAGE_MAP()
[email protected]b51352a2014-02-26 05:18:0497 return true;
98 }
99
[email protected]8e9ba762014-05-21 16:39:18100 void OnTestBounce() {
101 channel_->Send(new TestMsg_Bounce());
102 }
103
104 void OnSendBadMessage() {
105 channel_->Send(new TestMsg_BadMessage(BadType()));
106 }
107
Noel Gordon93d53af2017-07-06 12:48:08108 void OnAutomationBounce() { channel_->Send(new AutomationMsg_Bounce()); }
[email protected]8e9ba762014-05-21 16:39:18109
110 void OnBounce() {
111 channel_->Send(new WorkerMsg_Bounce());
112 }
113
114 void OnQuit() {
115 channel_->Send(new WorkerMsg_Quit());
116 base::MessageLoop::current()->QuitWhenIdle();
117 }
118
[email protected]b51352a2014-02-26 05:18:04119 private:
120 IPC::Channel* channel_;
121};
122
[email protected]74122042014-04-25 00:07:30123class MessageCountFilter : public IPC::MessageFilter {
[email protected]b51352a2014-02-26 05:18:04124 public:
[email protected]21bb77b2014-04-23 23:54:53125 enum FilterEvent {
126 NONE,
127 FILTER_ADDED,
128 CHANNEL_CONNECTED,
129 CHANNEL_ERROR,
130 CHANNEL_CLOSING,
131 FILTER_REMOVED
132 };
[email protected]b51352a2014-02-26 05:18:04133 MessageCountFilter()
134 : messages_received_(0),
135 supported_message_class_(0),
136 is_global_filter_(true),
[email protected]21bb77b2014-04-23 23:54:53137 last_filter_event_(NONE),
[email protected]b51352a2014-02-26 05:18:04138 message_filtering_enabled_(false) {}
139
tfarina10a5c062015-09-04 18:47:57140 MessageCountFilter(uint32_t supported_message_class)
[email protected]b51352a2014-02-26 05:18:04141 : messages_received_(0),
142 supported_message_class_(supported_message_class),
143 is_global_filter_(false),
[email protected]21bb77b2014-04-23 23:54:53144 last_filter_event_(NONE),
[email protected]b51352a2014-02-26 05:18:04145 message_filtering_enabled_(false) {}
146
rockote0072ebd2016-09-16 23:40:30147 void OnFilterAdded(IPC::Channel* channel) override {
148 EXPECT_TRUE(channel);
[email protected]21bb77b2014-04-23 23:54:53149 EXPECT_EQ(NONE, last_filter_event_);
150 last_filter_event_ = FILTER_ADDED;
151 }
152
dchengfe61fca2014-10-22 02:29:52153 void OnChannelConnected(int32_t peer_pid) override {
[email protected]21bb77b2014-04-23 23:54:53154 EXPECT_EQ(FILTER_ADDED, last_filter_event_);
155 EXPECT_NE(static_cast<int32_t>(base::kNullProcessId), peer_pid);
156 last_filter_event_ = CHANNEL_CONNECTED;
157 }
158
dchengfe61fca2014-10-22 02:29:52159 void OnChannelError() override {
[email protected]21bb77b2014-04-23 23:54:53160 EXPECT_EQ(CHANNEL_CONNECTED, last_filter_event_);
161 last_filter_event_ = CHANNEL_ERROR;
162 }
163
dchengfe61fca2014-10-22 02:29:52164 void OnChannelClosing() override {
[email protected]21bb77b2014-04-23 23:54:53165 // We may or may not have gotten OnChannelError; if not, the last event has
166 // to be OnChannelConnected.
rockot8a96cca42016-10-21 22:47:50167 EXPECT_NE(FILTER_REMOVED, last_filter_event_);
[email protected]21bb77b2014-04-23 23:54:53168 if (last_filter_event_ != CHANNEL_ERROR)
169 EXPECT_EQ(CHANNEL_CONNECTED, last_filter_event_);
170 last_filter_event_ = CHANNEL_CLOSING;
171 }
172
dchengfe61fca2014-10-22 02:29:52173 void OnFilterRemoved() override {
rockot8a96cca42016-10-21 22:47:50174 // A filter may be removed at any time, even before the channel is connected
175 // (and thus before OnFilterAdded is ever able to dispatch.) The only time
176 // we won't see OnFilterRemoved is immediately after OnFilterAdded, because
177 // OnChannelConnected is always the next event to fire after that.
178 EXPECT_NE(FILTER_ADDED, last_filter_event_);
[email protected]21bb77b2014-04-23 23:54:53179 last_filter_event_ = FILTER_REMOVED;
[email protected]b51352a2014-02-26 05:18:04180 }
181
dchengfe61fca2014-10-22 02:29:52182 bool OnMessageReceived(const IPC::Message& message) override {
[email protected]21bb77b2014-04-23 23:54:53183 // We should always get the OnFilterAdded and OnChannelConnected events
184 // prior to any messages.
185 EXPECT_EQ(CHANNEL_CONNECTED, last_filter_event_);
186
[email protected]b51352a2014-02-26 05:18:04187 if (!is_global_filter_) {
188 EXPECT_EQ(supported_message_class_, IPC_MESSAGE_CLASS(message));
189 }
190 ++messages_received_;
[email protected]8e9ba762014-05-21 16:39:18191
192 if (!message_filtering_enabled_)
193 return false;
194
195 bool handled = true;
196 IPC_BEGIN_MESSAGE_MAP(MessageCountFilter, message)
197 IPC_MESSAGE_HANDLER(TestMsg_BadMessage, OnBadMessage)
198 IPC_MESSAGE_UNHANDLED(handled = false)
199 IPC_END_MESSAGE_MAP()
200 return handled;
201 }
202
203 void OnBadMessage(const BadType& bad_type) {
204 // Should never be called since IPC wouldn't be deserialized correctly.
205 CHECK(false);
[email protected]b51352a2014-02-26 05:18:04206 }
207
dchengfe61fca2014-10-22 02:29:52208 bool GetSupportedMessageClasses(
tfarina10a5c062015-09-04 18:47:57209 std::vector<uint32_t>* supported_message_classes) const override {
[email protected]b51352a2014-02-26 05:18:04210 if (is_global_filter_)
211 return false;
212 supported_message_classes->push_back(supported_message_class_);
213 return true;
214 }
215
216 void set_message_filtering_enabled(bool enabled) {
217 message_filtering_enabled_ = enabled;
218 }
219
220 size_t messages_received() const { return messages_received_; }
[email protected]21bb77b2014-04-23 23:54:53221 FilterEvent last_filter_event() const { return last_filter_event_; }
[email protected]b51352a2014-02-26 05:18:04222
223 private:
dchengfe61fca2014-10-22 02:29:52224 ~MessageCountFilter() override {}
[email protected]b51352a2014-02-26 05:18:04225
226 size_t messages_received_;
tfarina10a5c062015-09-04 18:47:57227 uint32_t supported_message_class_;
[email protected]b51352a2014-02-26 05:18:04228 bool is_global_filter_;
[email protected]21bb77b2014-04-23 23:54:53229
230 FilterEvent last_filter_event_;
[email protected]b51352a2014-02-26 05:18:04231 bool message_filtering_enabled_;
232};
233
sammc4bcc4ed62016-10-27 10:13:59234class IPCChannelProxyTest : public IPCChannelMojoTestBase {
[email protected]b51352a2014-02-26 05:18:04235 public:
236 IPCChannelProxyTest() {}
dcheng1c3d9ac2014-12-23 19:59:59237 ~IPCChannelProxyTest() override {}
[email protected]b51352a2014-02-26 05:18:04238
dcheng1c3d9ac2014-12-23 19:59:59239 void SetUp() override {
sammc4bcc4ed62016-10-27 10:13:59240 IPCChannelMojoTestBase::SetUp();
[email protected]b51352a2014-02-26 05:18:04241
242 Init("ChannelProxyClient");
243
244 thread_.reset(new base::Thread("ChannelProxyTestServerThread"));
245 base::Thread::Options options;
246 options.message_loop_type = base::MessageLoop::TYPE_IO;
247 thread_->StartWithOptions(options);
248
249 listener_.reset(new QuitListener());
sammc4bcc4ed62016-10-27 10:13:59250 channel_proxy_ = IPC::ChannelProxy::Create(
251 TakeHandle().release(), IPC::Channel::MODE_SERVER, listener_.get(),
252 thread_->task_runner());
[email protected]b51352a2014-02-26 05:18:04253 }
254
dcheng1c3d9ac2014-12-23 19:59:59255 void TearDown() override {
sammc4bcc4ed62016-10-27 10:13:59256 channel_proxy_.reset();
[email protected]b51352a2014-02-26 05:18:04257 thread_.reset();
258 listener_.reset();
sammc4bcc4ed62016-10-27 10:13:59259 IPCChannelMojoTestBase::TearDown();
[email protected]b51352a2014-02-26 05:18:04260 }
261
262 void SendQuitMessageAndWaitForIdle() {
[email protected]8e9ba762014-05-21 16:39:18263 sender()->Send(new WorkerMsg_Quit);
fdoray8e32586852016-06-22 19:56:16264 base::RunLoop().Run();
[email protected]b51352a2014-02-26 05:18:04265 EXPECT_TRUE(WaitForClientShutdown());
266 }
267
[email protected]8e9ba762014-05-21 16:39:18268 bool DidListenerGetBadMessage() {
269 return listener_->bad_message_received_;
270 }
271
sammc4bcc4ed62016-10-27 10:13:59272 IPC::ChannelProxy* channel_proxy() { return channel_proxy_.get(); }
273 IPC::Sender* sender() { return channel_proxy_.get(); }
274
[email protected]b51352a2014-02-26 05:18:04275 private:
danakj03de39b22016-04-23 04:21:09276 std::unique_ptr<base::Thread> thread_;
277 std::unique_ptr<QuitListener> listener_;
sammc4bcc4ed62016-10-27 10:13:59278 std::unique_ptr<IPC::ChannelProxy> channel_proxy_;
[email protected]b51352a2014-02-26 05:18:04279};
280
amistry6de2ee4f2016-05-05 05:12:09281TEST_F(IPCChannelProxyTest, MessageClassFilters) {
[email protected]b51352a2014-02-26 05:18:04282 // Construct a filter per message class.
Noel Gordon93d53af2017-07-06 12:48:08283 std::vector<scoped_refptr<MessageCountFilter>> class_filters;
284 class_filters.push_back(
285 make_scoped_refptr(new MessageCountFilter(TestMsgStart)));
286 class_filters.push_back(
287 make_scoped_refptr(new MessageCountFilter(AutomationMsgStart)));
[email protected]8e9ba762014-05-21 16:39:18288 for (size_t i = 0; i < class_filters.size(); ++i)
289 channel_proxy()->AddFilter(class_filters[i].get());
[email protected]b51352a2014-02-26 05:18:04290
291 // Send a message for each class; each filter should receive just one message.
Noel Gordon93d53af2017-07-06 12:48:08292 sender()->Send(new TestMsg_Bounce);
293 sender()->Send(new AutomationMsg_Bounce);
[email protected]b51352a2014-02-26 05:18:04294
295 // Send some messages not assigned to a specific or valid message class.
[email protected]8e9ba762014-05-21 16:39:18296 sender()->Send(new WorkerMsg_Bounce);
[email protected]b51352a2014-02-26 05:18:04297
298 // Each filter should have received just the one sent message of the
299 // corresponding class.
300 SendQuitMessageAndWaitForIdle();
301 for (size_t i = 0; i < class_filters.size(); ++i)
302 EXPECT_EQ(1U, class_filters[i]->messages_received());
303}
304
amistry6de2ee4f2016-05-05 05:12:09305TEST_F(IPCChannelProxyTest, GlobalAndMessageClassFilters) {
[email protected]b51352a2014-02-26 05:18:04306 // Add a class and global filter.
[email protected]b51352a2014-02-26 05:18:04307 scoped_refptr<MessageCountFilter> class_filter(
[email protected]8e9ba762014-05-21 16:39:18308 new MessageCountFilter(TestMsgStart));
[email protected]b51352a2014-02-26 05:18:04309 class_filter->set_message_filtering_enabled(false);
310 channel_proxy()->AddFilter(class_filter.get());
311
312 scoped_refptr<MessageCountFilter> global_filter(new MessageCountFilter());
313 global_filter->set_message_filtering_enabled(false);
314 channel_proxy()->AddFilter(global_filter.get());
315
[email protected]8e9ba762014-05-21 16:39:18316 // A message of class Test should be seen by both the global filter and
317 // Test-specific filter.
318 sender()->Send(new TestMsg_Bounce);
[email protected]b51352a2014-02-26 05:18:04319
320 // A message of a different class should be seen only by the global filter.
Noel Gordon93d53af2017-07-06 12:48:08321 sender()->Send(new AutomationMsg_Bounce);
[email protected]b51352a2014-02-26 05:18:04322
323 // Flush all messages.
324 SendQuitMessageAndWaitForIdle();
325
326 // The class filter should have received only the class-specific message.
327 EXPECT_EQ(1U, class_filter->messages_received());
328
[email protected]8e9ba762014-05-21 16:39:18329 // The global filter should have received both messages, as well as the final
330 // QUIT message.
[email protected]b51352a2014-02-26 05:18:04331 EXPECT_EQ(3U, global_filter->messages_received());
332}
333
amistry6de2ee4f2016-05-05 05:12:09334TEST_F(IPCChannelProxyTest, FilterRemoval) {
[email protected]b51352a2014-02-26 05:18:04335 // Add a class and global filter.
[email protected]b51352a2014-02-26 05:18:04336 scoped_refptr<MessageCountFilter> class_filter(
[email protected]8e9ba762014-05-21 16:39:18337 new MessageCountFilter(TestMsgStart));
[email protected]b51352a2014-02-26 05:18:04338 scoped_refptr<MessageCountFilter> global_filter(new MessageCountFilter());
339
340 // Add and remove both types of filters.
341 channel_proxy()->AddFilter(class_filter.get());
342 channel_proxy()->AddFilter(global_filter.get());
343 channel_proxy()->RemoveFilter(global_filter.get());
344 channel_proxy()->RemoveFilter(class_filter.get());
345
346 // Send some messages; they should not be seen by either filter.
[email protected]8e9ba762014-05-21 16:39:18347 sender()->Send(new TestMsg_Bounce);
Noel Gordon93d53af2017-07-06 12:48:08348 sender()->Send(new AutomationMsg_Bounce);
[email protected]b51352a2014-02-26 05:18:04349
350 // Ensure that the filters were removed and did not receive any messages.
351 SendQuitMessageAndWaitForIdle();
[email protected]21bb77b2014-04-23 23:54:53352 EXPECT_EQ(MessageCountFilter::FILTER_REMOVED,
353 global_filter->last_filter_event());
354 EXPECT_EQ(MessageCountFilter::FILTER_REMOVED,
355 class_filter->last_filter_event());
[email protected]b51352a2014-02-26 05:18:04356 EXPECT_EQ(0U, class_filter->messages_received());
357 EXPECT_EQ(0U, global_filter->messages_received());
358}
359
[email protected]8e9ba762014-05-21 16:39:18360TEST_F(IPCChannelProxyTest, BadMessageOnListenerThread) {
361 scoped_refptr<MessageCountFilter> class_filter(
362 new MessageCountFilter(TestMsgStart));
363 class_filter->set_message_filtering_enabled(false);
364 channel_proxy()->AddFilter(class_filter.get());
365
366 sender()->Send(new TestMsg_SendBadMessage());
367
368 SendQuitMessageAndWaitForIdle();
369 EXPECT_TRUE(DidListenerGetBadMessage());
370}
371
372TEST_F(IPCChannelProxyTest, BadMessageOnIPCThread) {
373 scoped_refptr<MessageCountFilter> class_filter(
374 new MessageCountFilter(TestMsgStart));
375 class_filter->set_message_filtering_enabled(true);
376 channel_proxy()->AddFilter(class_filter.get());
377
378 sender()->Send(new TestMsg_SendBadMessage());
379
380 SendQuitMessageAndWaitForIdle();
381 EXPECT_TRUE(DidListenerGetBadMessage());
382}
383
sammc4bcc4ed62016-10-27 10:13:59384class IPCChannelBadMessageTest : public IPCChannelMojoTestBase {
[email protected]8e9ba762014-05-21 16:39:18385 public:
Daniel Cheng3e6beaa72014-12-31 03:48:36386 void SetUp() override {
sammc4bcc4ed62016-10-27 10:13:59387 IPCChannelMojoTestBase::SetUp();
[email protected]8e9ba762014-05-21 16:39:18388
389 Init("ChannelProxyClient");
390
391 listener_.reset(new QuitListener());
392 CreateChannel(listener_.get());
393 ASSERT_TRUE(ConnectChannel());
[email protected]8e9ba762014-05-21 16:39:18394 }
395
Daniel Cheng3e6beaa72014-12-31 03:48:36396 void TearDown() override {
sammc4bcc4ed62016-10-27 10:13:59397 IPCChannelMojoTestBase::TearDown();
[email protected]8e9ba762014-05-21 16:39:18398 listener_.reset();
[email protected]8e9ba762014-05-21 16:39:18399 }
400
401 void SendQuitMessageAndWaitForIdle() {
402 sender()->Send(new WorkerMsg_Quit);
fdoray8e32586852016-06-22 19:56:16403 base::RunLoop().Run();
[email protected]8e9ba762014-05-21 16:39:18404 EXPECT_TRUE(WaitForClientShutdown());
405 }
406
407 bool DidListenerGetBadMessage() {
408 return listener_->bad_message_received_;
409 }
410
411 private:
danakj03de39b22016-04-23 04:21:09412 std::unique_ptr<QuitListener> listener_;
[email protected]8e9ba762014-05-21 16:39:18413};
414
[email protected]0f415a82014-05-27 01:54:53415#if !defined(OS_WIN)
416 // TODO(jam): for some reason this is flaky on win buildbots.
[email protected]8e9ba762014-05-21 16:39:18417TEST_F(IPCChannelBadMessageTest, BadMessage) {
418 sender()->Send(new TestMsg_SendBadMessage());
419 SendQuitMessageAndWaitForIdle();
420 EXPECT_TRUE(DidListenerGetBadMessage());
421}
[email protected]0f415a82014-05-27 01:54:53422#endif
[email protected]8e9ba762014-05-21 16:39:18423
sammc4bcc4ed62016-10-27 10:13:59424DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(ChannelProxyClient) {
[email protected]b51352a2014-02-26 05:18:04425 ChannelReflectorListener listener;
sammc4bcc4ed62016-10-27 10:13:59426 Connect(&listener);
427 listener.Init(channel());
[email protected]b51352a2014-02-26 05:18:04428
fdoray8e32586852016-06-22 19:56:16429 base::RunLoop().Run();
sammc4bcc4ed62016-10-27 10:13:59430 Close();
[email protected]b51352a2014-02-26 05:18:04431}
432
433} // namespace