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