Merge lp:~thomas-voss/trust-store/watch-service-name-owner-changes into lp:trust-store/15.04
- watch-service-name-owner-changes
- Merge into 15.04
Status: | Needs review |
---|---|
Proposed branch: | lp:~thomas-voss/trust-store/watch-service-name-owner-changes |
Merge into: | lp:trust-store/15.04 |
Diff against target: |
846 lines (+368/-186) 10 files modified
src/CMakeLists.txt (+3/-0) src/core/trust/daemon.cpp (+18/-92) src/core/trust/dbus/agent_registry.h (+54/-5) src/core/trust/remote/dbus.cpp (+21/-9) src/core/trust/remote/dbus.h (+8/-2) src/core/trust/runtime.cpp (+105/-0) src/core/trust/runtime.h (+88/-0) tests/CMakeLists.txt (+3/-0) tests/dbus_test.cpp (+4/-6) tests/remote_agent_test.cpp (+64/-72) |
To merge this branch: | bzr merge lp:~thomas-voss/trust-store/watch-service-name-owner-changes |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ubuntu Phablet Team | Pending | ||
Review via email: mp+281483@code.launchpad.net |
This proposal supersedes a proposal from 2016-01-03.
Commit message
core::trust:
asynchronously if a new name owner is detected.
Description of the change
core::trust:
asynchronously if a new name owner is detected.
- 138. By Thomas Voß
-
Make core::trust:
:Runtime a proper class and do not expose its internals anymore. - 139. By Thomas Voß
-
Address a few minor niggles regarding object lifetimes and noexcept(true) guarantees.
- 140. By Thomas Voß
-
Wait a little longer to account for slow builders.
- 141. By Thomas Voß
-
Link correct bug report.
Unmerged revisions
- 141. By Thomas Voß
-
Link correct bug report.
- 140. By Thomas Voß
-
Wait a little longer to account for slow builders.
- 139. By Thomas Voß
-
Address a few minor niggles regarding object lifetimes and noexcept(true) guarantees.
- 138. By Thomas Voß
-
Make core::trust:
:Runtime a proper class and do not expose its internals anymore. - 137. By Thomas Voß
-
core::trust:
:dbus:: Agent:: Skeleton now watches for name owner changes, announcing itself
asynchronously if a new name owner is detected.
Preview Diff
1 | === modified file 'src/CMakeLists.txt' | |||
2 | --- src/CMakeLists.txt 2015-08-31 13:16:20 +0000 | |||
3 | +++ src/CMakeLists.txt 2016-01-04 15:02:54 +0000 | |||
4 | @@ -149,6 +149,9 @@ | |||
5 | 149 | trust-stored | 149 | trust-stored |
6 | 150 | 150 | ||
7 | 151 | core/trust/daemon.cpp | 151 | core/trust/daemon.cpp |
8 | 152 | |||
9 | 153 | core/trust/runtime.h | ||
10 | 154 | core/trust/runtime.cpp | ||
11 | 152 | ) | 155 | ) |
12 | 153 | 156 | ||
13 | 154 | add_executable( | 157 | add_executable( |
14 | 155 | 158 | ||
15 | === modified file 'src/core/trust/daemon.cpp' | |||
16 | --- src/core/trust/daemon.cpp 2015-08-31 14:00:41 +0000 | |||
17 | +++ src/core/trust/daemon.cpp 2016-01-04 15:02:54 +0000 | |||
18 | @@ -22,6 +22,7 @@ | |||
19 | 22 | #include <core/trust/cached_agent.h> | 22 | #include <core/trust/cached_agent.h> |
20 | 23 | #include <core/trust/expose.h> | 23 | #include <core/trust/expose.h> |
21 | 24 | #include <core/trust/i18n.h> | 24 | #include <core/trust/i18n.h> |
22 | 25 | #include <core/trust/runtime.h> | ||
23 | 25 | #include <core/trust/store.h> | 26 | #include <core/trust/store.h> |
24 | 26 | #include <core/trust/white_listing_agent.h> | 27 | #include <core/trust/white_listing_agent.h> |
25 | 27 | 28 | ||
26 | @@ -49,67 +50,6 @@ | |||
27 | 49 | 50 | ||
28 | 50 | namespace | 51 | namespace |
29 | 51 | { | 52 | { |
30 | 52 | struct Runtime | ||
31 | 53 | { | ||
32 | 54 | // Do not execute in parallel, serialize | ||
33 | 55 | // accesses. | ||
34 | 56 | static constexpr std::size_t concurrency_hint{2}; | ||
35 | 57 | |||
36 | 58 | // Our evil singleton pattern. Not bad though, we control the | ||
37 | 59 | // entire executable and rely on automatic cleanup of static | ||
38 | 60 | // instances. | ||
39 | 61 | static Runtime& instance() | ||
40 | 62 | { | ||
41 | 63 | static Runtime runtime; | ||
42 | 64 | return runtime; | ||
43 | 65 | } | ||
44 | 66 | |||
45 | 67 | ~Runtime() | ||
46 | 68 | { | ||
47 | 69 | io_service.stop(); | ||
48 | 70 | |||
49 | 71 | if (worker1.joinable()) | ||
50 | 72 | worker1.join(); | ||
51 | 73 | |||
52 | 74 | if (worker2.joinable()) | ||
53 | 75 | worker2.join(); | ||
54 | 76 | } | ||
55 | 77 | |||
56 | 78 | // We trap sig term to ensure a clean shutdown. | ||
57 | 79 | std::shared_ptr<core::posix::SignalTrap> signal_trap | ||
58 | 80 | { | ||
59 | 81 | core::posix::trap_signals_for_all_subsequent_threads( | ||
60 | 82 | { | ||
61 | 83 | core::posix::Signal::sig_term, | ||
62 | 84 | core::posix::Signal::sig_int | ||
63 | 85 | }) | ||
64 | 86 | }; | ||
65 | 87 | |||
66 | 88 | // Our io_service instance exposed to remote agents. | ||
67 | 89 | boost::asio::io_service io_service | ||
68 | 90 | { | ||
69 | 91 | concurrency_hint | ||
70 | 92 | }; | ||
71 | 93 | |||
72 | 94 | // We keep the io_service alive and introduce some artificial | ||
73 | 95 | // work. | ||
74 | 96 | boost::asio::io_service::work keep_alive | ||
75 | 97 | { | ||
76 | 98 | io_service | ||
77 | 99 | }; | ||
78 | 100 | |||
79 | 101 | // We immediate execute the io_service instance | ||
80 | 102 | std::thread worker1 | ||
81 | 103 | { | ||
82 | 104 | std::thread{[this]() { io_service.run(); }} | ||
83 | 105 | }; | ||
84 | 106 | |||
85 | 107 | std::thread worker2 | ||
86 | 108 | { | ||
87 | 109 | std::thread{[this]() { io_service.run(); }} | ||
88 | 110 | }; | ||
89 | 111 | }; | ||
90 | 112 | |||
91 | 113 | core::trust::Daemon::Dictionary fill_dictionary_from_unrecognized_options(const Options::parsed_options& parsed_options) | 53 | core::trust::Daemon::Dictionary fill_dictionary_from_unrecognized_options(const Options::parsed_options& parsed_options) |
92 | 114 | { | 54 | { |
93 | 115 | auto unrecognized = Options::collect_unrecognized( | 55 | auto unrecognized = Options::collect_unrecognized( |
94 | @@ -170,7 +110,7 @@ | |||
95 | 170 | "Could not create bus for name: " + bus_name | 110 | "Could not create bus for name: " + bus_name |
96 | 171 | }; | 111 | }; |
97 | 172 | 112 | ||
99 | 173 | bus->install_executor(core::dbus::asio::make_executor(bus, Runtime::instance().io_service)); | 113 | bus->install_executor(core::trust::Runtime::instance().make_executor_for_bus(bus)); |
100 | 174 | 114 | ||
101 | 175 | return bus; | 115 | return bus; |
102 | 176 | } | 116 | } |
103 | @@ -256,7 +196,7 @@ | |||
104 | 256 | core::trust::remote::posix::Skeleton::Configuration config | 196 | core::trust::remote::posix::Skeleton::Configuration config |
105 | 257 | { | 197 | { |
106 | 258 | agent, | 198 | agent, |
108 | 259 | Runtime::instance().io_service, | 199 | core::trust::Runtime::instance().service(), |
109 | 260 | boost::asio::local::stream_protocol::endpoint{dict.at("endpoint")}, | 200 | boost::asio::local::stream_protocol::endpoint{dict.at("endpoint")}, |
110 | 261 | core::trust::remote::helpers::proc_stat_start_time_resolver(), | 201 | core::trust::remote::helpers::proc_stat_start_time_resolver(), |
111 | 262 | core::trust::remote::helpers::aa_get_task_con_app_id_resolver(), | 202 | core::trust::remote::helpers::aa_get_task_con_app_id_resolver(), |
112 | @@ -289,16 +229,19 @@ | |||
113 | 289 | core::trust::remote::dbus::default_agent_registry_path | 229 | core::trust::remote::dbus::default_agent_registry_path |
114 | 290 | }); | 230 | }); |
115 | 291 | 231 | ||
116 | 232 | core::dbus::DBus daemon{bus}; | ||
117 | 233 | |||
118 | 292 | core::trust::remote::dbus::Agent::Skeleton::Configuration config | 234 | core::trust::remote::dbus::Agent::Skeleton::Configuration config |
119 | 293 | { | 235 | { |
120 | 294 | agent, | 236 | agent, |
121 | 295 | object, | 237 | object, |
122 | 238 | daemon.make_service_watcher(dbus_service_name), | ||
123 | 296 | service, | 239 | service, |
124 | 297 | bus, | 240 | bus, |
125 | 298 | core::trust::remote::helpers::aa_get_task_con_app_id_resolver() | 241 | core::trust::remote::helpers::aa_get_task_con_app_id_resolver() |
126 | 299 | }; | 242 | }; |
127 | 300 | 243 | ||
129 | 301 | return std::make_shared<core::trust::remote::dbus::Agent::Skeleton>(config); | 244 | return std::make_shared<core::trust::remote::dbus::Agent::Skeleton>(std::move(config)); |
130 | 302 | } | 245 | } |
131 | 303 | } | 246 | } |
132 | 304 | }; | 247 | }; |
133 | @@ -390,16 +333,6 @@ | |||
134 | 390 | // Executes the daemon with the given configuration. | 333 | // Executes the daemon with the given configuration. |
135 | 391 | core::posix::exit::Status core::trust::Daemon::Skeleton::main(const core::trust::Daemon::Skeleton::Configuration& configuration) | 334 | core::posix::exit::Status core::trust::Daemon::Skeleton::main(const core::trust::Daemon::Skeleton::Configuration& configuration) |
136 | 392 | { | 335 | { |
137 | 393 | Runtime::instance().signal_trap->signal_raised().connect([](core::posix::Signal) | ||
138 | 394 | { | ||
139 | 395 | Runtime::instance().signal_trap->stop(); | ||
140 | 396 | }); | ||
141 | 397 | |||
142 | 398 | std::thread worker | ||
143 | 399 | { | ||
144 | 400 | [configuration]() { configuration.bus->run(); } | ||
145 | 401 | }; | ||
146 | 402 | |||
147 | 403 | // Expose the local store to the bus, keeping it exposed for the | 336 | // Expose the local store to the bus, keeping it exposed for the |
148 | 404 | // lifetime of the returned token. | 337 | // lifetime of the returned token. |
149 | 405 | auto token = core::trust::expose_store_to_bus_with_name( | 338 | auto token = core::trust::expose_store_to_bus_with_name( |
150 | @@ -407,12 +340,7 @@ | |||
151 | 407 | configuration.bus, | 340 | configuration.bus, |
152 | 408 | configuration.service_name); | 341 | configuration.service_name); |
153 | 409 | 342 | ||
160 | 410 | Runtime::instance().signal_trap->run(); | 343 | core::trust::Runtime::instance().run(); |
155 | 411 | |||
156 | 412 | configuration.bus->stop(); | ||
157 | 413 | |||
158 | 414 | if (worker.joinable()) | ||
159 | 415 | worker.join(); | ||
161 | 416 | 344 | ||
162 | 417 | return core::posix::exit::Status::success; | 345 | return core::posix::exit::Status::success; |
163 | 418 | } | 346 | } |
164 | @@ -432,7 +360,7 @@ | |||
165 | 432 | 360 | ||
166 | 433 | core::trust::remote::posix::Stub::Configuration config | 361 | core::trust::remote::posix::Stub::Configuration config |
167 | 434 | { | 362 | { |
169 | 435 | Runtime::instance().io_service, | 363 | core::trust::Runtime::instance().service(), |
170 | 436 | boost::asio::local::stream_protocol::endpoint{dict.at("endpoint")}, | 364 | boost::asio::local::stream_protocol::endpoint{dict.at("endpoint")}, |
171 | 437 | core::trust::remote::helpers::proc_stat_start_time_resolver(), | 365 | core::trust::remote::helpers::proc_stat_start_time_resolver(), |
172 | 438 | core::trust::remote::posix::Stub::get_sock_opt_credentials_resolver(), | 366 | core::trust::remote::posix::Stub::get_sock_opt_credentials_resolver(), |
173 | @@ -522,13 +450,18 @@ | |||
174 | 522 | // A user can feed a request to the stub. | 450 | // A user can feed a request to the stub. |
175 | 523 | struct Shell : public std::enable_shared_from_this<Shell> | 451 | struct Shell : public std::enable_shared_from_this<Shell> |
176 | 524 | { | 452 | { |
178 | 525 | Shell(const std::shared_ptr<core::trust::Agent>& agent) | 453 | Shell(const std::shared_ptr<core::trust::Agent>& agent, boost::asio::io_service& ios) |
179 | 526 | : agent{agent}, | 454 | : agent{agent}, |
181 | 527 | stdin{Runtime::instance().io_service, STDIN_FILENO}, | 455 | stdin{ios, STDIN_FILENO}, |
182 | 528 | app_id_resolver{core::trust::remote::helpers::aa_get_task_con_app_id_resolver()} | 456 | app_id_resolver{core::trust::remote::helpers::aa_get_task_con_app_id_resolver()} |
183 | 529 | { | 457 | { |
184 | 530 | } | 458 | } |
185 | 531 | 459 | ||
186 | 460 | ~Shell() | ||
187 | 461 | { | ||
188 | 462 | stop(); | ||
189 | 463 | } | ||
190 | 464 | |||
191 | 532 | // Prints out the initial prompt and initiates a read operation on stdin. | 465 | // Prints out the initial prompt and initiates a read operation on stdin. |
192 | 533 | void start() | 466 | void start() |
193 | 534 | { | 467 | { |
194 | @@ -605,20 +538,13 @@ | |||
195 | 605 | core::posix::exit::Status core::trust::Daemon::Stub::main(const core::trust::Daemon::Stub::Configuration& configuration) | 538 | core::posix::exit::Status core::trust::Daemon::Stub::main(const core::trust::Daemon::Stub::Configuration& configuration) |
196 | 606 | { | 539 | { |
197 | 607 | // We setup our minimal shell here. | 540 | // We setup our minimal shell here. |
204 | 608 | auto shell = std::make_shared<Shell>(configuration.remote.agent); | 541 | auto shell = std::make_shared<Shell>(configuration.remote.agent, core::trust::Runtime::instance().service()); |
199 | 609 | |||
200 | 610 | Runtime::instance().signal_trap->signal_raised().connect([](core::posix::Signal) | ||
201 | 611 | { | ||
202 | 612 | Runtime::instance().signal_trap->stop(); | ||
203 | 613 | }); | ||
205 | 614 | 542 | ||
206 | 615 | // We start up our shell | 543 | // We start up our shell |
207 | 616 | shell->start(); | 544 | shell->start(); |
208 | 617 | 545 | ||
209 | 618 | // Wait until signal arrives. | 546 | // Wait until signal arrives. |
213 | 619 | Runtime::instance().signal_trap->run(); | 547 | core::trust::Runtime::instance().run(); |
211 | 620 | |||
212 | 621 | shell->stop(); | ||
214 | 622 | 548 | ||
215 | 623 | return core::posix::exit::Status::success; | 549 | return core::posix::exit::Status::success; |
216 | 624 | } | 550 | } |
217 | 625 | 551 | ||
218 | === modified file 'src/core/trust/dbus/agent_registry.h' | |||
219 | --- src/core/trust/dbus/agent_registry.h 2014-08-04 07:10:52 +0000 | |||
220 | +++ src/core/trust/dbus/agent_registry.h 2016-01-04 15:02:54 +0000 | |||
221 | @@ -114,8 +114,10 @@ | |||
222 | 114 | }; | 114 | }; |
223 | 115 | 115 | ||
224 | 116 | // A DBus stub implementation of core::trust::AgentRegistry. | 116 | // A DBus stub implementation of core::trust::AgentRegistry. |
226 | 117 | struct Stub : public core::trust::Agent::Registry | 117 | class Stub : public std::enable_shared_from_this<Stub>, |
227 | 118 | public core::trust::Agent::Registry | ||
228 | 118 | { | 119 | { |
229 | 120 | public: | ||
230 | 119 | // Functor for generating unique object paths. | 121 | // Functor for generating unique object paths. |
231 | 120 | typedef std::function<core::dbus::types::ObjectPath(const core::trust::Uid&)> ObjectPathGenerator; | 122 | typedef std::function<core::dbus::types::ObjectPath(const core::trust::Uid&)> ObjectPathGenerator; |
232 | 121 | 123 | ||
233 | @@ -139,12 +141,12 @@ | |||
234 | 139 | core::dbus::Service::Ptr service; | 141 | core::dbus::Service::Ptr service; |
235 | 140 | // The underlying bus instance. | 142 | // The underlying bus instance. |
236 | 141 | core::dbus::Bus::Ptr bus; | 143 | core::dbus::Bus::Ptr bus; |
238 | 142 | }; | 144 | }; |
239 | 143 | 145 | ||
243 | 144 | // Initializes stub access to the Stub. | 146 | // create returns a new shared Stub instance for configuration. |
244 | 145 | Stub(const Configuration& configuration) | 147 | static std::shared_ptr<Stub> create(const Configuration& configuration) |
242 | 146 | : configuration(configuration) | ||
245 | 147 | { | 148 | { |
246 | 149 | return std::shared_ptr<Stub>(new Stub(configuration)); | ||
247 | 148 | } | 150 | } |
248 | 149 | 151 | ||
249 | 150 | // Calls into the remote implementation to register the given agent implementation. | 152 | // Calls into the remote implementation to register the given agent implementation. |
250 | @@ -179,6 +181,46 @@ | |||
251 | 179 | locking_agent_registry.register_agent_for_user(uid, skeleton); | 181 | locking_agent_registry.register_agent_for_user(uid, skeleton); |
252 | 180 | } | 182 | } |
253 | 181 | 183 | ||
254 | 184 | // Calls into the remote implementation to register the given agent implementation. | ||
255 | 185 | // Throws std::runtime_error and std::logic_error in case of issues. | ||
256 | 186 | void register_agent_for_user_async(const core::trust::Uid& uid, const std::shared_ptr<core::trust::Agent>& impl, const std::function<void()>& then) | ||
257 | 187 | { | ||
258 | 188 | // We sample a path for the given uid | ||
259 | 189 | auto path = configuration.object_path_generator(uid); | ||
260 | 190 | // And construct the skeleton instance. | ||
261 | 191 | auto skeleton = std::shared_ptr<core::trust::dbus::Agent::Skeleton> | ||
262 | 192 | { | ||
263 | 193 | new core::trust::dbus::Agent::Skeleton | ||
264 | 194 | { | ||
265 | 195 | core::trust::dbus::Agent::Skeleton::Configuration | ||
266 | 196 | { | ||
267 | 197 | configuration.service->add_object_for_path(path), | ||
268 | 198 | configuration.bus, | ||
269 | 199 | std::bind(&core::trust::Agent::authenticate_request_with_parameters, impl, std::placeholders::_1) | ||
270 | 200 | } | ||
271 | 201 | } | ||
272 | 202 | }; | ||
273 | 203 | |||
274 | 204 | auto sp = shared_from_this(); | ||
275 | 205 | |||
276 | 206 | // And announce the agent. | ||
277 | 207 | configuration.object->invoke_method_asynchronously_with_callback< | ||
278 | 208 | Methods::RegisterAgentForUser, void | ||
279 | 209 | >([this, sp, then, uid, skeleton](const core::dbus::Result<void>& result) | ||
280 | 210 | { | ||
281 | 211 | if (result.is_error()) | ||
282 | 212 | { | ||
283 | 213 | std::cerr << "Failed to register agent for user: " << result.error().print() << std::endl; | ||
284 | 214 | } | ||
285 | 215 | else | ||
286 | 216 | { | ||
287 | 217 | // All good, update our own state prior to invoking the supplied callback. | ||
288 | 218 | locking_agent_registry.register_agent_for_user(uid, skeleton); | ||
289 | 219 | then(); | ||
290 | 220 | } | ||
291 | 221 | }, uid, path); | ||
292 | 222 | } | ||
293 | 223 | |||
294 | 182 | // Calls into the remote implementation to unregister any agent registered for the given uid. | 224 | // Calls into the remote implementation to unregister any agent registered for the given uid. |
295 | 183 | // Throws std::runtime_error and std::logic_error in case of issues. | 225 | // Throws std::runtime_error and std::logic_error in case of issues. |
296 | 184 | void unregister_agent_for_user(const core::trust::Uid& uid) override | 226 | void unregister_agent_for_user(const core::trust::Uid& uid) override |
297 | @@ -195,6 +237,13 @@ | |||
298 | 195 | }; | 237 | }; |
299 | 196 | } | 238 | } |
300 | 197 | 239 | ||
301 | 240 | private: | ||
302 | 241 | // Initializes stub access to the Stub. | ||
303 | 242 | Stub(const Configuration& configuration) | ||
304 | 243 | : configuration(configuration) | ||
305 | 244 | { | ||
306 | 245 | } | ||
307 | 246 | |||
308 | 198 | // We just store all creation-time arguments. | 247 | // We just store all creation-time arguments. |
309 | 199 | Configuration configuration; | 248 | Configuration configuration; |
310 | 200 | // Our local registry of agents | 249 | // Our local registry of agents |
311 | 201 | 250 | ||
312 | === modified file 'src/core/trust/remote/dbus.cpp' | |||
313 | --- src/core/trust/remote/dbus.cpp 2014-07-29 17:00:35 +0000 | |||
314 | +++ src/core/trust/remote/dbus.cpp 2016-01-04 15:02:54 +0000 | |||
315 | @@ -19,6 +19,7 @@ | |||
316 | 19 | #include <core/trust/remote/dbus.h> | 19 | #include <core/trust/remote/dbus.h> |
317 | 20 | 20 | ||
318 | 21 | #include <core/trust/dbus_agent.h> | 21 | #include <core/trust/dbus_agent.h> |
319 | 22 | #include <core/trust/runtime.h> | ||
320 | 22 | 23 | ||
321 | 23 | core::trust::remote::dbus::Agent::Stub::Stub(const core::trust::remote::dbus::Agent::Stub::Configuration& configuration) | 24 | core::trust::remote::dbus::Agent::Stub::Stub(const core::trust::remote::dbus::Agent::Stub::Configuration& configuration) |
322 | 24 | : agent_registry_skeleton | 25 | : agent_registry_skeleton |
323 | @@ -43,20 +44,31 @@ | |||
324 | 43 | return agent->authenticate_request_with_parameters(parameters); | 44 | return agent->authenticate_request_with_parameters(parameters); |
325 | 44 | } | 45 | } |
326 | 45 | 46 | ||
328 | 46 | core::trust::remote::dbus::Agent::Skeleton::Skeleton(const core::trust::remote::dbus::Agent::Skeleton::Configuration& configuration) | 47 | core::trust::remote::dbus::Agent::Skeleton::Skeleton(core::trust::remote::dbus::Agent::Skeleton::Configuration configuration) |
329 | 47 | : core::trust::remote::Agent::Skeleton{configuration.impl}, | 48 | : core::trust::remote::Agent::Skeleton{configuration.impl}, |
330 | 49 | config(std::move(configuration)), | ||
331 | 48 | agent_registry_stub | 50 | agent_registry_stub |
332 | 49 | { | 51 | { |
340 | 50 | core::trust::dbus::AgentRegistry::Stub::Configuration | 52 | core::trust::dbus::AgentRegistry::Stub::create( |
341 | 51 | { | 53 | core::trust::dbus::AgentRegistry::Stub::Configuration |
342 | 52 | configuration.agent_registry_object, | 54 | { |
343 | 53 | core::trust::dbus::AgentRegistry::Stub::counting_object_path_generator(), | 55 | config.agent_registry_object, |
344 | 54 | configuration.service, | 56 | core::trust::dbus::AgentRegistry::Stub::counting_object_path_generator(), |
345 | 55 | configuration.bus | 57 | config.service, |
346 | 56 | } | 58 | config.bus |
347 | 59 | }) | ||
348 | 57 | } | 60 | } |
349 | 58 | { | 61 | { |
351 | 59 | agent_registry_stub.register_agent_for_user(core::trust::Uid{::getuid()}, configuration.impl); | 62 | static const auto printing_cb = []() { std::cout << "Successfully registered agent for user." << std::endl; }; |
352 | 63 | |||
353 | 64 | agent_registry_stub->register_agent_for_user_async(core::trust::Uid{::getuid()}, config.impl, printing_cb); | ||
354 | 65 | |||
355 | 66 | // We don't have to track the lifetime of "this" as config.agent_registry_watcher is owned | ||
356 | 67 | // by "this". | ||
357 | 68 | config.agent_registry_watcher->service_registered().connect([this]() | ||
358 | 69 | { | ||
359 | 70 | agent_registry_stub->register_agent_for_user_async(core::trust::Uid{::getuid()}, config.impl, printing_cb); | ||
360 | 71 | }); | ||
361 | 60 | } | 72 | } |
362 | 61 | 73 | ||
363 | 62 | core::trust::Request::Answer core::trust::remote::dbus::Agent::Skeleton::authenticate_request_with_parameters(const core::trust::Agent::RequestParameters& parameters) | 74 | core::trust::Request::Answer core::trust::remote::dbus::Agent::Skeleton::authenticate_request_with_parameters(const core::trust::Agent::RequestParameters& parameters) |
364 | 63 | 75 | ||
365 | === modified file 'src/core/trust/remote/dbus.h' | |||
366 | --- src/core/trust/remote/dbus.h 2014-08-04 07:57:05 +0000 | |||
367 | +++ src/core/trust/remote/dbus.h 2016-01-04 15:02:54 +0000 | |||
368 | @@ -25,6 +25,8 @@ | |||
369 | 25 | #include <core/trust/dbus/agent.h> | 25 | #include <core/trust/dbus/agent.h> |
370 | 26 | #include <core/trust/dbus/agent_registry.h> | 26 | #include <core/trust/dbus/agent_registry.h> |
371 | 27 | 27 | ||
372 | 28 | #include <core/dbus/service_watcher.h> | ||
373 | 29 | |||
374 | 28 | #include <unistd.h> | 30 | #include <unistd.h> |
375 | 29 | #include <sys/types.h> | 31 | #include <sys/types.h> |
376 | 30 | 32 | ||
377 | @@ -86,6 +88,8 @@ | |||
378 | 86 | std::shared_ptr<Agent> impl; | 88 | std::shared_ptr<Agent> impl; |
379 | 87 | // The remote object implementing core.trust.dbus.AgentRegistry. | 89 | // The remote object implementing core.trust.dbus.AgentRegistry. |
380 | 88 | core::dbus::Object::Ptr agent_registry_object; | 90 | core::dbus::Object::Ptr agent_registry_object; |
381 | 91 | // The watcher monitoring the remote object implementing core.trust.dbus.AgentRegistry. | ||
382 | 92 | std::unique_ptr<core::dbus::ServiceWatcher> agent_registry_watcher; | ||
383 | 89 | // The service that objects implementing core.trust.dbus.Agent should be added to. | 93 | // The service that objects implementing core.trust.dbus.Agent should be added to. |
384 | 90 | core::dbus::Service::Ptr service; | 94 | core::dbus::Service::Ptr service; |
385 | 91 | // The underlying bus instance. | 95 | // The underlying bus instance. |
386 | @@ -95,13 +99,15 @@ | |||
387 | 95 | }; | 99 | }; |
388 | 96 | 100 | ||
389 | 97 | // Constructs a new Skeleton instance, installing impl for handling actual requests. | 101 | // Constructs a new Skeleton instance, installing impl for handling actual requests. |
391 | 98 | Skeleton(const Configuration& configuration); | 102 | Skeleton(Configuration configuration); |
392 | 99 | 103 | ||
393 | 100 | // From core::trust::Agent, dispatches to the actual implementation. | 104 | // From core::trust::Agent, dispatches to the actual implementation. |
394 | 101 | core::trust::Request::Answer authenticate_request_with_parameters(const RequestParameters& parameters); | 105 | core::trust::Request::Answer authenticate_request_with_parameters(const RequestParameters& parameters); |
395 | 102 | 106 | ||
396 | 107 | // Store all creation-time parameters. | ||
397 | 108 | Configuration config; | ||
398 | 103 | // Stub for accessing the remote agent registry. | 109 | // Stub for accessing the remote agent registry. |
400 | 104 | core::trust::dbus::AgentRegistry::Stub agent_registry_stub; | 110 | std::shared_ptr<core::trust::dbus::AgentRegistry::Stub> agent_registry_stub; |
401 | 105 | }; | 111 | }; |
402 | 106 | }; | 112 | }; |
403 | 107 | } | 113 | } |
404 | 108 | 114 | ||
405 | === added file 'src/core/trust/runtime.cpp' | |||
406 | --- src/core/trust/runtime.cpp 1970-01-01 00:00:00 +0000 | |||
407 | +++ src/core/trust/runtime.cpp 2016-01-04 15:02:54 +0000 | |||
408 | @@ -0,0 +1,105 @@ | |||
409 | 1 | /* | ||
410 | 2 | * Copyright © 2016 Canonical Ltd. | ||
411 | 3 | * | ||
412 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
413 | 5 | * under the terms of the GNU Lesser General Public License version 3, | ||
414 | 6 | * as published by the Free Software Foundation. | ||
415 | 7 | * | ||
416 | 8 | * This program is distributed in the hope that it will be useful, | ||
417 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
418 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
419 | 11 | * GNU Lesser General Public License for more details. | ||
420 | 12 | * | ||
421 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
422 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
423 | 15 | * | ||
424 | 16 | * Authored by: Thomas Voß <thomas.voss@canonical.com> | ||
425 | 17 | */ | ||
426 | 18 | |||
427 | 19 | #include <core/trust/runtime.h> | ||
428 | 20 | |||
429 | 21 | #include <core/dbus/asio/executor.h> | ||
430 | 22 | |||
431 | 23 | #include <iostream> | ||
432 | 24 | #include <stdexcept> | ||
433 | 25 | |||
434 | 26 | namespace | ||
435 | 27 | { | ||
436 | 28 | void execute_and_never_throw(boost::asio::io_service& ios) noexcept(true) | ||
437 | 29 | { | ||
438 | 30 | while (true) | ||
439 | 31 | { | ||
440 | 32 | try | ||
441 | 33 | { | ||
442 | 34 | ios.run(); | ||
443 | 35 | break; | ||
444 | 36 | } | ||
445 | 37 | catch (const std::exception& e) | ||
446 | 38 | { | ||
447 | 39 | std::cerr << __PRETTY_FUNCTION__ << ": " << e.what() << std::endl; | ||
448 | 40 | } | ||
449 | 41 | catch (...) | ||
450 | 42 | { | ||
451 | 43 | std::cerr << __PRETTY_FUNCTION__ << ": unknown exception" << std::endl; | ||
452 | 44 | } | ||
453 | 45 | } | ||
454 | 46 | } | ||
455 | 47 | } | ||
456 | 48 | |||
457 | 49 | core::trust::Runtime& core::trust::Runtime::instance() | ||
458 | 50 | { | ||
459 | 51 | static Runtime runtime; | ||
460 | 52 | return runtime; | ||
461 | 53 | } | ||
462 | 54 | |||
463 | 55 | core::trust::Runtime::Runtime() | ||
464 | 56 | : signal_trap{core::posix::trap_signals_for_all_subsequent_threads({core::posix::Signal::sig_term, core::posix::Signal::sig_int})}, | ||
465 | 57 | keep_alive{io_service} | ||
466 | 58 | { | ||
467 | 59 | for (std::size_t i = 0; i < Runtime::concurrency_hint; i++) | ||
468 | 60 | { | ||
469 | 61 | pool.emplace_back(execute_and_never_throw, std::ref(io_service)); | ||
470 | 62 | } | ||
471 | 63 | |||
472 | 64 | signal_trap->signal_raised().connect([this](const core::posix::Signal&) | ||
473 | 65 | { | ||
474 | 66 | stop(); | ||
475 | 67 | }); | ||
476 | 68 | } | ||
477 | 69 | |||
478 | 70 | core::trust::Runtime::~Runtime() | ||
479 | 71 | { | ||
480 | 72 | try | ||
481 | 73 | { | ||
482 | 74 | io_service.stop(); | ||
483 | 75 | |||
484 | 76 | for (auto& worker : pool) | ||
485 | 77 | if (worker.joinable()) | ||
486 | 78 | worker.join(); | ||
487 | 79 | } | ||
488 | 80 | catch (...) | ||
489 | 81 | { | ||
490 | 82 | // Empty on purpose. We just have to | ||
491 | 83 | // fulfill the noexcept(true) guarantee. | ||
492 | 84 | } | ||
493 | 85 | } | ||
494 | 86 | |||
495 | 87 | void core::trust::Runtime::run() | ||
496 | 88 | { | ||
497 | 89 | signal_trap->run(); | ||
498 | 90 | } | ||
499 | 91 | |||
500 | 92 | void core::trust::Runtime::stop() | ||
501 | 93 | { | ||
502 | 94 | signal_trap->stop(); | ||
503 | 95 | } | ||
504 | 96 | |||
505 | 97 | boost::asio::io_service& core::trust::Runtime::service() | ||
506 | 98 | { | ||
507 | 99 | return io_service; | ||
508 | 100 | } | ||
509 | 101 | |||
510 | 102 | core::dbus::Executor::Ptr core::trust::Runtime::make_executor_for_bus(const core::dbus::Bus::Ptr& bus) | ||
511 | 103 | { | ||
512 | 104 | return core::dbus::asio::make_executor(bus, io_service); | ||
513 | 105 | } | ||
514 | 0 | 106 | ||
515 | === added file 'src/core/trust/runtime.h' | |||
516 | --- src/core/trust/runtime.h 1970-01-01 00:00:00 +0000 | |||
517 | +++ src/core/trust/runtime.h 2016-01-04 15:02:54 +0000 | |||
518 | @@ -0,0 +1,88 @@ | |||
519 | 1 | /* | ||
520 | 2 | * Copyright © 2016 Canonical Ltd. | ||
521 | 3 | * | ||
522 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
523 | 5 | * under the terms of the GNU Lesser General Public License version 3, | ||
524 | 6 | * as published by the Free Software Foundation. | ||
525 | 7 | * | ||
526 | 8 | * This program is distributed in the hope that it will be useful, | ||
527 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
528 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
529 | 11 | * GNU Lesser General Public License for more details. | ||
530 | 12 | * | ||
531 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
532 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
533 | 15 | * | ||
534 | 16 | * Authored by: Thomas Voß <thomas.voss@canonical.com> | ||
535 | 17 | */ | ||
536 | 18 | |||
537 | 19 | #ifndef CORE_TRUST_RUNTIME_H_ | ||
538 | 20 | #define CORE_TRUST_RUNTIME_H_ | ||
539 | 21 | |||
540 | 22 | #include <core/posix/signal.h> | ||
541 | 23 | |||
542 | 24 | #include <core/dbus/bus.h> | ||
543 | 25 | #include <core/dbus/executor.h> | ||
544 | 26 | |||
545 | 27 | #include <boost/asio.hpp> | ||
546 | 28 | |||
547 | 29 | #include <memory> | ||
548 | 30 | #include <thread> | ||
549 | 31 | #include <vector> | ||
550 | 32 | |||
551 | 33 | namespace core | ||
552 | 34 | { | ||
553 | 35 | namespace trust | ||
554 | 36 | { | ||
555 | 37 | // A Runtime maintains a pool of workers enabling | ||
556 | 38 | // implementations to dispatch invocations and have their | ||
557 | 39 | // ready handlers automatically executed. | ||
558 | 40 | class Runtime | ||
559 | 41 | { | ||
560 | 42 | public: | ||
561 | 43 | // Do not execute in parallel, serialize | ||
562 | 44 | // accesses. | ||
563 | 45 | static constexpr std::size_t concurrency_hint{2}; | ||
564 | 46 | |||
565 | 47 | // Our evil singleton pattern. Not bad though, we control the | ||
566 | 48 | // entire executable and rely on automatic cleanup of static | ||
567 | 49 | // instances. | ||
568 | 50 | static Runtime& instance(); | ||
569 | 51 | |||
570 | 52 | // Gracefully shuts down operations. | ||
571 | 53 | ~Runtime() noexcept(true); | ||
572 | 54 | |||
573 | 55 | // run blocks until either stop is called or a | ||
574 | 56 | // signal requesting graceful shutdown is received. | ||
575 | 57 | void run(); | ||
576 | 58 | |||
577 | 59 | // requests the runtime to shut down, does not block. | ||
578 | 60 | void stop(); | ||
579 | 61 | |||
580 | 62 | // Returns a mutable reference to the underlying boost::asio::io_service | ||
581 | 63 | // powering the runtime's reactor. | ||
582 | 64 | boost::asio::io_service& service(); | ||
583 | 65 | |||
584 | 66 | // Creates an executor for a bus instance hooking into this Runtime instance. | ||
585 | 67 | core::dbus::Executor::Ptr make_executor_for_bus(const core::dbus::Bus::Ptr& bus); | ||
586 | 68 | |||
587 | 69 | private: | ||
588 | 70 | Runtime(); | ||
589 | 71 | |||
590 | 72 | // We trap sig term to ensure a clean shutdown. | ||
591 | 73 | std::shared_ptr<core::posix::SignalTrap> signal_trap; | ||
592 | 74 | |||
593 | 75 | // Our io_service instance exposed to remote agents. | ||
594 | 76 | boost::asio::io_service io_service; | ||
595 | 77 | |||
596 | 78 | // We keep the io_service alive and introduce some artificial | ||
597 | 79 | // work. | ||
598 | 80 | boost::asio::io_service::work keep_alive; | ||
599 | 81 | |||
600 | 82 | // We execute the io_service on a pool of worker threads. | ||
601 | 83 | std::vector<std::thread> pool; | ||
602 | 84 | }; | ||
603 | 85 | } | ||
604 | 86 | } | ||
605 | 87 | |||
606 | 88 | #endif // CORE_TRUST_RUNTIME_H_ | ||
607 | 0 | 89 | ||
608 | === modified file 'tests/CMakeLists.txt' | |||
609 | --- tests/CMakeLists.txt 2014-11-14 12:17:24 +0000 | |||
610 | +++ tests/CMakeLists.txt 2016-01-04 15:02:54 +0000 | |||
611 | @@ -46,6 +46,9 @@ | |||
612 | 46 | add_executable( | 46 | add_executable( |
613 | 47 | remote_agent_test | 47 | remote_agent_test |
614 | 48 | remote_agent_test.cpp | 48 | remote_agent_test.cpp |
615 | 49 | |||
616 | 50 | ${CMAKE_SOURCE_DIR}/src/core/trust/runtime.h | ||
617 | 51 | ${CMAKE_SOURCE_DIR}/src/core/trust/runtime.cpp | ||
618 | 49 | ) | 52 | ) |
619 | 50 | 53 | ||
620 | 51 | add_executable( | 54 | add_executable( |
621 | 52 | 55 | ||
622 | === modified file 'tests/dbus_test.cpp' | |||
623 | --- tests/dbus_test.cpp 2014-08-04 08:32:57 +0000 | |||
624 | +++ tests/dbus_test.cpp 2016-01-04 15:02:54 +0000 | |||
625 | @@ -370,21 +370,19 @@ | |||
626 | 370 | InvokeWithoutArgs(&state, &State::notify), | 370 | InvokeWithoutArgs(&state, &State::notify), |
627 | 371 | Return(core::trust::Request::Answer::denied))); | 371 | Return(core::trust::Request::Answer::denied))); |
628 | 372 | 372 | ||
631 | 373 | core::trust::dbus::AgentRegistry::Stub stub | 373 | auto stub = core::trust::dbus::AgentRegistry::Stub::create( |
630 | 374 | { | ||
632 | 375 | core::trust::dbus::AgentRegistry::Stub::Configuration | 374 | core::trust::dbus::AgentRegistry::Stub::Configuration |
633 | 376 | { | 375 | { |
634 | 377 | agent_registry_object, | 376 | agent_registry_object, |
635 | 378 | core::trust::dbus::AgentRegistry::Stub::counting_object_path_generator(), | 377 | core::trust::dbus::AgentRegistry::Stub::counting_object_path_generator(), |
636 | 379 | service, | 378 | service, |
637 | 380 | bus | 379 | bus |
640 | 381 | } | 380 | }); |
639 | 382 | }; | ||
641 | 383 | 381 | ||
642 | 384 | std::thread t{[bus]() { bus->run(); }}; | 382 | std::thread t{[bus]() { bus->run(); }}; |
643 | 385 | 383 | ||
644 | 386 | // We register for the current user id. | 384 | // We register for the current user id. |
646 | 387 | stub.register_agent_for_user(core::trust::Uid{::getuid()}, agent); | 385 | stub->register_agent_for_user(core::trust::Uid{::getuid()}, agent); |
647 | 388 | 386 | ||
648 | 389 | // Tell the other side that we are good to go. | 387 | // Tell the other side that we are good to go. |
649 | 390 | agent_registered.try_signal_ready_for(std::chrono::milliseconds{500}); | 388 | agent_registered.try_signal_ready_for(std::chrono::milliseconds{500}); |
650 | @@ -393,7 +391,7 @@ | |||
651 | 393 | state.wait(); | 391 | state.wait(); |
652 | 394 | 392 | ||
653 | 395 | // And unregister again. | 393 | // And unregister again. |
655 | 396 | stub.unregister_agent_for_user(core::trust::Uid{::getuid()}); | 394 | stub->unregister_agent_for_user(core::trust::Uid{::getuid()}); |
656 | 397 | 395 | ||
657 | 398 | bus->stop(); | 396 | bus->stop(); |
658 | 399 | 397 | ||
659 | 400 | 398 | ||
660 | === modified file 'tests/remote_agent_test.cpp' | |||
661 | --- tests/remote_agent_test.cpp 2015-08-14 09:53:12 +0000 | |||
662 | +++ tests/remote_agent_test.cpp 2016-01-04 15:02:54 +0000 | |||
663 | @@ -30,6 +30,8 @@ | |||
664 | 30 | #include <core/dbus/asio/executor.h> | 30 | #include <core/dbus/asio/executor.h> |
665 | 31 | #include <core/dbus/fixture.h> | 31 | #include <core/dbus/fixture.h> |
666 | 32 | 32 | ||
667 | 33 | #include <core/trust/runtime.h> | ||
668 | 34 | |||
669 | 33 | #include <gmock/gmock.h> | 35 | #include <gmock/gmock.h> |
670 | 34 | #include <gtest/gtest.h> | 36 | #include <gtest/gtest.h> |
671 | 35 | 37 | ||
672 | @@ -792,6 +794,12 @@ | |||
673 | 792 | { | 794 | { |
674 | 793 | struct DBus : public core::dbus::testing::Fixture | 795 | struct DBus : public core::dbus::testing::Fixture |
675 | 794 | { | 796 | { |
676 | 797 | core::dbus::Bus::Ptr session_bus_with_executor() | ||
677 | 798 | { | ||
678 | 799 | auto sb = session_bus(); | ||
679 | 800 | sb->install_executor(core::trust::Runtime::instance().make_executor_for_bus(sb)); | ||
680 | 801 | return sb; | ||
681 | 802 | } | ||
682 | 795 | }; | 803 | }; |
683 | 796 | 804 | ||
684 | 797 | std::string service_name | 805 | std::string service_name |
685 | @@ -804,10 +812,6 @@ | |||
686 | 804 | { | 812 | { |
687 | 805 | using namespace ::testing; | 813 | using namespace ::testing; |
688 | 806 | 814 | ||
689 | 807 | core::testing::CrossProcessSync | ||
690 | 808 | stub_ready, // signals stub --| I'm ready |--> skeleton | ||
691 | 809 | skeleton_ready; // signals skeleton --| I'm ready |--> stub | ||
692 | 810 | |||
693 | 811 | auto app = core::posix::fork([]() | 815 | auto app = core::posix::fork([]() |
694 | 812 | { | 816 | { |
695 | 813 | while(true) std::this_thread::sleep_for(std::chrono::milliseconds{500}); | 817 | while(true) std::this_thread::sleep_for(std::chrono::milliseconds{500}); |
696 | @@ -825,7 +829,50 @@ | |||
697 | 825 | const core::trust::Uid app_uid{::getuid()}; | 829 | const core::trust::Uid app_uid{::getuid()}; |
698 | 826 | const core::trust::Pid app_pid{app.pid()}; | 830 | const core::trust::Pid app_pid{app.pid()}; |
699 | 827 | 831 | ||
701 | 828 | auto stub = core::posix::fork([this, app_uid, app_pid, answer, &stub_ready, &skeleton_ready]() | 832 | auto skeleton = core::posix::fork([this, answer]() |
702 | 833 | { | ||
703 | 834 | auto bus = session_bus_with_executor(); | ||
704 | 835 | |||
705 | 836 | // We have to rely on a MockAgent to break the dependency on a running Mir instance. | ||
706 | 837 | auto mock_agent = std::make_shared<::testing::NiceMock<MockAgent>>(); | ||
707 | 838 | |||
708 | 839 | ON_CALL(*mock_agent, authenticate_request_with_parameters(_)) | ||
709 | 840 | .WillByDefault(Return(answer)); | ||
710 | 841 | |||
711 | 842 | std::string dbus_service_name = core::trust::remote::dbus::default_service_name_prefix + std::string{"."} + service_name; | ||
712 | 843 | |||
713 | 844 | auto service = core::dbus::Service::use_service(bus, dbus_service_name); | ||
714 | 845 | auto object = service->object_for_path(core::dbus::types::ObjectPath | ||
715 | 846 | { | ||
716 | 847 | core::trust::remote::dbus::default_agent_registry_path | ||
717 | 848 | }); | ||
718 | 849 | |||
719 | 850 | core::dbus::DBus daemon{bus}; | ||
720 | 851 | |||
721 | 852 | core::trust::remote::dbus::Agent::Skeleton::Configuration config | ||
722 | 853 | { | ||
723 | 854 | mock_agent, | ||
724 | 855 | object, | ||
725 | 856 | daemon.make_service_watcher(dbus_service_name), | ||
726 | 857 | service, | ||
727 | 858 | bus, | ||
728 | 859 | core::trust::remote::helpers::aa_get_task_con_app_id_resolver() | ||
729 | 860 | }; | ||
730 | 861 | |||
731 | 862 | auto skeleton = std::make_shared<core::trust::remote::dbus::Agent::Skeleton>(std::move(config)); | ||
732 | 863 | |||
733 | 864 | core::trust::Runtime::instance().run(); | ||
734 | 865 | return core::posix::exit::Status::success; | ||
735 | 866 | }, core::posix::StandardStream::empty); | ||
736 | 867 | |||
737 | 868 | |||
738 | 869 | // stubf models a trusted helper, with the following simplified | ||
739 | 870 | // mode of operation: | ||
740 | 871 | // (1.) Helper claims its unique name on the bus. | ||
741 | 872 | // (2.) Helper installs an AgentRegistry::Skeleton. | ||
742 | 873 | // (3.) Helper learns about per-user trust::Agent instances on the bus. | ||
743 | 874 | // (4.) Helper issues requests for authentication. | ||
744 | 875 | auto stubf = [this, app_uid, app_pid, answer]() | ||
745 | 829 | { | 876 | { |
746 | 830 | core::trust::Agent::RequestParameters ref_params | 877 | core::trust::Agent::RequestParameters ref_params |
747 | 831 | { | 878 | { |
748 | @@ -836,10 +883,7 @@ | |||
749 | 836 | "just an example description" | 883 | "just an example description" |
750 | 837 | }; | 884 | }; |
751 | 838 | 885 | ||
756 | 839 | auto bus = session_bus(); | 886 | auto bus = session_bus_with_executor(); |
753 | 840 | bus->install_executor(core::dbus::asio::make_executor(bus)); | ||
754 | 841 | |||
755 | 842 | std::thread worker{[bus]() { bus->run(); }}; | ||
757 | 843 | 887 | ||
758 | 844 | std::string dbus_service_name = core::trust::remote::dbus::default_service_name_prefix + std::string{"."} + service_name; | 888 | std::string dbus_service_name = core::trust::remote::dbus::default_service_name_prefix + std::string{"."} + service_name; |
759 | 845 | 889 | ||
760 | @@ -857,76 +901,24 @@ | |||
761 | 857 | 901 | ||
762 | 858 | auto stub = std::make_shared<core::trust::remote::dbus::Agent::Stub>(config); | 902 | auto stub = std::make_shared<core::trust::remote::dbus::Agent::Stub>(config); |
763 | 859 | 903 | ||
766 | 860 | stub_ready.try_signal_ready_for(std::chrono::milliseconds{1000}); | 904 | std::this_thread::sleep_for(std::chrono::seconds(10)); |
765 | 861 | skeleton_ready.wait_for_signal_ready_for(std::chrono::milliseconds{1000}); | ||
767 | 862 | 905 | ||
768 | 863 | for (unsigned int i = 0; i < 100; i++) | 906 | for (unsigned int i = 0; i < 100; i++) |
769 | 864 | EXPECT_EQ(answer, stub->authenticate_request_with_parameters(ref_params)); | 907 | EXPECT_EQ(answer, stub->authenticate_request_with_parameters(ref_params)); |
770 | 865 | 908 | ||
771 | 866 | bus->stop(); | ||
772 | 867 | |||
773 | 868 | if (worker.joinable()) | ||
774 | 869 | worker.join(); | ||
775 | 870 | |||
776 | 871 | return Test::HasFailure() ? | 909 | return Test::HasFailure() ? |
777 | 872 | core::posix::exit::Status::failure : | 910 | core::posix::exit::Status::failure : |
778 | 873 | core::posix::exit::Status::success; | 911 | core::posix::exit::Status::success; |
835 | 874 | }, core::posix::StandardStream::empty); | 912 | }; |
836 | 875 | 913 | ||
837 | 876 | auto skeleton = core::posix::fork([this, answer, &stub_ready, &skeleton_ready]() | 914 | std::this_thread::sleep_for(std::chrono::seconds(2)); |
838 | 877 | { | 915 | auto stub = core::posix::fork(stubf, core::posix::StandardStream::empty); |
839 | 878 | auto trap = core::posix::trap_signals_for_all_subsequent_threads({core::posix::Signal::sig_term}); | 916 | EXPECT_TRUE(ProcessExitedSuccessfully(stub.wait_for(core::posix::wait::Flags::untraced))); |
840 | 879 | 917 | ||
841 | 880 | trap->signal_raised().connect([trap](core::posix::Signal) | 918 | std::this_thread::sleep_for(std::chrono::seconds(2)); |
842 | 881 | { | 919 | stub = core::posix::fork(stubf, core::posix::StandardStream::empty); |
843 | 882 | trap->stop(); | 920 | EXPECT_TRUE(ProcessExitedSuccessfully(stub.wait_for(core::posix::wait::Flags::untraced))); |
844 | 883 | }); | 921 | |
789 | 884 | |||
790 | 885 | auto bus = session_bus(); | ||
791 | 886 | bus->install_executor(core::dbus::asio::make_executor(bus)); | ||
792 | 887 | |||
793 | 888 | std::thread worker{[bus]() { bus->run(); }}; | ||
794 | 889 | |||
795 | 890 | // We have to rely on a MockAgent to break the dependency on a running Mir instance. | ||
796 | 891 | auto mock_agent = std::make_shared<::testing::NiceMock<MockAgent>>(); | ||
797 | 892 | |||
798 | 893 | ON_CALL(*mock_agent, authenticate_request_with_parameters(_)) | ||
799 | 894 | .WillByDefault(Return(answer)); | ||
800 | 895 | |||
801 | 896 | std::string dbus_service_name = core::trust::remote::dbus::default_service_name_prefix + std::string{"."} + service_name; | ||
802 | 897 | |||
803 | 898 | stub_ready.wait_for_signal_ready_for(std::chrono::milliseconds{1000}); | ||
804 | 899 | |||
805 | 900 | auto service = core::dbus::Service::use_service(bus, dbus_service_name); | ||
806 | 901 | auto object = service->object_for_path(core::dbus::types::ObjectPath | ||
807 | 902 | { | ||
808 | 903 | core::trust::remote::dbus::default_agent_registry_path | ||
809 | 904 | }); | ||
810 | 905 | |||
811 | 906 | core::trust::remote::dbus::Agent::Skeleton::Configuration config | ||
812 | 907 | { | ||
813 | 908 | mock_agent, | ||
814 | 909 | object, | ||
815 | 910 | service, | ||
816 | 911 | bus, | ||
817 | 912 | core::trust::remote::helpers::aa_get_task_con_app_id_resolver() | ||
818 | 913 | }; | ||
819 | 914 | |||
820 | 915 | auto skeleton = std::make_shared<core::trust::remote::dbus::Agent::Skeleton>(config); | ||
821 | 916 | |||
822 | 917 | skeleton_ready.try_signal_ready_for(std::chrono::milliseconds{1000}); | ||
823 | 918 | |||
824 | 919 | trap->run(); | ||
825 | 920 | |||
826 | 921 | bus->stop(); | ||
827 | 922 | |||
828 | 923 | if (worker.joinable()) | ||
829 | 924 | worker.join(); | ||
830 | 925 | |||
831 | 926 | return core::posix::exit::Status::success; | ||
832 | 927 | }, core::posix::StandardStream::empty); | ||
833 | 928 | |||
834 | 929 | EXPECT_TRUE(ProcessExitedSuccessfully(stub.wait_for(core::posix::wait::Flags::untraced))); | ||
845 | 930 | skeleton.send_signal_or_throw(core::posix::Signal::sig_term); | 922 | skeleton.send_signal_or_throw(core::posix::Signal::sig_term); |
846 | 931 | EXPECT_TRUE(ProcessExitedSuccessfully(skeleton.wait_for(core::posix::wait::Flags::untraced))); | 923 | EXPECT_TRUE(ProcessExitedSuccessfully(skeleton.wait_for(core::posix::wait::Flags::untraced))); |
847 | 932 | 924 |