Home | History | Annotate | Download | only in tests
      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 
      5 #include "mojo/public/cpp/bindings/lib/router.h"
      6 
      7 #include <utility>
      8 
      9 #include "base/bind.h"
     10 #include "base/message_loop/message_loop.h"
     11 #include "base/run_loop.h"
     12 #include "base/threading/thread_task_runner_handle.h"
     13 #include "mojo/public/cpp/bindings/tests/message_queue.h"
     14 #include "mojo/public/cpp/bindings/tests/router_test_util.h"
     15 #include "testing/gtest/include/gtest/gtest.h"
     16 
     17 namespace mojo {
     18 namespace test {
     19 namespace {
     20 
     21 class RouterTest : public testing::Test {
     22  public:
     23   RouterTest() {}
     24 
     25   void SetUp() override {
     26     CreateMessagePipe(nullptr, &handle0_, &handle1_);
     27   }
     28 
     29   void TearDown() override {}
     30 
     31   void PumpMessages() { base::RunLoop().RunUntilIdle(); }
     32 
     33  protected:
     34   ScopedMessagePipeHandle handle0_;
     35   ScopedMessagePipeHandle handle1_;
     36 
     37  private:
     38   base::MessageLoop loop_;
     39 };
     40 
     41 TEST_F(RouterTest, BasicRequestResponse) {
     42   internal::Router router0(std::move(handle0_), internal::FilterChain(), false,
     43                            base::ThreadTaskRunnerHandle::Get());
     44   internal::Router router1(std::move(handle1_), internal::FilterChain(), false,
     45                            base::ThreadTaskRunnerHandle::Get());
     46 
     47   ResponseGenerator generator;
     48   router1.set_incoming_receiver(&generator);
     49 
     50   Message request;
     51   AllocRequestMessage(1, "hello", &request);
     52 
     53   MessageQueue message_queue;
     54   base::RunLoop run_loop;
     55   router0.AcceptWithResponder(
     56       &request, new MessageAccumulator(&message_queue, run_loop.QuitClosure()));
     57 
     58   run_loop.Run();
     59 
     60   EXPECT_FALSE(message_queue.IsEmpty());
     61 
     62   Message response;
     63   message_queue.Pop(&response);
     64 
     65   EXPECT_EQ(std::string("hello world!"),
     66             std::string(reinterpret_cast<const char*>(response.payload())));
     67 
     68   // Send a second message on the pipe.
     69   Message request2;
     70   AllocRequestMessage(1, "hello again", &request2);
     71 
     72   base::RunLoop run_loop2;
     73   router0.AcceptWithResponder(
     74       &request2,
     75       new MessageAccumulator(&message_queue, run_loop2.QuitClosure()));
     76 
     77   run_loop2.Run();
     78 
     79   EXPECT_FALSE(message_queue.IsEmpty());
     80 
     81   message_queue.Pop(&response);
     82 
     83   EXPECT_EQ(std::string("hello again world!"),
     84             std::string(reinterpret_cast<const char*>(response.payload())));
     85 }
     86 
     87 TEST_F(RouterTest, BasicRequestResponse_Synchronous) {
     88   internal::Router router0(std::move(handle0_), internal::FilterChain(), false,
     89                            base::ThreadTaskRunnerHandle::Get());
     90   internal::Router router1(std::move(handle1_), internal::FilterChain(), false,
     91                            base::ThreadTaskRunnerHandle::Get());
     92 
     93   ResponseGenerator generator;
     94   router1.set_incoming_receiver(&generator);
     95 
     96   Message request;
     97   AllocRequestMessage(1, "hello", &request);
     98 
     99   MessageQueue message_queue;
    100   router0.AcceptWithResponder(&request, new MessageAccumulator(&message_queue));
    101 
    102   router1.WaitForIncomingMessage(MOJO_DEADLINE_INDEFINITE);
    103   router0.WaitForIncomingMessage(MOJO_DEADLINE_INDEFINITE);
    104 
    105   EXPECT_FALSE(message_queue.IsEmpty());
    106 
    107   Message response;
    108   message_queue.Pop(&response);
    109 
    110   EXPECT_EQ(std::string("hello world!"),
    111             std::string(reinterpret_cast<const char*>(response.payload())));
    112 
    113   // Send a second message on the pipe.
    114   Message request2;
    115   AllocRequestMessage(1, "hello again", &request2);
    116 
    117   router0.AcceptWithResponder(&request2,
    118                               new MessageAccumulator(&message_queue));
    119 
    120   router1.WaitForIncomingMessage(MOJO_DEADLINE_INDEFINITE);
    121   router0.WaitForIncomingMessage(MOJO_DEADLINE_INDEFINITE);
    122 
    123   EXPECT_FALSE(message_queue.IsEmpty());
    124 
    125   message_queue.Pop(&response);
    126 
    127   EXPECT_EQ(std::string("hello again world!"),
    128             std::string(reinterpret_cast<const char*>(response.payload())));
    129 }
    130 
    131 TEST_F(RouterTest, RequestWithNoReceiver) {
    132   internal::Router router0(std::move(handle0_), internal::FilterChain(), false,
    133                            base::ThreadTaskRunnerHandle::Get());
    134   internal::Router router1(std::move(handle1_), internal::FilterChain(), false,
    135                            base::ThreadTaskRunnerHandle::Get());
    136 
    137   // Without an incoming receiver set on router1, we expect router0 to observe
    138   // an error as a result of sending a message.
    139 
    140   Message request;
    141   AllocRequestMessage(1, "hello", &request);
    142 
    143   MessageQueue message_queue;
    144   base::RunLoop run_loop, run_loop2;
    145   router0.set_connection_error_handler(run_loop.QuitClosure());
    146   router1.set_connection_error_handler(run_loop2.QuitClosure());
    147   router0.AcceptWithResponder(&request, new MessageAccumulator(&message_queue));
    148 
    149   run_loop.Run();
    150   run_loop2.Run();
    151 
    152   EXPECT_TRUE(router0.encountered_error());
    153   EXPECT_TRUE(router1.encountered_error());
    154   EXPECT_TRUE(message_queue.IsEmpty());
    155 }
    156 
    157 // Tests Router using the LazyResponseGenerator. The responses will not be
    158 // sent until after the requests have been accepted.
    159 TEST_F(RouterTest, LazyResponses) {
    160   internal::Router router0(std::move(handle0_), internal::FilterChain(), false,
    161                            base::ThreadTaskRunnerHandle::Get());
    162   internal::Router router1(std::move(handle1_), internal::FilterChain(), false,
    163                            base::ThreadTaskRunnerHandle::Get());
    164 
    165   base::RunLoop run_loop;
    166   LazyResponseGenerator generator(run_loop.QuitClosure());
    167   router1.set_incoming_receiver(&generator);
    168 
    169   Message request;
    170   AllocRequestMessage(1, "hello", &request);
    171 
    172   MessageQueue message_queue;
    173   base::RunLoop run_loop2;
    174   router0.AcceptWithResponder(
    175       &request,
    176       new MessageAccumulator(&message_queue, run_loop2.QuitClosure()));
    177   run_loop.Run();
    178 
    179   // The request has been received but the response has not been sent yet.
    180   EXPECT_TRUE(message_queue.IsEmpty());
    181 
    182   // Send the response.
    183   EXPECT_TRUE(generator.responder_is_valid());
    184   generator.CompleteWithResponse();
    185   run_loop2.Run();
    186 
    187   // Check the response.
    188   EXPECT_FALSE(message_queue.IsEmpty());
    189   Message response;
    190   message_queue.Pop(&response);
    191   EXPECT_EQ(std::string("hello world!"),
    192             std::string(reinterpret_cast<const char*>(response.payload())));
    193 
    194   // Send a second message on the pipe.
    195   base::RunLoop run_loop3;
    196   LazyResponseGenerator generator2(run_loop3.QuitClosure());
    197 
    198   router1.set_incoming_receiver(&generator2);
    199   Message request2;
    200   AllocRequestMessage(1, "hello again", &request2);
    201 
    202   base::RunLoop run_loop4;
    203   router0.AcceptWithResponder(
    204       &request2,
    205       new MessageAccumulator(&message_queue, run_loop4.QuitClosure()));
    206   run_loop3.Run();
    207 
    208   // The request has been received but the response has not been sent yet.
    209   EXPECT_TRUE(message_queue.IsEmpty());
    210 
    211   // Send the second response.
    212   EXPECT_TRUE(generator2.responder_is_valid());
    213   generator2.CompleteWithResponse();
    214   run_loop4.Run();
    215 
    216   // Check the second response.
    217   EXPECT_FALSE(message_queue.IsEmpty());
    218   message_queue.Pop(&response);
    219   EXPECT_EQ(std::string("hello again world!"),
    220             std::string(reinterpret_cast<const char*>(response.payload())));
    221 }
    222 
    223 void ForwardErrorHandler(bool* called, const base::Closure& callback) {
    224   *called = true;
    225   callback.Run();
    226 }
    227 
    228 // Tests that if the receiving application destroys the responder_ without
    229 // sending a response, then we trigger connection error at both sides. Moreover,
    230 // both sides still appear to have a valid message pipe handle bound.
    231 TEST_F(RouterTest, MissingResponses) {
    232   base::RunLoop run_loop0, run_loop1;
    233   internal::Router router0(std::move(handle0_), internal::FilterChain(), false,
    234                            base::ThreadTaskRunnerHandle::Get());
    235   bool error_handler_called0 = false;
    236   router0.set_connection_error_handler(
    237       base::Bind(&ForwardErrorHandler, &error_handler_called0,
    238                  run_loop0.QuitClosure()));
    239 
    240   internal::Router router1(std::move(handle1_), internal::FilterChain(), false,
    241                            base::ThreadTaskRunnerHandle::Get());
    242   bool error_handler_called1 = false;
    243   router1.set_connection_error_handler(
    244       base::Bind(&ForwardErrorHandler, &error_handler_called1,
    245                  run_loop1.QuitClosure()));
    246 
    247   base::RunLoop run_loop3;
    248   LazyResponseGenerator generator(run_loop3.QuitClosure());
    249   router1.set_incoming_receiver(&generator);
    250   router1.set_incoming_receiver(&generator);
    251 
    252   Message request;
    253   AllocRequestMessage(1, "hello", &request);
    254 
    255   MessageQueue message_queue;
    256   router0.AcceptWithResponder(&request, new MessageAccumulator(&message_queue));
    257   run_loop3.Run();
    258 
    259   // The request has been received but no response has been sent.
    260   EXPECT_TRUE(message_queue.IsEmpty());
    261 
    262   // Destroy the responder MessagerReceiver but don't send any response.
    263   generator.CompleteWithoutResponse();
    264   run_loop0.Run();
    265   run_loop1.Run();
    266 
    267   // Check that no response was received.
    268   EXPECT_TRUE(message_queue.IsEmpty());
    269 
    270   // Connection error handler is called at both sides.
    271   EXPECT_TRUE(error_handler_called0);
    272   EXPECT_TRUE(error_handler_called1);
    273 
    274   // The error flag is set at both sides.
    275   EXPECT_TRUE(router0.encountered_error());
    276   EXPECT_TRUE(router1.encountered_error());
    277 
    278   // The message pipe handle is valid at both sides.
    279   EXPECT_TRUE(router0.is_valid());
    280   EXPECT_TRUE(router1.is_valid());
    281 }
    282 
    283 TEST_F(RouterTest, LateResponse) {
    284   // Test that things won't blow up if we try to send a message to a
    285   // MessageReceiver, which was given to us via AcceptWithResponder,
    286   // after the router has gone away.
    287 
    288   base::RunLoop run_loop;
    289   LazyResponseGenerator generator(run_loop.QuitClosure());
    290   {
    291     internal::Router router0(std::move(handle0_), internal::FilterChain(),
    292                              false, base::ThreadTaskRunnerHandle::Get());
    293     internal::Router router1(std::move(handle1_), internal::FilterChain(),
    294                              false, base::ThreadTaskRunnerHandle::Get());
    295 
    296     router1.set_incoming_receiver(&generator);
    297 
    298     Message request;
    299     AllocRequestMessage(1, "hello", &request);
    300 
    301     MessageQueue message_queue;
    302     router0.AcceptWithResponder(&request,
    303                                 new MessageAccumulator(&message_queue));
    304 
    305     run_loop.Run();
    306 
    307     EXPECT_TRUE(generator.has_responder());
    308   }
    309 
    310   EXPECT_FALSE(generator.responder_is_valid());
    311   generator.CompleteWithResponse();  // This should end up doing nothing.
    312 }
    313 
    314 }  // namespace
    315 }  // namespace test
    316 }  // namespace mojo
    317