Speculative revert to fix ChromeOS PFQ mips builder
[chromium-blink-merge.git] / ipc / ipc_channel_proxy_unittest.cc
blob4144a8adba176dac778994fd9e32ab85a9808480
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
3 // found in the LICENSE file.
5 #include "build/build_config.h"
7 #include "base/pickle.h"
8 #include "base/threading/thread.h"
9 #include "ipc/ipc_message.h"
10 #include "ipc/ipc_test_base.h"
11 #include "ipc/message_filter.h"
13 // Get basic type definitions.
14 #define IPC_MESSAGE_IMPL
15 #include "ipc/ipc_channel_proxy_unittest_messages.h"
17 // Generate constructors.
18 #include "ipc/struct_constructor_macros.h"
19 #include "ipc/ipc_channel_proxy_unittest_messages.h"
21 // Generate destructors.
22 #include "ipc/struct_destructor_macros.h"
23 #include "ipc/ipc_channel_proxy_unittest_messages.h"
25 // Generate param traits write methods.
26 #include "ipc/param_traits_write_macros.h"
27 namespace IPC {
28 #include "ipc/ipc_channel_proxy_unittest_messages.h"
29 } // namespace IPC
31 // Generate param traits read methods.
32 #include "ipc/param_traits_read_macros.h"
33 namespace IPC {
34 #include "ipc/ipc_channel_proxy_unittest_messages.h"
35 } // namespace IPC
37 // Generate param traits log methods.
38 #include "ipc/param_traits_log_macros.h"
39 namespace IPC {
40 #include "ipc/ipc_channel_proxy_unittest_messages.h"
41 } // namespace IPC
44 namespace {
46 class QuitListener : public IPC::Listener {
47 public:
48 QuitListener() : bad_message_received_(false) {}
50 bool OnMessageReceived(const IPC::Message& message) override {
51 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()
55 return true;
58 void OnBadMessageReceived(const IPC::Message& message) override {
59 bad_message_received_ = true;
62 void OnQuit() {
63 base::MessageLoop::current()->QuitWhenIdle();
66 void OnBadMessage(const BadType& bad_type) {
67 // Should never be called since IPC wouldn't be deserialized correctly.
68 CHECK(false);
71 bool bad_message_received_;
74 class ChannelReflectorListener : public IPC::Listener {
75 public:
76 ChannelReflectorListener() : channel_(NULL) {}
78 void Init(IPC::Channel* channel) {
79 DCHECK(!channel_);
80 channel_ = channel;
83 bool OnMessageReceived(const IPC::Message& message) override {
84 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()
91 return true;
94 void OnTestBounce() {
95 channel_->Send(new TestMsg_Bounce());
98 void OnSendBadMessage() {
99 channel_->Send(new TestMsg_BadMessage(BadType()));
102 void OnUtilityBounce() {
103 channel_->Send(new UtilityMsg_Bounce());
106 void OnBounce() {
107 channel_->Send(new WorkerMsg_Bounce());
110 void OnQuit() {
111 channel_->Send(new WorkerMsg_Quit());
112 base::MessageLoop::current()->QuitWhenIdle();
115 private:
116 IPC::Channel* channel_;
119 class MessageCountFilter : public IPC::MessageFilter {
120 public:
121 enum FilterEvent {
122 NONE,
123 FILTER_ADDED,
124 CHANNEL_CONNECTED,
125 CHANNEL_ERROR,
126 CHANNEL_CLOSING,
127 FILTER_REMOVED
129 MessageCountFilter()
130 : messages_received_(0),
131 supported_message_class_(0),
132 is_global_filter_(true),
133 last_filter_event_(NONE),
134 message_filtering_enabled_(false) {}
136 MessageCountFilter(uint32 supported_message_class)
137 : messages_received_(0),
138 supported_message_class_(supported_message_class),
139 is_global_filter_(false),
140 last_filter_event_(NONE),
141 message_filtering_enabled_(false) {}
143 void OnFilterAdded(IPC::Sender* sender) override {
144 EXPECT_TRUE(sender);
145 EXPECT_EQ(NONE, last_filter_event_);
146 last_filter_event_ = FILTER_ADDED;
149 void OnChannelConnected(int32_t peer_pid) override {
150 EXPECT_EQ(FILTER_ADDED, last_filter_event_);
151 EXPECT_NE(static_cast<int32_t>(base::kNullProcessId), peer_pid);
152 last_filter_event_ = CHANNEL_CONNECTED;
155 void OnChannelError() override {
156 EXPECT_EQ(CHANNEL_CONNECTED, last_filter_event_);
157 last_filter_event_ = CHANNEL_ERROR;
160 void OnChannelClosing() override {
161 // 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;
168 void OnFilterRemoved() override {
169 // 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;
177 bool OnMessageReceived(const IPC::Message& message) override {
178 // We should always get the OnFilterAdded and OnChannelConnected events
179 // prior to any messages.
180 EXPECT_EQ(CHANNEL_CONNECTED, last_filter_event_);
182 if (!is_global_filter_) {
183 EXPECT_EQ(supported_message_class_, IPC_MESSAGE_CLASS(message));
185 ++messages_received_;
187 if (!message_filtering_enabled_)
188 return false;
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;
198 void OnBadMessage(const BadType& bad_type) {
199 // Should never be called since IPC wouldn't be deserialized correctly.
200 CHECK(false);
203 bool GetSupportedMessageClasses(
204 std::vector<uint32>* supported_message_classes) const override {
205 if (is_global_filter_)
206 return false;
207 supported_message_classes->push_back(supported_message_class_);
208 return true;
211 void set_message_filtering_enabled(bool enabled) {
212 message_filtering_enabled_ = enabled;
215 size_t messages_received() const { return messages_received_; }
216 FilterEvent last_filter_event() const { return last_filter_event_; }
218 private:
219 ~MessageCountFilter() override {}
221 size_t messages_received_;
222 uint32 supported_message_class_;
223 bool is_global_filter_;
225 FilterEvent last_filter_event_;
226 bool message_filtering_enabled_;
229 class IPCChannelProxyTest : public IPCTestBase {
230 public:
231 IPCChannelProxyTest() {}
232 ~IPCChannelProxyTest() override {}
234 void SetUp() override {
235 IPCTestBase::SetUp();
237 Init("ChannelProxyClient");
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);
244 listener_.reset(new QuitListener());
245 CreateChannelProxy(listener_.get(), thread_->task_runner().get());
247 ASSERT_TRUE(StartClient());
250 void TearDown() override {
251 DestroyChannelProxy();
252 thread_.reset();
253 listener_.reset();
254 IPCTestBase::TearDown();
257 void SendQuitMessageAndWaitForIdle() {
258 sender()->Send(new WorkerMsg_Quit);
259 base::MessageLoop::current()->Run();
260 EXPECT_TRUE(WaitForClientShutdown());
263 bool DidListenerGetBadMessage() {
264 return listener_->bad_message_received_;
267 private:
268 scoped_ptr<base::Thread> thread_;
269 scoped_ptr<QuitListener> listener_;
272 TEST_F(IPCChannelProxyTest, MessageClassFilters) {
273 // Construct a filter per message class.
274 std::vector<scoped_refptr<MessageCountFilter> > class_filters;
275 class_filters.push_back(make_scoped_refptr(
276 new MessageCountFilter(TestMsgStart)));
277 class_filters.push_back(make_scoped_refptr(
278 new MessageCountFilter(UtilityMsgStart)));
279 for (size_t i = 0; i < class_filters.size(); ++i)
280 channel_proxy()->AddFilter(class_filters[i].get());
282 // Send a message for each class; each filter should receive just one message.
283 sender()->Send(new TestMsg_Bounce());
284 sender()->Send(new UtilityMsg_Bounce());
286 // Send some messages not assigned to a specific or valid message class.
287 sender()->Send(new WorkerMsg_Bounce);
289 // Each filter should have received just the one sent message of the
290 // corresponding class.
291 SendQuitMessageAndWaitForIdle();
292 for (size_t i = 0; i < class_filters.size(); ++i)
293 EXPECT_EQ(1U, class_filters[i]->messages_received());
296 TEST_F(IPCChannelProxyTest, GlobalAndMessageClassFilters) {
297 // Add a class and global filter.
298 scoped_refptr<MessageCountFilter> class_filter(
299 new MessageCountFilter(TestMsgStart));
300 class_filter->set_message_filtering_enabled(false);
301 channel_proxy()->AddFilter(class_filter.get());
303 scoped_refptr<MessageCountFilter> global_filter(new MessageCountFilter());
304 global_filter->set_message_filtering_enabled(false);
305 channel_proxy()->AddFilter(global_filter.get());
307 // A message of class Test should be seen by both the global filter and
308 // Test-specific filter.
309 sender()->Send(new TestMsg_Bounce);
311 // A message of a different class should be seen only by the global filter.
312 sender()->Send(new UtilityMsg_Bounce);
314 // Flush all messages.
315 SendQuitMessageAndWaitForIdle();
317 // The class filter should have received only the class-specific message.
318 EXPECT_EQ(1U, class_filter->messages_received());
320 // The global filter should have received both messages, as well as the final
321 // QUIT message.
322 EXPECT_EQ(3U, global_filter->messages_received());
325 TEST_F(IPCChannelProxyTest, FilterRemoval) {
326 // Add a class and global filter.
327 scoped_refptr<MessageCountFilter> class_filter(
328 new MessageCountFilter(TestMsgStart));
329 scoped_refptr<MessageCountFilter> global_filter(new MessageCountFilter());
331 // Add and remove both types of filters.
332 channel_proxy()->AddFilter(class_filter.get());
333 channel_proxy()->AddFilter(global_filter.get());
334 channel_proxy()->RemoveFilter(global_filter.get());
335 channel_proxy()->RemoveFilter(class_filter.get());
337 // Send some messages; they should not be seen by either filter.
338 sender()->Send(new TestMsg_Bounce);
339 sender()->Send(new UtilityMsg_Bounce);
341 // Ensure that the filters were removed and did not receive any messages.
342 SendQuitMessageAndWaitForIdle();
343 EXPECT_EQ(MessageCountFilter::FILTER_REMOVED,
344 global_filter->last_filter_event());
345 EXPECT_EQ(MessageCountFilter::FILTER_REMOVED,
346 class_filter->last_filter_event());
347 EXPECT_EQ(0U, class_filter->messages_received());
348 EXPECT_EQ(0U, global_filter->messages_received());
351 // The test that follow trigger DCHECKS in debug build.
352 #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
354 TEST_F(IPCChannelProxyTest, BadMessageOnListenerThread) {
355 scoped_refptr<MessageCountFilter> class_filter(
356 new MessageCountFilter(TestMsgStart));
357 class_filter->set_message_filtering_enabled(false);
358 channel_proxy()->AddFilter(class_filter.get());
360 sender()->Send(new TestMsg_SendBadMessage());
362 SendQuitMessageAndWaitForIdle();
363 EXPECT_TRUE(DidListenerGetBadMessage());
366 TEST_F(IPCChannelProxyTest, BadMessageOnIPCThread) {
367 scoped_refptr<MessageCountFilter> class_filter(
368 new MessageCountFilter(TestMsgStart));
369 class_filter->set_message_filtering_enabled(true);
370 channel_proxy()->AddFilter(class_filter.get());
372 sender()->Send(new TestMsg_SendBadMessage());
374 SendQuitMessageAndWaitForIdle();
375 EXPECT_TRUE(DidListenerGetBadMessage());
378 class IPCChannelBadMessageTest : public IPCTestBase {
379 public:
380 void SetUp() override {
381 IPCTestBase::SetUp();
383 Init("ChannelProxyClient");
385 listener_.reset(new QuitListener());
386 CreateChannel(listener_.get());
387 ASSERT_TRUE(ConnectChannel());
389 ASSERT_TRUE(StartClient());
392 void TearDown() override {
393 listener_.reset();
394 IPCTestBase::TearDown();
397 void SendQuitMessageAndWaitForIdle() {
398 sender()->Send(new WorkerMsg_Quit);
399 base::MessageLoop::current()->Run();
400 EXPECT_TRUE(WaitForClientShutdown());
403 bool DidListenerGetBadMessage() {
404 return listener_->bad_message_received_;
407 private:
408 scoped_ptr<QuitListener> listener_;
411 #if !defined(OS_WIN)
412 // TODO(jam): for some reason this is flaky on win buildbots.
413 TEST_F(IPCChannelBadMessageTest, BadMessage) {
414 sender()->Send(new TestMsg_SendBadMessage());
415 SendQuitMessageAndWaitForIdle();
416 EXPECT_TRUE(DidListenerGetBadMessage());
418 #endif
420 #endif
422 MULTIPROCESS_IPC_TEST_CLIENT_MAIN(ChannelProxyClient) {
423 base::MessageLoopForIO main_message_loop;
424 ChannelReflectorListener listener;
425 scoped_ptr<IPC::Channel> channel(IPC::Channel::CreateClient(
426 IPCTestBase::GetChannelName("ChannelProxyClient"),
427 &listener));
428 CHECK(channel->Connect());
429 listener.Init(channel.get());
431 base::MessageLoop::current()->Run();
432 return 0;
435 } // namespace