Mir

Merge lp:~andreas-pokorny/mir/probe-libinput-platform into lp:mir

Proposed by Andreas Pokorny on 2015-10-01
Status: Merged
Approved by: Andreas Pokorny on 2015-10-05
Approved revision: 2984
Merged at revision: 2991
Proposed branch: lp:~andreas-pokorny/mir/probe-libinput-platform
Merge into: lp:mir
Diff against target: 340 lines (+196/-6)
11 files modified
debian/mir-test-tools.install (+1/-0)
include/test/mir_test_framework/executable_path.h (+1/-0)
src/CMakeLists.txt (+1/-0)
src/common/symbols.map (+3/-3)
src/platforms/evdev/platform_factory.cpp (+36/-1)
tests/CMakeLists.txt (+1/-0)
tests/acceptance-tests/CMakeLists.txt (+0/-2)
tests/mir_test_framework/CMakeLists.txt (+1/-0)
tests/mir_test_framework/executable_path.cpp (+18/-0)
tests/umock-acceptance-tests/CMakeLists.txt (+34/-0)
tests/umock-acceptance-tests/test_libinput.cpp (+100/-0)
To merge this branch: bzr merge lp:~andreas-pokorny/mir/probe-libinput-platform
Reviewer Review Type Date Requested Status
Alan Griffiths Approve on 2015-10-05
PS Jenkins bot continuous-integration Approve on 2015-10-05
Alexandros Frantzis (community) Approve on 2015-10-05
Brandon Schaefer (community) 2015-10-01 Approve on 2015-10-01
Review via email: mp+273046@code.launchpad.net

Commit Message

Add more checks in input-evdev platform probing and add umockdev acceptance tests

Now input-evdev claims to be capable of operation when it is not loaded within a nested server and is capable of opening at least one of the evdev devices it finds. mir_umock_acceptance_tests is a class of acceptance tests that require device access.

Description of the Change

A step towards automatically probing and loading all available and working input platforms. By probing that libinput is not running in a nested server or has no permission to open evdev devices.

This also adds an acceptance test that relies on libinput and umockdev to a new test binary which should in the end be the only binary of our ci tests that rely on umockdev.

To post a comment you must log in.
2978. By Andreas Pokorny on 2015-10-01

disable test for now..

2979. By Andreas Pokorny on 2015-10-01

slight comment clarification and typo

Brandon Schaefer (brandontschaefer) wrote :

Besides CI being angry LGTM

review: Approve
Alan Griffiths (alan-griffiths) wrote :

*Needs Discussion*

+// ThrowBack alert:
+// This test uses utility headers an external user cannot use, for the sake of this
+// test those utilities just remove some verobsity and avoid code duplication.
+#include "src/include/common/mir/shared_library.h"

I don't think any harm would result from publishing this header?

review: Needs Information
2980. By Andreas Pokorny on 2015-10-02

merge lp:mir

2981. By Andreas Pokorny on 2015-10-02

install new acceptance test binary

Andreas Pokorny (andreas-pokorny) wrote :

> *Needs Discussion*
>
> +// ThrowBack alert:
> +// This test uses utility headers an external user cannot use, for the sake
> of this
> +// test those utilities just remove some verobsity and avoid code
> duplication.
> +#include "src/include/common/mir/shared_library.h"
>
> I don't think any harm would result from publishing this header?

Ok..

2982. By Andreas Pokorny on 2015-10-02

ship shared_library

2983. By Andreas Pokorny on 2015-10-05

remove debug output

Alexandros Frantzis (afrantzis) wrote :

OK. Perhaps also move the SharedLibrary entries in the common/symbols.map from the "supposed to be private" section to the public section.

I don't like exposing internal helper functions/classes just for our own convenience, but since these end up in libmircommon (which is not supposed to be accessed by normal users), it's fine.

review: Approve
Alan Griffiths (alan-griffiths) wrote :

+ // dumb assumption - nobody runs this test cases as root..
+ // or allows accessing evdev input devices from non privileged users.

I wonder if we could express this in code.

Alan Griffiths (alan-griffiths) wrote :

