• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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