Home | History | Annotate | Download | only in message_pump
      1 // Copyright 2013 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/message_pump/message_pump_mojo.h"
      6 
      7 #include "base/macros.h"
      8 #include "base/message_loop/message_loop_test.h"
      9 #include "base/run_loop.h"
     10 #include "mojo/message_pump/message_pump_mojo_handler.h"
     11 #include "mojo/public/cpp/system/core.h"
     12 #include "testing/gtest/include/gtest/gtest.h"
     13 
     14 namespace mojo {
     15 namespace common {
     16 namespace test {
     17 
     18 std::unique_ptr<base::MessagePump> CreateMojoMessagePump() {
     19   return std::unique_ptr<base::MessagePump>(new MessagePumpMojo());
     20 }
     21 
     22 RUN_MESSAGE_LOOP_TESTS(Mojo, &CreateMojoMessagePump);
     23 
     24 class CountingMojoHandler : public MessagePumpMojoHandler {
     25  public:
     26   CountingMojoHandler() : success_count_(0), error_count_(0) {}
     27 
     28   void OnHandleReady(const Handle& handle) override {
     29     ReadMessageRaw(static_cast<const MessagePipeHandle&>(handle),
     30                    NULL,
     31                    NULL,
     32                    NULL,
     33                    NULL,
     34                    MOJO_READ_MESSAGE_FLAG_NONE);
     35     ++success_count_;
     36     if (success_count_ == success_callback_count_ &&
     37         !success_callback_.is_null()) {
     38       success_callback_.Run();
     39       success_callback_.Reset();
     40     }
     41   }
     42 
     43   void set_success_callback(const base::Closure& callback,
     44                             int success_count) {
     45     success_callback_ = callback;
     46     success_callback_count_ = success_count;
     47   }
     48 
     49   void OnHandleError(const Handle& handle, MojoResult result) override {
     50     ++error_count_;
     51     if (!error_callback_.is_null()) {
     52       error_callback_.Run();
     53       error_callback_.Reset();
     54     }
     55   }
     56 
     57   void set_error_callback(const base::Closure& callback) {
     58     error_callback_ = callback;
     59   }
     60 
     61   int success_count() { return success_count_; }
     62   int error_count() { return error_count_; }
     63 
     64  private:
     65   int success_count_;
     66   int error_count_;
     67 
     68   base::Closure error_callback_;
     69   int success_callback_count_;
     70 
     71   base::Closure success_callback_;
     72 
     73   DISALLOW_COPY_AND_ASSIGN(CountingMojoHandler);
     74 };
     75 
     76 class CountingObserver : public MessagePumpMojo::Observer {
     77  public:
     78   void WillSignalHandler() override { will_signal_handler_count++; }
     79   void DidSignalHandler() override { did_signal_handler_count++; }
     80 
     81   int will_signal_handler_count = 0;
     82   int did_signal_handler_count = 0;
     83 };
     84 
     85 TEST(MessagePumpMojo, RunUntilIdle) {
     86   base::MessageLoop message_loop(MessagePumpMojo::Create());
     87   CountingMojoHandler handler;
     88   base::RunLoop run_loop;
     89   handler.set_success_callback(run_loop.QuitClosure(), 2);
     90   MessagePipe handles;
     91   MessagePumpMojo::current()->AddHandler(&handler,
     92                                          handles.handle0.get(),
     93                                          MOJO_HANDLE_SIGNAL_READABLE,
     94                                          base::TimeTicks());
     95   WriteMessageRaw(
     96       handles.handle1.get(), NULL, 0, NULL, 0, MOJO_WRITE_MESSAGE_FLAG_NONE);
     97   WriteMessageRaw(
     98       handles.handle1.get(), NULL, 0, NULL, 0, MOJO_WRITE_MESSAGE_FLAG_NONE);
     99   MojoHandleSignalsState hss;
    100   ASSERT_EQ(MOJO_RESULT_OK,
    101             MojoWait(handles.handle0.get().value(), MOJO_HANDLE_SIGNAL_READABLE,
    102                       MOJO_DEADLINE_INDEFINITE, &hss));
    103   run_loop.Run();
    104   EXPECT_EQ(2, handler.success_count());
    105 }
    106 
    107 TEST(MessagePumpMojo, Observer) {
    108   base::MessageLoop message_loop(MessagePumpMojo::Create());
    109 
    110   CountingObserver observer;
    111   MessagePumpMojo::current()->AddObserver(&observer);
    112 
    113   CountingMojoHandler handler;
    114   base::RunLoop run_loop;
    115   handler.set_success_callback(run_loop.QuitClosure(), 1);
    116   MessagePipe handles;
    117   MessagePumpMojo::current()->AddHandler(&handler,
    118                                          handles.handle0.get(),
    119                                          MOJO_HANDLE_SIGNAL_READABLE,
    120                                          base::TimeTicks());
    121   WriteMessageRaw(
    122       handles.handle1.get(), NULL, 0, NULL, 0, MOJO_WRITE_MESSAGE_FLAG_NONE);
    123 
    124   MojoHandleSignalsState hss;
    125   ASSERT_EQ(MOJO_RESULT_OK,
    126             MojoWait(handles.handle0.get().value(), MOJO_HANDLE_SIGNAL_READABLE,
    127                       MOJO_DEADLINE_INDEFINITE, &hss));
    128   run_loop.Run();
    129   EXPECT_EQ(1, handler.success_count());
    130   EXPECT_EQ(1, observer.will_signal_handler_count);
    131   EXPECT_EQ(1, observer.did_signal_handler_count);
    132   MessagePumpMojo::current()->RemoveObserver(&observer);
    133 
    134   base::RunLoop run_loop2;
    135   handler.set_success_callback(run_loop2.QuitClosure(), 2);
    136   WriteMessageRaw(
    137       handles.handle1.get(), NULL, 0, NULL, 0, MOJO_WRITE_MESSAGE_FLAG_NONE);
    138   ASSERT_EQ(MOJO_RESULT_OK,
    139             MojoWait(handles.handle0.get().value(), MOJO_HANDLE_SIGNAL_READABLE,
    140                       MOJO_DEADLINE_INDEFINITE, &hss));
    141   run_loop2.Run();
    142   EXPECT_EQ(2, handler.success_count());
    143   EXPECT_EQ(1, observer.will_signal_handler_count);
    144   EXPECT_EQ(1, observer.did_signal_handler_count);
    145 }
    146 
    147 TEST(MessagePumpMojo, UnregisterAfterDeadline) {
    148   base::MessageLoop message_loop(MessagePumpMojo::Create());
    149   CountingMojoHandler handler;
    150   base::RunLoop run_loop;
    151   handler.set_error_callback(run_loop.QuitClosure());
    152   MessagePipe handles;
    153   MessagePumpMojo::current()->AddHandler(
    154       &handler,
    155       handles.handle0.get(),
    156       MOJO_HANDLE_SIGNAL_READABLE,
    157       base::TimeTicks::Now() - base::TimeDelta::FromSeconds(1));
    158   run_loop.Run();
    159   EXPECT_EQ(1, handler.error_count());
    160 }
    161 
    162 TEST(MessagePumpMojo, AddClosedHandle) {
    163   base::MessageLoop message_loop(MessagePumpMojo::Create());
    164   CountingMojoHandler handler;
    165   MessagePipe handles;
    166   Handle closed_handle = handles.handle0.get();
    167   handles.handle0.reset();
    168   MessagePumpMojo::current()->AddHandler(
    169       &handler, closed_handle, MOJO_HANDLE_SIGNAL_READABLE, base::TimeTicks());
    170   base::RunLoop run_loop;
    171   run_loop.RunUntilIdle();
    172   MessagePumpMojo::current()->RemoveHandler(closed_handle);
    173   EXPECT_EQ(0, handler.error_count());
    174   EXPECT_EQ(0, handler.success_count());
    175 }
    176 
    177 TEST(MessagePumpMojo, CloseAfterAdding) {
    178   base::MessageLoop message_loop(MessagePumpMojo::Create());
    179   CountingMojoHandler handler;
    180   MessagePipe handles;
    181   MessagePumpMojo::current()->AddHandler(&handler, handles.handle0.get(),
    182                                          MOJO_HANDLE_SIGNAL_READABLE,
    183                                          base::TimeTicks());
    184   handles.handle0.reset();
    185   base::RunLoop run_loop;
    186   run_loop.RunUntilIdle();
    187   EXPECT_EQ(1, handler.error_count());
    188   EXPECT_EQ(0, handler.success_count());
    189 }
    190 
    191 }  // namespace test
    192 }  // namespace common
    193 }  // namespace mojo
    194