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