Merge lp:~ssweeny/location-service/cleanups into lp:location-service/trunk

Proposed by Scott Sweeny
Status: Merged
Approved by: Scott Sweeny
Approved revision: 229
Merged at revision: 230
Proposed branch: lp:~ssweeny/location-service/cleanups
Merge into: lp:location-service/trunk
Diff against target: 283 lines (+135/-24)
8 files modified
include/location_service/com/ubuntu/location/provider_factory.h (+2/-0)
src/location_service/com/ubuntu/location/provider_factory.cpp (+7/-2)
src/location_service/com/ubuntu/location/service/daemon.cpp (+30/-22)
src/location_service/com/ubuntu/location/service/daemon.h (+4/-0)
src/location_service/com/ubuntu/location/service/program_options.h (+5/-0)
tests/daemon_and_cli_tests.cpp (+40/-0)
tests/mock_engine.h (+41/-0)
tests/provider_factory_test.cpp (+6/-0)
To merge this branch: bzr merge lp:~ssweeny/location-service/cleanups
Reviewer Review Type Date Requested Status
Thomas Voß (community) Approve
Konrad Zapałowicz Pending
Review via email: mp+291048@code.launchpad.net

This proposal supersedes a proposal from 2016-02-01.

Commit message

Small fixes around provider loading

Description of the change

A couple of small refactors previously discussed with tvoss:

 * provider loading loop
 * extracting undecorated provider names

Also, clear any stored daemon options before parsing new ones. They were persisting between test runs, which I believe invalidated the cli tests (happily with this fix they still pass).

To post a comment you must log in.
Revision history for this message
Thomas Voß (thomas-voss) wrote : Posted in a previous version of this proposal

A suggestion inline, let me know what you think.

review: Needs Information
Revision history for this message
Scott Sweeny (ssweeny) wrote : Posted in a previous version of this proposal

> A suggestion inline, let me know what you think.

Would that work with the current async loading code?

Revision history for this message
Konrad Zapałowicz (kzapalowicz) wrote : Posted in a previous version of this proposal

Looks good. One thing however: I do not like mixing the placement of & in functions signature, i.e.

foo(const int& a);
bar(const int &b);

we should agree on keeping it one way.

review: Approve
Revision history for this message
Scott Sweeny (ssweeny) wrote : Posted in a previous version of this proposal

> Looks good. One thing however: I do not like mixing the placement of & in
> functions signature, i.e.
>
> foo(const int& a);
> bar(const int &b);
>
> we should agree on keeping it one way.

I think that's the result of my preferences and QtCreator's preferences not matching up. I'll fix these up. Thanks!

Revision history for this message
Thomas Voß (thomas-voss) wrote : Posted in a previous version of this proposal

LGTM, *ideally*, we would have an interface "ProviderInstanceReceiver" that is implemented by Engine, but I will not block on that :)

review: Approve
Revision history for this message
Scott Sweeny (ssweeny) wrote :

Resubmitted against trunk

Revision history for this message
Thomas Voß (thomas-voss) wrote :

