Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(96)

Unified Diff: ipc/ipc_channel_proxy_unittest.cc

Issue 282303014: Add regression tests to ensure that IPC::Listener::OnBadMessageReceived is always called for all ca… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ipc/ipc_channel_proxy_unittest.cc
===================================================================
--- ipc/ipc_channel_proxy_unittest.cc (revision 271102)
+++ ipc/ipc_channel_proxy_unittest.cc (working copy)
@@ -8,47 +8,69 @@
#include "base/pickle.h"
#include "base/threading/thread.h"
#include "ipc/ipc_message.h"
-#include "ipc/ipc_message_macros.h"
#include "ipc/ipc_test_base.h"
#include "ipc/message_filter.h"
-namespace {
+// Get basic type definitions.
+#define IPC_MESSAGE_IMPL
+#include "ipc/ipc_channel_proxy_unittest_messages.h"
-#if defined(IPC_MESSAGE_START)
-#undef IPC_MESSAGE_START
-#endif
+// Generate constructors.
+#include "ipc/struct_constructor_macros.h"
+#include "ipc/ipc_channel_proxy_unittest_messages.h"
-enum Command {
- SEND,
- QUIT
-};
+// Generate destructors.
+#include "ipc/struct_destructor_macros.h"
+#include "ipc/ipc_channel_proxy_unittest_messages.h"
-static void Send(IPC::Sender* sender,
- int message_class,
- Command command) {
- const int IPC_MESSAGE_START = message_class;
- IPC::Message* message = new IPC::Message(0,
- IPC_MESSAGE_ID(),
- IPC::Message::PRIORITY_NORMAL);
- message->WriteInt(command);
- sender->Send(message);
-}
+// Generate param traits write methods.
+#include "ipc/param_traits_write_macros.h"
+namespace IPC {
+#include "ipc/ipc_channel_proxy_unittest_messages.h"
+} // namespace IPC
+// Generate param traits read methods.
+#include "ipc/param_traits_read_macros.h"
+namespace IPC {
+#include "ipc/ipc_channel_proxy_unittest_messages.h"
+} // namespace IPC
+
+// Generate param traits log methods.
+#include "ipc/param_traits_log_macros.h"
+namespace IPC {
+#include "ipc/ipc_channel_proxy_unittest_messages.h"
+} // namespace IPC
+
+
+namespace {
+
class QuitListener : public IPC::Listener {
public:
- QuitListener() {}
+ QuitListener() : bad_message_received_(false) {}
virtual ~QuitListener() {}
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
- PickleIterator iter(message);
+ IPC_BEGIN_MESSAGE_MAP(QuitListener, message)
+ IPC_MESSAGE_HANDLER(WorkerMsg_Quit, OnQuit)
+ IPC_MESSAGE_HANDLER(TestMsg_BadMessage, OnBadMessage)
+ IPC_END_MESSAGE_MAP()
+ return true;
+ }
- int command = SEND;
- EXPECT_TRUE(iter.ReadInt(&command));
- if (command == QUIT)
- base::MessageLoop::current()->QuitWhenIdle();
+ virtual void OnBadMessageReceived(const IPC::Message& message) OVERRIDE {
+ bad_message_received_ = true;
+ }
- return true;
+ void OnQuit() {
+ base::MessageLoop::current()->QuitWhenIdle();
}
+
+ void OnBadMessage(const BadType& bad_type) {
+ // Should never be called since IPC wouldn't be deserialized correctly.
+ CHECK(false);
+ }
+
+ bool bad_message_received_;
};
class ChannelReflectorListener : public IPC::Listener {
@@ -62,22 +84,37 @@
}
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
- CHECK(channel_);
+ IPC_BEGIN_MESSAGE_MAP(ChannelReflectorListener, message)
+ IPC_MESSAGE_HANDLER(TestMsg_Bounce, OnTestBounce)
+ IPC_MESSAGE_HANDLER(TestMsg_SendBadMessage, OnSendBadMessage)
+ IPC_MESSAGE_HANDLER(UtilityMsg_Bounce, OnUtilityBounce)
+ IPC_MESSAGE_HANDLER(WorkerMsg_Bounce, OnBounce)
+ IPC_MESSAGE_HANDLER(WorkerMsg_Quit, OnQuit)
+ IPC_END_MESSAGE_MAP()
+ return true;
+ }
- PickleIterator iter(message);
+ void OnTestBounce() {
+ channel_->Send(new TestMsg_Bounce());
+ }
- int command = SEND;
- EXPECT_TRUE(iter.ReadInt(&command));
- if (command == QUIT) {
- channel_->Send(new IPC::Message(message));
- base::MessageLoop::current()->QuitWhenIdle();
- return true;
- }
+ void OnSendBadMessage() {
+ channel_->Send(new TestMsg_BadMessage(BadType()));
+ }
- channel_->Send(new IPC::Message(message));
- return true;
+ void OnUtilityBounce() {
+ channel_->Send(new UtilityMsg_Bounce());
}
+ void OnBounce() {
+ channel_->Send(new WorkerMsg_Bounce());
+ }
+
+ void OnQuit() {
+ channel_->Send(new WorkerMsg_Quit());
+ base::MessageLoop::current()->QuitWhenIdle();
+ }
+
private:
IPC::Channel* channel_;
};
@@ -149,9 +186,23 @@
EXPECT_EQ(supported_message_class_, IPC_MESSAGE_CLASS(message));
}
++messages_received_;
- return message_filtering_enabled_;
+
+ if (!message_filtering_enabled_)
+ return false;
+
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(MessageCountFilter, message)
+ IPC_MESSAGE_HANDLER(TestMsg_BadMessage, OnBadMessage)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
}
+ void OnBadMessage(const BadType& bad_type) {
+ // Should never be called since IPC wouldn't be deserialized correctly.
+ CHECK(false);
+ }
+
virtual bool GetSupportedMessageClasses(
std::vector<uint32>* supported_message_classes) const OVERRIDE {
if (is_global_filter_)
@@ -207,11 +258,15 @@
}
void SendQuitMessageAndWaitForIdle() {
- Send(sender(), -1, QUIT);
+ sender()->Send(new WorkerMsg_Quit);
base::MessageLoop::current()->Run();
EXPECT_TRUE(WaitForClientShutdown());
}
+ bool DidListenerGetBadMessage() {
+ return listener_->bad_message_received_;
+ }
+
private:
scoped_ptr<base::Thread> thread_;
scoped_ptr<QuitListener> listener_;
@@ -220,20 +275,19 @@
TEST_F(IPCChannelProxyTest, MessageClassFilters) {
// Construct a filter per message class.
std::vector<scoped_refptr<MessageCountFilter> > class_filters;
- for (uint32 i = 0; i < LastIPCMsgStart; ++i) {
- class_filters.push_back(make_scoped_refptr(
- new MessageCountFilter(i)));
- channel_proxy()->AddFilter(class_filters.back().get());
- }
+ class_filters.push_back(make_scoped_refptr(
+ new MessageCountFilter(TestMsgStart)));
+ class_filters.push_back(make_scoped_refptr(
+ new MessageCountFilter(UtilityMsgStart)));
+ for (size_t i = 0; i < class_filters.size(); ++i)
+ channel_proxy()->AddFilter(class_filters[i].get());
// Send a message for each class; each filter should receive just one message.
- for (uint32 i = 0; i < LastIPCMsgStart; ++i)
- Send(sender(), i, SEND);
+ sender()->Send(new TestMsg_Bounce());
+ sender()->Send(new UtilityMsg_Bounce());
// Send some messages not assigned to a specific or valid message class.
- Send(sender(), -1, SEND);
- Send(sender(), LastIPCMsgStart, SEND);
- Send(sender(), LastIPCMsgStart + 1, SEND);
+ sender()->Send(new WorkerMsg_Bounce);
// Each filter should have received just the one sent message of the
// corresponding class.
@@ -244,9 +298,8 @@
TEST_F(IPCChannelProxyTest, GlobalAndMessageClassFilters) {
// Add a class and global filter.
- const int kMessageClass = 7;
scoped_refptr<MessageCountFilter> class_filter(
- new MessageCountFilter(kMessageClass));
+ new MessageCountFilter(TestMsgStart));
class_filter->set_message_filtering_enabled(false);
channel_proxy()->AddFilter(class_filter.get());
@@ -254,12 +307,12 @@
global_filter->set_message_filtering_enabled(false);
channel_proxy()->AddFilter(global_filter.get());
- // A message of class |kMessageClass| should be seen by both the global
- // filter and |kMessageClass|-specific filter.
- Send(sender(), kMessageClass, SEND);
+ // A message of class Test should be seen by both the global filter and
+ // Test-specific filter.
+ sender()->Send(new TestMsg_Bounce);
// A message of a different class should be seen only by the global filter.
- Send(sender(), kMessageClass + 1, SEND);
+ sender()->Send(new UtilityMsg_Bounce);
// Flush all messages.
SendQuitMessageAndWaitForIdle();
@@ -267,16 +320,15 @@
// The class filter should have received only the class-specific message.
EXPECT_EQ(1U, class_filter->messages_received());
- // The global filter should have received both SEND messages, as well as the
- // final QUIT message.
+ // The global filter should have received both messages, as well as the final
+ // QUIT message.
EXPECT_EQ(3U, global_filter->messages_received());
}
TEST_F(IPCChannelProxyTest, FilterRemoval) {
// Add a class and global filter.
- const int kMessageClass = 7;
scoped_refptr<MessageCountFilter> class_filter(
- new MessageCountFilter(kMessageClass));
+ new MessageCountFilter(TestMsgStart));
scoped_refptr<MessageCountFilter> global_filter(new MessageCountFilter());
// Add and remove both types of filters.
@@ -286,8 +338,8 @@
channel_proxy()->RemoveFilter(class_filter.get());
// Send some messages; they should not be seen by either filter.
- Send(sender(), 0, SEND);
- Send(sender(), kMessageClass, SEND);
+ sender()->Send(new TestMsg_Bounce);
+ sender()->Send(new UtilityMsg_Bounce);
// Ensure that the filters were removed and did not receive any messages.
SendQuitMessageAndWaitForIdle();
@@ -299,6 +351,77 @@
EXPECT_EQ(0U, global_filter->messages_received());
}
+// The test that follow trigger DCHECKS in debug build.
+#if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
+
+TEST_F(IPCChannelProxyTest, BadMessageOnListenerThread) {
+ scoped_refptr<MessageCountFilter> class_filter(
+ new MessageCountFilter(TestMsgStart));
+ class_filter->set_message_filtering_enabled(false);
+ channel_proxy()->AddFilter(class_filter.get());
+
+ sender()->Send(new TestMsg_SendBadMessage());
+
+ SendQuitMessageAndWaitForIdle();
+ EXPECT_TRUE(DidListenerGetBadMessage());
+}
+
+TEST_F(IPCChannelProxyTest, BadMessageOnIPCThread) {
+ scoped_refptr<MessageCountFilter> class_filter(
+ new MessageCountFilter(TestMsgStart));
+ class_filter->set_message_filtering_enabled(true);
+ channel_proxy()->AddFilter(class_filter.get());
+
+ sender()->Send(new TestMsg_SendBadMessage());
+
+ SendQuitMessageAndWaitForIdle();
+ EXPECT_TRUE(DidListenerGetBadMessage());
+}
+
+class IPCChannelBadMessageTest : public IPCTestBase {
+ public:
+ IPCChannelBadMessageTest() {}
+ virtual ~IPCChannelBadMessageTest() {}
+
+ virtual void SetUp() OVERRIDE {
+ IPCTestBase::SetUp();
+
+ Init("ChannelProxyClient");
+
+ listener_.reset(new QuitListener());
+ CreateChannel(listener_.get());
+ ASSERT_TRUE(ConnectChannel());
+
+ ASSERT_TRUE(StartClient());
+ }
+
+ virtual void TearDown() {
+ listener_.reset();
+ IPCTestBase::TearDown();
+ }
+
+ void SendQuitMessageAndWaitForIdle() {
+ sender()->Send(new WorkerMsg_Quit);
+ base::MessageLoop::current()->Run();
+ EXPECT_TRUE(WaitForClientShutdown());
+ }
+
+ bool DidListenerGetBadMessage() {
+ return listener_->bad_message_received_;
+ }
+
+ private:
+ scoped_ptr<QuitListener> listener_;
+};
+
+TEST_F(IPCChannelBadMessageTest, BadMessage) {
+ sender()->Send(new TestMsg_SendBadMessage());
+ SendQuitMessageAndWaitForIdle();
+ EXPECT_TRUE(DidListenerGetBadMessage());
+}
+
+#endif
+
MULTIPROCESS_IPC_TEST_CLIENT_MAIN(ChannelProxyClient) {
base::MessageLoopForIO main_message_loop;
ChannelReflectorListener listener;
« no previous file with comments | « content/browser/renderer_host/render_view_host_unittest.cc ('k') | ipc/ipc_channel_proxy_unittest_messages.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698