OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 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/public/cpp/application/service_provider_impl.h" |
| 6 |
| 7 #include <utility> |
| 8 |
| 9 #include "mojo/public/cpp/application/connect.h" |
| 10 #include "mojo/public/cpp/bindings/strong_binding.h" |
| 11 #include "mojo/public/cpp/environment/environment.h" |
| 12 #include "mojo/public/cpp/system/macros.h" |
| 13 #include "mojo/public/cpp/utility/run_loop.h" |
| 14 #include "mojo/public/interfaces/application/service_provider.mojom.h" |
| 15 #include "mojo/public/interfaces/bindings/tests/ping_service.mojom.h" |
| 16 #include "testing/gtest/include/gtest/gtest.h" |
| 17 |
| 18 namespace mojo { |
| 19 namespace { |
| 20 |
| 21 class ServiceProviderImplTest : public testing::Test { |
| 22 public: |
| 23 ServiceProviderImplTest() {} |
| 24 ~ServiceProviderImplTest() override { loop_.RunUntilIdle(); } |
| 25 |
| 26 RunLoop& loop() { return loop_; } |
| 27 |
| 28 protected: |
| 29 void QuitLoop(bool ok) { |
| 30 EXPECT_TRUE(ok); |
| 31 loop_.Quit(); |
| 32 } |
| 33 |
| 34 private: |
| 35 Environment env_; |
| 36 RunLoop loop_; |
| 37 |
| 38 MOJO_DISALLOW_COPY_AND_ASSIGN(ServiceProviderImplTest); |
| 39 }; |
| 40 |
| 41 class PingServiceImpl : public test::PingService { |
| 42 public: |
| 43 PingServiceImpl(InterfaceRequest<test::PingService> request) |
| 44 : strong_binding_(this, std::move(request)) {} |
| 45 ~PingServiceImpl() override {} |
| 46 |
| 47 // |test::PingService|: |
| 48 void Ping(const PingCallback& callback) override { callback.Run(); } |
| 49 |
| 50 private: |
| 51 StrongBinding<test::PingService> strong_binding_; |
| 52 |
| 53 MOJO_DISALLOW_COPY_AND_ASSIGN(PingServiceImpl); |
| 54 }; |
| 55 |
| 56 TEST_F(ServiceProviderImplTest, Basic) { |
| 57 const char kPing1[] = "Ping1"; |
| 58 const char kPing2[] = "Ping2"; |
| 59 const char kPing3[] = "Ping3"; |
| 60 |
| 61 ServiceProviderPtr sp; |
| 62 ServiceProviderImpl impl(GetProxy(&sp)); |
| 63 |
| 64 impl.AddServiceNew<test::PingService>( |
| 65 [](const ConnectionContext& connection_context, |
| 66 InterfaceRequest<test::PingService> request) { |
| 67 new PingServiceImpl(std::move(request)); |
| 68 }, |
| 69 kPing1); |
| 70 |
| 71 impl.AddServiceNew<test::PingService>( |
| 72 [](const ConnectionContext& connection_context, |
| 73 InterfaceRequest<test::PingService> request) { |
| 74 new PingServiceImpl(std::move(request)); |
| 75 }, |
| 76 kPing2); |
| 77 |
| 78 { |
| 79 test::PingServicePtr ping1; |
| 80 ConnectToService(sp.get(), GetProxy(&ping1), kPing1); |
| 81 ping1.set_connection_error_handler([this] { QuitLoop(false); }); |
| 82 ping1->Ping([this] { QuitLoop(true); }); |
| 83 loop().Run(); |
| 84 } |
| 85 loop().RunUntilIdle(); // Run stuff caused by destructors. |
| 86 |
| 87 { |
| 88 test::PingServicePtr ping2; |
| 89 ConnectToService(sp.get(), GetProxy(&ping2), kPing2); |
| 90 ping2.set_connection_error_handler([this] { QuitLoop(false); }); |
| 91 ping2->Ping([this] { QuitLoop(true); }); |
| 92 loop().Run(); |
| 93 } |
| 94 loop().RunUntilIdle(); // Run stuff caused by destructors. |
| 95 |
| 96 // "Ping3" isn't actually registered! |
| 97 { |
| 98 test::PingServicePtr ping3; |
| 99 ConnectToService(sp.get(), GetProxy(&ping3), kPing3); |
| 100 ping3.set_connection_error_handler([this] { QuitLoop(true); }); |
| 101 ping3->Ping([this] { QuitLoop(false); }); |
| 102 loop().Run(); |
| 103 } |
| 104 loop().RunUntilIdle(); // Run stuff caused by destructors. |
| 105 |
| 106 sp.reset(); |
| 107 loop().RunUntilIdle(); |
| 108 } |
| 109 |
| 110 TEST_F(ServiceProviderImplTest, CloseAndRebind) { |
| 111 const char kPing[] = "Ping"; |
| 112 |
| 113 ServiceProviderPtr sp1; |
| 114 ServiceProviderImpl impl(GetProxy(&sp1)); |
| 115 |
| 116 impl.AddServiceNew<test::PingService>( |
| 117 [](const ConnectionContext& connection_context, |
| 118 InterfaceRequest<test::PingService> request) { |
| 119 new PingServiceImpl(std::move(request)); |
| 120 }, |
| 121 kPing); |
| 122 |
| 123 { |
| 124 test::PingServicePtr ping; |
| 125 ConnectToService(sp1.get(), GetProxy(&ping), kPing); |
| 126 ping.set_connection_error_handler([this] { QuitLoop(false); }); |
| 127 ping->Ping([this] { QuitLoop(true); }); |
| 128 loop().Run(); |
| 129 } |
| 130 loop().RunUntilIdle(); // Run stuff caused by destructors. |
| 131 |
| 132 impl.Close(); |
| 133 sp1.reset(); |
| 134 loop().RunUntilIdle(); |
| 135 |
| 136 ServiceProviderPtr sp2; |
| 137 impl.Bind(GetProxy(&sp2)); |
| 138 |
| 139 { |
| 140 test::PingServicePtr ping; |
| 141 ConnectToService(sp2.get(), GetProxy(&ping), kPing); |
| 142 ping.set_connection_error_handler([this] { QuitLoop(false); }); |
| 143 ping->Ping([this] { QuitLoop(true); }); |
| 144 loop().Run(); |
| 145 } |
| 146 loop().RunUntilIdle(); // Run stuff caused by destructors. |
| 147 |
| 148 // Can close multiple times. |
| 149 impl.Close(); |
| 150 impl.Close(); |
| 151 sp2.reset(); |
| 152 loop().RunUntilIdle(); |
| 153 } |
| 154 |
| 155 TEST_F(ServiceProviderImplTest, Bind) { |
| 156 const char kPing[] = "Ping"; |
| 157 |
| 158 ServiceProviderPtr sp; |
| 159 ServiceProviderImpl impl; |
| 160 |
| 161 impl.Bind(GetProxy(&sp)); |
| 162 |
| 163 impl.AddServiceNew<test::PingService>( |
| 164 [](const ConnectionContext& connection_context, |
| 165 InterfaceRequest<test::PingService> request) { |
| 166 new PingServiceImpl(std::move(request)); |
| 167 }, |
| 168 kPing); |
| 169 |
| 170 { |
| 171 test::PingServicePtr ping; |
| 172 ConnectToService(sp.get(), GetProxy(&ping), kPing); |
| 173 ping.set_connection_error_handler([this] { QuitLoop(false); }); |
| 174 ping->Ping([this] { QuitLoop(true); }); |
| 175 loop().Run(); |
| 176 } |
| 177 loop().RunUntilIdle(); // Run stuff caused by destructors. |
| 178 |
| 179 sp.reset(); |
| 180 loop().RunUntilIdle(); |
| 181 } |
| 182 |
| 183 class FauxServiceProvider : public ServiceProvider { |
| 184 public: |
| 185 explicit FauxServiceProvider( |
| 186 std::function<void(const std::string& service_name)> |
| 187 on_connect_to_service) |
| 188 : on_connect_to_service_(on_connect_to_service) {} |
| 189 ~FauxServiceProvider() override {} |
| 190 |
| 191 // |ServiceProvider|: |
| 192 void ConnectToService(const String& service_name, |
| 193 ScopedMessagePipeHandle client_handle) override { |
| 194 on_connect_to_service_(service_name.get()); |
| 195 } |
| 196 |
| 197 private: |
| 198 std::function<void(const std::string& service_name)> on_connect_to_service_; |
| 199 |
| 200 MOJO_DISALLOW_COPY_AND_ASSIGN(FauxServiceProvider); |
| 201 }; |
| 202 |
| 203 TEST_F(ServiceProviderImplTest, FallbackServiceProvider) { |
| 204 const char kWhatever[] = "Whatever"; |
| 205 |
| 206 ServiceProviderPtr sp; |
| 207 ServiceProviderImpl impl(GetProxy(&sp)); |
| 208 |
| 209 { |
| 210 test::PingServicePtr ping; |
| 211 ConnectToService(sp.get(), GetProxy(&ping), kWhatever); |
| 212 ping.set_connection_error_handler([this] { QuitLoop(true); }); |
| 213 ping->Ping([this] { QuitLoop(false); }); |
| 214 loop().Run(); |
| 215 } |
| 216 loop().RunUntilIdle(); // Run stuff caused by destructors. |
| 217 |
| 218 bool was_run = false; |
| 219 FauxServiceProvider fallback_sp( |
| 220 [this, &kWhatever, &was_run](const std::string& service_name) { |
| 221 EXPECT_EQ(kWhatever, service_name); |
| 222 was_run = true; |
| 223 }); |
| 224 impl.set_fallback_service_provider(&fallback_sp); |
| 225 |
| 226 { |
| 227 test::PingServicePtr ping; |
| 228 ConnectToService(sp.get(), GetProxy(&ping), kWhatever); |
| 229 ping.set_connection_error_handler([this] { QuitLoop(true); }); |
| 230 EXPECT_FALSE(was_run); |
| 231 ping->Ping([this] { QuitLoop(false); }); |
| 232 loop().Run(); |
| 233 EXPECT_TRUE(was_run); |
| 234 } |
| 235 loop().RunUntilIdle(); // Run stuff caused by destructors. |
| 236 |
| 237 // Clear the fallback. |
| 238 impl.set_fallback_service_provider(nullptr); |
| 239 was_run = false; |
| 240 |
| 241 { |
| 242 test::PingServicePtr ping; |
| 243 ConnectToService(sp.get(), GetProxy(&ping), kWhatever); |
| 244 ping.set_connection_error_handler([this] { QuitLoop(true); }); |
| 245 ping->Ping([this] { QuitLoop(false); }); |
| 246 loop().Run(); |
| 247 } |
| 248 loop().RunUntilIdle(); // Run stuff caused by destructors. |
| 249 |
| 250 sp.reset(); |
| 251 loop().RunUntilIdle(); |
| 252 |
| 253 EXPECT_FALSE(was_run); |
| 254 } |
| 255 |
| 256 } // namespace |
| 257 } // namespace mojo |
OLD | NEW |