OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "mojo/public/cpp/bindings/lib/multiplex_router.h" | 5 #include "mojo/public/cpp/bindings/lib/multiplex_router.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/memory/ref_counted.h" | 9 #include "base/memory/ref_counted.h" |
10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| 11 #include "base/run_loop.h" |
11 #include "mojo/message_pump/message_pump_mojo.h" | 12 #include "mojo/message_pump/message_pump_mojo.h" |
12 #include "mojo/public/cpp/bindings/lib/interface_endpoint_client.h" | 13 #include "mojo/public/cpp/bindings/lib/interface_endpoint_client.h" |
13 #include "mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.h" | 14 #include "mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.h" |
14 #include "mojo/public/cpp/bindings/message.h" | 15 #include "mojo/public/cpp/bindings/message.h" |
15 #include "mojo/public/cpp/bindings/message_filter.h" | 16 #include "mojo/public/cpp/bindings/message_filter.h" |
16 #include "mojo/public/cpp/bindings/tests/message_queue.h" | 17 #include "mojo/public/cpp/bindings/tests/message_queue.h" |
17 #include "mojo/public/cpp/bindings/tests/router_test_util.h" | 18 #include "mojo/public/cpp/bindings/tests/router_test_util.h" |
18 #include "testing/gtest/include/gtest/gtest.h" | 19 #include "testing/gtest/include/gtest/gtest.h" |
19 | 20 |
20 namespace mojo { | 21 namespace mojo { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
64 InterfaceEndpointClient client0(std::move(endpoint0_), nullptr, | 65 InterfaceEndpointClient client0(std::move(endpoint0_), nullptr, |
65 make_scoped_ptr(new PassThroughFilter())); | 66 make_scoped_ptr(new PassThroughFilter())); |
66 ResponseGenerator generator; | 67 ResponseGenerator generator; |
67 InterfaceEndpointClient client1(std::move(endpoint1_), &generator, | 68 InterfaceEndpointClient client1(std::move(endpoint1_), &generator, |
68 make_scoped_ptr(new PassThroughFilter())); | 69 make_scoped_ptr(new PassThroughFilter())); |
69 | 70 |
70 Message request; | 71 Message request; |
71 AllocRequestMessage(1, "hello", &request); | 72 AllocRequestMessage(1, "hello", &request); |
72 | 73 |
73 MessageQueue message_queue; | 74 MessageQueue message_queue; |
74 client0.AcceptWithResponder(&request, new MessageAccumulator(&message_queue)); | 75 base::RunLoop run_loop; |
| 76 client0.AcceptWithResponder( |
| 77 &request, |
| 78 new MessageAccumulator(&message_queue, run_loop.QuitClosure())); |
75 | 79 |
76 PumpMessages(); | 80 run_loop.Run(); |
77 | 81 |
78 EXPECT_FALSE(message_queue.IsEmpty()); | 82 EXPECT_FALSE(message_queue.IsEmpty()); |
79 | 83 |
80 Message response; | 84 Message response; |
81 message_queue.Pop(&response); | 85 message_queue.Pop(&response); |
82 | 86 |
83 EXPECT_EQ(std::string("hello world!"), | 87 EXPECT_EQ(std::string("hello world!"), |
84 std::string(reinterpret_cast<const char*>(response.payload()))); | 88 std::string(reinterpret_cast<const char*>(response.payload()))); |
85 | 89 |
86 // Send a second message on the pipe. | 90 // Send a second message on the pipe. |
87 Message request2; | 91 Message request2; |
88 AllocRequestMessage(1, "hello again", &request2); | 92 AllocRequestMessage(1, "hello again", &request2); |
89 | 93 |
90 client0.AcceptWithResponder(&request2, | 94 base::RunLoop run_loop2; |
91 new MessageAccumulator(&message_queue)); | 95 client0.AcceptWithResponder( |
| 96 &request2, |
| 97 new MessageAccumulator(&message_queue, run_loop2.QuitClosure())); |
92 | 98 |
93 PumpMessages(); | 99 run_loop2.Run(); |
94 | 100 |
95 EXPECT_FALSE(message_queue.IsEmpty()); | 101 EXPECT_FALSE(message_queue.IsEmpty()); |
96 | 102 |
97 message_queue.Pop(&response); | 103 message_queue.Pop(&response); |
98 | 104 |
99 EXPECT_EQ(std::string("hello again world!"), | 105 EXPECT_EQ(std::string("hello again world!"), |
100 std::string(reinterpret_cast<const char*>(response.payload()))); | 106 std::string(reinterpret_cast<const char*>(response.payload()))); |
101 } | 107 } |
102 | 108 |
103 TEST_F(MultiplexRouterTest, BasicRequestResponse_Synchronous) { | 109 TEST_F(MultiplexRouterTest, BasicRequestResponse_Synchronous) { |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 InterfaceEndpointClient client1(std::move(endpoint1_), nullptr, | 154 InterfaceEndpointClient client1(std::move(endpoint1_), nullptr, |
149 make_scoped_ptr(new PassThroughFilter())); | 155 make_scoped_ptr(new PassThroughFilter())); |
150 | 156 |
151 // Without an incoming receiver set on client1, we expect client0 to observe | 157 // Without an incoming receiver set on client1, we expect client0 to observe |
152 // an error as a result of sending a message. | 158 // an error as a result of sending a message. |
153 | 159 |
154 Message request; | 160 Message request; |
155 AllocRequestMessage(1, "hello", &request); | 161 AllocRequestMessage(1, "hello", &request); |
156 | 162 |
157 MessageQueue message_queue; | 163 MessageQueue message_queue; |
158 client0.AcceptWithResponder(&request, new MessageAccumulator(&message_queue)); | 164 base::RunLoop run_loop, run_loop2; |
| 165 client0.set_connection_error_handler(run_loop.QuitClosure()); |
| 166 client1.set_connection_error_handler(run_loop2.QuitClosure()); |
| 167 client0.AcceptWithResponder( |
| 168 &request, new MessageAccumulator(&message_queue, run_loop.QuitClosure())); |
159 | 169 |
160 PumpMessages(); | 170 run_loop.Run(); |
| 171 run_loop2.Run(); |
161 | 172 |
162 EXPECT_TRUE(client0.encountered_error()); | 173 EXPECT_TRUE(client0.encountered_error()); |
163 EXPECT_TRUE(client1.encountered_error()); | 174 EXPECT_TRUE(client1.encountered_error()); |
164 EXPECT_TRUE(message_queue.IsEmpty()); | 175 EXPECT_TRUE(message_queue.IsEmpty()); |
165 } | 176 } |
166 | 177 |
167 // Tests MultiplexRouter using the LazyResponseGenerator. The responses will not | 178 // Tests MultiplexRouter using the LazyResponseGenerator. The responses will not |
168 // be sent until after the requests have been accepted. | 179 // be sent until after the requests have been accepted. |
169 TEST_F(MultiplexRouterTest, LazyResponses) { | 180 TEST_F(MultiplexRouterTest, LazyResponses) { |
170 InterfaceEndpointClient client0(std::move(endpoint0_), nullptr, | 181 InterfaceEndpointClient client0(std::move(endpoint0_), nullptr, |
171 make_scoped_ptr(new PassThroughFilter())); | 182 make_scoped_ptr(new PassThroughFilter())); |
172 LazyResponseGenerator generator; | 183 base::RunLoop run_loop; |
| 184 LazyResponseGenerator generator(run_loop.QuitClosure()); |
173 InterfaceEndpointClient client1(std::move(endpoint1_), &generator, | 185 InterfaceEndpointClient client1(std::move(endpoint1_), &generator, |
174 make_scoped_ptr(new PassThroughFilter())); | 186 make_scoped_ptr(new PassThroughFilter())); |
175 | 187 |
176 Message request; | 188 Message request; |
177 AllocRequestMessage(1, "hello", &request); | 189 AllocRequestMessage(1, "hello", &request); |
178 | 190 |
179 MessageQueue message_queue; | 191 MessageQueue message_queue; |
180 client0.AcceptWithResponder(&request, new MessageAccumulator(&message_queue)); | 192 base::RunLoop run_loop2; |
181 PumpMessages(); | 193 client0.AcceptWithResponder( |
| 194 &request, |
| 195 new MessageAccumulator(&message_queue, run_loop2.QuitClosure())); |
| 196 run_loop.Run(); |
182 | 197 |
183 // The request has been received but the response has not been sent yet. | 198 // The request has been received but the response has not been sent yet. |
184 EXPECT_TRUE(message_queue.IsEmpty()); | 199 EXPECT_TRUE(message_queue.IsEmpty()); |
185 | 200 |
186 // Send the response. | 201 // Send the response. |
187 EXPECT_TRUE(generator.responder_is_valid()); | 202 EXPECT_TRUE(generator.responder_is_valid()); |
188 generator.CompleteWithResponse(); | 203 generator.CompleteWithResponse(); |
189 PumpMessages(); | 204 run_loop2.Run(); |
190 | 205 |
191 // Check the response. | 206 // Check the response. |
192 EXPECT_FALSE(message_queue.IsEmpty()); | 207 EXPECT_FALSE(message_queue.IsEmpty()); |
193 Message response; | 208 Message response; |
194 message_queue.Pop(&response); | 209 message_queue.Pop(&response); |
195 EXPECT_EQ(std::string("hello world!"), | 210 EXPECT_EQ(std::string("hello world!"), |
196 std::string(reinterpret_cast<const char*>(response.payload()))); | 211 std::string(reinterpret_cast<const char*>(response.payload()))); |
197 | 212 |
198 // Send a second message on the pipe. | 213 // Send a second message on the pipe. |
| 214 base::RunLoop run_loop3; |
| 215 generator.set_closure(run_loop3.QuitClosure()); |
199 Message request2; | 216 Message request2; |
200 AllocRequestMessage(1, "hello again", &request2); | 217 AllocRequestMessage(1, "hello again", &request2); |
201 | 218 |
202 client0.AcceptWithResponder(&request2, | 219 base::RunLoop run_loop4; |
203 new MessageAccumulator(&message_queue)); | 220 client0.AcceptWithResponder( |
204 PumpMessages(); | 221 &request2, |
| 222 new MessageAccumulator(&message_queue, run_loop4.QuitClosure())); |
| 223 run_loop3.Run(); |
205 | 224 |
206 // The request has been received but the response has not been sent yet. | 225 // The request has been received but the response has not been sent yet. |
207 EXPECT_TRUE(message_queue.IsEmpty()); | 226 EXPECT_TRUE(message_queue.IsEmpty()); |
208 | 227 |
209 // Send the second response. | 228 // Send the second response. |
210 EXPECT_TRUE(generator.responder_is_valid()); | 229 EXPECT_TRUE(generator.responder_is_valid()); |
211 generator.CompleteWithResponse(); | 230 generator.CompleteWithResponse(); |
212 PumpMessages(); | 231 run_loop4.Run(); |
213 | 232 |
214 // Check the second response. | 233 // Check the second response. |
215 EXPECT_FALSE(message_queue.IsEmpty()); | 234 EXPECT_FALSE(message_queue.IsEmpty()); |
216 message_queue.Pop(&response); | 235 message_queue.Pop(&response); |
217 EXPECT_EQ(std::string("hello again world!"), | 236 EXPECT_EQ(std::string("hello again world!"), |
218 std::string(reinterpret_cast<const char*>(response.payload()))); | 237 std::string(reinterpret_cast<const char*>(response.payload()))); |
219 } | 238 } |
220 | 239 |
221 // Tests that if the receiving application destroys the responder_ without | 240 // Tests that if the receiving application destroys the responder_ without |
222 // sending a response, then we trigger connection error at both sides. Moreover, | 241 // sending a response, then we trigger connection error at both sides. Moreover, |
223 // both sides still appear to have a valid message pipe handle bound. | 242 // both sides still appear to have a valid message pipe handle bound. |
224 TEST_F(MultiplexRouterTest, MissingResponses) { | 243 TEST_F(MultiplexRouterTest, MissingResponses) { |
| 244 base::RunLoop run_loop0, run_loop1; |
225 InterfaceEndpointClient client0(std::move(endpoint0_), nullptr, | 245 InterfaceEndpointClient client0(std::move(endpoint0_), nullptr, |
226 make_scoped_ptr(new PassThroughFilter())); | 246 make_scoped_ptr(new PassThroughFilter())); |
227 bool error_handler_called0 = false; | 247 bool error_handler_called0 = false; |
228 client0.set_connection_error_handler( | 248 client0.set_connection_error_handler( |
229 [&error_handler_called0]() { error_handler_called0 = true; }); | 249 [&error_handler_called0, &run_loop0]() { |
| 250 error_handler_called0 = true; |
| 251 run_loop0.Quit(); |
| 252 }); |
230 | 253 |
231 LazyResponseGenerator generator; | 254 base::RunLoop run_loop3; |
| 255 LazyResponseGenerator generator(run_loop3.QuitClosure()); |
232 InterfaceEndpointClient client1(std::move(endpoint1_), &generator, | 256 InterfaceEndpointClient client1(std::move(endpoint1_), &generator, |
233 make_scoped_ptr(new PassThroughFilter())); | 257 make_scoped_ptr(new PassThroughFilter())); |
234 bool error_handler_called1 = false; | 258 bool error_handler_called1 = false; |
235 client1.set_connection_error_handler( | 259 client1.set_connection_error_handler( |
236 [&error_handler_called1]() { error_handler_called1 = true; }); | 260 [&error_handler_called1, &run_loop1]() { |
| 261 error_handler_called1 = true; |
| 262 run_loop1.Quit(); |
| 263 }); |
237 | 264 |
238 Message request; | 265 Message request; |
239 AllocRequestMessage(1, "hello", &request); | 266 AllocRequestMessage(1, "hello", &request); |
240 | 267 |
241 MessageQueue message_queue; | 268 MessageQueue message_queue; |
242 client0.AcceptWithResponder(&request, new MessageAccumulator(&message_queue)); | 269 client0.AcceptWithResponder(&request, new MessageAccumulator(&message_queue)); |
243 PumpMessages(); | 270 run_loop3.Run(); |
244 | 271 |
245 // The request has been received but no response has been sent. | 272 // The request has been received but no response has been sent. |
246 EXPECT_TRUE(message_queue.IsEmpty()); | 273 EXPECT_TRUE(message_queue.IsEmpty()); |
247 | 274 |
248 // Destroy the responder MessagerReceiver but don't send any response. | 275 // Destroy the responder MessagerReceiver but don't send any response. |
249 generator.CompleteWithoutResponse(); | 276 generator.CompleteWithoutResponse(); |
250 PumpMessages(); | 277 run_loop0.Run(); |
| 278 run_loop1.Run(); |
251 | 279 |
252 // Check that no response was received. | 280 // Check that no response was received. |
253 EXPECT_TRUE(message_queue.IsEmpty()); | 281 EXPECT_TRUE(message_queue.IsEmpty()); |
254 | 282 |
255 // Connection error handler is called at both sides. | 283 // Connection error handler is called at both sides. |
256 EXPECT_TRUE(error_handler_called0); | 284 EXPECT_TRUE(error_handler_called0); |
257 EXPECT_TRUE(error_handler_called1); | 285 EXPECT_TRUE(error_handler_called1); |
258 | 286 |
259 // The error flag is set at both sides. | 287 // The error flag is set at both sides. |
260 EXPECT_TRUE(client0.encountered_error()); | 288 EXPECT_TRUE(client0.encountered_error()); |
261 EXPECT_TRUE(client1.encountered_error()); | 289 EXPECT_TRUE(client1.encountered_error()); |
262 | 290 |
263 // The message pipe handle is valid at both sides. | 291 // The message pipe handle is valid at both sides. |
264 EXPECT_TRUE(router0_->is_valid()); | 292 EXPECT_TRUE(router0_->is_valid()); |
265 EXPECT_TRUE(router1_->is_valid()); | 293 EXPECT_TRUE(router1_->is_valid()); |
266 } | 294 } |
267 | 295 |
268 TEST_F(MultiplexRouterTest, LateResponse) { | 296 TEST_F(MultiplexRouterTest, LateResponse) { |
269 // Test that things won't blow up if we try to send a message to a | 297 // Test that things won't blow up if we try to send a message to a |
270 // MessageReceiver, which was given to us via AcceptWithResponder, | 298 // MessageReceiver, which was given to us via AcceptWithResponder, |
271 // after the router has gone away. | 299 // after the router has gone away. |
272 | 300 |
273 LazyResponseGenerator generator; | 301 base::RunLoop run_loop; |
| 302 LazyResponseGenerator generator(run_loop.QuitClosure()); |
274 { | 303 { |
275 InterfaceEndpointClient client0(std::move(endpoint0_), nullptr, | 304 InterfaceEndpointClient client0(std::move(endpoint0_), nullptr, |
276 make_scoped_ptr(new PassThroughFilter())); | 305 make_scoped_ptr(new PassThroughFilter())); |
277 InterfaceEndpointClient client1(std::move(endpoint1_), &generator, | 306 InterfaceEndpointClient client1(std::move(endpoint1_), &generator, |
278 make_scoped_ptr(new PassThroughFilter())); | 307 make_scoped_ptr(new PassThroughFilter())); |
279 | 308 |
280 Message request; | 309 Message request; |
281 AllocRequestMessage(1, "hello", &request); | 310 AllocRequestMessage(1, "hello", &request); |
282 | 311 |
283 MessageQueue message_queue; | 312 MessageQueue message_queue; |
284 client0.AcceptWithResponder(&request, | 313 client0.AcceptWithResponder(&request, |
285 new MessageAccumulator(&message_queue)); | 314 new MessageAccumulator(&message_queue)); |
286 | 315 |
287 PumpMessages(); | 316 run_loop.Run(); |
288 | 317 |
289 EXPECT_TRUE(generator.has_responder()); | 318 EXPECT_TRUE(generator.has_responder()); |
290 } | 319 } |
291 | 320 |
292 EXPECT_FALSE(generator.responder_is_valid()); | 321 EXPECT_FALSE(generator.responder_is_valid()); |
293 generator.CompleteWithResponse(); // This should end up doing nothing. | 322 generator.CompleteWithResponse(); // This should end up doing nothing. |
294 } | 323 } |
295 | 324 |
296 // TODO(yzshen): add more tests. | 325 // TODO(yzshen): add more tests. |
297 | 326 |
298 } // namespace | 327 } // namespace |
299 } // namespace test | 328 } // namespace test |
300 } // namespace mojo | 329 } // namespace mojo |
OLD | NEW |