Merge lp:~thomas-voss/trust-store/watch-service-name-owner-changes into lp:trust-store

Proposed by Thomas Voß
Status: Superseded
Proposed branch: lp:~thomas-voss/trust-store/watch-service-name-owner-changes
Merge into: lp:trust-store
Diff against target: 800 lines (+318/-186)
12 files modified
CMakeLists.txt (+2/-2)
debian/changelog (+8/-12)
debian/control (+4/-4)
src/CMakeLists.txt (+3/-0)
src/core/trust/daemon.cpp (+16/-90)
src/core/trust/dbus/agent_registry.h (+38/-0)
src/core/trust/remote/dbus.cpp (+20/-5)
src/core/trust/remote/dbus.h (+7/-1)
src/core/trust/runtime.cpp (+80/-0)
src/core/trust/runtime.h (+73/-0)
tests/CMakeLists.txt (+3/-0)
tests/remote_agent_test.cpp (+64/-72)
To merge this branch: bzr merge lp:~thomas-voss/trust-store/watch-service-name-owner-changes
Reviewer Review Type Date Requested Status
Ubuntu Phablet Team Pending
Review via email: mp+281482@code.launchpad.net

This proposal has been superseded by a proposal from 2016-01-03.

Commit message

core::trust::dbus::Agent::Skeleton now watches for name owner changes, announcing itself
asynchronously if a new name owner is detected.

Description of the change

core::trust::dbus::Agent::Skeleton now watches for name owner changes, announcing itself
asynchronously if a new name owner is detected.