Nit: We should update src/common/symbols.map to reflect the publishing of mir::SharedLibrary::*.

[aside] The mix of public and non-public symbols in libmircommon looks entirely accidental and without reason. Maybe we should review this design?

review: Needs Fixing
2984. By Andreas Pokorny on 2015-10-05

move Shared Library to disclosed section

Alan Griffiths (alan-griffiths) wrote :

thanks

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/mir-test-tools.install'
2--- debian/mir-test-tools.install 2015-09-24 15:42:21 +0000
3+++ debian/mir-test-tools.install 2015-10-05 09:54:18 +0000
4@@ -1,6 +1,7 @@
5 usr/bin/mir_stress
6 usr/bin/mir_unit_tests
7 usr/bin/mir_acceptance_tests
8+usr/bin/mir_umock_acceptance_tests
9 usr/bin/mir_integration_tests*
10 usr/bin/mir_performance_tests
11 usr/bin/mir_privileged_tests
12
13=== renamed file 'src/include/common/mir/shared_library.h' => 'include/common/mir/shared_library.h'
14=== modified file 'include/test/mir_test_framework/executable_path.h'
15--- include/test/mir_test_framework/executable_path.h 2015-09-08 21:22:41 +0000
16+++ include/test/mir_test_framework/executable_path.h 2015-10-05 09:54:18 +0000
17@@ -28,6 +28,7 @@
18 std::string library_path();
19 std::string udev_recordings_path();
20 std::string server_platform(std::string const& name);
21+std::string server_input_platform(std::string const& name);
22 std::string client_platform(std::string const& name);
23 }
24 #endif /* MIR_TEST_FRAMEWORK_EXECUTABLE_PATH_H_ */
25
26=== modified file 'src/CMakeLists.txt'
27--- src/CMakeLists.txt 2015-09-29 13:41:51 +0000
28+++ src/CMakeLists.txt 2015-10-05 09:54:18 +0000
29@@ -48,6 +48,7 @@
30
31 # We need the ABI versions in the tests
32 set(MIR_SERVER_GRAPHICS_PLATFORM_ABI ${MIR_SERVER_GRAPHICS_PLATFORM_ABI} PARENT_SCOPE)
33+set(MIR_SERVER_INPUT_PLATFORM_ABI ${MIR_SERVER_INPUT_PLATFORM_ABI} PARENT_SCOPE)
34 set(MIR_CLIENT_PLATFORM_ABI ${MIR_CLIENT_PLATFORM_ABI} PARENT_SCOPE)
35 set(MIR_INPUT_PLATFORM_VERSION_SCRIPT ${MIR_INPUT_PLATFORM_VERSION_SCRIPT} PARENT_SCOPE)
36 set(MIR_CLIENT_PLATFORM_VERSION ${MIR_CLIENT_PLATFORM_VERSION} PARENT_SCOPE)
37
38=== modified file 'src/common/symbols.map'
39--- src/common/symbols.map 2015-09-17 06:06:28 +0000
40+++ src/common/symbols.map 2015-10-05 09:54:18 +0000
41@@ -65,6 +65,9 @@
42 mir::logging::Logger::Logger*;
43 mir::logging::Logger::operator*;
44 mir::logging::set_logger*;
45+ mir::SharedLibrary::load_symbol*;
46+ mir::SharedLibrary::?SharedLibrary*;
47+ mir::SharedLibrary::SharedLibrary*;
48 non-virtual?thunk?to?mir::dispatch::ActionQueue::?ActionQueue*;
49 non-virtual?thunk?to?mir::dispatch::Dispatchable::?Dispatchable*;
50 non-virtual?thunk?to?mir::dispatch::MultiplexingDispatchable::dispatch*;
51@@ -119,9 +122,6 @@
52 mir::report::lttng::TracepointProvider::?TracepointProvider*;
53 mir::report::lttng::TracepointProvider::TracepointProvider*;
54 mir::set_thread_name*;
55- mir::SharedLibrary::load_symbol*;
56- mir::SharedLibrary::?SharedLibrary*;
57- mir::SharedLibrary::SharedLibrary*;
58 vtable?for?mir::logging::DumbConsoleLogger;
59 vtable?for?mir::time::SteadyClock;
60 vtable?for?mir::time::Clock;
61
62=== modified file 'src/platforms/evdev/platform_factory.cpp'
63--- src/platforms/evdev/platform_factory.cpp 2015-09-14 06:13:21 +0000
64+++ src/platforms/evdev/platform_factory.cpp 2015-10-05 09:54:18 +0000
65@@ -18,6 +18,15 @@
66
67 #include "platform.h"
68 #include "mir/udev/wrapper.h"
69+#include "mir/fd.h"
70+
71+#include <sys/types.h>
72+#include <sys/stat.h>
73+#include <fcntl.h>
74+
75+#include <memory>
76+#include <string>
77+#include <iostream>
78
79 namespace mo = mir::options;
80 namespace mi = mir::input;
81@@ -33,6 +42,28 @@
82 MIR_VERSION_MINOR,
83 MIR_VERSION_MICRO
84 };
85+bool can_open_input_devices()
86+{
87+ mu::Enumerator input_enumerator{std::make_shared<mu::Context>()};
88+ input_enumerator.match_subsystem("input");
89+ input_enumerator.scan_devices();
90+
91+ bool device_found = false;
92+
93+ for (auto& device : input_enumerator)
94+ {
95+ if (device.devnode() != nullptr)
96+ {
97+ device_found = true;
98+
99+ mir::Fd input_device(::open(device.devnode(), O_RDONLY|O_NONBLOCK));
100+ if (input_device > 0)
101+ return true;
102+ }
103+ }
104+ return ! device_found;
105+}
106+
107 }
108
109 mir::UniqueModulePtr<mi::Platform> create_input_platform(
110@@ -59,7 +90,11 @@
111 {
112 return mi::PlatformPriority::unsupported;
113 }
114- return mi::PlatformPriority::supported;
115+
116+ if (can_open_input_devices())
117+ return mi::PlatformPriority::supported;
118+
119+ return mi::PlatformPriority::unsupported;
120 }
121
122 mir::ModuleProperties const* describe_input_module()
123
124=== modified file 'tests/CMakeLists.txt'
125--- tests/CMakeLists.txt 2015-09-17 20:32:32 +0000
126+++ tests/CMakeLists.txt 2015-10-05 09:54:18 +0000
127@@ -65,6 +65,7 @@
128
129 if (MIR_BUILD_ACCEPTANCE_TESTS)
130 add_subdirectory(acceptance-tests/)
131+ add_subdirectory(umock-acceptance-tests/)
132 endif (MIR_BUILD_ACCEPTANCE_TESTS)
133
134 if (MIR_BUILD_PERFORMANCE_TESTS)
135
136=== modified file 'tests/acceptance-tests/CMakeLists.txt'
137--- tests/acceptance-tests/CMakeLists.txt 2015-09-21 22:33:58 +0000
138+++ tests/acceptance-tests/CMakeLists.txt 2015-10-05 09:54:18 +0000
139@@ -3,7 +3,6 @@
140 include_directories(
141 ${CMAKE_SOURCE_DIR}
142 ${PROJECT_SOURCE_DIR}/include/cookie
143- ${UMOCKDEV_INCLUDE_DIRS}
144 )
145
146 set(
147@@ -79,7 +78,6 @@
148 mirclient-debug-extension
149 mirserver
150
151- ${UMOCKDEV_LIBRARIES}
152 ${CMAKE_THREAD_LIBS_INIT} # Link in pthread.
153 )
154
155
156=== modified file 'tests/mir_test_framework/CMakeLists.txt'
157--- tests/mir_test_framework/CMakeLists.txt 2015-09-18 10:26:57 +0000
158+++ tests/mir_test_framework/CMakeLists.txt 2015-10-05 09:54:18 +0000
159@@ -16,6 +16,7 @@
160 -DMIR_SERVER_PLATFORM_PATH="${MIR_SERVER_PLATFORM_PATH}"
161 -DMIR_CLIENT_PLATFORM_ABI_STRING="${MIR_CLIENT_PLATFORM_ABI}"
162 -DMIR_SERVER_GRAPHICS_PLATFORM_ABI_STRING="${MIR_SERVER_GRAPHICS_PLATFORM_ABI}"
163+ -DMIR_SERVER_INPUT_PLATFORM_ABI_STRING="${MIR_SERVER_INPUT_PLATFORM_ABI}"
164 -DMIR_INSTALL_PREFIX="${CMAKE_INSTALL_PREFIX}"
165 -DMIR_BUILD_PREFIX="${CMAKE_BINARY_DIR}"
166 )
167
168=== modified file 'tests/mir_test_framework/executable_path.cpp'
169--- tests/mir_test_framework/executable_path.cpp 2015-09-16 00:42:28 +0000
170+++ tests/mir_test_framework/executable_path.cpp 2015-10-05 09:54:18 +0000
171@@ -76,6 +76,24 @@
172 BOOST_THROW_EXCEPTION(std::runtime_error("Failed to find server platform in standard search locations"));
173 }
174
175+std::string mir_test_framework::server_input_platform(std::string const& name)
176+{
177+ std::string libname{name};
178+
179+ if (libname.find(".so") == std::string::npos)
180+ libname += ".so." MIR_SERVER_INPUT_PLATFORM_ABI_STRING;
181+
182+ for (auto const& option :
183+ {library_path() + "/server-modules/", library_path() + "/server-platform/", std::string(MIR_SERVER_PLATFORM_PATH) + '/'})
184+ {
185+ auto path_to_test = option + libname;
186+ if (boost::filesystem::exists(path_to_test))
187+ return path_to_test;
188+ }
189+
190+ BOOST_THROW_EXCEPTION(std::runtime_error("Failed to find server platform in standard search locations"));
191+}
192+
193 std::string mir_test_framework::client_platform(std::string const& name)
194 {
195 std::string libname{name};
196
197=== added directory 'tests/umock-acceptance-tests'
198=== added file 'tests/umock-acceptance-tests/CMakeLists.txt'
199--- tests/umock-acceptance-tests/CMakeLists.txt 1970-01-01 00:00:00 +0000
200+++ tests/umock-acceptance-tests/CMakeLists.txt 2015-10-05 09:54:18 +0000
201@@ -0,0 +1,34 @@
202+include(CMakeDependentOption)
203+
204+include_directories(
205+ ${CMAKE_SOURCE_DIR}
206+ ${CMAKE_SOURCE_DIR}/tests/include/
207+ ${UMOCKDEV_INCLUDE_DIRS}
208+)
209+
210+mir_add_wrapped_executable(
211+ mir_umock_acceptance_tests
212+
213+ test_libinput.cpp
214+ )
215+
216+add_dependencies(mir_umock_acceptance_tests GMock)
217+
218+target_link_libraries(mir_umock_acceptance_tests
219+ mir-test-assist
220+ mir-test-framework-static
221+
222+ ${UMOCKDEV_LIBRARIES}
223+ ${CMAKE_THREAD_LIBS_INIT} # Link in pthread.
224+)
225+
226+CMAKE_DEPENDENT_OPTION(
227+ MIR_RUN_ACCEPTANCE_TESTS
228+ "Run acceptance tests as part of default testing"
229+ ON
230+ "MIR_BUILD_ACCEPTANCE_TESTS"
231+ OFF)
232+
233+if (MIR_RUN_ACCEPTANCE_TESTS)
234+ mir_discover_tests_with_fd_leak_detection(mir_umock_acceptance_tests LD_PRELOAD=libumockdev-preload.so.0 G_SLICE=always-malloc G_DEBUG=gc-friendly)
235+endif (MIR_RUN_ACCEPTANCE_TESTS)
236
237=== added file 'tests/umock-acceptance-tests/test_libinput.cpp'
238--- tests/umock-acceptance-tests/test_libinput.cpp 1970-01-01 00:00:00 +0000
239+++ tests/umock-acceptance-tests/test_libinput.cpp 2015-10-05 09:54:18 +0000
240@@ -0,0 +1,100 @@
241+/*
242+ * Copyright © 2015 Canonical Ltd.
243+ *
244+ * This program is free software: you can redistribute it and/or modify
245+ * it under the terms of the GNU General Public License version 3 as
246+ * published by the Free Software Foundation.
247+ *
248+ * This program is distributed in the hope that it will be useful,
249+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
250+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
251+ * GNU General Public License for more details.
252+ *
253+ * You should have received a copy of the GNU General Public License
254+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
255+ *
256+ * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com>
257+ */
258+
259+#include "mir/input/platform.h"
260+#include "mir/shared_library.h"
261+#include "mir/options/option.h"
262+
263+#include "mir_test_framework/udev_environment.h"
264+#include "mir_test_framework/executable_path.h"
265+
266+#include <gmock/gmock.h>
267+#include <gtest/gtest.h>
268+
269+namespace mtf = mir_test_framework;
270+namespace mo = mir::options;
271+using namespace ::testing;
272+namespace
273+{
274+
275+struct MockOption : mo::Option
276+{
277+ MOCK_CONST_METHOD1(is_set, bool(char const*));
278+ MOCK_CONST_METHOD2(get, bool(char const*, bool));
279+ MOCK_CONST_METHOD2(get, int(char const*, int));
280+ MOCK_CONST_METHOD2(get, std::string(char const* name, char const*));
281+ MOCK_CONST_METHOD1(get, boost::any const&(char const*));
282+};
283+
284+auto get_libinput_platform()
285+{
286+ auto path = mtf::server_input_platform("input-evdev");
287+ return std::make_shared<mir::SharedLibrary>(path);
288+}
289+
290+char const probe_input_platform_symbol[] = "probe_input_platform";
291+char const host_socket_opt[] = "host-socket";
292+
293+}
294+
295+TEST(LibInput, DISABLED_probes_as_unsupported_without_device_access)
296+{
297+ NiceMock<MockOption> options;
298+
299+ // dumb assumption - nobody runs this test cases as root..
300+ // or allows accessing evdev input devices from non privileged users.
301+ auto library = get_libinput_platform();
302+ auto probe_fun = library->load_function<mir::input::ProbePlatform>(probe_input_platform_symbol);
303+ EXPECT_THAT(probe_fun(options), Eq(mir::input::PlatformPriority::unsupported));
304+}
305+
306+TEST(LibInput, probes_as_supported_with_at_least_one_device_to_deal_with)
307+{
308+ mtf::UdevEnvironment env;
309+ env.add_standard_device("laptop-keyboard");
310+ NiceMock<MockOption> options;
311+
312+ auto library = get_libinput_platform();
313+ auto probe_fun = library->load_function<mir::input::ProbePlatform>(probe_input_platform_symbol);
314+ EXPECT_THAT(probe_fun(options), Ge(mir::input::PlatformPriority::supported));
315+}
316+
317+TEST(LibInput, probes_as_unsupported_on_nested_configs)
318+{
319+ mtf::UdevEnvironment env;
320+ env.add_standard_device("laptop-keyboard");
321+ NiceMock<MockOption> options;
322+ ON_CALL(options,is_set(StrEq(host_socket_opt)))
323+ .WillByDefault(Return(true));
324+ ON_CALL(options,get(StrEq(host_socket_opt), Matcher<char const*>(_)))
325+ .WillByDefault(Return("something"));
326+
327+ auto library = get_libinput_platform();
328+ auto probe_fun = library->load_function<mir::input::ProbePlatform>(probe_input_platform_symbol);
329+ EXPECT_THAT(probe_fun(options), Eq(mir::input::PlatformPriority::unsupported));
330+}
331+
332+TEST(LibInput, probes_as_supported_when_umock_dev_available_or_before_input_devices_are_available)
333+{
334+ mtf::UdevEnvironment env;
335+ NiceMock<MockOption> options;
336+
337+ auto library = get_libinput_platform();
338+ auto probe_fun = library->load_function<mir::input::ProbePlatform>(probe_input_platform_symbol);
339+ EXPECT_THAT(probe_fun(options), Eq(mir::input::PlatformPriority::supported));
340+}

Subscribers

People subscribed via source and target branches