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
=== modified file 'include/location_service/com/ubuntu/location/provider_factory.h'
--- include/location_service/com/ubuntu/location/provider_factory.h 2015-11-19 17:56:19 +0000
+++ include/location_service/com/ubuntu/location/provider_factory.h 2016-04-05 21:09:59 +0000
@@ -59,6 +59,8 @@
5959
60 void enumerate(const std::function<void(const std::string&, const Factory&)>& enumerator);60 void enumerate(const std::function<void(const std::string&, const Factory&)>& enumerator);
6161
62 static std::string extract_undecorated_name(const std::string& name);
63
62 private:64 private:
63 ProviderFactory() = default;65 ProviderFactory() = default;
64 ~ProviderFactory() = default;66 ~ProviderFactory() = default;
6567
=== modified file 'src/location_service/com/ubuntu/location/provider_factory.cpp'
--- src/location_service/com/ubuntu/location/provider_factory.cpp 2015-11-19 17:56:19 +0000
+++ src/location_service/com/ubuntu/location/provider_factory.cpp 2016-04-05 21:09:59 +0000
@@ -43,7 +43,7 @@
43 const std::string& name, 43 const std::string& name,
44 const cul::ProviderFactory::Configuration& config)44 const cul::ProviderFactory::Configuration& config)
45{45{
46 auto undecorated_name = name.substr(0, name.find("@"));46 auto undecorated_name = extract_undecorated_name(name);
4747
48 std::lock_guard<std::mutex> lg(guard);48 std::lock_guard<std::mutex> lg(guard);
49 if (factory_store.count(undecorated_name) == 0)49 if (factory_store.count(undecorated_name) == 0)
@@ -57,7 +57,7 @@
57 const cul::ProviderFactory::Configuration& config,57 const cul::ProviderFactory::Configuration& config,
58 const std::function<void(Provider::Ptr)>& cb)58 const std::function<void(Provider::Ptr)>& cb)
59{59{
60 auto undecorated_name = name.substr(0, name.find("@"));60 auto undecorated_name = extract_undecorated_name(name);
6161
62 std::lock_guard<std::mutex> lg(guard);62 std::lock_guard<std::mutex> lg(guard);
63 if (factory_store.count(undecorated_name) == 0)63 if (factory_store.count(undecorated_name) == 0)
@@ -79,4 +79,9 @@
79 });79 });
80}80}
8181
82std::string cul::ProviderFactory::extract_undecorated_name(const std::string& name)
83{
84 return name.substr(0, name.find("@"));
85}
86
8287
8388
=== modified file 'src/location_service/com/ubuntu/location/service/daemon.cpp'
--- src/location_service/com/ubuntu/location/service/daemon.cpp 2016-03-31 10:15:53 +0000
+++ src/location_service/com/ubuntu/location/service/daemon.cpp 2016-04-05 21:09:59 +0000
@@ -109,6 +109,9 @@
109{109{
110 location::service::Daemon::Configuration result;110 location::service::Daemon::Configuration result;
111111
112 // Make sure options are cleared between runs (needed for testing)
113 mutable_daemon_options().clear();
114
112 if (!mutable_daemon_options().parse_from_command_line_args(argc, (const char**)argv))115 if (!mutable_daemon_options().parse_from_command_line_args(argc, (const char**)argv))
113 throw std::runtime_error{"Could not parse command-line, aborting..."};116 throw std::runtime_error{"Could not parse command-line, aborting..."};
114117
@@ -169,6 +172,32 @@
169 mutable_daemon_options().print_help(out);172 mutable_daemon_options().print_help(out);
170}173}
171174
175void location::service::Daemon::load_providers(const Configuration& config, std::shared_ptr<Engine> engine)
176{
177 for (const std::string& provider : config.providers)
178 {
179 std::cout << "Instantiating and configuring: " << provider << std::endl;
180
181 try
182 {
183 auto result = std::async(std::launch::async, [provider, config, engine] {
184 return location::ProviderFactory::instance().create_provider_for_name_with_config(
185 provider,
186 config.provider_options.count(provider) > 0 ?
187 config.provider_options.at(provider) : location::Configuration {},
188 [engine](Provider::Ptr provider)
189 {
190 engine->add_provider(provider);
191 }
192 );
193 });
194 } catch(const std::runtime_error& e)
195 {
196 std::cerr << "Issue instantiating provider: " << e.what() << std::endl;
197 }
198 }
199}
200
172int location::service::Daemon::main(const location::service::Daemon::Configuration& config)201int location::service::Daemon::main(const location::service::Daemon::Configuration& config)
173{202{
174 // Ensure that log files dating back to before the fix203 // Ensure that log files dating back to before the fix
@@ -200,28 +229,7 @@
200229
201 location::service::DefaultConfiguration dc;230 location::service::DefaultConfiguration dc;
202 auto engine = dc.the_engine(std::set<location::Provider::Ptr>{}, dc.the_provider_selection_policy(), config.settings);231 auto engine = dc.the_engine(std::set<location::Provider::Ptr>{}, dc.the_provider_selection_policy(), config.settings);
203 for (const std::string& provider : config.providers)232 load_providers(config, engine);
204 {
205 std::cout << "Instantiating and configuring: " << provider << std::endl;
206
207 try
208 {
209 auto result = std::async(std::launch::async, [provider, config, engine] {
210 return location::ProviderFactory::instance().create_provider_for_name_with_config(
211 provider,
212 config.provider_options.count(provider) > 0 ?
213 config.provider_options.at(provider) : location::Configuration {},
214 [engine](Provider::Ptr provider)
215 {
216 engine->add_provider(provider);
217 }
218 );
219 });
220 } catch(const std::runtime_error& e)
221 {
222 std::cerr << "Issue instantiating provider: " << e.what() << std::endl;
223 }
224 }
225233
226 config.incoming->install_executor(dbus::asio::make_executor(config.incoming, runtime->service()));234 config.incoming->install_executor(dbus::asio::make_executor(config.incoming, runtime->service()));
227 config.outgoing->install_executor(dbus::asio::make_executor(config.outgoing, runtime->service()));235 config.outgoing->install_executor(dbus::asio::make_executor(config.outgoing, runtime->service()));
228236
=== modified file 'src/location_service/com/ubuntu/location/service/daemon.h'
--- src/location_service/com/ubuntu/location/service/daemon.h 2015-01-25 12:45:30 +0000
+++ src/location_service/com/ubuntu/location/service/daemon.h 2016-04-05 21:09:59 +0000
@@ -19,6 +19,7 @@
19#define LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_DAEMON_H_19#define LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_DAEMON_H_
2020
21#include <com/ubuntu/location/configuration.h>21#include <com/ubuntu/location/configuration.h>
22#include <com/ubuntu/location/engine.h>
22#include <com/ubuntu/location/settings.h>23#include <com/ubuntu/location/settings.h>
2324
24#include <com/ubuntu/location/service/dbus_connection_factory.h>25#include <com/ubuntu/location/service/dbus_connection_factory.h>
@@ -163,6 +164,9 @@
163 /** @brief Pretty-prints the CLI's help text to the given output stream. */164 /** @brief Pretty-prints the CLI's help text to the given output stream. */
164 static void print_help(std::ostream& out);165 static void print_help(std::ostream& out);
165166
167 /** @brief Instantiates and configures each provider selected in the config */
168 static void load_providers(const Configuration& config, std::shared_ptr<location::Engine> engine);
169
166 /**170 /**
167 * @brief Executes the daemon with the given configuration.171 * @brief Executes the daemon with the given configuration.
168 * @return EXIT_SUCCESS or EXIT_FAILURE.172 * @return EXIT_SUCCESS or EXIT_FAILURE.
169173
=== modified file 'src/location_service/com/ubuntu/location/service/program_options.h'
--- src/location_service/com/ubuntu/location/service/program_options.h 2014-06-20 07:40:34 +0000
+++ src/location_service/com/ubuntu/location/service/program_options.h 2016-04-05 21:09:59 +0000
@@ -157,6 +157,11 @@
157 enumerator(s);157 enumerator(s);
158 }158 }
159159
160 void clear()
161 {
162 vm.clear();
163 }
164
160 void print(std::ostream& out) const165 void print(std::ostream& out) const
161 {166 {
162 for (const auto& pair : vm)167 for (const auto& pair : vm)
163168
=== modified file 'tests/daemon_and_cli_tests.cpp'
--- tests/daemon_and_cli_tests.cpp 2014-12-17 09:26:11 +0000
+++ tests/daemon_and_cli_tests.cpp 2016-04-05 21:09:59 +0000
@@ -17,6 +17,7 @@
17 */17 */
1818
19#include <com/ubuntu/location/service/daemon.h>19#include <com/ubuntu/location/service/daemon.h>
20#include <com/ubuntu/location/service/default_configuration.h>
2021
21#include <com/ubuntu/location/boost_ptree_settings.h>22#include <com/ubuntu/location/boost_ptree_settings.h>
22#include <com/ubuntu/location/space_vehicle.h>23#include <com/ubuntu/location/space_vehicle.h>
@@ -28,8 +29,11 @@
28#include <core/testing/cross_process_sync.h>29#include <core/testing/cross_process_sync.h>
29#include <core/testing/fork_and_run.h>30#include <core/testing/fork_and_run.h>
3031
32#include <gmock/gmock.h>
31#include <gtest/gtest.h>33#include <gtest/gtest.h>
3234
35#include "mock_engine.h"
36
33#include <ctime>37#include <ctime>
3438
35#include <thread>39#include <thread>
@@ -263,3 +267,39 @@
263 EXPECT_EQ("test2", config.provider_options.at(config.providers[0]).get<std::string>("option2"));267 EXPECT_EQ("test2", config.provider_options.at(config.providers[0]).get<std::string>("option2"));
264 EXPECT_EQ("test3", config.provider_options.at(config.providers[0]).get<std::string>("option3"));268 EXPECT_EQ("test3", config.provider_options.at(config.providers[0]).get<std::string>("option3"));
265}269}
270
271TEST(Daemon, ProviderLoadingWorks)
272{
273 const char* args[] =
274 {
275 "--bus", "session",
276 "--provider", "dummy::Provider",
277 };
278
279 auto config = location::service::Daemon::Configuration::from_command_line_args(4, args, null_dbus_connection_factory);
280 location::service::DefaultConfiguration dc;
281 auto engine = std::make_shared<MockEngine>(dc.the_provider_selection_policy(), config.settings);
282
283 EXPECT_CALL(*engine, add_provider(::testing::_));
284
285 location::service::Daemon::load_providers(config, engine);
286}
287
288TEST(Daemon, MultipleProviderLoadingWorks)
289{
290 const char* args[] =
291 {
292 "--bus", "session",
293 "--provider", "dummy::Provider",
294 "--provider", "dummy::DelayedProvider",
295 "--dummy::DelayedProvider::DelayInMs=250"
296 };
297
298 auto config = location::service::Daemon::Configuration::from_command_line_args(7, args, null_dbus_connection_factory);
299 location::service::DefaultConfiguration dc;
300 auto engine = std::make_shared<MockEngine>(dc.the_provider_selection_policy(), config.settings);
301
302 EXPECT_CALL(*engine, add_provider(::testing::_)).Times(2);
303
304 location::service::Daemon::load_providers(config, engine);
305}
266306
=== added file 'tests/mock_engine.h'
--- tests/mock_engine.h 1970-01-01 00:00:00 +0000
+++ tests/mock_engine.h 2016-04-05 21:09:59 +0000
@@ -0,0 +1,41 @@
1/*
2 * Copyright © 2016 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Scott Sweeny <scott.sweeny@canonical.com
17 */
18#ifndef MOCK_ENGINE_H
19#define MOCK_ENGINE_H
20
21#include <com/ubuntu/location/engine.h>
22#include <com/ubuntu/location/provider.h>
23
24#include <gmock/gmock.h>
25
26struct MockEngine : public com::ubuntu::location::Engine
27{
28 MockEngine(
29 const com::ubuntu::location::ProviderSelectionPolicy::Ptr& provider_selection_policy,
30 const com::ubuntu::location::Settings::Ptr& settings)
31 : com::ubuntu::location::Engine(provider_selection_policy, settings)
32 {
33 }
34
35 // has_provider and remove_provider cannot be mocked because they are marked noexcept
36 MOCK_METHOD1(determine_provider_selection_for_criteria, com::ubuntu::location::ProviderSelection(const com::ubuntu::location::Criteria&));
37 MOCK_METHOD1(add_provider, void(const com::ubuntu::location::Provider::Ptr&));
38 MOCK_METHOD1(for_each_provider, void(const std::function<void(const com::ubuntu::location::Provider::Ptr&)>& enumerator));
39};
40
41#endif // MOCK_ENGINE_H
042
=== modified file 'tests/provider_factory_test.cpp'
--- tests/provider_factory_test.cpp 2013-12-10 09:42:54 +0000
+++ tests/provider_factory_test.cpp 2016-04-05 21:09:59 +0000
@@ -53,3 +53,9 @@
53 "AnUnknownProvider", 53 "AnUnknownProvider",
54 cul::ProviderFactory::Configuration{}));54 cul::ProviderFactory::Configuration{}));
55}55}
56
57TEST(ProviderFactory, extracting_undecorated_provider_name_works)
58{
59 EXPECT_EQ("remote::Provider", cul::ProviderFactory::extract_undecorated_name("remote::Provider@gps"));
60 EXPECT_EQ("remote::Provider", cul::ProviderFactory::extract_undecorated_name("remote::Provider@espoo"));
61}

Subscribers

People subscribed via source and target branches