To post a comment you must log in.
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.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2015-08-31 13:16:20 +0000
3+++ CMakeLists.txt 2016-01-03 20:28:56 +0000
4@@ -46,8 +46,8 @@
5 pkg_check_modules(GLOG libglog REQUIRED)
6 pkg_check_modules(PROCESS_CPP process-cpp REQUIRED)
7
8-set(TRUST_STORE_VERSION_MAJOR 2)
9-set(TRUST_STORE_VERSION_MINOR 0)
10+set(TRUST_STORE_VERSION_MAJOR 1)
11+set(TRUST_STORE_VERSION_MINOR 1)
12 set(TRUST_STORE_VERSION_PATCH 0)
13
14 include(CTest)
15
16=== modified file 'debian/changelog'
17--- debian/changelog 2015-08-31 15:11:26 +0000
18+++ debian/changelog 2016-01-03 20:28:56 +0000
19@@ -1,18 +1,14 @@
20-trust-store (2.0.0+15.10.20150831.3-0ubuntu1) wily; urgency=medium
21+trust-store (1.1.0+15.04.20151126-0ubuntu1) vivid; urgency=medium
22
23- [ Alfonso Sanchez-Beato (email Canonical) ]
24- * Merge wily changes upstream
25+ [ Thomas Voß ]
26+ * Revert bump to major revision 2, vivid (+overlay) still has
27+ 1.1.0 and gcc 4.9.
28
29 [ CI Train Bot ]
30- * No-change rebuild.
31-
32- -- CI Train Bot <ci-train-bot@canonical.com> Mon, 31 Aug 2015 15:11:25 +0000
33-
34-trust-store (2.0.0-0ubuntu1) wily; urgency=medium
35-
36- * Bump major revision to account for toolchain update. Fixes LP:#1452341
37-
38- -- Thomas Voß <thomas.voss@canonical.com> Thu, 23 Jul 2015 09:22:15 +0200
39+ * New rebuild forced.
40+ * Resync trunk.
41+
42+ -- Thomas Voß <ci-train-bot@canonical.com> Thu, 26 Nov 2015 07:32:48 +0000
43
44 trust-store (1.1.0+15.04.20150820-0ubuntu1) vivid; urgency=medium
45
46
47=== modified file 'debian/control'
48--- debian/control 2015-08-31 13:16:20 +0000
49+++ debian/control 2016-01-03 20:28:56 +0000
50@@ -30,7 +30,7 @@
51 # upstream branch
52 Vcs-Bzr: lp:trust-store
53
54-Package: libtrust-store2
55+Package: libtrust-store1
56 Architecture: any
57 Multi-Arch: same
58 Pre-Depends: ${misc:Pre-Depends},
59@@ -48,7 +48,7 @@
60 Multi-Arch: same
61 Pre-Depends: ${misc:Pre-Depends},
62 Recommends: libtrust-store-doc,
63-Depends: libtrust-store2 (= ${binary:Version}),
64+Depends: libtrust-store1 (= ${binary:Version}),
65 ${misc:Depends},
66 Description: C++11 library for persisting trust requests - dev files
67 Provides a common implementation of a trust store to be used by trusted
68@@ -60,7 +60,7 @@
69 Package: trust-store-bin
70 Section: devel
71 Architecture: any
72-Depends: libtrust-store2 (= ${binary:Version}),
73+Depends: libtrust-store1 (= ${binary:Version}),
74 ${misc:Depends},
75 Description: Daemon binaries to be used by services.
76 Provides a common implementation of a trust store to be used by trusted
77@@ -71,7 +71,7 @@
78 Package: trust-store-tests
79 Section: libdevel
80 Architecture: any
81-Depends: libtrust-store2 (= ${binary:Version}),
82+Depends: libtrust-store1 (= ${binary:Version}),
83 ${misc:Depends},
84 Suggests: libtrust-store-dev,
85 Description: Test files for libtrust-store1
86
87=== renamed file 'debian/libtrust-store2.install' => 'debian/libtrust-store1.install'
88=== modified file 'src/CMakeLists.txt'
89--- src/CMakeLists.txt 2015-08-31 13:16:20 +0000
90+++ src/CMakeLists.txt 2016-01-03 20:28:56 +0000
91@@ -149,6 +149,9 @@
92 trust-stored
93
94 core/trust/daemon.cpp
95+
96+ core/trust/runtime.h
97+ core/trust/runtime.cpp
98 )
99
100 add_executable(
101
102=== modified file 'src/core/trust/daemon.cpp'
103--- src/core/trust/daemon.cpp 2015-08-31 14:00:41 +0000
104+++ src/core/trust/daemon.cpp 2016-01-03 20:28:56 +0000
105@@ -22,6 +22,7 @@
106 #include <core/trust/cached_agent.h>
107 #include <core/trust/expose.h>
108 #include <core/trust/i18n.h>
109+#include <core/trust/runtime.h>
110 #include <core/trust/store.h>
111 #include <core/trust/white_listing_agent.h>
112
113@@ -49,67 +50,6 @@
114
115 namespace
116 {
117- struct Runtime
118- {
119- // Do not execute in parallel, serialize
120- // accesses.
121- static constexpr std::size_t concurrency_hint{2};
122-
123- // Our evil singleton pattern. Not bad though, we control the
124- // entire executable and rely on automatic cleanup of static
125- // instances.
126- static Runtime& instance()
127- {
128- static Runtime runtime;
129- return runtime;
130- }
131-
132- ~Runtime()
133- {
134- io_service.stop();
135-
136- if (worker1.joinable())
137- worker1.join();
138-
139- if (worker2.joinable())
140- worker2.join();
141- }
142-
143- // We trap sig term to ensure a clean shutdown.
144- std::shared_ptr<core::posix::SignalTrap> signal_trap
145- {
146- core::posix::trap_signals_for_all_subsequent_threads(
147- {
148- core::posix::Signal::sig_term,
149- core::posix::Signal::sig_int
150- })
151- };
152-
153- // Our io_service instance exposed to remote agents.
154- boost::asio::io_service io_service
155- {
156- concurrency_hint
157- };
158-
159- // We keep the io_service alive and introduce some artificial
160- // work.
161- boost::asio::io_service::work keep_alive
162- {
163- io_service
164- };
165-
166- // We immediate execute the io_service instance
167- std::thread worker1
168- {
169- std::thread{[this]() { io_service.run(); }}
170- };
171-
172- std::thread worker2
173- {
174- std::thread{[this]() { io_service.run(); }}
175- };
176- };
177-
178 core::trust::Daemon::Dictionary fill_dictionary_from_unrecognized_options(const Options::parsed_options& parsed_options)
179 {
180 auto unrecognized = Options::collect_unrecognized(
181@@ -170,7 +110,7 @@
182 "Could not create bus for name: " + bus_name
183 };
184
185- bus->install_executor(core::dbus::asio::make_executor(bus, Runtime::instance().io_service));
186+ bus->install_executor(core::dbus::asio::make_executor(bus, core::trust::Runtime::instance().io_service));
187
188 return bus;
189 }
190@@ -256,7 +196,7 @@
191 core::trust::remote::posix::Skeleton::Configuration config
192 {
193 agent,
194- Runtime::instance().io_service,
195+ core::trust::Runtime::instance().io_service,
196 boost::asio::local::stream_protocol::endpoint{dict.at("endpoint")},
197 core::trust::remote::helpers::proc_stat_start_time_resolver(),
198 core::trust::remote::helpers::aa_get_task_con_app_id_resolver(),
199@@ -289,16 +229,19 @@
200 core::trust::remote::dbus::default_agent_registry_path
201 });
202
203+ core::dbus::DBus daemon{bus};
204+
205 core::trust::remote::dbus::Agent::Skeleton::Configuration config
206 {
207 agent,
208 object,
209+ daemon.make_service_watcher(dbus_service_name),
210 service,
211 bus,
212 core::trust::remote::helpers::aa_get_task_con_app_id_resolver()
213 };
214
215- return std::make_shared<core::trust::remote::dbus::Agent::Skeleton>(config);
216+ return std::make_shared<core::trust::remote::dbus::Agent::Skeleton>(std::move(config));
217 }
218 }
219 };
220@@ -390,16 +333,6 @@
221 // Executes the daemon with the given configuration.
222 core::posix::exit::Status core::trust::Daemon::Skeleton::main(const core::trust::Daemon::Skeleton::Configuration& configuration)
223 {
224- Runtime::instance().signal_trap->signal_raised().connect([](core::posix::Signal)
225- {
226- Runtime::instance().signal_trap->stop();
227- });
228-
229- std::thread worker
230- {
231- [configuration]() { configuration.bus->run(); }
232- };
233-
234 // Expose the local store to the bus, keeping it exposed for the
235 // lifetime of the returned token.
236 auto token = core::trust::expose_store_to_bus_with_name(
237@@ -407,12 +340,7 @@
238 configuration.bus,
239 configuration.service_name);
240
241- Runtime::instance().signal_trap->run();
242-
243- configuration.bus->stop();
244-
245- if (worker.joinable())
246- worker.join();
247+ core::trust::Runtime::instance().run();
248
249 return core::posix::exit::Status::success;
250 }
251@@ -432,7 +360,7 @@
252
253 core::trust::remote::posix::Stub::Configuration config
254 {
255- Runtime::instance().io_service,
256+ core::trust::Runtime::instance().io_service,
257 boost::asio::local::stream_protocol::endpoint{dict.at("endpoint")},
258 core::trust::remote::helpers::proc_stat_start_time_resolver(),
259 core::trust::remote::posix::Stub::get_sock_opt_credentials_resolver(),
260@@ -524,11 +452,16 @@
261 {
262 Shell(const std::shared_ptr<core::trust::Agent>& agent)
263 : agent{agent},
264- stdin{Runtime::instance().io_service, STDIN_FILENO},
265+ stdin{core::trust::Runtime::instance().io_service, STDIN_FILENO},
266 app_id_resolver{core::trust::remote::helpers::aa_get_task_con_app_id_resolver()}
267 {
268 }
269
270+ ~Shell()
271+ {
272+ stop();
273+ }
274+
275 // Prints out the initial prompt and initiates a read operation on stdin.
276 void start()
277 {
278@@ -607,18 +540,11 @@
279 // We setup our minimal shell here.
280 auto shell = std::make_shared<Shell>(configuration.remote.agent);
281
282- Runtime::instance().signal_trap->signal_raised().connect([](core::posix::Signal)
283- {
284- Runtime::instance().signal_trap->stop();
285- });
286-
287 // We start up our shell
288 shell->start();
289
290 // Wait until signal arrives.
291- Runtime::instance().signal_trap->run();
292-
293- shell->stop();
294+ core::trust::Runtime::instance().run();
295
296 return core::posix::exit::Status::success;
297 }
298
299=== modified file 'src/core/trust/dbus/agent_registry.h'
300--- src/core/trust/dbus/agent_registry.h 2014-08-04 07:10:52 +0000
301+++ src/core/trust/dbus/agent_registry.h 2016-01-03 20:28:56 +0000
302@@ -179,6 +179,44 @@
303 locking_agent_registry.register_agent_for_user(uid, skeleton);
304 }
305
306+ // Calls into the remote implementation to register the given agent implementation.
307+ // Throws std::runtime_error and std::logic_error in case of issues.
308+ void register_agent_for_user_async(const core::trust::Uid& uid, const std::shared_ptr<core::trust::Agent>& impl, const std::function<void()>& then)
309+ {
310+ // We sample a path for the given uid
311+ auto path = configuration.object_path_generator(uid);
312+ // And construct the skeleton instance.
313+ auto skeleton = std::shared_ptr<core::trust::dbus::Agent::Skeleton>
314+ {
315+ new core::trust::dbus::Agent::Skeleton
316+ {
317+ core::trust::dbus::Agent::Skeleton::Configuration
318+ {
319+ configuration.service->add_object_for_path(path),
320+ configuration.bus,
321+ std::bind(&core::trust::Agent::authenticate_request_with_parameters, impl, std::placeholders::_1)
322+ }
323+ }
324+ };
325+
326+ // And announce the agent.
327+ configuration.object->invoke_method_asynchronously_with_callback<
328+ Methods::RegisterAgentForUser, void
329+ >([this, then, uid, skeleton](const core::dbus::Result<void>& result)
330+ {
331+ if (result.is_error())
332+ {
333+ std::cerr << "Failed to register agent for user: " << result.error().print() << std::endl;
334+ }
335+ else
336+ {
337+ // All good, update our own state prior to invoking the supplied callback.
338+ locking_agent_registry.register_agent_for_user(uid, skeleton);
339+ then();
340+ }
341+ }, uid, path);
342+ }
343+
344 // Calls into the remote implementation to unregister any agent registered for the given uid.
345 // Throws std::runtime_error and std::logic_error in case of issues.
346 void unregister_agent_for_user(const core::trust::Uid& uid) override
347
348=== modified file 'src/core/trust/remote/dbus.cpp'
349--- src/core/trust/remote/dbus.cpp 2014-07-29 17:00:35 +0000
350+++ src/core/trust/remote/dbus.cpp 2016-01-03 20:28:56 +0000
351@@ -19,6 +19,7 @@
352 #include <core/trust/remote/dbus.h>
353
354 #include <core/trust/dbus_agent.h>
355+#include <core/trust/runtime.h>
356
357 core::trust::remote::dbus::Agent::Stub::Stub(const core::trust::remote::dbus::Agent::Stub::Configuration& configuration)
358 : agent_registry_skeleton
359@@ -43,20 +44,34 @@
360 return agent->authenticate_request_with_parameters(parameters);
361 }
362
363-core::trust::remote::dbus::Agent::Skeleton::Skeleton(const core::trust::remote::dbus::Agent::Skeleton::Configuration& configuration)
364+core::trust::remote::dbus::Agent::Skeleton::Skeleton(core::trust::remote::dbus::Agent::Skeleton::Configuration configuration)
365 : core::trust::remote::Agent::Skeleton{configuration.impl},
366+ config(std::move(configuration)),
367 agent_registry_stub
368 {
369 core::trust::dbus::AgentRegistry::Stub::Configuration
370 {
371- configuration.agent_registry_object,
372+ config.agent_registry_object,
373 core::trust::dbus::AgentRegistry::Stub::counting_object_path_generator(),
374- configuration.service,
375- configuration.bus
376+ config.service,
377+ config.bus
378 }
379 }
380 {
381- agent_registry_stub.register_agent_for_user(core::trust::Uid{::getuid()}, configuration.impl);
382+ agent_registry_stub.register_agent_for_user_async(core::trust::Uid{::getuid()}, config.impl, []()
383+ {
384+ std::cout << "Error registering agent for user." << std::endl;
385+ });
386+
387+ // We don't have to track the lifetime of "this" as config.agent_registry_watcher is owned
388+ // by "this".
389+ config.agent_registry_watcher->service_registered().connect([this]()
390+ {
391+ agent_registry_stub.register_agent_for_user_async(core::trust::Uid{::getuid()}, config.impl, []()
392+ {
393+ std::cout << "Error registering agent for user." << std::endl;
394+ });
395+ });
396 }
397
398 core::trust::Request::Answer core::trust::remote::dbus::Agent::Skeleton::authenticate_request_with_parameters(const core::trust::Agent::RequestParameters& parameters)
399
400=== modified file 'src/core/trust/remote/dbus.h'
401--- src/core/trust/remote/dbus.h 2014-08-04 07:57:05 +0000
402+++ src/core/trust/remote/dbus.h 2016-01-03 20:28:56 +0000
403@@ -25,6 +25,8 @@
404 #include <core/trust/dbus/agent.h>
405 #include <core/trust/dbus/agent_registry.h>
406
407+#include <core/dbus/service_watcher.h>
408+
409 #include <unistd.h>
410 #include <sys/types.h>
411
412@@ -86,6 +88,8 @@
413 std::shared_ptr<Agent> impl;
414 // The remote object implementing core.trust.dbus.AgentRegistry.
415 core::dbus::Object::Ptr agent_registry_object;
416+ // The watcher monitoring the remote object implementing core.trust.dbus.AgentRegistry.
417+ std::unique_ptr<core::dbus::ServiceWatcher> agent_registry_watcher;
418 // The service that objects implementing core.trust.dbus.Agent should be added to.
419 core::dbus::Service::Ptr service;
420 // The underlying bus instance.
421@@ -95,11 +99,13 @@
422 };
423
424 // Constructs a new Skeleton instance, installing impl for handling actual requests.
425- Skeleton(const Configuration& configuration);
426+ Skeleton(Configuration configuration);
427
428 // From core::trust::Agent, dispatches to the actual implementation.
429 core::trust::Request::Answer authenticate_request_with_parameters(const RequestParameters& parameters);
430
431+ // Store all creation-time parameters.
432+ Configuration config;
433 // Stub for accessing the remote agent registry.
434 core::trust::dbus::AgentRegistry::Stub agent_registry_stub;
435 };
436
437=== added file 'src/core/trust/runtime.cpp'
438--- src/core/trust/runtime.cpp 1970-01-01 00:00:00 +0000
439+++ src/core/trust/runtime.cpp 2016-01-03 20:28:56 +0000
440@@ -0,0 +1,80 @@
441+/*
442+ * Copyright © 2016 Canonical Ltd.
443+ *
444+ * This program is free software: you can redistribute it and/or modify it
445+ * under the terms of the GNU Lesser General Public License version 3,
446+ * as published by the Free Software Foundation.
447+ *
448+ * This program is distributed in the hope that it will be useful,
449+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
450+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
451+ * GNU Lesser General Public License for more details.
452+ *
453+ * You should have received a copy of the GNU Lesser General Public License
454+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
455+ *
456+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
457+ */
458+
459+#include <core/trust/runtime.h>
460+
461+#include <iostream>
462+#include <stdexcept>
463+
464+namespace
465+{
466+void execute_and_never_throw(boost::asio::io_service& ios) noexcept(true)
467+{
468+ while (true)
469+ {
470+ try
471+ {
472+ ios.run();
473+ break;
474+ }
475+ catch (const std::exception& e)
476+ {
477+ std::cerr << __PRETTY_FUNCTION__ << ": " << e.what() << std::endl;
478+ }
479+ catch (...)
480+ {
481+ std::cerr << __PRETTY_FUNCTION__ << ": unknown exception" << std::endl;
482+ }
483+ }
484+}
485+}
486+
487+core::trust::Runtime& core::trust::Runtime::instance()
488+{
489+ static Runtime runtime;
490+ return runtime;
491+}
492+
493+core::trust::Runtime::Runtime()
494+ : signal_trap{core::posix::trap_signals_for_all_subsequent_threads({core::posix::Signal::sig_term, core::posix::Signal::sig_int})},
495+ keep_alive{io_service}
496+{
497+ for (std::size_t i = 0; i < Runtime::concurrency_hint; i++)
498+ {
499+ pool.emplace_back(execute_and_never_throw, std::ref(io_service));
500+ }
501+
502+ signal_trap->signal_raised().connect([this](const core::posix::Signal&)
503+ {
504+ signal_trap->stop();
505+ });
506+}
507+
508+core::trust::Runtime::~Runtime()
509+{
510+ io_service.stop();
511+
512+ for (auto& worker : pool)
513+ if (worker.joinable())
514+ worker.join();
515+}
516+
517+void core::trust::Runtime::run()
518+{
519+ signal_trap->run();
520+}
521
522=== added file 'src/core/trust/runtime.h'
523--- src/core/trust/runtime.h 1970-01-01 00:00:00 +0000
524+++ src/core/trust/runtime.h 2016-01-03 20:28:56 +0000
525@@ -0,0 +1,73 @@
526+/*
527+ * Copyright © 2016 Canonical Ltd.
528+ *
529+ * This program is free software: you can redistribute it and/or modify it
530+ * under the terms of the GNU Lesser General Public License version 3,
531+ * as published by the Free Software Foundation.
532+ *
533+ * This program is distributed in the hope that it will be useful,
534+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
535+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
536+ * GNU Lesser General Public License for more details.
537+ *
538+ * You should have received a copy of the GNU Lesser General Public License
539+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
540+ *
541+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
542+ */
543+
544+#ifndef CORE_TRUST_RUNTIME_H_
545+#define CORE_TRUST_RUNTIME_H_
546+
547+#include <core/posix/signal.h>
548+
549+#include <boost/asio.hpp>
550+
551+#include <memory>
552+#include <thread>
553+#include <vector>
554+
555+namespace core
556+{
557+namespace trust
558+{
559+// A Runtime maintains a pool of workers enabling
560+// implementations to dispatch invocations and have their
561+// ready handlers automatically executed.
562+struct Runtime
563+{
564+ // Do not execute in parallel, serialize
565+ // accesses.
566+ static constexpr std::size_t concurrency_hint{2};
567+
568+ // Our evil singleton pattern. Not bad though, we control the
569+ // entire executable and rely on automatic cleanup of static
570+ // instances.
571+ static Runtime& instance();
572+
573+ Runtime();
574+
575+ // Gracefully shuts down operations.
576+ ~Runtime() noexcept(true);
577+
578+ // run blocks until either stop is called or a
579+ // signal requesting graceful shutdown is received.
580+ void run();
581+
582+ // We trap sig term to ensure a clean shutdown.
583+ std::shared_ptr<core::posix::SignalTrap> signal_trap;
584+
585+ // Our io_service instance exposed to remote agents.
586+ boost::asio::io_service io_service;
587+
588+ // We keep the io_service alive and introduce some artificial
589+ // work.
590+ boost::asio::io_service::work keep_alive;
591+
592+ // We execute the io_service on a pool of worker threads.
593+ std::vector<std::thread> pool;
594+};
595+}
596+}
597+
598+#endif // CORE_TRUST_RUNTIME_H_
599
600=== modified file 'tests/CMakeLists.txt'
601--- tests/CMakeLists.txt 2014-11-14 12:17:24 +0000
602+++ tests/CMakeLists.txt 2016-01-03 20:28:56 +0000
603@@ -46,6 +46,9 @@
604 add_executable(
605 remote_agent_test
606 remote_agent_test.cpp
607+
608+ ${CMAKE_SOURCE_DIR}/src/core/trust/runtime.h
609+ ${CMAKE_SOURCE_DIR}/src/core/trust/runtime.cpp
610 )
611
612 add_executable(
613
614=== modified file 'tests/remote_agent_test.cpp'
615--- tests/remote_agent_test.cpp 2015-08-14 09:53:12 +0000
616+++ tests/remote_agent_test.cpp 2016-01-03 20:28:56 +0000
617@@ -30,6 +30,8 @@
618 #include <core/dbus/asio/executor.h>
619 #include <core/dbus/fixture.h>
620
621+#include <core/trust/runtime.h>
622+
623 #include <gmock/gmock.h>
624 #include <gtest/gtest.h>
625
626@@ -792,6 +794,12 @@
627 {
628 struct DBus : public core::dbus::testing::Fixture
629 {
630+ core::dbus::Bus::Ptr session_bus_with_executor()
631+ {
632+ auto sb = session_bus();
633+ sb->install_executor(core::dbus::asio::make_executor(sb, core::trust::Runtime::instance().io_service));
634+ return sb;
635+ }
636 };
637
638 std::string service_name
639@@ -804,10 +812,6 @@
640 {
641 using namespace ::testing;
642
643- core::testing::CrossProcessSync
644- stub_ready, // signals stub --| I'm ready |--> skeleton
645- skeleton_ready; // signals skeleton --| I'm ready |--> stub
646-
647 auto app = core::posix::fork([]()
648 {
649 while(true) std::this_thread::sleep_for(std::chrono::milliseconds{500});
650@@ -825,7 +829,50 @@
651 const core::trust::Uid app_uid{::getuid()};
652 const core::trust::Pid app_pid{app.pid()};
653
654- auto stub = core::posix::fork([this, app_uid, app_pid, answer, &stub_ready, &skeleton_ready]()
655+ auto skeleton = core::posix::fork([this, answer]()
656+ {
657+ auto bus = session_bus_with_executor();
658+
659+ // We have to rely on a MockAgent to break the dependency on a running Mir instance.
660+ auto mock_agent = std::make_shared<::testing::NiceMock<MockAgent>>();
661+
662+ ON_CALL(*mock_agent, authenticate_request_with_parameters(_))
663+ .WillByDefault(Return(answer));
664+
665+ std::string dbus_service_name = core::trust::remote::dbus::default_service_name_prefix + std::string{"."} + service_name;
666+
667+ auto service = core::dbus::Service::use_service(bus, dbus_service_name);
668+ auto object = service->object_for_path(core::dbus::types::ObjectPath
669+ {
670+ core::trust::remote::dbus::default_agent_registry_path
671+ });
672+
673+ core::dbus::DBus daemon{bus};
674+
675+ core::trust::remote::dbus::Agent::Skeleton::Configuration config
676+ {
677+ mock_agent,
678+ object,
679+ daemon.make_service_watcher(dbus_service_name),
680+ service,
681+ bus,
682+ core::trust::remote::helpers::aa_get_task_con_app_id_resolver()
683+ };
684+
685+ auto skeleton = std::make_shared<core::trust::remote::dbus::Agent::Skeleton>(std::move(config));
686+
687+ core::trust::Runtime::instance().run();
688+ return core::posix::exit::Status::success;
689+ }, core::posix::StandardStream::empty);
690+
691+
692+ // stubf models a trusted helper, with the following simplified
693+ // mode of operation:
694+ // (1.) Helper claims its unique name on the bus.
695+ // (2.) Helper installs an AgentRegistry::Skeleton.
696+ // (3.) Helper learns about per-user trust::Agent instances on the bus.
697+ // (4.) Helper issues requests for authentication.
698+ auto stubf = [this, app_uid, app_pid, answer]()
699 {
700 core::trust::Agent::RequestParameters ref_params
701 {
702@@ -836,10 +883,7 @@
703 "just an example description"
704 };
705
706- auto bus = session_bus();
707- bus->install_executor(core::dbus::asio::make_executor(bus));
708-
709- std::thread worker{[bus]() { bus->run(); }};
710+ auto bus = session_bus_with_executor();
711
712 std::string dbus_service_name = core::trust::remote::dbus::default_service_name_prefix + std::string{"."} + service_name;
713
714@@ -857,76 +901,24 @@
715
716 auto stub = std::make_shared<core::trust::remote::dbus::Agent::Stub>(config);
717
718- stub_ready.try_signal_ready_for(std::chrono::milliseconds{1000});
719- skeleton_ready.wait_for_signal_ready_for(std::chrono::milliseconds{1000});
720+ std::this_thread::sleep_for(std::chrono::seconds(1));
721
722 for (unsigned int i = 0; i < 100; i++)
723 EXPECT_EQ(answer, stub->authenticate_request_with_parameters(ref_params));
724
725- bus->stop();
726-
727- if (worker.joinable())
728- worker.join();
729-
730 return Test::HasFailure() ?
731 core::posix::exit::Status::failure :
732 core::posix::exit::Status::success;
733- }, core::posix::StandardStream::empty);
734-
735- auto skeleton = core::posix::fork([this, answer, &stub_ready, &skeleton_ready]()
736- {
737- auto trap = core::posix::trap_signals_for_all_subsequent_threads({core::posix::Signal::sig_term});
738-
739- trap->signal_raised().connect([trap](core::posix::Signal)
740- {
741- trap->stop();
742- });
743-
744- auto bus = session_bus();
745- bus->install_executor(core::dbus::asio::make_executor(bus));
746-
747- std::thread worker{[bus]() { bus->run(); }};
748-
749- // We have to rely on a MockAgent to break the dependency on a running Mir instance.
750- auto mock_agent = std::make_shared<::testing::NiceMock<MockAgent>>();
751-
752- ON_CALL(*mock_agent, authenticate_request_with_parameters(_))
753- .WillByDefault(Return(answer));
754-
755- std::string dbus_service_name = core::trust::remote::dbus::default_service_name_prefix + std::string{"."} + service_name;
756-
757- stub_ready.wait_for_signal_ready_for(std::chrono::milliseconds{1000});
758-
759- auto service = core::dbus::Service::use_service(bus, dbus_service_name);
760- auto object = service->object_for_path(core::dbus::types::ObjectPath
761- {
762- core::trust::remote::dbus::default_agent_registry_path
763- });
764-
765- core::trust::remote::dbus::Agent::Skeleton::Configuration config
766- {
767- mock_agent,
768- object,
769- service,
770- bus,
771- core::trust::remote::helpers::aa_get_task_con_app_id_resolver()
772- };
773-
774- auto skeleton = std::make_shared<core::trust::remote::dbus::Agent::Skeleton>(config);
775-
776- skeleton_ready.try_signal_ready_for(std::chrono::milliseconds{1000});
777-
778- trap->run();
779-
780- bus->stop();
781-
782- if (worker.joinable())
783- worker.join();
784-
785- return core::posix::exit::Status::success;
786- }, core::posix::StandardStream::empty);
787-
788- EXPECT_TRUE(ProcessExitedSuccessfully(stub.wait_for(core::posix::wait::Flags::untraced)));
789+ };
790+
791+ std::this_thread::sleep_for(std::chrono::seconds(2));
792+ auto stub = core::posix::fork(stubf, core::posix::StandardStream::empty);
793+ EXPECT_TRUE(ProcessExitedSuccessfully(stub.wait_for(core::posix::wait::Flags::untraced)));
794+
795+ std::this_thread::sleep_for(std::chrono::seconds(2));
796+ stub = core::posix::fork(stubf, core::posix::StandardStream::empty);
797+ EXPECT_TRUE(ProcessExitedSuccessfully(stub.wait_for(core::posix::wait::Flags::untraced)));
798+
799 skeleton.send_signal_or_throw(core::posix::Signal::sig_term);
800 EXPECT_TRUE(ProcessExitedSuccessfully(skeleton.wait_for(core::posix::wait::Flags::untraced)));
801

Subscribers

People subscribed via source and target branches