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
CreateMojoMessagePump()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:
CountingMojoHandler()26 CountingMojoHandler() : success_count_(0), error_count_(0) {}
27
OnHandleReady(const Handle & handle)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
set_success_callback(const base::Closure & callback,int success_count)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
OnHandleError(const Handle & handle,MojoResult result)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
set_error_callback(const base::Closure & callback)57 void set_error_callback(const base::Closure& callback) {
58 error_callback_ = callback;
59 }
60
success_count()61 int success_count() { return success_count_; }
error_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:
WillSignalHandler()78 void WillSignalHandler() override { will_signal_handler_count++; }
DidSignalHandler()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
TEST(MessagePumpMojo,RunUntilIdle)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
TEST(MessagePumpMojo,Observer)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
TEST(MessagePumpMojo,UnregisterAfterDeadline)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
TEST(MessagePumpMojo,AddClosedHandle)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
TEST(MessagePumpMojo,CloseAfterAdding)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