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 // Note: This file tests both binding.h (mojo::Binding) and strong_binding.h | 5 // Note: This file tests both binding.h (mojo::Binding) and strong_binding.h |
6 // (mojo::StrongBinding). | 6 // (mojo::StrongBinding). |
7 | 7 |
| 8 #include "mojo/public/cpp/bindings/binding.h" |
| 9 |
8 #include <stdint.h> | 10 #include <stdint.h> |
| 11 #include <utility> |
9 | 12 |
10 #include "base/message_loop/message_loop.h" | 13 #include "base/message_loop/message_loop.h" |
11 #include "mojo/message_pump/message_pump_mojo.h" | 14 #include "mojo/message_pump/message_pump_mojo.h" |
12 #include "mojo/public/cpp/bindings/binding.h" | |
13 #include "mojo/public/cpp/bindings/strong_binding.h" | 15 #include "mojo/public/cpp/bindings/strong_binding.h" |
14 #include "mojo/public/cpp/system/macros.h" | 16 #include "mojo/public/cpp/system/macros.h" |
15 #include "mojo/public/interfaces/bindings/tests/sample_interfaces.mojom.h" | 17 #include "mojo/public/interfaces/bindings/tests/sample_interfaces.mojom.h" |
16 #include "mojo/public/interfaces/bindings/tests/sample_service.mojom.h" | 18 #include "mojo/public/interfaces/bindings/tests/sample_service.mojom.h" |
17 #include "testing/gtest/include/gtest/gtest.h" | 19 #include "testing/gtest/include/gtest/gtest.h" |
18 | 20 |
19 namespace mojo { | 21 namespace mojo { |
20 namespace { | 22 namespace { |
21 | 23 |
22 class BindingTestBase : public testing::Test { | 24 class BindingTestBase : public testing::Test { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 // BindingTest ----------------------------------------------------------------- | 61 // BindingTest ----------------------------------------------------------------- |
60 | 62 |
61 using BindingTest = BindingTestBase; | 63 using BindingTest = BindingTestBase; |
62 | 64 |
63 TEST_F(BindingTest, Close) { | 65 TEST_F(BindingTest, Close) { |
64 bool called = false; | 66 bool called = false; |
65 sample::ServicePtr ptr; | 67 sample::ServicePtr ptr; |
66 auto request = GetProxy(&ptr); | 68 auto request = GetProxy(&ptr); |
67 ptr.set_connection_error_handler([&called]() { called = true; }); | 69 ptr.set_connection_error_handler([&called]() { called = true; }); |
68 ServiceImpl impl; | 70 ServiceImpl impl; |
69 Binding<sample::Service> binding(&impl, request.Pass()); | 71 Binding<sample::Service> binding(&impl, std::move(request)); |
70 | 72 |
71 binding.Close(); | 73 binding.Close(); |
72 EXPECT_FALSE(called); | 74 EXPECT_FALSE(called); |
73 loop().RunUntilIdle(); | 75 loop().RunUntilIdle(); |
74 EXPECT_TRUE(called); | 76 EXPECT_TRUE(called); |
75 } | 77 } |
76 | 78 |
77 // Tests that destroying a mojo::Binding closes the bound message pipe handle. | 79 // Tests that destroying a mojo::Binding closes the bound message pipe handle. |
78 TEST_F(BindingTest, DestroyClosesMessagePipe) { | 80 TEST_F(BindingTest, DestroyClosesMessagePipe) { |
79 bool encountered_error = false; | 81 bool encountered_error = false; |
80 ServiceImpl impl; | 82 ServiceImpl impl; |
81 sample::ServicePtr ptr; | 83 sample::ServicePtr ptr; |
82 auto request = GetProxy(&ptr); | 84 auto request = GetProxy(&ptr); |
83 ptr.set_connection_error_handler( | 85 ptr.set_connection_error_handler( |
84 [&encountered_error]() { encountered_error = true; }); | 86 [&encountered_error]() { encountered_error = true; }); |
85 bool called = false; | 87 bool called = false; |
86 auto called_cb = [&called](int32_t result) { called = true; }; | 88 auto called_cb = [&called](int32_t result) { called = true; }; |
87 { | 89 { |
88 Binding<sample::Service> binding(&impl, request.Pass()); | 90 Binding<sample::Service> binding(&impl, std::move(request)); |
89 ptr->Frobinate(nullptr, sample::Service::BAZ_OPTIONS_REGULAR, nullptr, | 91 ptr->Frobinate(nullptr, sample::Service::BAZ_OPTIONS_REGULAR, nullptr, |
90 called_cb); | 92 called_cb); |
91 loop().RunUntilIdle(); | 93 loop().RunUntilIdle(); |
92 EXPECT_TRUE(called); | 94 EXPECT_TRUE(called); |
93 EXPECT_FALSE(encountered_error); | 95 EXPECT_FALSE(encountered_error); |
94 } | 96 } |
95 // Now that the Binding is out of scope we should detect an error on the other | 97 // Now that the Binding is out of scope we should detect an error on the other |
96 // end of the pipe. | 98 // end of the pipe. |
97 loop().RunUntilIdle(); | 99 loop().RunUntilIdle(); |
98 EXPECT_TRUE(encountered_error); | 100 EXPECT_TRUE(encountered_error); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
140 // called. | 142 // called. |
141 ptr.reset(); | 143 ptr.reset(); |
142 loop().RunUntilIdle(); | 144 loop().RunUntilIdle(); |
143 EXPECT_FALSE(called); | 145 EXPECT_FALSE(called); |
144 } | 146 } |
145 | 147 |
146 class ServiceImplWithBinding : public ServiceImpl { | 148 class ServiceImplWithBinding : public ServiceImpl { |
147 public: | 149 public: |
148 ServiceImplWithBinding(bool* was_deleted, | 150 ServiceImplWithBinding(bool* was_deleted, |
149 InterfaceRequest<sample::Service> request) | 151 InterfaceRequest<sample::Service> request) |
150 : ServiceImpl(was_deleted), binding_(this, request.Pass()) { | 152 : ServiceImpl(was_deleted), binding_(this, std::move(request)) { |
151 binding_.set_connection_error_handler([this]() { delete this; }); | 153 binding_.set_connection_error_handler([this]() { delete this; }); |
152 } | 154 } |
153 | 155 |
154 private: | 156 private: |
155 Binding<sample::Service> binding_; | 157 Binding<sample::Service> binding_; |
156 | 158 |
157 MOJO_DISALLOW_COPY_AND_ASSIGN(ServiceImplWithBinding); | 159 MOJO_DISALLOW_COPY_AND_ASSIGN(ServiceImplWithBinding); |
158 }; | 160 }; |
159 | 161 |
160 // Tests that the binding may be deleted in the connection error handler. | 162 // Tests that the binding may be deleted in the connection error handler. |
(...skipping 24 matching lines...) Expand all Loading... |
185 called = false; | 187 called = false; |
186 auto request = binding.Unbind(); | 188 auto request = binding.Unbind(); |
187 EXPECT_FALSE(binding.is_bound()); | 189 EXPECT_FALSE(binding.is_bound()); |
188 // All calls should fail when not bound... | 190 // All calls should fail when not bound... |
189 ptr->Frobinate(nullptr, sample::Service::BAZ_OPTIONS_REGULAR, nullptr, | 191 ptr->Frobinate(nullptr, sample::Service::BAZ_OPTIONS_REGULAR, nullptr, |
190 called_cb); | 192 called_cb); |
191 loop().RunUntilIdle(); | 193 loop().RunUntilIdle(); |
192 EXPECT_FALSE(called); | 194 EXPECT_FALSE(called); |
193 | 195 |
194 called = false; | 196 called = false; |
195 binding.Bind(request.Pass()); | 197 binding.Bind(std::move(request)); |
196 EXPECT_TRUE(binding.is_bound()); | 198 EXPECT_TRUE(binding.is_bound()); |
197 // ...and should succeed again when the rebound. | 199 // ...and should succeed again when the rebound. |
198 ptr->Frobinate(nullptr, sample::Service::BAZ_OPTIONS_REGULAR, nullptr, | 200 ptr->Frobinate(nullptr, sample::Service::BAZ_OPTIONS_REGULAR, nullptr, |
199 called_cb); | 201 called_cb); |
200 loop().RunUntilIdle(); | 202 loop().RunUntilIdle(); |
201 EXPECT_TRUE(called); | 203 EXPECT_TRUE(called); |
202 } | 204 } |
203 | 205 |
204 class IntegerAccessorImpl : public sample::IntegerAccessor { | 206 class IntegerAccessorImpl : public sample::IntegerAccessor { |
205 public: | 207 public: |
(...skipping 16 matching lines...) Expand all Loading... |
222 Binding<sample::IntegerAccessor> binding(&impl, &ptr); | 224 Binding<sample::IntegerAccessor> binding(&impl, &ptr); |
223 EXPECT_EQ(3u, ptr.version()); | 225 EXPECT_EQ(3u, ptr.version()); |
224 } | 226 } |
225 | 227 |
226 TEST_F(BindingTest, PauseResume) { | 228 TEST_F(BindingTest, PauseResume) { |
227 bool called = false; | 229 bool called = false; |
228 auto called_cb = [&called](int32_t result) { called = true; }; | 230 auto called_cb = [&called](int32_t result) { called = true; }; |
229 sample::ServicePtr ptr; | 231 sample::ServicePtr ptr; |
230 auto request = GetProxy(&ptr); | 232 auto request = GetProxy(&ptr); |
231 ServiceImpl impl; | 233 ServiceImpl impl; |
232 Binding<sample::Service> binding(&impl, request.Pass()); | 234 Binding<sample::Service> binding(&impl, std::move(request)); |
233 binding.PauseIncomingMethodCallProcessing(); | 235 binding.PauseIncomingMethodCallProcessing(); |
234 ptr->Frobinate(nullptr, sample::Service::BAZ_OPTIONS_REGULAR, nullptr, | 236 ptr->Frobinate(nullptr, sample::Service::BAZ_OPTIONS_REGULAR, nullptr, |
235 called_cb); | 237 called_cb); |
236 EXPECT_FALSE(called); | 238 EXPECT_FALSE(called); |
237 loop().RunUntilIdle(); | 239 loop().RunUntilIdle(); |
238 // Frobinate() should not be called as the binding is paused. | 240 // Frobinate() should not be called as the binding is paused. |
239 EXPECT_FALSE(called); | 241 EXPECT_FALSE(called); |
240 | 242 |
241 // Resume the binding, which should trigger processing. | 243 // Resume the binding, which should trigger processing. |
242 binding.ResumeIncomingMethodCallProcessing(); | 244 binding.ResumeIncomingMethodCallProcessing(); |
243 loop().RunUntilIdle(); | 245 loop().RunUntilIdle(); |
244 EXPECT_TRUE(called); | 246 EXPECT_TRUE(called); |
245 } | 247 } |
246 | 248 |
247 // Verifies the connection error handler is not run while a binding is paused. | 249 // Verifies the connection error handler is not run while a binding is paused. |
248 TEST_F(BindingTest, ErrorHandleNotRunWhilePaused) { | 250 TEST_F(BindingTest, ErrorHandleNotRunWhilePaused) { |
249 bool called = false; | 251 bool called = false; |
250 sample::ServicePtr ptr; | 252 sample::ServicePtr ptr; |
251 auto request = GetProxy(&ptr); | 253 auto request = GetProxy(&ptr); |
252 ServiceImpl impl; | 254 ServiceImpl impl; |
253 Binding<sample::Service> binding(&impl, request.Pass()); | 255 Binding<sample::Service> binding(&impl, std::move(request)); |
254 binding.set_connection_error_handler([&called]() { called = true; }); | 256 binding.set_connection_error_handler([&called]() { called = true; }); |
255 binding.PauseIncomingMethodCallProcessing(); | 257 binding.PauseIncomingMethodCallProcessing(); |
256 | 258 |
257 ptr.reset(); | 259 ptr.reset(); |
258 loop().RunUntilIdle(); | 260 loop().RunUntilIdle(); |
259 // The connection error handle should not be called as the binding is paused. | 261 // The connection error handle should not be called as the binding is paused. |
260 EXPECT_FALSE(called); | 262 EXPECT_FALSE(called); |
261 | 263 |
262 // Resume the binding, which should trigger the error handler. | 264 // Resume the binding, which should trigger the error handler. |
263 binding.ResumeIncomingMethodCallProcessing(); | 265 binding.ResumeIncomingMethodCallProcessing(); |
(...skipping 11 matching lines...) Expand all Loading... |
275 bool encountered_error = false; | 277 bool encountered_error = false; |
276 bool was_deleted = false; | 278 bool was_deleted = false; |
277 ServiceImpl impl(&was_deleted); | 279 ServiceImpl impl(&was_deleted); |
278 sample::ServicePtr ptr; | 280 sample::ServicePtr ptr; |
279 auto request = GetProxy(&ptr); | 281 auto request = GetProxy(&ptr); |
280 ptr.set_connection_error_handler( | 282 ptr.set_connection_error_handler( |
281 [&encountered_error]() { encountered_error = true; }); | 283 [&encountered_error]() { encountered_error = true; }); |
282 bool called = false; | 284 bool called = false; |
283 auto called_cb = [&called](int32_t result) { called = true; }; | 285 auto called_cb = [&called](int32_t result) { called = true; }; |
284 { | 286 { |
285 StrongBinding<sample::Service> binding(&impl, request.Pass()); | 287 StrongBinding<sample::Service> binding(&impl, std::move(request)); |
286 ptr->Frobinate(nullptr, sample::Service::BAZ_OPTIONS_REGULAR, nullptr, | 288 ptr->Frobinate(nullptr, sample::Service::BAZ_OPTIONS_REGULAR, nullptr, |
287 called_cb); | 289 called_cb); |
288 loop().RunUntilIdle(); | 290 loop().RunUntilIdle(); |
289 EXPECT_TRUE(called); | 291 EXPECT_TRUE(called); |
290 EXPECT_FALSE(encountered_error); | 292 EXPECT_FALSE(encountered_error); |
291 } | 293 } |
292 // Now that the StrongBinding is out of scope we should detect an error on the | 294 // Now that the StrongBinding is out of scope we should detect an error on the |
293 // other end of the pipe. | 295 // other end of the pipe. |
294 loop().RunUntilIdle(); | 296 loop().RunUntilIdle(); |
295 EXPECT_TRUE(encountered_error); | 297 EXPECT_TRUE(encountered_error); |
296 // But destroying the StrongBinding doesn't destroy the object. | 298 // But destroying the StrongBinding doesn't destroy the object. |
297 ASSERT_FALSE(was_deleted); | 299 ASSERT_FALSE(was_deleted); |
298 } | 300 } |
299 | 301 |
300 class ServiceImplWithStrongBinding : public ServiceImpl { | 302 class ServiceImplWithStrongBinding : public ServiceImpl { |
301 public: | 303 public: |
302 ServiceImplWithStrongBinding(bool* was_deleted, | 304 ServiceImplWithStrongBinding(bool* was_deleted, |
303 InterfaceRequest<sample::Service> request) | 305 InterfaceRequest<sample::Service> request) |
304 : ServiceImpl(was_deleted), binding_(this, request.Pass()) {} | 306 : ServiceImpl(was_deleted), binding_(this, std::move(request)) {} |
305 | 307 |
306 StrongBinding<sample::Service>& binding() { return binding_; } | 308 StrongBinding<sample::Service>& binding() { return binding_; } |
307 | 309 |
308 private: | 310 private: |
309 StrongBinding<sample::Service> binding_; | 311 StrongBinding<sample::Service> binding_; |
310 | 312 |
311 MOJO_DISALLOW_COPY_AND_ASSIGN(ServiceImplWithStrongBinding); | 313 MOJO_DISALLOW_COPY_AND_ASSIGN(ServiceImplWithStrongBinding); |
312 }; | 314 }; |
313 | 315 |
314 // Tests the typical case, where the implementation object owns the | 316 // Tests the typical case, where the implementation object owns the |
(...skipping 18 matching lines...) Expand all Loading... |
333 // pipe being closed). Also checks that the connection error handler doesn't get | 335 // pipe being closed). Also checks that the connection error handler doesn't get |
334 // called. | 336 // called. |
335 TEST_F(StrongBindingTest, ExplicitDeleteImpl) { | 337 TEST_F(StrongBindingTest, ExplicitDeleteImpl) { |
336 bool ptr_error_handler_called = false; | 338 bool ptr_error_handler_called = false; |
337 sample::ServicePtr ptr; | 339 sample::ServicePtr ptr; |
338 auto request = GetProxy(&ptr); | 340 auto request = GetProxy(&ptr); |
339 ptr.set_connection_error_handler( | 341 ptr.set_connection_error_handler( |
340 [&ptr_error_handler_called]() { ptr_error_handler_called = true; }); | 342 [&ptr_error_handler_called]() { ptr_error_handler_called = true; }); |
341 bool was_deleted = false; | 343 bool was_deleted = false; |
342 ServiceImplWithStrongBinding* impl = | 344 ServiceImplWithStrongBinding* impl = |
343 new ServiceImplWithStrongBinding(&was_deleted, request.Pass()); | 345 new ServiceImplWithStrongBinding(&was_deleted, std::move(request)); |
344 bool binding_error_handler_called = false; | 346 bool binding_error_handler_called = false; |
345 impl->binding().set_connection_error_handler( | 347 impl->binding().set_connection_error_handler( |
346 [&binding_error_handler_called]() { | 348 [&binding_error_handler_called]() { |
347 binding_error_handler_called = true; | 349 binding_error_handler_called = true; |
348 }); | 350 }); |
349 | 351 |
350 loop().RunUntilIdle(); | 352 loop().RunUntilIdle(); |
351 EXPECT_FALSE(ptr_error_handler_called); | 353 EXPECT_FALSE(ptr_error_handler_called); |
352 EXPECT_FALSE(was_deleted); | 354 EXPECT_FALSE(was_deleted); |
353 | 355 |
354 delete impl; | 356 delete impl; |
355 EXPECT_FALSE(ptr_error_handler_called); | 357 EXPECT_FALSE(ptr_error_handler_called); |
356 EXPECT_TRUE(was_deleted); | 358 EXPECT_TRUE(was_deleted); |
357 was_deleted = false; // It shouldn't be double-deleted! | 359 was_deleted = false; // It shouldn't be double-deleted! |
358 loop().RunUntilIdle(); | 360 loop().RunUntilIdle(); |
359 EXPECT_TRUE(ptr_error_handler_called); | 361 EXPECT_TRUE(ptr_error_handler_called); |
360 EXPECT_FALSE(was_deleted); | 362 EXPECT_FALSE(was_deleted); |
361 | 363 |
362 EXPECT_FALSE(binding_error_handler_called); | 364 EXPECT_FALSE(binding_error_handler_called); |
363 } | 365 } |
364 | 366 |
365 } // namespace | 367 } // namespace |
366 } // mojo | 368 } // mojo |
OLD | NEW |