blob: 65e40ef53459af70da265b612ba5a63f51004ca9 [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
Carlos Caballerodd8bf7b042019-07-30 14:14:1511#include "base/message_loop/message_pump_type.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
[email protected]8e9ba762014-05-21 16:39:1827// Generate param traits write methods.
28#include "ipc/param_traits_write_macros.h"
29namespace IPC {
30#include "ipc/ipc_channel_proxy_unittest_messages.h"
31} // namespace IPC
32
33// Generate param traits read methods.
34#include "ipc/param_traits_read_macros.h"
35namespace IPC {
36#include "ipc/ipc_channel_proxy_unittest_messages.h"
37} // namespace IPC
38
39// Generate param traits log methods.
40#include "ipc/param_traits_log_macros.h"
41namespace IPC {
42#include "ipc/ipc_channel_proxy_unittest_messages.h"
43} // namespace IPC
44
45
[email protected]b51352a2014-02-26 05:18:0446namespace {
47
Wezd95d48042018-02-26 20:50:4748void CreateRunLoopAndRun(base::RunLoop** run_loop_ptr) {
49 base::RunLoop run_loop;
50 *run_loop_ptr = &run_loop;
51 run_loop.Run();
52 *run_loop_ptr = nullptr;
53}
54
[email protected]b51352a2014-02-26 05:18:0455class QuitListener : public IPC::Listener {
56 public:
Wezd95d48042018-02-26 20:50:4757 QuitListener() = default;
[email protected]b51352a2014-02-26 05:18:0458
dchengfe61fca2014-10-22 02:29:5259 bool OnMessageReceived(const IPC::Message& message) override {
[email protected]8e9ba762014-05-21 16:39:1860 IPC_BEGIN_MESSAGE_MAP(QuitListener, message)
61 IPC_MESSAGE_HANDLER(WorkerMsg_Quit, OnQuit)
62 IPC_MESSAGE_HANDLER(TestMsg_BadMessage, OnBadMessage)
63 IPC_END_MESSAGE_MAP()
[email protected]b51352a2014-02-26 05:18:0464 return true;
65 }
[email protected]8e9ba762014-05-21 16:39:1866
dchengfe61fca2014-10-22 02:29:5267 void OnBadMessageReceived(const IPC::Message& message) override {
[email protected]8e9ba762014-05-21 16:39:1868 bad_message_received_ = true;
69 }
70
Wezd95d48042018-02-26 20:50:4771 void OnChannelError() override { CHECK(quit_message_received_); }
72
73 void OnQuit() {
74 quit_message_received_ = true;
75 run_loop_->QuitWhenIdle();
76 }
[email protected]8e9ba762014-05-21 16:39:1877
78 void OnBadMessage(const BadType& bad_type) {
79 // Should never be called since IPC wouldn't be deserialized correctly.
80 CHECK(false);
81 }
82
Wezd95d48042018-02-26 20:50:4783 bool bad_message_received_ = false;
84 bool quit_message_received_ = false;
85 base::RunLoop* run_loop_ = nullptr;
[email protected]b51352a2014-02-26 05:18:0486};
87
88class ChannelReflectorListener : public IPC::Listener {
89 public:
Wezd95d48042018-02-26 20:50:4790 ChannelReflectorListener() = default;
[email protected]b51352a2014-02-26 05:18:0491
92 void Init(IPC::Channel* channel) {
93 DCHECK(!channel_);
94 channel_ = channel;
95 }
96
dchengfe61fca2014-10-22 02:29:5297 bool OnMessageReceived(const IPC::Message& message) override {
[email protected]8e9ba762014-05-21 16:39:1898 IPC_BEGIN_MESSAGE_MAP(ChannelReflectorListener, message)
99 IPC_MESSAGE_HANDLER(TestMsg_Bounce, OnTestBounce)
100 IPC_MESSAGE_HANDLER(TestMsg_SendBadMessage, OnSendBadMessage)
Noel Gordon93d53af2017-07-06 12:48:08101 IPC_MESSAGE_HANDLER(AutomationMsg_Bounce, OnAutomationBounce)
[email protected]8e9ba762014-05-21 16:39:18102 IPC_MESSAGE_HANDLER(WorkerMsg_Bounce, OnBounce)
103 IPC_MESSAGE_HANDLER(WorkerMsg_Quit, OnQuit)
104 IPC_END_MESSAGE_MAP()
[email protected]b51352a2014-02-26 05:18:04105 return true;
106 }
107
[email protected]8e9ba762014-05-21 16:39:18108 void OnTestBounce() {
109 channel_->Send(new TestMsg_Bounce());
110 }
111
112 void OnSendBadMessage() {
113 channel_->Send(new TestMsg_BadMessage(BadType()));
114 }
115
Noel Gordon93d53af2017-07-06 12:48:08116 void OnAutomationBounce() { channel_->Send(new AutomationMsg_Bounce()); }
[email protected]8e9ba762014-05-21 16:39:18117
118 void OnBounce() {
119 channel_->Send(new WorkerMsg_Bounce());
120 }
121
122 void OnQuit() {
123 channel_->Send(new WorkerMsg_Quit());
Wezd95d48042018-02-26 20:50:47124 run_loop_->QuitWhenIdle();
[email protected]8e9ba762014-05-21 16:39:18125 }
126
Wezd95d48042018-02-26 20:50:47127 base::RunLoop* run_loop_ = nullptr;
128
[email protected]b51352a2014-02-26 05:18:04129 private:
Wezd95d48042018-02-26 20:50:47130 IPC::Channel* channel_ = nullptr;
[email protected]b51352a2014-02-26 05:18:04131};
132
[email protected]74122042014-04-25 00:07:30133class MessageCountFilter : public IPC::MessageFilter {
[email protected]b51352a2014-02-26 05:18:04134 public:
[email protected]21bb77b2014-04-23 23:54:53135 enum FilterEvent {
136 NONE,
137 FILTER_ADDED,
138 CHANNEL_CONNECTED,
139 CHANNEL_ERROR,
140 CHANNEL_CLOSING,
141 FILTER_REMOVED
142 };
[email protected]b51352a2014-02-26 05:18:04143
Wezd95d48042018-02-26 20:50:47144 MessageCountFilter() = default;
tfarina10a5c062015-09-04 18:47:57145 MessageCountFilter(uint32_t supported_message_class)
Wezd95d48042018-02-26 20:50:47146 : supported_message_class_(supported_message_class),
147 is_global_filter_(false) {}
[email protected]b51352a2014-02-26 05:18:04148
rockote0072ebd2016-09-16 23:40:30149 void OnFilterAdded(IPC::Channel* channel) override {
150 EXPECT_TRUE(channel);
[email protected]21bb77b2014-04-23 23:54:53151 EXPECT_EQ(NONE, last_filter_event_);
152 last_filter_event_ = FILTER_ADDED;
153 }
154
dchengfe61fca2014-10-22 02:29:52155 void OnChannelConnected(int32_t peer_pid) override {
[email protected]21bb77b2014-04-23 23:54:53156 EXPECT_EQ(FILTER_ADDED, last_filter_event_);
157 EXPECT_NE(static_cast<int32_t>(base::kNullProcessId), peer_pid);
158 last_filter_event_ = CHANNEL_CONNECTED;
159 }
160
dchengfe61fca2014-10-22 02:29:52161 void OnChannelError() override {
[email protected]21bb77b2014-04-23 23:54:53162 EXPECT_EQ(CHANNEL_CONNECTED, last_filter_event_);
163 last_filter_event_ = CHANNEL_ERROR;
164 }
165
dchengfe61fca2014-10-22 02:29:52166 void OnChannelClosing() override {
[email protected]21bb77b2014-04-23 23:54:53167 // We may or may not have gotten OnChannelError; if not, the last event has
168 // to be OnChannelConnected.
rockot8a96cca42016-10-21 22:47:50169 EXPECT_NE(FILTER_REMOVED, last_filter_event_);
[email protected]21bb77b2014-04-23 23:54:53170 if (last_filter_event_ != CHANNEL_ERROR)
171 EXPECT_EQ(CHANNEL_CONNECTED, last_filter_event_);
172 last_filter_event_ = CHANNEL_CLOSING;
173 }
174
dchengfe61fca2014-10-22 02:29:52175 void OnFilterRemoved() override {
rockot8a96cca42016-10-21 22:47:50176 // A filter may be removed at any time, even before the channel is connected
177 // (and thus before OnFilterAdded is ever able to dispatch.) The only time
178 // we won't see OnFilterRemoved is immediately after OnFilterAdded, because
179 // OnChannelConnected is always the next event to fire after that.
180 EXPECT_NE(FILTER_ADDED, last_filter_event_);
[email protected]21bb77b2014-04-23 23:54:53181 last_filter_event_ = FILTER_REMOVED;
[email protected]b51352a2014-02-26 05:18:04182 }
183
dchengfe61fca2014-10-22 02:29:52184 bool OnMessageReceived(const IPC::Message& message) override {
[email protected]21bb77b2014-04-23 23:54:53185 // We should always get the OnFilterAdded and OnChannelConnected events
186 // prior to any messages.
187 EXPECT_EQ(CHANNEL_CONNECTED, last_filter_event_);
188
[email protected]b51352a2014-02-26 05:18:04189 if (!is_global_filter_) {
190 EXPECT_EQ(supported_message_class_, IPC_MESSAGE_CLASS(message));
191 }
192 ++messages_received_;
[email protected]8e9ba762014-05-21 16:39:18193
194 if (!message_filtering_enabled_)
195 return false;
196
197 bool handled = true;
198 IPC_BEGIN_MESSAGE_MAP(MessageCountFilter, message)
199 IPC_MESSAGE_HANDLER(TestMsg_BadMessage, OnBadMessage)
200 IPC_MESSAGE_UNHANDLED(handled = false)
201 IPC_END_MESSAGE_MAP()
202 return handled;
203 }
204
205 void OnBadMessage(const BadType& bad_type) {
206 // Should never be called since IPC wouldn't be deserialized correctly.
207 CHECK(false);
[email protected]b51352a2014-02-26 05:18:04208 }
209
dchengfe61fca2014-10-22 02:29:52210 bool GetSupportedMessageClasses(
tfarina10a5c062015-09-04 18:47:57211 std::vector<uint32_t>* supported_message_classes) const override {
[email protected]b51352a2014-02-26 05:18:04212 if (is_global_filter_)
213 return false;
214 supported_message_classes->push_back(supported_message_class_);
215 return true;
216 }
217
218 void set_message_filtering_enabled(bool enabled) {
219 message_filtering_enabled_ = enabled;
220 }
221
222 size_t messages_received() const { return messages_received_; }
[email protected]21bb77b2014-04-23 23:54:53223 FilterEvent last_filter_event() const { return last_filter_event_; }
[email protected]b51352a2014-02-26 05:18:04224
225 private:
Chris Watkins2d879af2017-11-30 02:11:59226 ~MessageCountFilter() override = default;
[email protected]b51352a2014-02-26 05:18:04227
Wezd95d48042018-02-26 20:50:47228 size_t messages_received_ = 0;
229 uint32_t supported_message_class_ = 0;
230 bool is_global_filter_ = true;
[email protected]21bb77b2014-04-23 23:54:53231
Wezd95d48042018-02-26 20:50:47232 FilterEvent last_filter_event_ = NONE;
233 bool message_filtering_enabled_ = false;
[email protected]b51352a2014-02-26 05:18:04234};
235
sammc4bcc4ed62016-10-27 10:13:59236class IPCChannelProxyTest : public IPCChannelMojoTestBase {
[email protected]b51352a2014-02-26 05:18:04237 public:
Chris Watkins2d879af2017-11-30 02:11:59238 IPCChannelProxyTest() = default;
239 ~IPCChannelProxyTest() override = default;
[email protected]b51352a2014-02-26 05:18:04240
dcheng1c3d9ac2014-12-23 19:59:59241 void SetUp() override {
sammc4bcc4ed62016-10-27 10:13:59242 IPCChannelMojoTestBase::SetUp();
[email protected]b51352a2014-02-26 05:18:04243
244 Init("ChannelProxyClient");
245
246 thread_.reset(new base::Thread("ChannelProxyTestServerThread"));
247 base::Thread::Options options;
Carlos Caballerodd8bf7b042019-07-30 14:14:15248 options.message_pump_type = base::MessagePumpType::IO;
[email protected]b51352a2014-02-26 05:18:04249 thread_->StartWithOptions(options);
250
251 listener_.reset(new QuitListener());
sammc4bcc4ed62016-10-27 10:13:59252 channel_proxy_ = IPC::ChannelProxy::Create(
253 TakeHandle().release(), IPC::Channel::MODE_SERVER, listener_.get(),
Hajime Hoshiff15e972017-11-09 06:37:09254 thread_->task_runner(), base::ThreadTaskRunnerHandle::Get());
[email protected]b51352a2014-02-26 05:18:04255 }
256
dcheng1c3d9ac2014-12-23 19:59:59257 void TearDown() override {
sammc4bcc4ed62016-10-27 10:13:59258 channel_proxy_.reset();
[email protected]b51352a2014-02-26 05:18:04259 thread_.reset();
260 listener_.reset();
sammc4bcc4ed62016-10-27 10:13:59261 IPCChannelMojoTestBase::TearDown();
[email protected]b51352a2014-02-26 05:18:04262 }
263
264 void SendQuitMessageAndWaitForIdle() {
[email protected]8e9ba762014-05-21 16:39:18265 sender()->Send(new WorkerMsg_Quit);
Wezd95d48042018-02-26 20:50:47266 CreateRunLoopAndRun(&listener_->run_loop_);
[email protected]b51352a2014-02-26 05:18:04267 EXPECT_TRUE(WaitForClientShutdown());
268 }
269
[email protected]8e9ba762014-05-21 16:39:18270 bool DidListenerGetBadMessage() {
271 return listener_->bad_message_received_;
272 }
273
sammc4bcc4ed62016-10-27 10:13:59274 IPC::ChannelProxy* channel_proxy() { return channel_proxy_.get(); }
275 IPC::Sender* sender() { return channel_proxy_.get(); }
276
[email protected]b51352a2014-02-26 05:18:04277 private:
danakj03de39b22016-04-23 04:21:09278 std::unique_ptr<base::Thread> thread_;
279 std::unique_ptr<QuitListener> listener_;
sammc4bcc4ed62016-10-27 10:13:59280 std::unique_ptr<IPC::ChannelProxy> channel_proxy_;
[email protected]b51352a2014-02-26 05:18:04281};
282
amistry6de2ee4f2016-05-05 05:12:09283TEST_F(IPCChannelProxyTest, MessageClassFilters) {
[email protected]b51352a2014-02-26 05:18:04284 // Construct a filter per message class.
Noel Gordon93d53af2017-07-06 12:48:08285 std::vector<scoped_refptr<MessageCountFilter>> class_filters;
286 class_filters.push_back(
kylechar96f3eba2017-09-25 20:23:56287 base::MakeRefCounted<MessageCountFilter>(TestMsgStart));
Noel Gordon93d53af2017-07-06 12:48:08288 class_filters.push_back(
kylechar96f3eba2017-09-25 20:23:56289 base::MakeRefCounted<MessageCountFilter>(AutomationMsgStart));
[email protected]8e9ba762014-05-21 16:39:18290 for (size_t i = 0; i < class_filters.size(); ++i)
291 channel_proxy()->AddFilter(class_filters[i].get());
[email protected]b51352a2014-02-26 05:18:04292
293 // Send a message for each class; each filter should receive just one message.
Noel Gordon93d53af2017-07-06 12:48:08294 sender()->Send(new TestMsg_Bounce);
295 sender()->Send(new AutomationMsg_Bounce);
[email protected]b51352a2014-02-26 05:18:04296
297 // Send some messages not assigned to a specific or valid message class.
[email protected]8e9ba762014-05-21 16:39:18298 sender()->Send(new WorkerMsg_Bounce);
[email protected]b51352a2014-02-26 05:18:04299
300 // Each filter should have received just the one sent message of the
301 // corresponding class.
302 SendQuitMessageAndWaitForIdle();
303 for (size_t i = 0; i < class_filters.size(); ++i)
304 EXPECT_EQ(1U, class_filters[i]->messages_received());
305}
306
amistry6de2ee4f2016-05-05 05:12:09307TEST_F(IPCChannelProxyTest, GlobalAndMessageClassFilters) {
[email protected]b51352a2014-02-26 05:18:04308 // Add a class and global filter.
[email protected]b51352a2014-02-26 05:18:04309 scoped_refptr<MessageCountFilter> class_filter(
[email protected]8e9ba762014-05-21 16:39:18310 new MessageCountFilter(TestMsgStart));
[email protected]b51352a2014-02-26 05:18:04311 class_filter->set_message_filtering_enabled(false);
312 channel_proxy()->AddFilter(class_filter.get());
313
314 scoped_refptr<MessageCountFilter> global_filter(new MessageCountFilter());
315 global_filter->set_message_filtering_enabled(false);
316 channel_proxy()->AddFilter(global_filter.get());
317
[email protected]8e9ba762014-05-21 16:39:18318 // A message of class Test should be seen by both the global filter and
319 // Test-specific filter.
320 sender()->Send(new TestMsg_Bounce);
[email protected]b51352a2014-02-26 05:18:04321
322 // A message of a different class should be seen only by the global filter.
Noel Gordon93d53af2017-07-06 12:48:08323 sender()->Send(new AutomationMsg_Bounce);
[email protected]b51352a2014-02-26 05:18:04324
325 // Flush all messages.
326 SendQuitMessageAndWaitForIdle();
327
328 // The class filter should have received only the class-specific message.
329 EXPECT_EQ(1U, class_filter->messages_received());
330
[email protected]8e9ba762014-05-21 16:39:18331 // The global filter should have received both messages, as well as the final
332 // QUIT message.
[email protected]b51352a2014-02-26 05:18:04333 EXPECT_EQ(3U, global_filter->messages_received());
334}
335
amistry6de2ee4f2016-05-05 05:12:09336TEST_F(IPCChannelProxyTest, FilterRemoval) {
[email protected]b51352a2014-02-26 05:18:04337 // Add a class and global filter.
[email protected]b51352a2014-02-26 05:18:04338 scoped_refptr<MessageCountFilter> class_filter(
[email protected]8e9ba762014-05-21 16:39:18339 new MessageCountFilter(TestMsgStart));
[email protected]b51352a2014-02-26 05:18:04340 scoped_refptr<MessageCountFilter> global_filter(new MessageCountFilter());
341
342 // Add and remove both types of filters.
343 channel_proxy()->AddFilter(class_filter.get());
344 channel_proxy()->AddFilter(global_filter.get());
345 channel_proxy()->RemoveFilter(global_filter.get());
346 channel_proxy()->RemoveFilter(class_filter.get());
347
348 // Send some messages; they should not be seen by either filter.
[email protected]8e9ba762014-05-21 16:39:18349 sender()->Send(new TestMsg_Bounce);
Noel Gordon93d53af2017-07-06 12:48:08350 sender()->Send(new AutomationMsg_Bounce);
[email protected]b51352a2014-02-26 05:18:04351
352 // Ensure that the filters were removed and did not receive any messages.
353 SendQuitMessageAndWaitForIdle();
[email protected]21bb77b2014-04-23 23:54:53354 EXPECT_EQ(MessageCountFilter::FILTER_REMOVED,
355 global_filter->last_filter_event());
356 EXPECT_EQ(MessageCountFilter::FILTER_REMOVED,
357 class_filter->last_filter_event());
[email protected]b51352a2014-02-26 05:18:04358 EXPECT_EQ(0U, class_filter->messages_received());
359 EXPECT_EQ(0U, global_filter->messages_received());
360}
361
[email protected]8e9ba762014-05-21 16:39:18362TEST_F(IPCChannelProxyTest, BadMessageOnListenerThread) {
363 scoped_refptr<MessageCountFilter> class_filter(
364 new MessageCountFilter(TestMsgStart));
365 class_filter->set_message_filtering_enabled(false);
366 channel_proxy()->AddFilter(class_filter.get());
367
368 sender()->Send(new TestMsg_SendBadMessage());
369
370 SendQuitMessageAndWaitForIdle();
371 EXPECT_TRUE(DidListenerGetBadMessage());
372}
373
374TEST_F(IPCChannelProxyTest, BadMessageOnIPCThread) {
375 scoped_refptr<MessageCountFilter> class_filter(
376 new MessageCountFilter(TestMsgStart));
377 class_filter->set_message_filtering_enabled(true);
378 channel_proxy()->AddFilter(class_filter.get());
379
380 sender()->Send(new TestMsg_SendBadMessage());
381
382 SendQuitMessageAndWaitForIdle();
383 EXPECT_TRUE(DidListenerGetBadMessage());
384}
385
sammc4bcc4ed62016-10-27 10:13:59386class IPCChannelBadMessageTest : public IPCChannelMojoTestBase {
[email protected]8e9ba762014-05-21 16:39:18387 public:
Daniel Cheng3e6beaa72014-12-31 03:48:36388 void SetUp() override {
sammc4bcc4ed62016-10-27 10:13:59389 IPCChannelMojoTestBase::SetUp();
[email protected]8e9ba762014-05-21 16:39:18390
391 Init("ChannelProxyClient");
392
393 listener_.reset(new QuitListener());
394 CreateChannel(listener_.get());
395 ASSERT_TRUE(ConnectChannel());
[email protected]8e9ba762014-05-21 16:39:18396 }
397
Daniel Cheng3e6beaa72014-12-31 03:48:36398 void TearDown() override {
sammc4bcc4ed62016-10-27 10:13:59399 IPCChannelMojoTestBase::TearDown();
[email protected]8e9ba762014-05-21 16:39:18400 listener_.reset();
[email protected]8e9ba762014-05-21 16:39:18401 }
402
403 void SendQuitMessageAndWaitForIdle() {
404 sender()->Send(new WorkerMsg_Quit);
Wezd95d48042018-02-26 20:50:47405 CreateRunLoopAndRun(&listener_->run_loop_);
[email protected]8e9ba762014-05-21 16:39:18406 EXPECT_TRUE(WaitForClientShutdown());
407 }
408
409 bool DidListenerGetBadMessage() {
410 return listener_->bad_message_received_;
411 }
412
413 private:
danakj03de39b22016-04-23 04:21:09414 std::unique_ptr<QuitListener> listener_;
[email protected]8e9ba762014-05-21 16:39:18415};
416
417TEST_F(IPCChannelBadMessageTest, BadMessage) {
418 sender()->Send(new TestMsg_SendBadMessage());
419 SendQuitMessageAndWaitForIdle();
420 EXPECT_TRUE(DidListenerGetBadMessage());
421}
422
sammc4bcc4ed62016-10-27 10:13:59423DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(ChannelProxyClient) {
[email protected]b51352a2014-02-26 05:18:04424 ChannelReflectorListener listener;
sammc4bcc4ed62016-10-27 10:13:59425 Connect(&listener);
426 listener.Init(channel());
[email protected]b51352a2014-02-26 05:18:04427
Wezd95d48042018-02-26 20:50:47428 CreateRunLoopAndRun(&listener.run_loop_);
429
sammc4bcc4ed62016-10-27 10:13:59430 Close();
[email protected]b51352a2014-02-26 05:18:04431}
432
433} // namespace