LGTM.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'include/location_service/com/ubuntu/location/provider_factory.h'
2--- include/location_service/com/ubuntu/location/provider_factory.h 2015-11-19 17:56:19 +0000
3+++ include/location_service/com/ubuntu/location/provider_factory.h 2016-04-05 21:09:59 +0000
4@@ -59,6 +59,8 @@
5
6 void enumerate(const std::function<void(const std::string&, const Factory&)>& enumerator);
7
8+ static std::string extract_undecorated_name(const std::string& name);
9+
10 private:
11 ProviderFactory() = default;
12 ~ProviderFactory() = default;
13
14=== modified file 'src/location_service/com/ubuntu/location/provider_factory.cpp'
15--- src/location_service/com/ubuntu/location/provider_factory.cpp 2015-11-19 17:56:19 +0000
16+++ src/location_service/com/ubuntu/location/provider_factory.cpp 2016-04-05 21:09:59 +0000
17@@ -43,7 +43,7 @@
18 const std::string& name,
19 const cul::ProviderFactory::Configuration& config)
20 {
21- auto undecorated_name = name.substr(0, name.find("@"));
22+ auto undecorated_name = extract_undecorated_name(name);
23
24 std::lock_guard<std::mutex> lg(guard);
25 if (factory_store.count(undecorated_name) == 0)
26@@ -57,7 +57,7 @@
27 const cul::ProviderFactory::Configuration& config,
28 const std::function<void(Provider::Ptr)>& cb)
29 {
30- auto undecorated_name = name.substr(0, name.find("@"));
31+ auto undecorated_name = extract_undecorated_name(name);
32
33 std::lock_guard<std::mutex> lg(guard);
34 if (factory_store.count(undecorated_name) == 0)
35@@ -79,4 +79,9 @@
36 });
37 }
38
39+std::string cul::ProviderFactory::extract_undecorated_name(const std::string& name)
40+{
41+ return name.substr(0, name.find("@"));
42+}
43+
44
45
46=== modified file 'src/location_service/com/ubuntu/location/service/daemon.cpp'
47--- src/location_service/com/ubuntu/location/service/daemon.cpp 2016-03-31 10:15:53 +0000
48+++ src/location_service/com/ubuntu/location/service/daemon.cpp 2016-04-05 21:09:59 +0000
49@@ -109,6 +109,9 @@
50 {
51 location::service::Daemon::Configuration result;
52
53+ // Make sure options are cleared between runs (needed for testing)
54+ mutable_daemon_options().clear();
55+
56 if (!mutable_daemon_options().parse_from_command_line_args(argc, (const char**)argv))
57 throw std::runtime_error{"Could not parse command-line, aborting..."};
58
59@@ -169,6 +172,32 @@
60 mutable_daemon_options().print_help(out);
61 }
62
63+void location::service::Daemon::load_providers(const Configuration& config, std::shared_ptr<Engine> engine)
64+{
65+ for (const std::string& provider : config.providers)
66+ {
67+ std::cout << "Instantiating and configuring: " << provider << std::endl;
68+
69+ try
70+ {
71+ auto result = std::async(std::launch::async, [provider, config, engine] {
72+ return location::ProviderFactory::instance().create_provider_for_name_with_config(
73+ provider,
74+ config.provider_options.count(provider) > 0 ?
75+ config.provider_options.at(provider) : location::Configuration {},
76+ [engine](Provider::Ptr provider)
77+ {
78+ engine->add_provider(provider);
79+ }
80+ );
81+ });
82+ } catch(const std::runtime_error& e)
83+ {
84+ std::cerr << "Issue instantiating provider: " << e.what() << std::endl;
85+ }
86+ }
87+}
88+
89 int location::service::Daemon::main(const location::service::Daemon::Configuration& config)
90 {
91 // Ensure that log files dating back to before the fix
92@@ -200,28 +229,7 @@
93
94 location::service::DefaultConfiguration dc;
95 auto engine = dc.the_engine(std::set<location::Provider::Ptr>{}, dc.the_provider_selection_policy(), config.settings);
96- for (const std::string& provider : config.providers)
97- {
98- std::cout << "Instantiating and configuring: " << provider << std::endl;
99-
100- try
101- {
102- auto result = std::async(std::launch::async, [provider, config, engine] {
103- return location::ProviderFactory::instance().create_provider_for_name_with_config(
104- provider,
105- config.provider_options.count(provider) > 0 ?
106- config.provider_options.at(provider) : location::Configuration {},
107- [engine](Provider::Ptr provider)
108- {
109- engine->add_provider(provider);
110- }
111- );
112- });
113- } catch(const std::runtime_error& e)
114- {
115- std::cerr << "Issue instantiating provider: " << e.what() << std::endl;
116- }
117- }
118+ load_providers(config, engine);
119
120 config.incoming->install_executor(dbus::asio::make_executor(config.incoming, runtime->service()));
121 config.outgoing->install_executor(dbus::asio::make_executor(config.outgoing, runtime->service()));
122
123=== modified file 'src/location_service/com/ubuntu/location/service/daemon.h'
124--- src/location_service/com/ubuntu/location/service/daemon.h 2015-01-25 12:45:30 +0000
125+++ src/location_service/com/ubuntu/location/service/daemon.h 2016-04-05 21:09:59 +0000
126@@ -19,6 +19,7 @@
127 #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_DAEMON_H_
128
129 #include <com/ubuntu/location/configuration.h>
130+#include <com/ubuntu/location/engine.h>
131 #include <com/ubuntu/location/settings.h>
132
133 #include <com/ubuntu/location/service/dbus_connection_factory.h>
134@@ -163,6 +164,9 @@
135 /** @brief Pretty-prints the CLI's help text to the given output stream. */
136 static void print_help(std::ostream& out);
137
138+ /** @brief Instantiates and configures each provider selected in the config */
139+ static void load_providers(const Configuration& config, std::shared_ptr<location::Engine> engine);
140+
141 /**
142 * @brief Executes the daemon with the given configuration.
143 * @return EXIT_SUCCESS or EXIT_FAILURE.
144
145=== modified file 'src/location_service/com/ubuntu/location/service/program_options.h'
146--- src/location_service/com/ubuntu/location/service/program_options.h 2014-06-20 07:40:34 +0000
147+++ src/location_service/com/ubuntu/location/service/program_options.h 2016-04-05 21:09:59 +0000
148@@ -157,6 +157,11 @@
149 enumerator(s);
150 }
151
152+ void clear()
153+ {
154+ vm.clear();
155+ }
156+
157 void print(std::ostream& out) const
158 {
159 for (const auto& pair : vm)
160
161=== modified file 'tests/daemon_and_cli_tests.cpp'
162--- tests/daemon_and_cli_tests.cpp 2014-12-17 09:26:11 +0000
163+++ tests/daemon_and_cli_tests.cpp 2016-04-05 21:09:59 +0000
164@@ -17,6 +17,7 @@
165 */
166
167 #include <com/ubuntu/location/service/daemon.h>
168+#include <com/ubuntu/location/service/default_configuration.h>
169
170 #include <com/ubuntu/location/boost_ptree_settings.h>
171 #include <com/ubuntu/location/space_vehicle.h>
172@@ -28,8 +29,11 @@
173 #include <core/testing/cross_process_sync.h>
174 #include <core/testing/fork_and_run.h>
175
176+#include <gmock/gmock.h>
177 #include <gtest/gtest.h>
178
179+#include "mock_engine.h"
180+
181 #include <ctime>
182
183 #include <thread>
184@@ -263,3 +267,39 @@
185 EXPECT_EQ("test2", config.provider_options.at(config.providers[0]).get<std::string>("option2"));
186 EXPECT_EQ("test3", config.provider_options.at(config.providers[0]).get<std::string>("option3"));
187 }
188+
189+TEST(Daemon, ProviderLoadingWorks)
190+{
191+ const char* args[] =
192+ {
193+ "--bus", "session",
194+ "--provider", "dummy::Provider",
195+ };
196+
197+ auto config = location::service::Daemon::Configuration::from_command_line_args(4, args, null_dbus_connection_factory);
198+ location::service::DefaultConfiguration dc;
199+ auto engine = std::make_shared<MockEngine>(dc.the_provider_selection_policy(), config.settings);
200+
201+ EXPECT_CALL(*engine, add_provider(::testing::_));
202+
203+ location::service::Daemon::load_providers(config, engine);
204+}
205+
206+TEST(Daemon, MultipleProviderLoadingWorks)
207+{
208+ const char* args[] =
209+ {
210+ "--bus", "session",
211+ "--provider", "dummy::Provider",
212+ "--provider", "dummy::DelayedProvider",
213+ "--dummy::DelayedProvider::DelayInMs=250"
214+ };
215+
216+ auto config = location::service::Daemon::Configuration::from_command_line_args(7, args, null_dbus_connection_factory);
217+ location::service::DefaultConfiguration dc;
218+ auto engine = std::make_shared<MockEngine>(dc.the_provider_selection_policy(), config.settings);
219+
220+ EXPECT_CALL(*engine, add_provider(::testing::_)).Times(2);
221+
222+ location::service::Daemon::load_providers(config, engine);
223+}
224
225=== added file 'tests/mock_engine.h'
226--- tests/mock_engine.h 1970-01-01 00:00:00 +0000
227+++ tests/mock_engine.h 2016-04-05 21:09:59 +0000
228@@ -0,0 +1,41 @@
229+/*
230+ * Copyright © 2016 Canonical Ltd.
231+ *
232+ * This program is free software: you can redistribute it and/or modify it
233+ * under the terms of the GNU Lesser General Public License version 3,
234+ * as published by the Free Software Foundation.
235+ *
236+ * This program is distributed in the hope that it will be useful,
237+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
238+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
239+ * GNU Lesser General Public License for more details.
240+ *
241+ * You should have received a copy of the GNU Lesser General Public License
242+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
243+ *
244+ * Authored by: Scott Sweeny <scott.sweeny@canonical.com
245+ */
246+#ifndef MOCK_ENGINE_H
247+#define MOCK_ENGINE_H
248+
249+#include <com/ubuntu/location/engine.h>
250+#include <com/ubuntu/location/provider.h>
251+
252+#include <gmock/gmock.h>
253+
254+struct MockEngine : public com::ubuntu::location::Engine
255+{
256+ MockEngine(
257+ const com::ubuntu::location::ProviderSelectionPolicy::Ptr& provider_selection_policy,
258+ const com::ubuntu::location::Settings::Ptr& settings)
259+ : com::ubuntu::location::Engine(provider_selection_policy, settings)
260+ {
261+ }
262+
263+ // has_provider and remove_provider cannot be mocked because they are marked noexcept
264+ MOCK_METHOD1(determine_provider_selection_for_criteria, com::ubuntu::location::ProviderSelection(const com::ubuntu::location::Criteria&));
265+ MOCK_METHOD1(add_provider, void(const com::ubuntu::location::Provider::Ptr&));
266+ MOCK_METHOD1(for_each_provider, void(const std::function<void(const com::ubuntu::location::Provider::Ptr&)>& enumerator));
267+};
268+
269+#endif // MOCK_ENGINE_H
270
271=== modified file 'tests/provider_factory_test.cpp'
272--- tests/provider_factory_test.cpp 2013-12-10 09:42:54 +0000
273+++ tests/provider_factory_test.cpp 2016-04-05 21:09:59 +0000
274@@ -53,3 +53,9 @@
275 "AnUnknownProvider",
276 cul::ProviderFactory::Configuration{}));
277 }
278+
279+TEST(ProviderFactory, extracting_undecorated_provider_name_works)
280+{
281+ EXPECT_EQ("remote::Provider", cul::ProviderFactory::extract_undecorated_name("remote::Provider@gps"));
282+ EXPECT_EQ("remote::Provider", cul::ProviderFactory::extract_undecorated_name("remote::Provider@espoo"));
283+}

Subscribers

People subscribed via source and target branches