ipc_channel_proxy_unittest.cc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  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.
  4. #include "build/build_config.h"
  5. #include <stddef.h>
  6. #include <stdint.h>
  7. #include <memory>
  8. #include "base/message_loop/message_pump_type.h"
  9. #include "base/pickle.h"
  10. #include "base/run_loop.h"
  11. #include "base/threading/thread.h"
  12. #include "ipc/ipc_message.h"
  13. #include "ipc/ipc_test_base.h"
  14. #include "ipc/message_filter.h"
  15. // Get basic type definitions.
  16. #define IPC_MESSAGE_IMPL
  17. #include "ipc/ipc_channel_proxy_unittest_messages.h"
  18. // Generate constructors.
  19. #include "ipc/struct_constructor_macros.h"
  20. #include "ipc/ipc_channel_proxy_unittest_messages.h"
  21. // Generate param traits write methods.
  22. #include "ipc/param_traits_write_macros.h"
  23. namespace IPC {
  24. #include "ipc/ipc_channel_proxy_unittest_messages.h"
  25. } // namespace IPC
  26. // Generate param traits read methods.
  27. #include "ipc/param_traits_read_macros.h"
  28. namespace IPC {
  29. #include "ipc/ipc_channel_proxy_unittest_messages.h"
  30. } // namespace IPC
  31. // Generate param traits log methods.
  32. #include "ipc/param_traits_log_macros.h"
  33. namespace IPC {
  34. #include "ipc/ipc_channel_proxy_unittest_messages.h"
  35. } // namespace IPC
  36. namespace {
  37. void CreateRunLoopAndRun(base::RunLoop** run_loop_ptr) {
  38. base::RunLoop run_loop;
  39. *run_loop_ptr = &run_loop;
  40. run_loop.Run();
  41. *run_loop_ptr = nullptr;
  42. }
  43. class QuitListener : public IPC::Listener {
  44. public:
  45. QuitListener() = default;
  46. bool OnMessageReceived(const IPC::Message& message) override {
  47. IPC_BEGIN_MESSAGE_MAP(QuitListener, message)
  48. IPC_MESSAGE_HANDLER(WorkerMsg_Quit, OnQuit)
  49. IPC_MESSAGE_HANDLER(TestMsg_BadMessage, OnBadMessage)
  50. IPC_END_MESSAGE_MAP()
  51. return true;
  52. }
  53. void OnBadMessageReceived(const IPC::Message& message) override {
  54. bad_message_received_ = true;
  55. }
  56. void OnChannelError() override { CHECK(quit_message_received_); }
  57. void OnQuit() {
  58. quit_message_received_ = true;
  59. run_loop_->QuitWhenIdle();
  60. }
  61. void OnBadMessage(const BadType& bad_type) {
  62. // Should never be called since IPC wouldn't be deserialized correctly.
  63. CHECK(false);
  64. }
  65. bool bad_message_received_ = false;
  66. bool quit_message_received_ = false;
  67. base::RunLoop* run_loop_ = nullptr;
  68. };
  69. class ChannelReflectorListener : public IPC::Listener {
  70. public:
  71. ChannelReflectorListener() = default;
  72. void Init(IPC::Channel* channel) {
  73. DCHECK(!channel_);
  74. channel_ = channel;
  75. }
  76. bool OnMessageReceived(const IPC::Message& message) override {
  77. IPC_BEGIN_MESSAGE_MAP(ChannelReflectorListener, message)
  78. IPC_MESSAGE_HANDLER(TestMsg_Bounce, OnTestBounce)
  79. IPC_MESSAGE_HANDLER(TestMsg_SendBadMessage, OnSendBadMessage)
  80. IPC_MESSAGE_HANDLER(AutomationMsg_Bounce, OnAutomationBounce)
  81. IPC_MESSAGE_HANDLER(WorkerMsg_Bounce, OnBounce)
  82. IPC_MESSAGE_HANDLER(WorkerMsg_Quit, OnQuit)
  83. IPC_END_MESSAGE_MAP()
  84. return true;
  85. }
  86. void OnTestBounce() {
  87. channel_->Send(new TestMsg_Bounce());
  88. }
  89. void OnSendBadMessage() {
  90. channel_->Send(new TestMsg_BadMessage(BadType()));
  91. }
  92. void OnAutomationBounce() { channel_->Send(new AutomationMsg_Bounce()); }
  93. void OnBounce() {
  94. channel_->Send(new WorkerMsg_Bounce());
  95. }
  96. void OnQuit() {
  97. channel_->Send(new WorkerMsg_Quit());
  98. run_loop_->QuitWhenIdle();
  99. }
  100. base::RunLoop* run_loop_ = nullptr;
  101. private:
  102. IPC::Channel* channel_ = nullptr;
  103. };
  104. class MessageCountFilter : public IPC::MessageFilter {
  105. public:
  106. enum FilterEvent {
  107. NONE,
  108. FILTER_ADDED,
  109. CHANNEL_CONNECTED,
  110. CHANNEL_ERROR,
  111. CHANNEL_CLOSING,
  112. FILTER_REMOVED
  113. };
  114. MessageCountFilter() = default;
  115. MessageCountFilter(uint32_t supported_message_class)
  116. : supported_message_class_(supported_message_class),
  117. is_global_filter_(false) {}
  118. void OnFilterAdded(IPC::Channel* channel) override {
  119. EXPECT_TRUE(channel);
  120. EXPECT_EQ(NONE, last_filter_event_);
  121. last_filter_event_ = FILTER_ADDED;
  122. }
  123. void OnChannelConnected(int32_t peer_pid) override {
  124. EXPECT_EQ(FILTER_ADDED, last_filter_event_);
  125. EXPECT_NE(static_cast<int32_t>(base::kNullProcessId), peer_pid);
  126. last_filter_event_ = CHANNEL_CONNECTED;
  127. }
  128. void OnChannelError() override {
  129. EXPECT_EQ(CHANNEL_CONNECTED, last_filter_event_);
  130. last_filter_event_ = CHANNEL_ERROR;
  131. }
  132. void OnChannelClosing() override {
  133. // We may or may not have gotten OnChannelError; if not, the last event has
  134. // to be OnChannelConnected.
  135. EXPECT_NE(FILTER_REMOVED, last_filter_event_);
  136. if (last_filter_event_ != CHANNEL_ERROR)
  137. EXPECT_EQ(CHANNEL_CONNECTED, last_filter_event_);
  138. last_filter_event_ = CHANNEL_CLOSING;
  139. }
  140. void OnFilterRemoved() override {
  141. // A filter may be removed at any time, even before the channel is connected
  142. // (and thus before OnFilterAdded is ever able to dispatch.) The only time
  143. // we won't see OnFilterRemoved is immediately after OnFilterAdded, because
  144. // OnChannelConnected is always the next event to fire after that.
  145. EXPECT_NE(FILTER_ADDED, last_filter_event_);
  146. last_filter_event_ = FILTER_REMOVED;
  147. }
  148. bool OnMessageReceived(const IPC::Message& message) override {
  149. // We should always get the OnFilterAdded and OnChannelConnected events
  150. // prior to any messages.
  151. EXPECT_EQ(CHANNEL_CONNECTED, last_filter_event_);
  152. if (!is_global_filter_) {
  153. EXPECT_EQ(supported_message_class_, IPC_MESSAGE_CLASS(message));
  154. }
  155. ++messages_received_;
  156. if (!message_filtering_enabled_)
  157. return false;
  158. bool handled = true;
  159. IPC_BEGIN_MESSAGE_MAP(MessageCountFilter, message)
  160. IPC_MESSAGE_HANDLER(TestMsg_BadMessage, OnBadMessage)
  161. IPC_MESSAGE_UNHANDLED(handled = false)
  162. IPC_END_MESSAGE_MAP()
  163. return handled;
  164. }
  165. void OnBadMessage(const BadType& bad_type) {
  166. // Should never be called since IPC wouldn't be deserialized correctly.
  167. CHECK(false);
  168. }
  169. bool GetSupportedMessageClasses(
  170. std::vector<uint32_t>* supported_message_classes) const override {
  171. if (is_global_filter_)
  172. return false;
  173. supported_message_classes->push_back(supported_message_class_);
  174. return true;
  175. }
  176. void set_message_filtering_enabled(bool enabled) {
  177. message_filtering_enabled_ = enabled;
  178. }
  179. size_t messages_received() const { return messages_received_; }
  180. FilterEvent last_filter_event() const { return last_filter_event_; }
  181. private:
  182. ~MessageCountFilter() override = default;
  183. size_t messages_received_ = 0;
  184. uint32_t supported_message_class_ = 0;
  185. bool is_global_filter_ = true;
  186. FilterEvent last_filter_event_ = NONE;
  187. bool message_filtering_enabled_ = false;
  188. };
  189. class IPCChannelProxyTest : public IPCChannelMojoTestBase {
  190. public:
  191. IPCChannelProxyTest() = default;
  192. ~IPCChannelProxyTest() override = default;
  193. void SetUp() override {
  194. IPCChannelMojoTestBase::SetUp();
  195. Init("ChannelProxyClient");
  196. thread_ = std::make_unique<base::Thread>("ChannelProxyTestServerThread");
  197. base::Thread::Options options;
  198. options.message_pump_type = base::MessagePumpType::IO;
  199. thread_->StartWithOptions(std::move(options));
  200. listener_ = std::make_unique<QuitListener>();
  201. channel_proxy_ = IPC::ChannelProxy::Create(
  202. TakeHandle().release(), IPC::Channel::MODE_SERVER, listener_.get(),
  203. thread_->task_runner(), base::ThreadTaskRunnerHandle::Get());
  204. }
  205. void TearDown() override {
  206. channel_proxy_.reset();
  207. thread_.reset();
  208. listener_.reset();
  209. IPCChannelMojoTestBase::TearDown();
  210. }
  211. void SendQuitMessageAndWaitForIdle() {
  212. sender()->Send(new WorkerMsg_Quit);
  213. CreateRunLoopAndRun(&listener_->run_loop_);
  214. EXPECT_TRUE(WaitForClientShutdown());
  215. }
  216. bool DidListenerGetBadMessage() {
  217. return listener_->bad_message_received_;
  218. }
  219. IPC::ChannelProxy* channel_proxy() { return channel_proxy_.get(); }
  220. IPC::Sender* sender() { return channel_proxy_.get(); }
  221. private:
  222. std::unique_ptr<base::Thread> thread_;
  223. std::unique_ptr<QuitListener> listener_;
  224. std::unique_ptr<IPC::ChannelProxy> channel_proxy_;
  225. };
  226. TEST_F(IPCChannelProxyTest, MessageClassFilters) {
  227. // Construct a filter per message class.
  228. std::vector<scoped_refptr<MessageCountFilter>> class_filters;
  229. class_filters.push_back(
  230. base::MakeRefCounted<MessageCountFilter>(TestMsgStart));
  231. class_filters.push_back(
  232. base::MakeRefCounted<MessageCountFilter>(AutomationMsgStart));
  233. for (size_t i = 0; i < class_filters.size(); ++i)
  234. channel_proxy()->AddFilter(class_filters[i].get());
  235. // Send a message for each class; each filter should receive just one message.
  236. sender()->Send(new TestMsg_Bounce);
  237. sender()->Send(new AutomationMsg_Bounce);
  238. // Send some messages not assigned to a specific or valid message class.
  239. sender()->Send(new WorkerMsg_Bounce);
  240. // Each filter should have received just the one sent message of the
  241. // corresponding class.
  242. SendQuitMessageAndWaitForIdle();
  243. for (size_t i = 0; i < class_filters.size(); ++i)
  244. EXPECT_EQ(1U, class_filters[i]->messages_received());
  245. }
  246. TEST_F(IPCChannelProxyTest, GlobalAndMessageClassFilters) {
  247. // Add a class and global filter.
  248. scoped_refptr<MessageCountFilter> class_filter(
  249. new MessageCountFilter(TestMsgStart));
  250. class_filter->set_message_filtering_enabled(false);
  251. channel_proxy()->AddFilter(class_filter.get());
  252. scoped_refptr<MessageCountFilter> global_filter(new MessageCountFilter());
  253. global_filter->set_message_filtering_enabled(false);
  254. channel_proxy()->AddFilter(global_filter.get());
  255. // A message of class Test should be seen by both the global filter and
  256. // Test-specific filter.
  257. sender()->Send(new TestMsg_Bounce);
  258. // A message of a different class should be seen only by the global filter.
  259. sender()->Send(new AutomationMsg_Bounce);
  260. // Flush all messages.
  261. SendQuitMessageAndWaitForIdle();
  262. // The class filter should have received only the class-specific message.
  263. EXPECT_EQ(1U, class_filter->messages_received());
  264. // The global filter should have received both messages, as well as the final
  265. // QUIT message.
  266. EXPECT_EQ(3U, global_filter->messages_received());
  267. }
  268. TEST_F(IPCChannelProxyTest, FilterRemoval) {
  269. // Add a class and global filter.
  270. scoped_refptr<MessageCountFilter> class_filter(
  271. new MessageCountFilter(TestMsgStart));
  272. scoped_refptr<MessageCountFilter> global_filter(new MessageCountFilter());
  273. // Add and remove both types of filters.
  274. channel_proxy()->AddFilter(class_filter.get());
  275. channel_proxy()->AddFilter(global_filter.get());
  276. channel_proxy()->RemoveFilter(global_filter.get());
  277. channel_proxy()->RemoveFilter(class_filter.get());
  278. // Send some messages; they should not be seen by either filter.
  279. sender()->Send(new TestMsg_Bounce);
  280. sender()->Send(new AutomationMsg_Bounce);
  281. // Ensure that the filters were removed and did not receive any messages.
  282. SendQuitMessageAndWaitForIdle();
  283. EXPECT_EQ(MessageCountFilter::FILTER_REMOVED,
  284. global_filter->last_filter_event());
  285. EXPECT_EQ(MessageCountFilter::FILTER_REMOVED,
  286. class_filter->last_filter_event());
  287. EXPECT_EQ(0U, class_filter->messages_received());
  288. EXPECT_EQ(0U, global_filter->messages_received());
  289. }
  290. TEST_F(IPCChannelProxyTest, BadMessageOnListenerThread) {
  291. scoped_refptr<MessageCountFilter> class_filter(
  292. new MessageCountFilter(TestMsgStart));
  293. class_filter->set_message_filtering_enabled(false);
  294. channel_proxy()->AddFilter(class_filter.get());
  295. sender()->Send(new TestMsg_SendBadMessage());
  296. SendQuitMessageAndWaitForIdle();
  297. EXPECT_TRUE(DidListenerGetBadMessage());
  298. }
  299. TEST_F(IPCChannelProxyTest, BadMessageOnIPCThread) {
  300. scoped_refptr<MessageCountFilter> class_filter(
  301. new MessageCountFilter(TestMsgStart));
  302. class_filter->set_message_filtering_enabled(true);
  303. channel_proxy()->AddFilter(class_filter.get());
  304. sender()->Send(new TestMsg_SendBadMessage());
  305. SendQuitMessageAndWaitForIdle();
  306. EXPECT_TRUE(DidListenerGetBadMessage());
  307. }
  308. class IPCChannelBadMessageTest : public IPCChannelMojoTestBase {
  309. public:
  310. void SetUp() override {
  311. IPCChannelMojoTestBase::SetUp();
  312. Init("ChannelProxyClient");
  313. listener_ = std::make_unique<QuitListener>();
  314. CreateChannel(listener_.get());
  315. ASSERT_TRUE(ConnectChannel());
  316. }
  317. void TearDown() override {
  318. IPCChannelMojoTestBase::TearDown();
  319. listener_.reset();
  320. }
  321. void SendQuitMessageAndWaitForIdle() {
  322. sender()->Send(new WorkerMsg_Quit);
  323. CreateRunLoopAndRun(&listener_->run_loop_);
  324. EXPECT_TRUE(WaitForClientShutdown());
  325. }
  326. bool DidListenerGetBadMessage() {
  327. return listener_->bad_message_received_;
  328. }
  329. private:
  330. std::unique_ptr<QuitListener> listener_;
  331. };
  332. TEST_F(IPCChannelBadMessageTest, BadMessage) {
  333. sender()->Send(new TestMsg_SendBadMessage());
  334. SendQuitMessageAndWaitForIdle();
  335. EXPECT_TRUE(DidListenerGetBadMessage());
  336. }
  337. DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(ChannelProxyClient) {
  338. ChannelReflectorListener listener;
  339. Connect(&listener);
  340. listener.Init(channel());
  341. CreateRunLoopAndRun(&listener.run_loop_);
  342. Close();
  343. }
  344. } // namespace