OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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 <stdint.h> | 5 #include <stdint.h> |
6 #include <utility> | 6 #include <utility> |
7 | 7 |
| 8 #include "base/bind.h" |
8 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
| 10 #include "base/run_loop.h" |
9 #include "mojo/message_pump/message_pump_mojo.h" | 11 #include "mojo/message_pump/message_pump_mojo.h" |
10 #include "mojo/public/cpp/bindings/binding.h" | 12 #include "mojo/public/cpp/bindings/binding.h" |
11 #include "mojo/public/cpp/bindings/strong_binding.h" | 13 #include "mojo/public/cpp/bindings/strong_binding.h" |
12 #include "mojo/public/interfaces/bindings/tests/math_calculator.mojom.h" | 14 #include "mojo/public/interfaces/bindings/tests/math_calculator.mojom.h" |
13 #include "mojo/public/interfaces/bindings/tests/sample_interfaces.mojom.h" | 15 #include "mojo/public/interfaces/bindings/tests/sample_interfaces.mojom.h" |
14 #include "mojo/public/interfaces/bindings/tests/sample_service.mojom.h" | 16 #include "mojo/public/interfaces/bindings/tests/sample_service.mojom.h" |
15 #include "mojo/public/interfaces/bindings/tests/scoping.mojom.h" | 17 #include "mojo/public/interfaces/bindings/tests/scoping.mojom.h" |
16 #include "testing/gtest/include/gtest/gtest.h" | 18 #include "testing/gtest/include/gtest/gtest.h" |
17 | 19 |
18 namespace mojo { | 20 namespace mojo { |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
68 | 70 |
69 private: | 71 private: |
70 double total_; | 72 double total_; |
71 Binding<math::Calculator> binding_; | 73 Binding<math::Calculator> binding_; |
72 }; | 74 }; |
73 | 75 |
74 class MathCalculatorUI { | 76 class MathCalculatorUI { |
75 public: | 77 public: |
76 explicit MathCalculatorUI(math::CalculatorPtr calculator) | 78 explicit MathCalculatorUI(math::CalculatorPtr calculator) |
77 : calculator_(std::move(calculator)), | 79 : calculator_(std::move(calculator)), |
78 output_(0.0), | 80 output_(0.0) {} |
79 callback_(MakeRunnable(&MathCalculatorUI::Output, this)) {} | |
80 | 81 |
81 bool WaitForIncomingResponse() { | 82 bool WaitForIncomingResponse() { |
82 return calculator_.WaitForIncomingResponse(); | 83 return calculator_.WaitForIncomingResponse(); |
83 } | 84 } |
84 | 85 |
85 bool encountered_error() const { return calculator_.encountered_error(); } | 86 bool encountered_error() const { return calculator_.encountered_error(); } |
| 87 void set_connection_error_handler(const base::Closure& closure) { |
| 88 calculator_.set_connection_error_handler(closure); |
| 89 } |
86 | 90 |
87 void Add(double value) { calculator_->Add(value, callback_); } | 91 void Add(double value, const base::Closure& closure) { |
| 92 calculator_->Add( |
| 93 value, |
| 94 base::Bind(&MathCalculatorUI::Output, base::Unretained(this), closure)); |
| 95 } |
88 | 96 |
89 void Subtract(double value) { calculator_->Add(-value, callback_); } | 97 void Multiply(double value, const base::Closure& closure) { |
90 | 98 calculator_->Multiply( |
91 void Multiply(double value) { calculator_->Multiply(value, callback_); } | 99 value, |
92 | 100 base::Bind(&MathCalculatorUI::Output, base::Unretained(this), closure)); |
93 void Divide(double value) { calculator_->Multiply(1.0 / value, callback_); } | 101 } |
94 | 102 |
95 double GetOutput() const { return output_; } | 103 double GetOutput() const { return output_; } |
96 | 104 |
97 private: | 105 private: |
98 void Output(double output) { output_ = output; } | 106 void Output(const base::Closure& closure, double output) { |
| 107 output_ = output; |
| 108 if (!closure.is_null()) |
| 109 closure.Run(); |
| 110 } |
99 | 111 |
100 math::CalculatorPtr calculator_; | 112 math::CalculatorPtr calculator_; |
101 double output_; | 113 double output_; |
102 Callback<void(double)> callback_; | 114 base::Closure closure_; |
103 }; | 115 }; |
104 | 116 |
105 class SelfDestructingMathCalculatorUI { | 117 class SelfDestructingMathCalculatorUI { |
106 public: | 118 public: |
107 explicit SelfDestructingMathCalculatorUI(math::CalculatorPtr calculator) | 119 explicit SelfDestructingMathCalculatorUI(math::CalculatorPtr calculator) |
108 : calculator_(std::move(calculator)), nesting_level_(0) { | 120 : calculator_(std::move(calculator)), nesting_level_(0) { |
109 ++num_instances_; | 121 ++num_instances_; |
110 } | 122 } |
111 | 123 |
112 void BeginTest(bool nested) { | 124 void BeginTest(bool nested, const base::Closure& closure) { |
113 nesting_level_ = nested ? 2 : 1; | 125 nesting_level_ = nested ? 2 : 1; |
114 calculator_->Add( | 126 calculator_->Add( |
115 1.0, MakeRunnable(&SelfDestructingMathCalculatorUI::Output, this)); | 127 1.0, |
| 128 base::Bind(&SelfDestructingMathCalculatorUI::Output, |
| 129 base::Unretained(this), closure)); |
116 } | 130 } |
117 | 131 |
118 static int num_instances() { return num_instances_; } | 132 static int num_instances() { return num_instances_; } |
119 | 133 |
120 void Output(double value) { | 134 void Output(const base::Closure& closure, double value) { |
121 if (--nesting_level_ > 0) { | 135 if (--nesting_level_ > 0) { |
122 // Add some more and wait for re-entrant call to Output! | 136 // Add some more and wait for re-entrant call to Output! |
123 calculator_->Add( | 137 calculator_->Add( |
124 1.0, MakeRunnable(&SelfDestructingMathCalculatorUI::Output, this)); | 138 1.0, |
125 base::MessageLoop::current()->RunUntilIdle(); | 139 base::Bind(&SelfDestructingMathCalculatorUI::Output, |
| 140 base::Unretained(this), closure)); |
126 } else { | 141 } else { |
| 142 closure.Run(); |
127 delete this; | 143 delete this; |
128 } | 144 } |
129 } | 145 } |
130 | 146 |
131 private: | 147 private: |
132 ~SelfDestructingMathCalculatorUI() { --num_instances_; } | 148 ~SelfDestructingMathCalculatorUI() { --num_instances_; } |
133 | 149 |
134 math::CalculatorPtr calculator_; | 150 math::CalculatorPtr calculator_; |
135 int nesting_level_; | 151 int nesting_level_; |
136 static int num_instances_; | 152 static int num_instances_; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 Binding<sample::Service> binding_; | 186 Binding<sample::Service> binding_; |
171 }; | 187 }; |
172 | 188 |
173 class IntegerAccessorImpl : public sample::IntegerAccessor { | 189 class IntegerAccessorImpl : public sample::IntegerAccessor { |
174 public: | 190 public: |
175 IntegerAccessorImpl() : integer_(0) {} | 191 IntegerAccessorImpl() : integer_(0) {} |
176 ~IntegerAccessorImpl() override {} | 192 ~IntegerAccessorImpl() override {} |
177 | 193 |
178 int64_t integer() const { return integer_; } | 194 int64_t integer() const { return integer_; } |
179 | 195 |
| 196 void set_closure(const base::Closure& closure) { closure_ = closure; } |
| 197 |
180 private: | 198 private: |
181 // sample::IntegerAccessor implementation. | 199 // sample::IntegerAccessor implementation. |
182 void GetInteger(const GetIntegerCallback& callback) override { | 200 void GetInteger(const GetIntegerCallback& callback) override { |
183 callback.Run(integer_, sample::ENUM_VALUE); | 201 callback.Run(integer_, sample::ENUM_VALUE); |
184 } | 202 } |
185 void SetInteger(int64_t data, sample::Enum type) override { integer_ = data; } | 203 void SetInteger(int64_t data, sample::Enum type) override { |
| 204 integer_ = data; |
| 205 if (!closure_.is_null()) { |
| 206 closure_.Run(); |
| 207 closure_.Reset(); |
| 208 } |
| 209 } |
186 | 210 |
187 int64_t integer_; | 211 int64_t integer_; |
| 212 base::Closure closure_; |
188 }; | 213 }; |
189 | 214 |
190 class InterfacePtrTest : public testing::Test { | 215 class InterfacePtrTest : public testing::Test { |
191 public: | 216 public: |
192 InterfacePtrTest() : loop_(common::MessagePumpMojo::Create()) {} | 217 InterfacePtrTest() : loop_(common::MessagePumpMojo::Create()) {} |
193 ~InterfacePtrTest() override { loop_.RunUntilIdle(); } | 218 ~InterfacePtrTest() override { loop_.RunUntilIdle(); } |
194 | 219 |
195 void PumpMessages() { loop_.RunUntilIdle(); } | 220 void PumpMessages() { loop_.RunUntilIdle(); } |
196 | 221 |
197 private: | 222 private: |
198 base::MessageLoop loop_; | 223 base::MessageLoop loop_; |
199 }; | 224 }; |
200 | 225 |
201 TEST_F(InterfacePtrTest, IsBound) { | 226 TEST_F(InterfacePtrTest, IsBound) { |
202 math::CalculatorPtr calc; | 227 math::CalculatorPtr calc; |
203 EXPECT_FALSE(calc.is_bound()); | 228 EXPECT_FALSE(calc.is_bound()); |
204 MathCalculatorImpl calc_impl(GetProxy(&calc)); | 229 MathCalculatorImpl calc_impl(GetProxy(&calc)); |
205 EXPECT_TRUE(calc.is_bound()); | 230 EXPECT_TRUE(calc.is_bound()); |
206 } | 231 } |
207 | 232 |
208 TEST_F(InterfacePtrTest, EndToEnd) { | 233 TEST_F(InterfacePtrTest, EndToEnd) { |
209 math::CalculatorPtr calc; | 234 math::CalculatorPtr calc; |
210 MathCalculatorImpl calc_impl(GetProxy(&calc)); | 235 MathCalculatorImpl calc_impl(GetProxy(&calc)); |
211 | 236 |
212 // Suppose this is instantiated in a process that has pipe1_. | 237 // Suppose this is instantiated in a process that has pipe1_. |
213 MathCalculatorUI calculator_ui(std::move(calc)); | 238 MathCalculatorUI calculator_ui(std::move(calc)); |
214 | 239 |
215 calculator_ui.Add(2.0); | 240 base::RunLoop run_loop, run_loop2; |
216 calculator_ui.Multiply(5.0); | 241 calculator_ui.Add(2.0, run_loop.QuitClosure()); |
217 | 242 calculator_ui.Multiply(5.0, run_loop2.QuitClosure()); |
218 PumpMessages(); | 243 run_loop.Run(); |
| 244 run_loop2.Run(); |
219 | 245 |
220 EXPECT_EQ(10.0, calculator_ui.GetOutput()); | 246 EXPECT_EQ(10.0, calculator_ui.GetOutput()); |
221 } | 247 } |
222 | 248 |
223 TEST_F(InterfacePtrTest, EndToEnd_Synchronous) { | 249 TEST_F(InterfacePtrTest, EndToEnd_Synchronous) { |
224 math::CalculatorPtr calc; | 250 math::CalculatorPtr calc; |
225 MathCalculatorImpl calc_impl(GetProxy(&calc)); | 251 MathCalculatorImpl calc_impl(GetProxy(&calc)); |
226 | 252 |
227 // Suppose this is instantiated in a process that has pipe1_. | 253 // Suppose this is instantiated in a process that has pipe1_. |
228 MathCalculatorUI calculator_ui(std::move(calc)); | 254 MathCalculatorUI calculator_ui(std::move(calc)); |
229 | 255 |
230 EXPECT_EQ(0.0, calculator_ui.GetOutput()); | 256 EXPECT_EQ(0.0, calculator_ui.GetOutput()); |
231 | 257 |
232 calculator_ui.Add(2.0); | 258 calculator_ui.Add(2.0, base::Closure()); |
233 EXPECT_EQ(0.0, calculator_ui.GetOutput()); | 259 EXPECT_EQ(0.0, calculator_ui.GetOutput()); |
234 calc_impl.WaitForIncomingMethodCall(); | 260 calc_impl.WaitForIncomingMethodCall(); |
235 calculator_ui.WaitForIncomingResponse(); | 261 calculator_ui.WaitForIncomingResponse(); |
236 EXPECT_EQ(2.0, calculator_ui.GetOutput()); | 262 EXPECT_EQ(2.0, calculator_ui.GetOutput()); |
237 | 263 |
238 calculator_ui.Multiply(5.0); | 264 calculator_ui.Multiply(5.0, base::Closure()); |
239 EXPECT_EQ(2.0, calculator_ui.GetOutput()); | 265 EXPECT_EQ(2.0, calculator_ui.GetOutput()); |
240 calc_impl.WaitForIncomingMethodCall(); | 266 calc_impl.WaitForIncomingMethodCall(); |
241 calculator_ui.WaitForIncomingResponse(); | 267 calculator_ui.WaitForIncomingResponse(); |
242 EXPECT_EQ(10.0, calculator_ui.GetOutput()); | 268 EXPECT_EQ(10.0, calculator_ui.GetOutput()); |
243 } | 269 } |
244 | 270 |
245 TEST_F(InterfacePtrTest, Movable) { | 271 TEST_F(InterfacePtrTest, Movable) { |
246 math::CalculatorPtr a; | 272 math::CalculatorPtr a; |
247 math::CalculatorPtr b; | 273 math::CalculatorPtr b; |
248 MathCalculatorImpl calc_impl(GetProxy(&b)); | 274 MathCalculatorImpl calc_impl(GetProxy(&b)); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
289 EXPECT_FALSE(ptr.get()); | 315 EXPECT_FALSE(ptr.get()); |
290 EXPECT_FALSE(ptr); | 316 EXPECT_FALSE(ptr); |
291 } | 317 } |
292 | 318 |
293 TEST_F(InterfacePtrTest, EncounteredError) { | 319 TEST_F(InterfacePtrTest, EncounteredError) { |
294 math::CalculatorPtr proxy; | 320 math::CalculatorPtr proxy; |
295 MathCalculatorImpl calc_impl(GetProxy(&proxy)); | 321 MathCalculatorImpl calc_impl(GetProxy(&proxy)); |
296 | 322 |
297 MathCalculatorUI calculator_ui(std::move(proxy)); | 323 MathCalculatorUI calculator_ui(std::move(proxy)); |
298 | 324 |
299 calculator_ui.Add(2.0); | 325 base::RunLoop run_loop; |
300 PumpMessages(); | 326 calculator_ui.Add(2.0, run_loop.QuitClosure()); |
| 327 run_loop.Run(); |
301 EXPECT_EQ(2.0, calculator_ui.GetOutput()); | 328 EXPECT_EQ(2.0, calculator_ui.GetOutput()); |
302 EXPECT_FALSE(calculator_ui.encountered_error()); | 329 EXPECT_FALSE(calculator_ui.encountered_error()); |
303 | 330 |
304 calculator_ui.Multiply(5.0); | 331 calculator_ui.Multiply(5.0, base::Closure()); |
305 EXPECT_FALSE(calculator_ui.encountered_error()); | 332 EXPECT_FALSE(calculator_ui.encountered_error()); |
306 | 333 |
307 // Close the server. | 334 // Close the server. |
308 calc_impl.CloseMessagePipe(); | 335 calc_impl.CloseMessagePipe(); |
309 | 336 |
310 // The state change isn't picked up locally yet. | 337 // The state change isn't picked up locally yet. |
| 338 base::RunLoop run_loop2; |
| 339 calculator_ui.set_connection_error_handler(run_loop2.QuitClosure()); |
311 EXPECT_FALSE(calculator_ui.encountered_error()); | 340 EXPECT_FALSE(calculator_ui.encountered_error()); |
312 | 341 |
313 PumpMessages(); | 342 run_loop2.Run(); |
314 | 343 |
315 // OK, now we see the error. | 344 // OK, now we see the error. |
316 EXPECT_TRUE(calculator_ui.encountered_error()); | 345 EXPECT_TRUE(calculator_ui.encountered_error()); |
317 } | 346 } |
318 | 347 |
319 TEST_F(InterfacePtrTest, EncounteredErrorCallback) { | 348 TEST_F(InterfacePtrTest, EncounteredErrorCallback) { |
320 math::CalculatorPtr proxy; | 349 math::CalculatorPtr proxy; |
321 MathCalculatorImpl calc_impl(GetProxy(&proxy)); | 350 MathCalculatorImpl calc_impl(GetProxy(&proxy)); |
322 | 351 |
323 bool encountered_error = false; | 352 bool encountered_error = false; |
| 353 base::RunLoop run_loop; |
324 proxy.set_connection_error_handler( | 354 proxy.set_connection_error_handler( |
325 [&encountered_error]() { encountered_error = true; }); | 355 [&encountered_error, &run_loop]() { |
| 356 encountered_error = true; |
| 357 run_loop.Quit(); |
| 358 }); |
326 | 359 |
327 MathCalculatorUI calculator_ui(std::move(proxy)); | 360 MathCalculatorUI calculator_ui(std::move(proxy)); |
328 | 361 |
329 calculator_ui.Add(2.0); | 362 base::RunLoop run_loop2; |
330 PumpMessages(); | 363 calculator_ui.Add(2.0, run_loop2.QuitClosure()); |
| 364 run_loop2.Run(); |
331 EXPECT_EQ(2.0, calculator_ui.GetOutput()); | 365 EXPECT_EQ(2.0, calculator_ui.GetOutput()); |
332 EXPECT_FALSE(calculator_ui.encountered_error()); | 366 EXPECT_FALSE(calculator_ui.encountered_error()); |
333 | 367 |
334 calculator_ui.Multiply(5.0); | 368 calculator_ui.Multiply(5.0, base::Closure()); |
335 EXPECT_FALSE(calculator_ui.encountered_error()); | 369 EXPECT_FALSE(calculator_ui.encountered_error()); |
336 | 370 |
337 // Close the server. | 371 // Close the server. |
338 calc_impl.CloseMessagePipe(); | 372 calc_impl.CloseMessagePipe(); |
339 | 373 |
340 // The state change isn't picked up locally yet. | 374 // The state change isn't picked up locally yet. |
341 EXPECT_FALSE(calculator_ui.encountered_error()); | 375 EXPECT_FALSE(calculator_ui.encountered_error()); |
342 | 376 |
343 PumpMessages(); | 377 run_loop.Run(); |
344 | 378 |
345 // OK, now we see the error. | 379 // OK, now we see the error. |
346 EXPECT_TRUE(calculator_ui.encountered_error()); | 380 EXPECT_TRUE(calculator_ui.encountered_error()); |
347 | 381 |
348 // We should have also been able to observe the error through the error | 382 // We should have also been able to observe the error through the error |
349 // handler. | 383 // handler. |
350 EXPECT_TRUE(encountered_error); | 384 EXPECT_TRUE(encountered_error); |
351 } | 385 } |
352 | 386 |
353 TEST_F(InterfacePtrTest, DestroyInterfacePtrOnMethodResponse) { | 387 TEST_F(InterfacePtrTest, DestroyInterfacePtrOnMethodResponse) { |
354 math::CalculatorPtr proxy; | 388 math::CalculatorPtr proxy; |
355 MathCalculatorImpl calc_impl(GetProxy(&proxy)); | 389 MathCalculatorImpl calc_impl(GetProxy(&proxy)); |
356 | 390 |
357 EXPECT_EQ(0, SelfDestructingMathCalculatorUI::num_instances()); | 391 EXPECT_EQ(0, SelfDestructingMathCalculatorUI::num_instances()); |
358 | 392 |
359 SelfDestructingMathCalculatorUI* impl = | 393 SelfDestructingMathCalculatorUI* impl = |
360 new SelfDestructingMathCalculatorUI(std::move(proxy)); | 394 new SelfDestructingMathCalculatorUI(std::move(proxy)); |
361 impl->BeginTest(false); | 395 base::RunLoop run_loop; |
362 | 396 impl->BeginTest(false, run_loop.QuitClosure()); |
363 PumpMessages(); | 397 run_loop.Run(); |
364 | 398 |
365 EXPECT_EQ(0, SelfDestructingMathCalculatorUI::num_instances()); | 399 EXPECT_EQ(0, SelfDestructingMathCalculatorUI::num_instances()); |
366 } | 400 } |
367 | 401 |
368 TEST_F(InterfacePtrTest, NestedDestroyInterfacePtrOnMethodResponse) { | 402 TEST_F(InterfacePtrTest, NestedDestroyInterfacePtrOnMethodResponse) { |
369 math::CalculatorPtr proxy; | 403 math::CalculatorPtr proxy; |
370 MathCalculatorImpl calc_impl(GetProxy(&proxy)); | 404 MathCalculatorImpl calc_impl(GetProxy(&proxy)); |
371 | 405 |
372 EXPECT_EQ(0, SelfDestructingMathCalculatorUI::num_instances()); | 406 EXPECT_EQ(0, SelfDestructingMathCalculatorUI::num_instances()); |
373 | 407 |
374 SelfDestructingMathCalculatorUI* impl = | 408 SelfDestructingMathCalculatorUI* impl = |
375 new SelfDestructingMathCalculatorUI(std::move(proxy)); | 409 new SelfDestructingMathCalculatorUI(std::move(proxy)); |
376 impl->BeginTest(true); | 410 base::RunLoop run_loop; |
377 | 411 impl->BeginTest(true, run_loop.QuitClosure()); |
378 PumpMessages(); | 412 run_loop.Run(); |
379 | 413 |
380 EXPECT_EQ(0, SelfDestructingMathCalculatorUI::num_instances()); | 414 EXPECT_EQ(0, SelfDestructingMathCalculatorUI::num_instances()); |
381 } | 415 } |
382 | 416 |
383 TEST_F(InterfacePtrTest, ReentrantWaitForIncomingMethodCall) { | 417 TEST_F(InterfacePtrTest, ReentrantWaitForIncomingMethodCall) { |
384 sample::ServicePtr proxy; | 418 sample::ServicePtr proxy; |
385 ReentrantServiceImpl impl(GetProxy(&proxy)); | 419 ReentrantServiceImpl impl(GetProxy(&proxy)); |
386 | 420 |
| 421 base::RunLoop run_loop, run_loop2; |
| 422 auto called_cb = [&run_loop](int32_t result) { run_loop.Quit(); }; |
| 423 auto called_cb2 = [&run_loop2](int32_t result) { run_loop2.Quit(); }; |
387 proxy->Frobinate(nullptr, sample::Service::BAZ_OPTIONS_REGULAR, nullptr, | 424 proxy->Frobinate(nullptr, sample::Service::BAZ_OPTIONS_REGULAR, nullptr, |
388 sample::Service::FrobinateCallback()); | 425 called_cb); |
389 proxy->Frobinate(nullptr, sample::Service::BAZ_OPTIONS_REGULAR, nullptr, | 426 proxy->Frobinate(nullptr, sample::Service::BAZ_OPTIONS_REGULAR, nullptr, |
390 sample::Service::FrobinateCallback()); | 427 called_cb2); |
391 | 428 |
392 PumpMessages(); | 429 run_loop.Run(); |
| 430 run_loop2.Run(); |
393 | 431 |
394 EXPECT_EQ(2, impl.max_call_depth()); | 432 EXPECT_EQ(2, impl.max_call_depth()); |
395 } | 433 } |
396 | 434 |
397 TEST_F(InterfacePtrTest, QueryVersion) { | 435 TEST_F(InterfacePtrTest, QueryVersion) { |
398 IntegerAccessorImpl impl; | 436 IntegerAccessorImpl impl; |
399 sample::IntegerAccessorPtr ptr; | 437 sample::IntegerAccessorPtr ptr; |
400 Binding<sample::IntegerAccessor> binding(&impl, GetProxy(&ptr)); | 438 Binding<sample::IntegerAccessor> binding(&impl, GetProxy(&ptr)); |
401 | 439 |
402 EXPECT_EQ(0u, ptr.version()); | 440 EXPECT_EQ(0u, ptr.version()); |
403 | 441 |
404 auto callback = [](uint32_t version) { EXPECT_EQ(3u, version); }; | 442 base::RunLoop run_loop; |
| 443 auto callback = [&run_loop](uint32_t version) { |
| 444 EXPECT_EQ(3u, version); |
| 445 run_loop.Quit(); |
| 446 }; |
405 ptr.QueryVersion(callback); | 447 ptr.QueryVersion(callback); |
406 | 448 |
407 PumpMessages(); | 449 run_loop.Run(); |
408 | 450 |
409 EXPECT_EQ(3u, ptr.version()); | 451 EXPECT_EQ(3u, ptr.version()); |
410 } | 452 } |
411 | 453 |
412 TEST_F(InterfacePtrTest, RequireVersion) { | 454 TEST_F(InterfacePtrTest, RequireVersion) { |
413 IntegerAccessorImpl impl; | 455 IntegerAccessorImpl impl; |
414 sample::IntegerAccessorPtr ptr; | 456 sample::IntegerAccessorPtr ptr; |
415 Binding<sample::IntegerAccessor> binding(&impl, GetProxy(&ptr)); | 457 Binding<sample::IntegerAccessor> binding(&impl, GetProxy(&ptr)); |
416 | 458 |
417 EXPECT_EQ(0u, ptr.version()); | 459 EXPECT_EQ(0u, ptr.version()); |
418 | 460 |
419 ptr.RequireVersion(1u); | 461 ptr.RequireVersion(1u); |
420 EXPECT_EQ(1u, ptr.version()); | 462 EXPECT_EQ(1u, ptr.version()); |
| 463 base::RunLoop run_loop; |
| 464 impl.set_closure(run_loop.QuitClosure()); |
421 ptr->SetInteger(123, sample::ENUM_VALUE); | 465 ptr->SetInteger(123, sample::ENUM_VALUE); |
422 PumpMessages(); | 466 run_loop.Run(); |
423 EXPECT_FALSE(ptr.encountered_error()); | 467 EXPECT_FALSE(ptr.encountered_error()); |
424 EXPECT_EQ(123, impl.integer()); | 468 EXPECT_EQ(123, impl.integer()); |
425 | 469 |
426 ptr.RequireVersion(3u); | 470 ptr.RequireVersion(3u); |
427 EXPECT_EQ(3u, ptr.version()); | 471 EXPECT_EQ(3u, ptr.version()); |
| 472 base::RunLoop run_loop2; |
| 473 impl.set_closure(run_loop2.QuitClosure()); |
428 ptr->SetInteger(456, sample::ENUM_VALUE); | 474 ptr->SetInteger(456, sample::ENUM_VALUE); |
429 PumpMessages(); | 475 run_loop2.Run(); |
430 EXPECT_FALSE(ptr.encountered_error()); | 476 EXPECT_FALSE(ptr.encountered_error()); |
431 EXPECT_EQ(456, impl.integer()); | 477 EXPECT_EQ(456, impl.integer()); |
432 | 478 |
433 // Require a version that is not supported by the impl side. | 479 // Require a version that is not supported by the impl side. |
434 ptr.RequireVersion(4u); | 480 ptr.RequireVersion(4u); |
435 // This value is set to the input of RequireVersion() synchronously. | 481 // This value is set to the input of RequireVersion() synchronously. |
436 EXPECT_EQ(4u, ptr.version()); | 482 EXPECT_EQ(4u, ptr.version()); |
| 483 base::RunLoop run_loop3; |
| 484 ptr.set_connection_error_handler(run_loop3.QuitClosure()); |
437 ptr->SetInteger(789, sample::ENUM_VALUE); | 485 ptr->SetInteger(789, sample::ENUM_VALUE); |
438 PumpMessages(); | 486 run_loop3.Run(); |
439 EXPECT_TRUE(ptr.encountered_error()); | 487 EXPECT_TRUE(ptr.encountered_error()); |
440 // The call to SetInteger() after RequireVersion(4u) is ignored. | 488 // The call to SetInteger() after RequireVersion(4u) is ignored. |
441 EXPECT_EQ(456, impl.integer()); | 489 EXPECT_EQ(456, impl.integer()); |
442 } | 490 } |
443 | 491 |
444 class StrongMathCalculatorImpl : public math::Calculator { | 492 class StrongMathCalculatorImpl : public math::Calculator { |
445 public: | 493 public: |
446 StrongMathCalculatorImpl(ScopedMessagePipeHandle handle, | 494 StrongMathCalculatorImpl(ScopedMessagePipeHandle handle, |
447 bool* error_received, | 495 bool* error_received, |
448 bool* destroyed) | 496 bool* destroyed, |
| 497 const base::Closure& closure) |
449 : error_received_(error_received), | 498 : error_received_(error_received), |
450 destroyed_(destroyed), | 499 destroyed_(destroyed), |
| 500 closure_(closure), |
451 binding_(this, std::move(handle)) { | 501 binding_(this, std::move(handle)) { |
452 binding_.set_connection_error_handler( | 502 binding_.set_connection_error_handler( |
453 [this]() { *error_received_ = true; }); | 503 [this]() { *error_received_ = true; closure_.Run(); }); |
454 } | 504 } |
455 ~StrongMathCalculatorImpl() override { *destroyed_ = true; } | 505 ~StrongMathCalculatorImpl() override { *destroyed_ = true; } |
456 | 506 |
457 // math::Calculator implementation. | 507 // math::Calculator implementation. |
458 void Clear(const CalcCallback& callback) override { callback.Run(total_); } | 508 void Clear(const CalcCallback& callback) override { callback.Run(total_); } |
459 | 509 |
460 void Add(double value, const CalcCallback& callback) override { | 510 void Add(double value, const CalcCallback& callback) override { |
461 total_ += value; | 511 total_ += value; |
462 callback.Run(total_); | 512 callback.Run(total_); |
463 } | 513 } |
464 | 514 |
465 void Multiply(double value, const CalcCallback& callback) override { | 515 void Multiply(double value, const CalcCallback& callback) override { |
466 total_ *= value; | 516 total_ *= value; |
467 callback.Run(total_); | 517 callback.Run(total_); |
468 } | 518 } |
469 | 519 |
470 private: | 520 private: |
471 double total_ = 0.0; | 521 double total_ = 0.0; |
472 bool* error_received_; | 522 bool* error_received_; |
473 bool* destroyed_; | 523 bool* destroyed_; |
| 524 base::Closure closure_; |
474 | 525 |
475 StrongBinding<math::Calculator> binding_; | 526 StrongBinding<math::Calculator> binding_; |
476 }; | 527 }; |
477 | 528 |
478 TEST(StrongConnectorTest, Math) { | 529 TEST(StrongConnectorTest, Math) { |
479 base::MessageLoop loop(common::MessagePumpMojo::Create()); | 530 base::MessageLoop loop(common::MessagePumpMojo::Create()); |
480 | 531 |
481 bool error_received = false; | 532 bool error_received = false; |
482 bool destroyed = false; | 533 bool destroyed = false; |
483 MessagePipe pipe; | 534 MessagePipe pipe; |
| 535 base::RunLoop run_loop; |
484 new StrongMathCalculatorImpl(std::move(pipe.handle0), &error_received, | 536 new StrongMathCalculatorImpl(std::move(pipe.handle0), &error_received, |
485 &destroyed); | 537 &destroyed, run_loop.QuitClosure()); |
486 | 538 |
487 math::CalculatorPtr calc; | 539 math::CalculatorPtr calc; |
488 calc.Bind(InterfacePtrInfo<math::Calculator>(std::move(pipe.handle1), 0u)); | 540 calc.Bind(InterfacePtrInfo<math::Calculator>(std::move(pipe.handle1), 0u)); |
489 | 541 |
490 { | 542 { |
491 // Suppose this is instantiated in a process that has the other end of the | 543 // Suppose this is instantiated in a process that has the other end of the |
492 // message pipe. | 544 // message pipe. |
493 MathCalculatorUI calculator_ui(std::move(calc)); | 545 MathCalculatorUI calculator_ui(std::move(calc)); |
494 | 546 |
495 calculator_ui.Add(2.0); | 547 base::RunLoop run_loop, run_loop2; |
496 calculator_ui.Multiply(5.0); | 548 calculator_ui.Add(2.0, run_loop.QuitClosure()); |
497 | 549 calculator_ui.Multiply(5.0, run_loop2.QuitClosure()); |
498 loop.RunUntilIdle(); | 550 run_loop.Run(); |
| 551 run_loop2.Run(); |
499 | 552 |
500 EXPECT_EQ(10.0, calculator_ui.GetOutput()); | 553 EXPECT_EQ(10.0, calculator_ui.GetOutput()); |
501 EXPECT_FALSE(error_received); | 554 EXPECT_FALSE(error_received); |
502 EXPECT_FALSE(destroyed); | 555 EXPECT_FALSE(destroyed); |
503 } | 556 } |
504 // Destroying calculator_ui should close the pipe and generate an error on the | 557 // Destroying calculator_ui should close the pipe and generate an error on the |
505 // other | 558 // other |
506 // end which will destroy the instance since it is strongly bound. | 559 // end which will destroy the instance since it is strongly bound. |
507 | 560 |
508 loop.RunUntilIdle(); | 561 run_loop.Run(); |
509 EXPECT_TRUE(error_received); | 562 EXPECT_TRUE(error_received); |
510 EXPECT_TRUE(destroyed); | 563 EXPECT_TRUE(destroyed); |
511 } | 564 } |
512 | 565 |
513 class WeakMathCalculatorImpl : public math::Calculator { | 566 class WeakMathCalculatorImpl : public math::Calculator { |
514 public: | 567 public: |
515 WeakMathCalculatorImpl(ScopedMessagePipeHandle handle, | 568 WeakMathCalculatorImpl(ScopedMessagePipeHandle handle, |
516 bool* error_received, | 569 bool* error_received, |
517 bool* destroyed) | 570 bool* destroyed, |
| 571 const base::Closure& closure) |
518 : error_received_(error_received), | 572 : error_received_(error_received), |
519 destroyed_(destroyed), | 573 destroyed_(destroyed), |
| 574 closure_(closure), |
520 binding_(this, std::move(handle)) { | 575 binding_(this, std::move(handle)) { |
521 binding_.set_connection_error_handler( | 576 binding_.set_connection_error_handler( |
522 [this]() { *error_received_ = true; }); | 577 [this]() { *error_received_ = true; closure_.Run(); }); |
523 } | 578 } |
524 ~WeakMathCalculatorImpl() override { *destroyed_ = true; } | 579 ~WeakMathCalculatorImpl() override { *destroyed_ = true; } |
525 | 580 |
526 void Clear(const CalcCallback& callback) override { callback.Run(total_); } | 581 void Clear(const CalcCallback& callback) override { callback.Run(total_); } |
527 | 582 |
528 void Add(double value, const CalcCallback& callback) override { | 583 void Add(double value, const CalcCallback& callback) override { |
529 total_ += value; | 584 total_ += value; |
530 callback.Run(total_); | 585 callback.Run(total_); |
531 } | 586 } |
532 | 587 |
533 void Multiply(double value, const CalcCallback& callback) override { | 588 void Multiply(double value, const CalcCallback& callback) override { |
534 total_ *= value; | 589 total_ *= value; |
535 callback.Run(total_); | 590 callback.Run(total_); |
536 } | 591 } |
537 | 592 |
538 private: | 593 private: |
539 double total_ = 0.0; | 594 double total_ = 0.0; |
540 bool* error_received_; | 595 bool* error_received_; |
541 bool* destroyed_; | 596 bool* destroyed_; |
| 597 base::Closure closure_; |
542 | 598 |
543 Binding<math::Calculator> binding_; | 599 Binding<math::Calculator> binding_; |
544 }; | 600 }; |
545 | 601 |
546 TEST(WeakConnectorTest, Math) { | 602 TEST(WeakConnectorTest, Math) { |
547 base::MessageLoop loop(common::MessagePumpMojo::Create()); | 603 base::MessageLoop loop(common::MessagePumpMojo::Create()); |
548 | 604 |
549 bool error_received = false; | 605 bool error_received = false; |
550 bool destroyed = false; | 606 bool destroyed = false; |
551 MessagePipe pipe; | 607 MessagePipe pipe; |
| 608 base::RunLoop run_loop; |
552 WeakMathCalculatorImpl impl(std::move(pipe.handle0), &error_received, | 609 WeakMathCalculatorImpl impl(std::move(pipe.handle0), &error_received, |
553 &destroyed); | 610 &destroyed, run_loop.QuitClosure()); |
554 | 611 |
555 math::CalculatorPtr calc; | 612 math::CalculatorPtr calc; |
556 calc.Bind(InterfacePtrInfo<math::Calculator>(std::move(pipe.handle1), 0u)); | 613 calc.Bind(InterfacePtrInfo<math::Calculator>(std::move(pipe.handle1), 0u)); |
557 | 614 |
558 { | 615 { |
559 // Suppose this is instantiated in a process that has the other end of the | 616 // Suppose this is instantiated in a process that has the other end of the |
560 // message pipe. | 617 // message pipe. |
561 MathCalculatorUI calculator_ui(std::move(calc)); | 618 MathCalculatorUI calculator_ui(std::move(calc)); |
562 | 619 |
563 calculator_ui.Add(2.0); | 620 base::RunLoop run_loop, run_loop2; |
564 calculator_ui.Multiply(5.0); | 621 calculator_ui.Add(2.0, run_loop.QuitClosure()); |
565 | 622 calculator_ui.Multiply(5.0, run_loop2.QuitClosure()); |
566 loop.RunUntilIdle(); | 623 run_loop.Run(); |
| 624 run_loop2.Run(); |
567 | 625 |
568 EXPECT_EQ(10.0, calculator_ui.GetOutput()); | 626 EXPECT_EQ(10.0, calculator_ui.GetOutput()); |
569 EXPECT_FALSE(error_received); | 627 EXPECT_FALSE(error_received); |
570 EXPECT_FALSE(destroyed); | 628 EXPECT_FALSE(destroyed); |
571 // Destroying calculator_ui should close the pipe and generate an error on | 629 // Destroying calculator_ui should close the pipe and generate an error on |
572 // the other | 630 // the other |
573 // end which will destroy the instance since it is strongly bound. | 631 // end which will destroy the instance since it is strongly bound. |
574 } | 632 } |
575 | 633 |
576 loop.RunUntilIdle(); | 634 run_loop.Run(); |
577 EXPECT_TRUE(error_received); | 635 EXPECT_TRUE(error_received); |
578 EXPECT_FALSE(destroyed); | 636 EXPECT_FALSE(destroyed); |
579 } | 637 } |
580 | 638 |
581 class CImpl : public C { | 639 class CImpl : public C { |
582 public: | 640 public: |
583 CImpl(bool* d_called, InterfaceRequest<C> request) | 641 CImpl(bool* d_called, InterfaceRequest<C> request, |
584 : d_called_(d_called), binding_(this, std::move(request)) {} | 642 const base::Closure& closure) |
| 643 : d_called_(d_called), binding_(this, std::move(request)), |
| 644 closure_(closure) {} |
585 ~CImpl() override {} | 645 ~CImpl() override {} |
586 | 646 |
587 private: | 647 private: |
588 void D() override { | 648 void D() override { |
589 *d_called_ = true; | 649 *d_called_ = true; |
| 650 closure_.Run(); |
590 } | 651 } |
591 | 652 |
592 bool* d_called_; | 653 bool* d_called_; |
593 StrongBinding<C> binding_; | 654 StrongBinding<C> binding_; |
| 655 base::Closure closure_; |
594 }; | 656 }; |
595 | 657 |
596 class BImpl : public B { | 658 class BImpl : public B { |
597 public: | 659 public: |
598 BImpl(bool* d_called, InterfaceRequest<B> request) | 660 BImpl(bool* d_called, InterfaceRequest<B> request, |
599 : d_called_(d_called), binding_(this, std::move(request)) {} | 661 const base::Closure& closure) |
| 662 : d_called_(d_called), binding_(this, std::move(request)), |
| 663 closure_(closure) {} |
600 ~BImpl() override {} | 664 ~BImpl() override {} |
601 | 665 |
602 private: | 666 private: |
603 void GetC(InterfaceRequest<C> c) override { | 667 void GetC(InterfaceRequest<C> c) override { |
604 new CImpl(d_called_, std::move(c)); | 668 new CImpl(d_called_, std::move(c), closure_); |
605 } | 669 } |
606 | 670 |
607 bool* d_called_; | 671 bool* d_called_; |
608 StrongBinding<B> binding_; | 672 StrongBinding<B> binding_; |
| 673 base::Closure closure_; |
609 }; | 674 }; |
610 | 675 |
611 class AImpl : public A { | 676 class AImpl : public A { |
612 public: | 677 public: |
613 explicit AImpl(InterfaceRequest<A> request) | 678 AImpl(InterfaceRequest<A> request, const base::Closure& closure) |
614 : d_called_(false), binding_(this, std::move(request)) {} | 679 : d_called_(false), binding_(this, std::move(request)), |
| 680 closure_(closure) {} |
615 ~AImpl() override {} | 681 ~AImpl() override {} |
616 | 682 |
617 bool d_called() const { return d_called_; } | 683 bool d_called() const { return d_called_; } |
618 | 684 |
619 private: | 685 private: |
620 void GetB(InterfaceRequest<B> b) override { | 686 void GetB(InterfaceRequest<B> b) override { |
621 new BImpl(&d_called_, std::move(b)); | 687 new BImpl(&d_called_, std::move(b), closure_); |
622 } | 688 } |
623 | 689 |
624 bool d_called_; | 690 bool d_called_; |
625 Binding<A> binding_; | 691 Binding<A> binding_; |
| 692 base::Closure closure_; |
626 }; | 693 }; |
627 | 694 |
628 TEST_F(InterfacePtrTest, Scoping) { | 695 TEST_F(InterfacePtrTest, Scoping) { |
629 APtr a; | 696 APtr a; |
630 AImpl a_impl(GetProxy(&a)); | 697 base::RunLoop run_loop; |
| 698 AImpl a_impl(GetProxy(&a), run_loop.QuitClosure()); |
631 | 699 |
632 EXPECT_FALSE(a_impl.d_called()); | 700 EXPECT_FALSE(a_impl.d_called()); |
633 | 701 |
634 { | 702 { |
635 BPtr b; | 703 BPtr b; |
636 a->GetB(GetProxy(&b)); | 704 a->GetB(GetProxy(&b)); |
637 CPtr c; | 705 CPtr c; |
638 b->GetC(GetProxy(&c)); | 706 b->GetC(GetProxy(&c)); |
639 c->D(); | 707 c->D(); |
640 } | 708 } |
641 | 709 |
642 // While B & C have fallen out of scope, the pipes will remain until they are | 710 // While B & C have fallen out of scope, the pipes will remain until they are |
643 // flushed. | 711 // flushed. |
644 EXPECT_FALSE(a_impl.d_called()); | 712 EXPECT_FALSE(a_impl.d_called()); |
645 PumpMessages(); | 713 run_loop.Run(); |
646 EXPECT_TRUE(a_impl.d_called()); | 714 EXPECT_TRUE(a_impl.d_called()); |
647 } | 715 } |
648 | 716 |
649 } // namespace | 717 } // namespace |
650 } // namespace test | 718 } // namespace test |
651 } // namespace mojo | 719 } // namespace mojo |
OLD | NEW |