Mir

Merge lp:~raof/mir/prober-drm-device-probe into lp:~mir-team/mir/trunk

Proposed by Chris Halse Rogers
Status: Merged
Approved by: Chris Halse Rogers
Approved revision: no longer in the source branch.
Merged at revision: 798
Proposed branch: lp:~raof/mir/prober-drm-device-probe
Merge into: lp:~mir-team/mir/trunk
Diff against target: 1176 lines (+577/-22)
26 files modified
CMakeLists.txt (+12/-1)
cmake/MirCommon.cmake (+10/-0)
cmake/src/mir/mir_discover_gtest_tests.cpp (+13/-0)
debian/control (+3/-0)
include/test/mir_test_doubles/mock_drm.h (+4/-0)
include/test/mir_test_framework/udev_environment.h (+43/-0)
src/server/graphics/gbm/CMakeLists.txt (+2/-0)
src/server/graphics/gbm/gbm_display_helpers.cpp (+122/-14)
src/server/graphics/gbm/gbm_display_helpers.h (+23/-2)
src/server/graphics/gbm/gbm_platform.cpp (+1/-1)
src/server/graphics/gbm/gbm_platform.h (+1/-0)
tests/mir_test_doubles/CMakeLists.txt (+1/-2)
tests/mir_test_doubles/mock_drm.cpp (+73/-0)
tests/mir_test_framework/CMakeLists.txt (+17/-0)
tests/mir_test_framework/udev_environment.cpp (+49/-0)
tests/mir_test_framework/udev_recordings/standard-drm-devices.umockdev (+138/-0)
tests/unit-tests/CMakeLists.txt (+11/-2)
tests/unit-tests/graphics/gbm/test_gbm_buffer.cpp (+7/-0)
tests/unit-tests/graphics/gbm/test_gbm_buffer_allocator.cpp (+5/-0)
tests/unit-tests/graphics/gbm/test_gbm_display.cpp (+6/-0)
tests/unit-tests/graphics/gbm/test_gbm_display_configuration.cpp (+7/-0)
tests/unit-tests/graphics/gbm/test_gbm_display_multi_monitor.cpp (+7/-0)
tests/unit-tests/graphics/gbm/test_gbm_platform.cpp (+5/-0)
tests/unit-tests/graphics/test_display.cpp (+9/-0)
tests/unit-tests/graphics/test_graphics_platform.cpp (+7/-0)
tools/setup-partial-armhf-chroot.sh (+1/-0)
To merge this branch: bzr merge lp:~raof/mir/prober-drm-device-probe
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Thomas Voß (community) Approve
Daniel van Vugt Needs Fixing
Alexandros Frantzis (community) Approve
Robert Ancell Approve
Review via email: mp+170765@code.launchpad.net

Commit message

Improve GBM platform's device probing, by actually making it probe devices

Description of the change

Improve the GBM platform's device probing by actually probing devices

To post a comment you must log in.
Revision history for this message
Chris Halse Rogers (raof) wrote :

This is better than what we've currently got, but I'd prefer not to merge it yet because what we currently have accidentally works on my hybrid laptop and this only works about half the time; when the intel card gets to be the first drm device.

Revision history for this message
Chris Halse Rogers (raof) wrote :

Now actually selects a card that can possibly drive an output!

Revision history for this message
Robert Ancell (robert-ancell) wrote :

Makes sense

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

201 + close(tmp_fd);

We also need to reset tmp_fd to -1. Otherwise we may end up returning an inappropriate fd instead of failing.

156 + udev_enumerate *enumerator = udev_enumerate_new(udev.ctx);
170 + udev_device *dev = udev_device_new_from_syspath(udev.ctx, sys_path);

Not a blocker for this MP, but ideally we would have RAII classes for udev resources to avoid the explicit new/unref matching.

Some style nits:

128 + const char *sys_path = udev_list_entry_get_name(device);

char const*

97 + char *busid = drmGetBusid(fd);
117 + udev_enumerate *children = udev_enumerate_new(udev.ctx);
248 + udev *ctx;
270 + int is_appropriate_device(UdevHelper const& udev, udev_device *dev);
... and at other places

'*' with type

+int mggh::DRMHelper::is_appropriate_device(UdevHelper const &udev, udev_device *drm_device)

'&' and '*' with type

124 + if (!udev_enumerate_scan_devices(children)) {
127 + udev_list_entry_foreach(device, devices) {
132 + if (strcmp(sys_path, udev_device_get_syspath(drm_device))) {
168 + udev_list_entry_foreach(device, devices) {
... and at other places

Opening brace should be on a separate line.

323 + .WillByDefault(DoAll(InvokeWithoutArgs([this]() {this->busid = (char *)malloc(10);}),

static_cast<char*>()

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Chris Halse Rogers (raof) wrote :

@Alf: If you want to make a better UdevHelper class a blocker for the MP, I can certainly accommodate that ☺

Barring that (and getting the CI passing), stylistic comments should all be resolved.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

401 + va_list ap;
402 + mode_t mode;
403 + va_start(ap, flags);
404 + mode = va_arg(ap, mode_t);
405 + va_end(ap);
406 +
407 + return (*real_open)(path, flags, mode);

The C/C++ calling convention is to push parameters on the stack in reverse order. This means a function never needs to know exactly how many parameters the caller really passed. Yes, really.

So you should just implement the 3-parameter version of open and not bother with va_list stuff, I think.

review: Needs Fixing
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

Looks good as a first step. I am looking forward to:

1. 155 + // TODO: Wrap this up in a nice class

2. Tests to cover interaction with various udev configurations. If we continue with the link-time seam for injecting udev, perhaps it would be worth it to set up an infrastructure to create configurations easily (e.g. like we do with FakeDRMResources for KMS).

review: Approve
Revision history for this message
Robert Carr (robertcarr) wrote :

I think this is worth having integration or "acceptance testing" for. Especially if we expect our usage of udev to grow. It looks cumbersome to test, but will only become more so!

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Abstain. There are enough issues blocking this without my opinion right now.

review: Abstain
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Please make umockdev optional:

-- checking for module 'umockdev-1.0'
-- package 'umockdev-1.0' not found
CMake Error at /usr/share/cmake-2.8/Modules/FindPkgConfig.cmake:279 (message):
  A required package was not found
Call Stack (most recent call first):
  /usr/share/cmake-2.8/Modules/FindPkgConfig.cmake:333 (_pkg_check_modules_internal)
  CMakeLists.txt:131 (pkg_check_modules)

Not just for the sake of raring, but particularly for other distros that don't have umockdev packages.

review: Needs Fixing
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

^^^ I mean just disable those tests when umockdev is missing. It shouldn't be a build failure.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

I think this is a step forward, but now I get all my tests skipped if I'm missing umockdev. I think that's extreme. We should only skip those tests (GBM?) that are not possible without umockdev.

I would like to see most of the tests still runnable without umockdev, as they are today in lp:mir.

I don't yet approve, but also understand that my vote is not a veto.

review: Needs Fixing
Revision history for this message
Chris Halse Rogers (raof) wrote :

I think the test-suite should be an all-or-nothing affair - if valgrind didn't take ages I'd be agitating to drop the non-memcheck option. The more optional bits of the test-suite there are the more likely it is that you accidentally miss out.

Dropping the test-suite entirely when you don't have the prerequisites for all of it makes it very clear.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Thomas Voß (thomas-voss) wrote :

LGTM, the udev functionality should see some refactoring but that can happen in a follow-up MP.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) :
review: Approve (continuous-integration)

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 2013-06-27 04:17:19 +0000
3+++ CMakeLists.txt 2013-07-02 07:08:27 +0000
4@@ -110,6 +110,9 @@
5
6 add_definitions(-DANDROID_USE_STD)
7
8+# By default we can run our tests
9+set( MIR_TESTS_AVAILABLE TRUE )
10+
11 if (MIR_PLATFORM STREQUAL "android")
12 include_directories(SYSTEM ${PROJECT_SOURCE_DIR}/3rd_party/android-deps)
13 list(APPEND CMAKE_SYSTEM_INCLUDE_PATH "${PROJECT_SOURCE_DIR}/3rd_party/android-deps")
14@@ -127,6 +130,12 @@
15 find_package( PkgConfig )
16 pkg_check_modules( GBM REQUIRED gbm>=9.0.0)
17 pkg_check_modules( DRM REQUIRED libdrm )
18+ pkg_check_modules( UDEV REQUIRED libudev )
19+ pkg_check_modules( UMOCKDEV umockdev-1.0 )
20+ if ( NOT UMOCKDEV_FOUND )
21+ message( WARNING "Umockdev not found, tests are disabled" )
22+ set(MIR_TESTS_AVAILABLE FALSE)
23+ endif ()
24 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__GBM__")
25 else ()
26 message (FATAL_ERROR "MIR_BACKEND must be either 'android' or 'gbm'")
27@@ -184,7 +193,9 @@
28 set (CMAKE_CXX_FLAGS ${OLD_CMAKE_CXX_FLAGS})
29
30 add_subdirectory(benchmarks/)
31-add_subdirectory(tests/)
32+if (MIR_TESTS_AVAILABLE)
33+ add_subdirectory(tests/)
34+endif ()
35 add_subdirectory(tools/)
36 add_subdirectory(examples/)
37 add_subdirectory(guides/)
38
39=== modified file 'cmake/MirCommon.cmake'
40--- cmake/MirCommon.cmake 2013-03-13 04:54:15 +0000
41+++ cmake/MirCommon.cmake 2013-07-02 07:08:27 +0000
42@@ -29,6 +29,9 @@
43 function (mir_discover_tests EXECUTABLE)
44 if(BUILD_ANDROID OR DISABLE_GTEST_TEST_DISCOVERY)
45 add_test(${EXECUTABLE} ${VALGRIND_EXECUTABLE} ${VALGRIND_ARGS} "${EXECUTABLE_OUTPUT_PATH}/${EXECUTABLE}")
46+ if (${ARGC} GREATER 1)
47+ set_property(TEST ${EXECUTABLE} PROPERTY ENVIRONMENT ${ARGN})
48+ endif ()
49 else()
50 set(CHECK_TEST_DISCOVERY_TARGET_NAME "check_discover_tests_in_${EXECUTABLE}")
51 set(TEST_DISCOVERY_TARGET_NAME "discover_tests_in_${EXECUTABLE}")
52@@ -41,9 +44,16 @@
53 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
54 COMMENT "Check that discovering Tests in ${EXECUTABLE} works")
55
56+ if (${ARGC} GREATER 1)
57+ foreach (env ${ARGN})
58+ list(APPEND EXTRA_ENV_FLAGS "--add-environment" "${env}")
59+ endforeach()
60+ endif()
61+
62 add_custom_target(
63 ${TEST_DISCOVERY_TARGET_NAME} ALL
64 ${EXECUTABLE_OUTPUT_PATH}/${EXECUTABLE} --gtest_list_tests | ${CMAKE_BINARY_DIR}/mir_gtest/mir_discover_gtest_tests --executable=${EXECUTABLE_OUTPUT_PATH}/${EXECUTABLE} ${ENABLE_MEMCHECK_FLAG}
65+ ${EXTRA_ENV_FLAGS}
66 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
67 COMMENT "Discovering Tests in ${EXECUTABLE}" VERBATIM)
68
69
70=== modified file 'cmake/src/mir/mir_discover_gtest_tests.cpp'
71--- cmake/src/mir/mir_discover_gtest_tests.cpp 2013-03-21 03:32:59 +0000
72+++ cmake/src/mir/mir_discover_gtest_tests.cpp 2013-07-02 07:08:27 +0000
73@@ -111,6 +111,7 @@
74 const char* executable;
75 bool enable_memcheck;
76 bool memcheck_test;
77+ std::vector<std::pair<std::string, std::string>> extra_environment;
78 };
79
80 bool parse_configuration_from_cmd_line(int argc, char** argv, Configuration& config)
81@@ -119,6 +120,7 @@
82 {"executable", required_argument, 0, 0},
83 {"enable-memcheck", no_argument, 0, 0},
84 {"memcheck-test", no_argument, 0, 0},
85+ {"add-environment", required_argument, 0, 0},
86 {0, 0, 0, 0}
87 };
88
89@@ -152,6 +154,13 @@
90 config.enable_memcheck = true;
91 else if (!strcmp(optname, "memcheck-test"))
92 config.memcheck_test = true;
93+ else if (!strcmp(optname, "add-environment"))
94+ {
95+ char const* equal_pos = strchr(optarg, '=');
96+ if (!equal_pos)
97+ return false;
98+ config.extra_environment.push_back(std::make_pair(std::string(optarg, equal_pos - optarg), std::string(equal_pos + 1)));
99+ }
100 }
101
102 return true;
103@@ -258,6 +267,10 @@
104 testfilecmake.open(string(test_suite + "_test.cmake").c_str(), ios::out | ios::trunc);
105 if (testfilecmake.is_open())
106 {
107+ for (auto& env_pair : config.extra_environment)
108+ {
109+ testfilecmake << "SET( ENV{"<<env_pair.first<<"} \""<<env_pair.second<<"\" )"<<std::endl;
110+ }
111 for (auto test = tests.begin(); test != tests.end(); ++ test)
112 {
113 static char cmd_line[1024] = "";
114
115=== modified file 'debian/control'
116--- debian/control 2013-06-27 14:16:45 +0000
117+++ debian/control 2013-07-02 07:08:27 +0000
118@@ -22,6 +22,9 @@
119 libgoogle-glog-dev,
120 liblttng-ust-dev,
121 libxkbcommon-dev,
122+ libumockdev-dev,
123+ umockdev,
124+ libudev-dev,
125 valgrind,
126 Standards-Version: 3.9.4
127 Homepage: https://launchpad.net/mir
128
129=== modified file 'include/test/mir_test_doubles/mock_drm.h'
130--- include/test/mir_test_doubles/mock_drm.h 2013-05-02 04:17:41 +0000
131+++ include/test/mir_test_doubles/mock_drm.h 2013-07-02 07:08:27 +0000
132@@ -124,7 +124,11 @@
133 MOCK_METHOD5(drmModeSetCursor, int (int fd, uint32_t crtcId, uint32_t bo_handle, uint32_t width, uint32_t height));
134 MOCK_METHOD4(drmModeMoveCursor,int (int fd, uint32_t crtcId, int x, int y));
135
136+ MOCK_METHOD2(drmSetInterfaceVersion, int (int fd, drmSetVersion* sv));
137+ MOCK_METHOD1(drmGetBusid, char* (int fd));
138+
139 FakeDRMResources fake_drm;
140+ char* busid;
141 };
142
143 }
144
145=== added file 'include/test/mir_test_framework/udev_environment.h'
146--- include/test/mir_test_framework/udev_environment.h 1970-01-01 00:00:00 +0000
147+++ include/test/mir_test_framework/udev_environment.h 2013-07-02 07:08:27 +0000
148@@ -0,0 +1,43 @@
149+/*
150+ * Copyright © 2013 Canonical Ltd.
151+ *
152+ * This program is free software: you can redistribute it and/or modify
153+ * it under the terms of the GNU General Public License version 3 as
154+ * published by the Free Software Foundation.
155+ *
156+ * This program is distributed in the hope that it will be useful,
157+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
158+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
159+ * GNU General Public License for more details.
160+ *
161+ * You should have received a copy of the GNU General Public License
162+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
163+ *
164+ * Authored by:
165+ * Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
166+ */
167+
168+#ifndef MIR_TESTING_UDEV_ENVIRONMENT
169+#define MIR_TESTING_UDEV_ENVIRONMENT
170+
171+#include <umockdev.h>
172+
173+namespace mir
174+{
175+namespace mir_test_framework
176+{
177+class UdevEnvironment
178+{
179+public:
180+ UdevEnvironment();
181+ ~UdevEnvironment() noexcept;
182+
183+ void add_standard_drm_devices();
184+
185+ UMockdevTestbed *testbed;
186+};
187+
188+}
189+}
190+
191+#endif //MIR_TESTING_UDEV_ENVIRONMENT
192
193=== modified file 'src/server/graphics/gbm/CMakeLists.txt'
194--- src/server/graphics/gbm/CMakeLists.txt 2013-06-25 08:11:24 +0000
195+++ src/server/graphics/gbm/CMakeLists.txt 2013-07-02 07:08:27 +0000
196@@ -3,6 +3,7 @@
197 ${GBM_INCLUDE_DIRS}
198 ${EGL_INCLUDE_DIRS}
199 ${GLESv2_INCLUDE_DIRS}
200+ ${UDEV_INCLUDE_DIRS}
201 )
202
203 # gbm.h and drm.h have trailing commas at the end of enum definitions
204@@ -40,6 +41,7 @@
205 ${GBM_LDFLAGS} ${GBM_LIBRARIES}
206 ${EGL_LDFLAGS} ${EGL_LIBRARIES}
207 ${GLESv2_LDFLAGS} ${GLESv2_LIBRARIES}
208+ ${UDEV_LDFLAGS} ${UDEV_LIBRARIES}
209 )
210
211 install(TARGETS mirplatformgraphics LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
212
213=== modified file 'src/server/graphics/gbm/gbm_display_helpers.cpp'
214--- src/server/graphics/gbm/gbm_display_helpers.cpp 2013-06-12 10:27:50 +0000
215+++ src/server/graphics/gbm/gbm_display_helpers.cpp 2013-07-02 07:08:27 +0000
216@@ -26,17 +26,37 @@
217 #include <sstream>
218 #include <stdexcept>
219 #include <xf86drm.h>
220+#include <libudev.h>
221+#include <fcntl.h>
222
223 namespace mgg = mir::graphics::gbm;
224 namespace mggh = mir::graphics::gbm::helpers;
225
226+/**************
227+ * UdevHelper *
228+ **************/
229+
230+mggh::UdevHelper::UdevHelper()
231+{
232+ ctx = udev_new();
233+
234+ if (!ctx)
235+ BOOST_THROW_EXCEPTION(
236+ std::runtime_error("Failed to create udev context"));
237+}
238+
239+mggh::UdevHelper::~UdevHelper() noexcept
240+{
241+ udev_unref(ctx);
242+}
243+
244 /*************
245 * DRMHelper *
246 *************/
247
248-void mggh::DRMHelper::setup()
249+void mggh::DRMHelper::setup(UdevHelper const& udev)
250 {
251- fd = open_drm_device();
252+ fd = open_drm_device(udev);
253
254 if (fd < 0)
255 BOOST_THROW_EXCEPTION(std::runtime_error("Failed to open DRM device\n"));
256@@ -50,7 +70,13 @@
257 std::runtime_error(
258 "Tried to get authenticated DRM fd before setting up the DRM master"));
259
260- int auth_fd = open_drm_device();
261+ char* busid = drmGetBusid(fd);
262+ if (!busid)
263+ BOOST_THROW_EXCEPTION(
264+ boost::enable_error_info(
265+ std::runtime_error("Failed to get BusID of DRM device")) << boost::errinfo_errno(errno));
266+ int auth_fd = drmOpen(NULL, busid);
267+ free(busid);
268
269 if (auth_fd < 0)
270 BOOST_THROW_EXCEPTION(
271@@ -137,26 +163,108 @@
272 }
273 }
274
275-int mggh::DRMHelper::open_drm_device()
276+int mggh::DRMHelper::is_appropriate_device(UdevHelper const& udev, udev_device* drm_device)
277 {
278- static const char *drivers[] = {
279- "i915", "radeon", "nouveau", 0
280- };
281+ udev_enumerate* children = udev_enumerate_new(udev.ctx);
282+ udev_enumerate_add_match_parent(children, drm_device);
283+
284+ char const* devtype = udev_device_get_devtype(drm_device);
285+ if (!devtype || strcmp(devtype, "drm_minor"))
286+ return EINVAL;
287+
288+ if (!udev_enumerate_scan_devices(children))
289+ {
290+ udev_list_entry *devices, *device;
291+ devices = udev_enumerate_get_list_entry(children);
292+ udev_list_entry_foreach(device, devices)
293+ {
294+ char const* sys_path = udev_list_entry_get_name(device);
295+
296+ // For some reason udev regards the device as a parent of itself
297+ // If there are any other children, they should be outputs.
298+ if (strcmp(sys_path, udev_device_get_syspath(drm_device)))
299+ {
300+ udev_enumerate_unref(children);
301+ return 0;
302+ }
303+ }
304+ }
305+ udev_enumerate_unref(children);
306+
307+ return ENOMEDIUM;
308+}
309+
310+int mggh::DRMHelper::open_drm_device(UdevHelper const& udev)
311+{
312 int tmp_fd = -1;
313-
314- const char** driver{drivers};
315-
316- while (tmp_fd < 0 && *driver)
317+ int error;
318+
319+ // TODO: Wrap this up in a nice class
320+ udev_enumerate* enumerator = udev_enumerate_new(udev.ctx);
321+ udev_enumerate_add_match_subsystem(enumerator, "drm");
322+ udev_enumerate_add_match_sysname(enumerator, "card[0-9]");
323+
324+ udev_list_entry *devices, *device;
325+
326+ if ((error = udev_enumerate_scan_devices(enumerator)))
327+ BOOST_THROW_EXCEPTION(
328+ boost::enable_error_info(
329+ std::runtime_error("Failed to enumerate udev devices")) << boost::errinfo_errno(error));
330+
331+ devices = udev_enumerate_get_list_entry(enumerator);
332+ udev_list_entry_foreach(device, devices)
333 {
334- tmp_fd = drmOpen(*driver, NULL);
335- ++driver;
336+ char const* sys_path = udev_list_entry_get_name(device);
337+ udev_device* dev = udev_device_new_from_syspath(udev.ctx, sys_path);
338+
339+ // Devices can disappear on us.
340+ if (!dev)
341+ continue;
342+
343+ if ((error = is_appropriate_device(udev, dev)))
344+ {
345+ udev_device_unref(dev);
346+ continue;
347+ }
348+
349+ char const* dev_path = udev_device_get_devnode(dev);
350+
351+ // If directly opening the DRM device is good enough for X it's good enough for us!
352+ tmp_fd = open(dev_path, O_RDWR, O_CLOEXEC);
353+ if (tmp_fd < 0)
354+ {
355+ error = errno;
356+ udev_device_unref(dev);
357+ continue;
358+ }
359+
360+ udev_device_unref(dev);
361+
362+ // Check that the drm device is usable by setting the interface version we use (1.4)
363+ drmSetVersion sv
364+ {
365+ .drm_di_major = 1,
366+ .drm_di_minor = 4,
367+ .drm_dd_major = -1, /* Don't care */
368+ .drm_dd_minor = -1 /* Don't care */
369+ };
370+ if ((error = drmSetInterfaceVersion(tmp_fd, &sv)))
371+ {
372+ close(tmp_fd);
373+ tmp_fd = -1;
374+ continue;
375+ }
376+
377+ // We currently only handle one DRM device
378+ break;
379 }
380+ udev_enumerate_unref(enumerator);
381
382 if (tmp_fd < 0)
383 {
384 BOOST_THROW_EXCEPTION(
385 boost::enable_error_info(
386- std::runtime_error("Problem opening DRM device")) << boost::errinfo_errno(-tmp_fd));
387+ std::runtime_error("Error opening DRM device")) << boost::errinfo_errno(error));
388 }
389
390 return tmp_fd;
391
392=== modified file 'src/server/graphics/gbm/gbm_display_helpers.h'
393--- src/server/graphics/gbm/gbm_display_helpers.h 2013-06-12 10:27:50 +0000
394+++ src/server/graphics/gbm/gbm_display_helpers.h 2013-07-02 07:08:27 +0000
395@@ -31,6 +31,7 @@
396
397 #include <EGL/egl.h>
398 #include <xf86drmMode.h>
399+#include <libudev.h>
400
401 namespace mir
402 {
403@@ -44,6 +45,22 @@
404 namespace helpers
405 {
406
407+// TODO (RAOF): This is going to morph into an approximately fully-featured
408+// C++ udev library, and probably a top-level Mir interface.
409+//
410+// For now, do the simple thing.
411+struct UdevHelper
412+{
413+public:
414+ UdevHelper();
415+ ~UdevHelper() noexcept;
416+
417+ UdevHelper(UdevHelper const&) = delete;
418+ UdevHelper &operator=(UdevHelper const&) = delete;
419+
420+ udev* ctx;
421+};
422+
423 class DRMHelper
424 {
425 public:
426@@ -53,7 +70,7 @@
427 DRMHelper(const DRMHelper &) = delete;
428 DRMHelper& operator=(const DRMHelper&) = delete;
429
430- void setup();
431+ void setup(UdevHelper const& udev);
432 int get_authenticated_fd();
433 void auth_magic(drm_magic_t magic) const;
434
435@@ -63,7 +80,11 @@
436 int fd;
437
438 private:
439- int open_drm_device();
440+ // TODO: This herustic is temporary; should be replaced with
441+ // handling >1 DRM device.
442+ int is_appropriate_device(UdevHelper const& udev, udev_device* dev);
443+
444+ int open_drm_device(UdevHelper const& udev);
445 };
446
447 class GBMHelper
448
449=== modified file 'src/server/graphics/gbm/gbm_platform.cpp'
450--- src/server/graphics/gbm/gbm_platform.cpp 2013-06-25 03:25:49 +0000
451+++ src/server/graphics/gbm/gbm_platform.cpp 2013-07-02 07:08:27 +0000
452@@ -84,7 +84,7 @@
453 : listener{listener},
454 vt{vt}
455 {
456- drm.setup();
457+ drm.setup(udev);
458 gbm.setup(drm);
459 internal_display_clients_present = false;
460 }
461
462=== modified file 'src/server/graphics/gbm/gbm_platform.h'
463--- src/server/graphics/gbm/gbm_platform.h 2013-06-12 10:23:43 +0000
464+++ src/server/graphics/gbm/gbm_platform.h 2013-07-02 07:08:27 +0000
465@@ -56,6 +56,7 @@
466 /* From DRMAuthenticator */
467 void drm_auth_magic(drm_magic_t magic);
468
469+ helpers::UdevHelper udev;
470 helpers::DRMHelper drm;
471 helpers::GBMHelper gbm;
472
473
474=== modified file 'tests/mir_test_doubles/CMakeLists.txt'
475--- tests/mir_test_doubles/CMakeLists.txt 2013-05-20 15:55:48 +0000
476+++ tests/mir_test_doubles/CMakeLists.txt 2013-07-02 07:08:27 +0000
477@@ -46,7 +46,6 @@
478
479 ${PROTOBUF_LIBRARIES}
480 ${Boost_LIBRARIES}
481- ${GTEST_BOTH_LIBRARIES}
482 ${GMOCK_LIBRARY}
483 ${GMOCK_MAIN_LIBRARY}
484 ${CMAKE_THREAD_LIBS_INIT} # Link in pthread.
485@@ -59,7 +58,7 @@
486 target_link_libraries(
487 mir-test-doubles-platform
488
489- ${GTEST_BOTH_LIBRARIES}
490+ -ldl
491 ${GMOCK_LIBRARY}
492 ${GMOCK_MAIN_LIBRARY}
493 ${CMAKE_THREAD_LIBS_INIT} # Link in pthread.
494
495=== modified file 'tests/mir_test_doubles/mock_drm.cpp'
496--- tests/mir_test_doubles/mock_drm.cpp 2013-05-02 04:17:41 +0000
497+++ tests/mir_test_doubles/mock_drm.cpp 2013-07-02 07:08:27 +0000
498@@ -23,6 +23,7 @@
499
500 #include <stdexcept>
501 #include <unistd.h>
502+#include <dlfcn.h>
503
504 namespace mgg=mir::test::doubles;
505 namespace geom = mir::geometry;
506@@ -235,6 +236,13 @@
507
508 ON_CALL(*this, drmModeGetConnector(_, _))
509 .WillByDefault(WithArgs<1>(Invoke(&fake_drm, &FakeDRMResources::find_connector)));
510+
511+ ON_CALL(*this, drmSetInterfaceVersion(_, _))
512+ .WillByDefault(Return(0));
513+
514+ ON_CALL(*this, drmGetBusid(_))
515+ .WillByDefault(DoAll(InvokeWithoutArgs([this]() {this->busid = static_cast<char*>(malloc(10));}),
516+ ReturnPointee(&this->busid)));
517 }
518
519 mgg::MockDRM::~MockDRM() noexcept
520@@ -371,3 +379,68 @@
521 {
522 return global_mock->drmModeMoveCursor(fd, crtcId, x, y);
523 }
524+
525+int drmSetInterfaceVersion(int fd, drmSetVersion* sv)
526+{
527+ return global_mock->drmSetInterfaceVersion(fd, sv);
528+}
529+
530+char* drmGetBusid(int fd)
531+{
532+ return global_mock->drmGetBusid(fd);
533+}
534+
535+// We need to wrap open as we sometimes open() the DRM device
536+// We need to explicitly mark this as C because we don't match the
537+// libc header; we only care about the three-parameter version
538+extern "C"
539+{
540+int open(char const* path, int flags, mode_t mode)
541+{
542+ char const* drm_prefix = "/dev/dri/";
543+ if (!strncmp(path, drm_prefix, strlen(drm_prefix)))
544+ return global_mock->drmOpen("i915", NULL);
545+
546+ int (*real_open)(char const *path, int flags, mode_t mode);
547+ *(void **)(&real_open) = dlsym(RTLD_NEXT, "open");
548+
549+ return (*real_open)(path, flags, mode);
550+}
551+
552+int open64(char const* path, int flags, mode_t mode)
553+{
554+ char const* drm_prefix = "/dev/dri/";
555+ if (!strncmp(path, drm_prefix, strlen(drm_prefix)))
556+ return global_mock->drmOpen("i915", NULL);
557+
558+ int (*real_open64)(char const *path, int flags, mode_t mode);
559+ *(void **)(&real_open64) = dlsym(RTLD_NEXT, "open64");
560+
561+ return (*real_open64)(path, flags, mode);
562+}
563+
564+int __open(char const* path, int flags, mode_t mode)
565+{
566+ char const* drm_prefix = "/dev/dri/";
567+ if (!strncmp(path, drm_prefix, strlen(drm_prefix)))
568+ return global_mock->drmOpen("i915", NULL);
569+
570+ int (*real_open)(char const *path, int flags, mode_t mode);
571+ *(void **)(&real_open) = dlsym(RTLD_NEXT, "__open");
572+
573+ return (*real_open)(path, flags, mode);
574+}
575+
576+int __open64(char const* path, int flags, mode_t mode)
577+{
578+ char const* drm_prefix = "/dev/dri/";
579+ if (!strncmp(path, drm_prefix, strlen(drm_prefix)))
580+ return global_mock->drmOpen("i915", NULL);
581+
582+ int (*real_open64)(char const *path, int flags, mode_t mode);
583+ *(void **)(&real_open64) = dlsym(RTLD_NEXT, "__open64");
584+
585+ return (*real_open64)(path, flags, mode);
586+}
587+
588+}
589
590=== modified file 'tests/mir_test_framework/CMakeLists.txt'
591--- tests/mir_test_framework/CMakeLists.txt 2013-06-13 21:58:25 +0000
592+++ tests/mir_test_framework/CMakeLists.txt 2013-07-02 07:08:27 +0000
593@@ -1,3 +1,5 @@
594+add_definitions(-DUDEVMOCK_DIR="${CMAKE_CURRENT_SOURCE_DIR}/udev_recordings")
595+
596 include_directories(
597 ${Boost_INCLUDE_DIRS}
598 ${GLESv2_INCLUDE_DIRS}
599@@ -18,6 +20,13 @@
600 socket_detect_server.cpp
601 )
602
603+if (MIR_PLATFORM STREQUAL "gbm")
604+ include_directories(${UMOCKDEV_INCLUDE_DIRS})
605+ list(APPEND TEST_FRAMEWORK_SRCS
606+ udev_environment.cpp
607+ )
608+endif()
609+
610 add_library(
611 mir-test-framework STATIC
612 ${TEST_FRAMEWORK_SRCS})
613@@ -38,3 +47,11 @@
614 ${GMOCK_MAIN_LIBRARY}
615 ${CMAKE_THREAD_LIBS_INIT} # Link in pthread.
616 )
617+
618+if (MIR_PLATFORM STREQUAL "gbm")
619+ target_link_libraries(
620+ mir-test-framework
621+
622+ ${UMOCKDEV_LIBRARIES}
623+ )
624+endif()
625
626=== added file 'tests/mir_test_framework/udev_environment.cpp'
627--- tests/mir_test_framework/udev_environment.cpp 1970-01-01 00:00:00 +0000
628+++ tests/mir_test_framework/udev_environment.cpp 2013-07-02 07:08:27 +0000
629@@ -0,0 +1,49 @@
630+/*
631+ * Copyright © 2013 Canonical Ltd.
632+ *
633+ * This program is free software: you can redistribute it and/or modify
634+ * it under the terms of the GNU General Public License version 3 as
635+ * published by the Free Software Foundation.
636+ *
637+ * This program is distributed in the hope that it will be useful,
638+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
639+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
640+ * GNU General Public License for more details.
641+ *
642+ * You should have received a copy of the GNU General Public License
643+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
644+ *
645+ * Authored by:
646+ * Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
647+ */
648+
649+#include "mir_test_framework/udev_environment.h"
650+
651+#include <umockdev.h>
652+
653+#include <fstream>
654+#include <sstream>
655+
656+namespace mtf = mir::mir_test_framework;
657+
658+mtf::UdevEnvironment::UdevEnvironment()
659+{
660+ testbed = umockdev_testbed_new();
661+}
662+
663+mtf::UdevEnvironment::~UdevEnvironment() noexcept
664+{
665+ g_object_unref(testbed);
666+}
667+
668+void mtf::UdevEnvironment::add_standard_drm_devices()
669+{
670+ // Temporary, until umockdev grows add_from_file
671+ std::ifstream udev_dump(UDEVMOCK_DIR"/standard-drm-devices.umockdev");
672+ std::stringstream buffer;
673+ buffer<<udev_dump.rdbuf();
674+
675+ umockdev_testbed_add_from_string(testbed,
676+ buffer.str().c_str(),
677+ NULL);
678+}
679
680=== added directory 'tests/mir_test_framework/udev_recordings'
681=== added file 'tests/mir_test_framework/udev_recordings/standard-drm-devices.umockdev'
682--- tests/mir_test_framework/udev_recordings/standard-drm-devices.umockdev 1970-01-01 00:00:00 +0000
683+++ tests/mir_test_framework/udev_recordings/standard-drm-devices.umockdev 2013-07-02 07:08:27 +0000
684@@ -0,0 +1,138 @@
685+P: /devices/pci0000:00/0000:00:02.0/drm/card1/card1-HDMI-A-1
686+E: SUBSYSTEM=drm
687+A: dpms=On
688+H: edid=00FFFFFFFFFFFF0010AC16F04C574B300415010380342078EA1EC5AE4F34B1260E5054A54B008180A940D100714F0101010101010101283C80A070B023403020360006442100001A000000FF00483339304D31314A304B574C0A000000FC0044454C4C2055323431300A2020000000FD00384C1E5111000A202020202020013E020329F15090050403020716011F121314201511062309070767030C001000382D83010000E3050301023A801871382D40582C450006442100001E011D8018711C1620582C250006442100009E011D007251D01E206E28550006442100001E8C0AD08A20E02D10103E960006442100001800000000000000000000000000003E
689+A: enabled=enabled
690+A: modes=1920x1200\n1920x1080\n1920x1080\n1920x1080\n1920x1080i\n1920x1080i\n1600x1200\n1280x1024\n1280x1024\n1152x864\n1280x720\n1280x720\n1440x576i\n1024x768\n1024x768\n1440x480i\n800x600\n800x600\n720x576\n720x480\n640x480\n640x480\n640x480\n720x400
691+A: status=connected
692+
693+P: /devices/pci0000:00/0000:00:02.0/drm/card1
694+N: dri/card1
695+E: DEVNAME=/dev/dri/card1
696+E: DEVTYPE=drm_minor
697+E: ID_FOR_SEAT=drm-pci-0000_00_02_0
698+E: ID_PATH=pci-0000:00:02.0
699+E: ID_PATH_TAG=pci-0000_00_02_0
700+E: MAJOR=226
701+E: MINOR=1
702+E: SUBSYSTEM=drm
703+E: TAGS=:seat:uaccess:
704+A: dev=226:1
705+A: gt_RP0_freq_mhz=1200
706+A: gt_RP1_freq_mhz=650
707+A: gt_RPn_freq_mhz=650
708+A: gt_cur_freq_mhz=1200
709+A: gt_max_freq_mhz=1200
710+A: gt_min_freq_mhz=650
711+
712+P: /devices/pci0000:00/0000:00:02.0
713+E: DRIVER=i915
714+E: ID_MODEL_FROM_DATABASE=2nd Generation Core Processor Family Integrated Graphics Controller
715+E: ID_PCI_CLASS_FROM_DATABASE=Display controller
716+E: ID_PCI_INTERFACE_FROM_DATABASE=VGA controller
717+E: ID_PCI_SUBCLASS_FROM_DATABASE=VGA compatible controller
718+E: ID_VENDOR_FROM_DATABASE=Intel Corporation
719+E: MODALIAS=pci:v00008086d00000116sv00001028sd000004C1bc03sc00i00
720+E: PCI_CLASS=30000
721+E: PCI_ID=8086:0116
722+E: PCI_SLOT_NAME=0000:00:02.0
723+E: PCI_SUBSYS_ID=1028:04C1
724+E: SUBSYSTEM=pci
725+A: boot_vga=1
726+A: broken_parity_status=0
727+A: class=0x030000
728+H: config=86801601070490000900000300000000040000E0000000000C0000D0000000000150000000000000000000002810C1040000000090000000000000000B010000
729+A: consistent_dma_mask_bits=40
730+A: d3cold_allowed=1
731+A: device=0x0116
732+A: dma_mask_bits=40
733+A: irq=50
734+A: local_cpulist=0-3
735+A: local_cpus=00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000000f
736+A: modalias=pci:v00008086d00000116sv00001028sd000004C1bc03sc00i00
737+A: msi_bus=
738+A: numa_node=-1
739+A: resource=0x00000000e0000000 0x00000000e03fffff 0x0000000000140204\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x00000000d0000000 0x00000000dfffffff 0x000000000014220c\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000005000 0x000000000000503f 0x0000000000040101\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000002\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000
740+A: subsystem_device=0x04c1
741+A: subsystem_vendor=0x1028
742+A: vendor=0x8086
743+
744+P: /devices/pci0000:00/0000:00:01.0/0000:01:00.0/drm/card0
745+N: dri/card0
746+E: DEVNAME=/dev/dri/card0
747+E: DEVTYPE=drm_minor
748+E: ID_FOR_SEAT=drm-pci-0000_01_00_0
749+E: ID_PATH=pci-0000:01:00.0
750+E: ID_PATH_TAG=pci-0000_01_00_0
751+E: MAJOR=226
752+E: MINOR=0
753+E: PRIMARY_DEVICE_FOR_DISPLAY=1
754+E: SUBSYSTEM=drm
755+E: TAGS=:seat:uaccess:
756+A: dev=226:0
757+
758+P: /devices/pci0000:00/0000:00:01.0/0000:01:00.0
759+E: DRIVER=radeon
760+E: ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6600M/6700M/7600M Series]
761+E: ID_PCI_CLASS_FROM_DATABASE=Display controller
762+E: ID_PCI_INTERFACE_FROM_DATABASE=VGA controller
763+E: ID_PCI_SUBCLASS_FROM_DATABASE=VGA compatible controller
764+E: ID_VENDOR_FROM_DATABASE=Advanced Micro Devices, Inc. [AMD/ATI]
765+E: MODALIAS=pci:v00001002d00006741sv00001028sd000004C1bc03sc00i00
766+E: PCI_CLASS=30000
767+E: PCI_ID=1002:6741
768+E: PCI_SLOT_NAME=0000:01:00.0
769+E: PCI_SUBSYS_ID=1028:04C1
770+E: SUBSYSTEM=pci
771+A: boot_vga=0
772+A: broken_parity_status=0
773+A: class=0x030000
774+H: config=FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
775+A: consistent_dma_mask_bits=40
776+A: d3cold_allowed=1
777+A: device=0x6741
778+A: dma_mask_bits=40
779+A: irq=49
780+A: local_cpulist=0-3
781+A: local_cpus=00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000000f
782+A: modalias=pci:v00001002d00006741sv00001028sd000004C1bc03sc00i00
783+A: msi_bus=
784+A: numa_node=-1
785+A: power_method=profile
786+A: power_profile=default
787+A: resource=0x00000000c0000000 0x00000000cfffffff 0x000000000014220c\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x00000000e1700000 0x00000000e171ffff 0x0000000000140204\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000004000 0x00000000000040ff 0x0000000000040101\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x00000000e1720000 0x00000000e173ffff 0x000000000004e200\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000
788+A: subsystem_device=0x04c1
789+A: subsystem_vendor=0x1028
790+A: vendor=0x1002
791+
792+P: /devices/pci0000:00/0000:00:01.0
793+E: DRIVER=pcieport
794+E: ID_MODEL_FROM_DATABASE=Xeon E3-1200/2nd Generation Core Processor Family PCI Express Root Port
795+E: ID_PCI_CLASS_FROM_DATABASE=Bridge
796+E: ID_PCI_INTERFACE_FROM_DATABASE=Normal decode
797+E: ID_PCI_SUBCLASS_FROM_DATABASE=PCI bridge
798+E: ID_VENDOR_FROM_DATABASE=Intel Corporation
799+E: MODALIAS=pci:v00008086d00000101sv00008086sd00002010bc06sc04i00
800+E: PCI_CLASS=60400
801+E: PCI_ID=8086:0101
802+E: PCI_SLOT_NAME=0000:00:01.0
803+E: PCI_SUBSYS_ID=8086:2010
804+E: SUBSYSTEM=pci
805+A: broken_parity_status=0
806+A: class=0x060400
807+H: config=868001010704100009000406100081000000000000000000000101004040000070E170E101C0F1CF00000000000000000000000088000000000000000B010000
808+A: consistent_dma_mask_bits=32
809+A: d3cold_allowed=0
810+A: device=0x0101
811+A: dma_mask_bits=32
812+A: irq=40
813+A: local_cpulist=0-3
814+A: local_cpus=00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000000f
815+A: modalias=pci:v00008086d00000101sv00008086sd00002010bc06sc04i00
816+A: msi_bus=1
817+A: numa_node=-1
818+A: resource=0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000004000 0x0000000000004fff 0x0000000000000100\n0x00000000e1700000 0x00000000e17fffff 0x0000000000000200\n0x00000000c0000000 0x00000000cfffffff 0x0000000000102201\n0x0000000000000000 0x0000000000000000 0x0000000000000000
819+A: subsystem_device=0x2010
820+A: subsystem_vendor=0x8086
821+A: vendor=0x8086
822+
823
824=== modified file 'tests/unit-tests/CMakeLists.txt'
825--- tests/unit-tests/CMakeLists.txt 2013-06-25 03:25:49 +0000
826+++ tests/unit-tests/CMakeLists.txt 2013-07-02 07:08:27 +0000
827@@ -1,5 +1,5 @@
828 add_definitions(-DTEST_RECORDINGS_DIR="${CMAKE_CURRENT_SOURCE_DIR}/input_recordings/")
829-include_directories(${DRM_INCLUDE_DIRS} ${GBM_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR})
830+include_directories(${DRM_INCLUDE_DIRS} ${GBM_INCLUDE_DIRS} ${UMOCKDEV_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR})
831
832 set(
833 UNIT_TEST_SOURCES
834@@ -37,6 +37,7 @@
835
836 mir-test-doubles
837 mir-test-doubles-platform
838+ mir-test-framework
839
840 3rd_party
841
842@@ -48,4 +49,12 @@
843 ${CMAKE_THREAD_LIBS_INIT} # Link in pthread.
844 )
845
846-mir_discover_tests(unit-tests)
847+if (MIR_PLATFORM STREQUAL "gbm")
848+ target_link_libraries(
849+ unit-tests
850+
851+ ${UMOCKDEV_LIBRARIES}
852+ )
853+endif()
854+
855+mir_discover_tests(unit-tests LD_PRELOAD=libumockdev-preload.so.0)
856
857=== modified file 'tests/unit-tests/graphics/gbm/test_gbm_buffer.cpp'
858--- tests/unit-tests/graphics/gbm/test_gbm_buffer.cpp 2013-06-14 16:18:33 +0000
859+++ tests/unit-tests/graphics/gbm/test_gbm_buffer.cpp 2013-07-02 07:08:27 +0000
860@@ -21,6 +21,8 @@
861 #include "mir_test_doubles/mock_drm.h"
862 #include "mir_test_doubles/mock_gbm.h"
863
864+#include "mir_test_framework/udev_environment.h"
865+
866 #include "src/server/graphics/gbm/gbm_platform.h"
867 #include "src/server/graphics/gbm/gbm_buffer.h"
868 #include "src/server/graphics/gbm/gbm_buffer_allocator.h"
869@@ -43,6 +45,7 @@
870 namespace mgg=mir::graphics::gbm;
871 namespace geom=mir::geometry;
872 namespace mtd=mir::test::doubles;
873+namespace mtf=mir::mir_test_framework;
874
875 class GBMGraphicBufferBasic : public ::testing::Test
876 {
877@@ -51,6 +54,8 @@
878 {
879 using namespace testing;
880
881+ fake_devices.add_standard_drm_devices();
882+
883 size = geom::Size{geom::Width{300}, geom::Height{200}};
884 pf = geom::PixelFormat::argb_8888;
885 stride = geom::Stride{4 * size.width.as_uint32_t()};
886@@ -89,6 +94,8 @@
887 geom::Stride stride;
888 mc::BufferUsage usage;
889 mc::BufferProperties buffer_properties;
890+
891+ mtf::UdevEnvironment fake_devices;
892 };
893
894 TEST_F(GBMGraphicBufferBasic, dimensions_test)
895
896=== modified file 'tests/unit-tests/graphics/gbm/test_gbm_buffer_allocator.cpp'
897--- tests/unit-tests/graphics/gbm/test_gbm_buffer_allocator.cpp 2013-06-14 18:24:09 +0000
898+++ tests/unit-tests/graphics/gbm/test_gbm_buffer_allocator.cpp 2013-07-02 07:08:27 +0000
899@@ -27,6 +27,7 @@
900 #include "mir_test_doubles/mock_gl.h"
901 #include "mir_test_doubles/mock_buffer_initializer.h"
902 #include "mir_test_doubles/null_virtual_terminal.h"
903+#include "mir_test_framework/udev_environment.h"
904 #include "mir/graphics/null_display_report.h"
905
906 #include <memory>
907@@ -42,6 +43,7 @@
908 namespace mc = mir::compositor;
909 namespace geom = mir::geometry;
910 namespace mtd = mir::test::doubles;
911+namespace mtf = mir::mir_test_framework;
912
913 class GBMBufferAllocatorTest : public ::testing::Test
914 {
915@@ -50,6 +52,8 @@
916 {
917 using namespace testing;
918
919+ fake_devices.add_standard_drm_devices();
920+
921 size = geom::Size{geom::Width{300}, geom::Height{200}};
922 pf = geom::PixelFormat::argb_8888;
923 usage = mc::BufferUsage::hardware;
924@@ -77,6 +81,7 @@
925 std::shared_ptr<mgg::GBMPlatform> platform;
926 std::shared_ptr<testing::NiceMock<mtd::MockBufferInitializer>> mock_buffer_initializer;
927 std::unique_ptr<mgg::GBMBufferAllocator> allocator;
928+ mtf::UdevEnvironment fake_devices;
929 };
930
931 TEST_F(GBMBufferAllocatorTest, allocator_returns_non_null_buffer)
932
933=== modified file 'tests/unit-tests/graphics/gbm/test_gbm_display.cpp'
934--- tests/unit-tests/graphics/gbm/test_gbm_display.cpp 2013-05-29 06:50:07 +0000
935+++ tests/unit-tests/graphics/gbm/test_gbm_display.cpp 2013-07-02 07:08:27 +0000
936@@ -33,6 +33,8 @@
937 #include "mir_test_doubles/mock_drm.h"
938 #include "mir_test_doubles/mock_gbm.h"
939
940+#include "mir_test_framework/udev_environment.h"
941+
942 #include <gtest/gtest.h>
943 #include <memory>
944 #include <stdexcept>
945@@ -41,6 +43,7 @@
946 namespace mgg=mir::graphics::gbm;
947 namespace ml=mir::logging;
948 namespace mtd=mir::test::doubles;
949+namespace mtf=mir::mir_test_framework;
950
951 namespace
952 {
953@@ -93,6 +96,8 @@
954 .Times(AtLeast(0));
955 EXPECT_CALL(mock_gbm, gbm_device_get_fd(_))
956 .Times(AtLeast(0));
957+
958+ fake_devices.add_standard_drm_devices();
959 }
960
961 std::shared_ptr<mgg::GBMPlatform> create_platform()
962@@ -192,6 +197,7 @@
963 ::testing::NiceMock<mtd::MockGBM> mock_gbm;
964 std::shared_ptr<testing::NiceMock<mtd::MockDisplayReport>> const mock_report;
965 std::shared_ptr<mg::DisplayReport> const null_report;
966+ mtf::UdevEnvironment fake_devices;
967 };
968
969 }
970
971=== modified file 'tests/unit-tests/graphics/gbm/test_gbm_display_configuration.cpp'
972--- tests/unit-tests/graphics/gbm/test_gbm_display_configuration.cpp 2013-05-20 15:55:48 +0000
973+++ tests/unit-tests/graphics/gbm/test_gbm_display_configuration.cpp 2013-07-02 07:08:27 +0000
974@@ -27,6 +27,8 @@
975 #include "mir/graphics/null_display_report.h"
976 #include "mir_test_doubles/null_virtual_terminal.h"
977
978+#include "mir_test_framework/udev_environment.h"
979+
980 #include "mir_test_doubles/mock_drm.h"
981 #include "mir_test_doubles/mock_gbm.h"
982
983@@ -39,6 +41,7 @@
984 namespace mgg = mir::graphics::gbm;
985 namespace geom = mir::geometry;
986 namespace mtd = mir::test::doubles;
987+namespace mtf = mir::mir_test_framework;
988
989 namespace
990 {
991@@ -80,6 +83,8 @@
992 .WillByDefault(Return(reinterpret_cast<const GLubyte*>(gl_exts)));
993
994 setup_sample_modes();
995+
996+ fake_devices.add_standard_drm_devices();
997 }
998
999 std::shared_ptr<mgg::GBMPlatform> create_platform()
1000@@ -110,6 +115,8 @@
1001 std::vector<drmModeModeInfo> modes0;
1002 std::vector<mg::DisplayConfigurationMode> conf_modes0;
1003 std::vector<drmModeModeInfo> modes_empty;
1004+
1005+ mtf::UdevEnvironment fake_devices;
1006 };
1007
1008 }
1009
1010=== modified file 'tests/unit-tests/graphics/gbm/test_gbm_display_multi_monitor.cpp'
1011--- tests/unit-tests/graphics/gbm/test_gbm_display_multi_monitor.cpp 2013-05-20 15:55:48 +0000
1012+++ tests/unit-tests/graphics/gbm/test_gbm_display_multi_monitor.cpp 2013-07-02 07:08:27 +0000
1013@@ -25,6 +25,8 @@
1014 #include "mir/graphics/null_display_report.h"
1015 #include "mir_test_doubles/null_virtual_terminal.h"
1016
1017+#include "mir_test_framework/udev_environment.h"
1018+
1019 #include "mir_test_doubles/mock_drm.h"
1020 #include "mir_test_doubles/mock_gbm.h"
1021
1022@@ -35,6 +37,7 @@
1023 namespace mgg = mir::graphics::gbm;
1024 namespace geom = mir::geometry;
1025 namespace mtd = mir::test::doubles;
1026+namespace mtf = mir::mir_test_framework;
1027
1028 namespace
1029 {
1030@@ -68,6 +71,8 @@
1031 .Times(AtLeast(0));
1032 EXPECT_CALL(mock_gbm, gbm_device_get_fd(_))
1033 .Times(AtLeast(0));
1034+
1035+ fake_devices.add_standard_drm_devices();
1036 }
1037
1038 std::shared_ptr<mgg::GBMPlatform> create_platform()
1039@@ -131,6 +136,8 @@
1040 std::vector<uint32_t> crtc_ids;
1041 std::vector<uint32_t> encoder_ids;
1042 std::vector<uint32_t> connector_ids;
1043+
1044+ mtf::UdevEnvironment fake_devices;
1045 };
1046
1047 }
1048
1049=== modified file 'tests/unit-tests/graphics/gbm/test_gbm_platform.cpp'
1050--- tests/unit-tests/graphics/gbm/test_gbm_platform.cpp 2013-05-30 03:50:54 +0000
1051+++ tests/unit-tests/graphics/gbm/test_gbm_platform.cpp 2013-07-02 07:08:27 +0000
1052@@ -28,6 +28,8 @@
1053
1054 #include <gtest/gtest.h>
1055
1056+#include "mir_test_framework/udev_environment.h"
1057+
1058 #include "mir_test_doubles/mock_drm.h"
1059 #include "mir_test_doubles/mock_gbm.h"
1060
1061@@ -42,6 +44,7 @@
1062 namespace mg = mir::graphics;
1063 namespace mgg = mir::graphics::gbm;
1064 namespace mtd = mir::test::doubles;
1065+namespace mtf = mir::mir_test_framework;
1066
1067 namespace
1068 {
1069@@ -53,6 +56,7 @@
1070 {
1071 ::testing::Mock::VerifyAndClearExpectations(&mock_drm);
1072 ::testing::Mock::VerifyAndClearExpectations(&mock_gbm);
1073+ fake_devices.add_standard_drm_devices();
1074 }
1075
1076 std::shared_ptr<mg::Platform> create_platform()
1077@@ -64,6 +68,7 @@
1078
1079 ::testing::NiceMock<mtd::MockDRM> mock_drm;
1080 ::testing::NiceMock<mtd::MockGBM> mock_gbm;
1081+ mtf::UdevEnvironment fake_devices;
1082 };
1083 }
1084
1085
1086=== modified file 'tests/unit-tests/graphics/test_display.cpp'
1087--- tests/unit-tests/graphics/test_display.cpp 2013-06-12 10:27:50 +0000
1088+++ tests/unit-tests/graphics/test_display.cpp 2013-07-02 07:08:27 +0000
1089@@ -26,6 +26,7 @@
1090 #include "mir_test_doubles/mock_gbm.h"
1091 #include "mir_test_doubles/null_virtual_terminal.h"
1092 #include "src/server/graphics/gbm/gbm_platform.h"
1093+#include "mir_test_framework/udev_environment.h"
1094 #else
1095 #include "src/server/graphics/android/android_framebuffer_window_query.h"
1096 #include "src/server/graphics/android/android_display.h"
1097@@ -38,6 +39,9 @@
1098
1099 namespace mg = mir::graphics;
1100 namespace mtd = mir::test::doubles;
1101+#ifndef ANDROID
1102+namespace mtf = mir::mir_test_framework;
1103+#endif
1104
1105 class DisplayTest : public ::testing::Test
1106 {
1107@@ -58,6 +62,10 @@
1108 .WillByDefault(Return(egl_exts));
1109 ON_CALL(mock_gl, glGetString(GL_EXTENSIONS))
1110 .WillByDefault(Return(reinterpret_cast<const GLubyte*>(gl_exts)));
1111+
1112+#ifndef ANDROID
1113+ fake_devices.add_standard_drm_devices();
1114+#endif
1115 }
1116
1117 std::shared_ptr<mg::Display> create_display()
1118@@ -93,6 +101,7 @@
1119 #else
1120 ::testing::NiceMock<mtd::MockDRM> mock_drm;
1121 ::testing::NiceMock<mtd::MockGBM> mock_gbm;
1122+ mtf::UdevEnvironment fake_devices;
1123 #endif
1124 };
1125
1126
1127=== modified file 'tests/unit-tests/graphics/test_graphics_platform.cpp'
1128--- tests/unit-tests/graphics/test_graphics_platform.cpp 2013-06-25 03:25:49 +0000
1129+++ tests/unit-tests/graphics/test_graphics_platform.cpp 2013-07-02 07:08:27 +0000
1130@@ -27,6 +27,7 @@
1131 #include "mir_test_doubles/mock_gbm.h"
1132 #include "mir_test_doubles/null_virtual_terminal.h"
1133 #include "src/server/graphics/gbm/gbm_platform.h"
1134+#include "mir_test_framework/udev_environment.h"
1135 #else
1136 #include "mir_test_doubles/mock_android_hw.h"
1137 #endif
1138@@ -44,6 +45,9 @@
1139 namespace geom = mir::geometry;
1140 namespace mtd = mir::test::doubles;
1141 namespace mo = mir::options;
1142+#ifndef ANDROID
1143+namespace mtf = mir::mir_test_framework;
1144+#endif
1145
1146 class GraphicsPlatform : public ::testing::Test
1147 {
1148@@ -71,6 +75,8 @@
1149 .WillByDefault(Return(reinterpret_cast<func_ptr_t>(eglDestroyImageKHR)));
1150 ON_CALL(mock_egl, eglGetProcAddress(StrEq("glEGLImageTargetTexture2DOES")))
1151 .WillByDefault(Return(reinterpret_cast<func_ptr_t>(glEGLImageTargetTexture2DOES)));
1152+
1153+ fake_devices.add_standard_drm_devices();
1154 #endif
1155 }
1156
1157@@ -95,6 +101,7 @@
1158 #else
1159 ::testing::NiceMock<mtd::MockDRM> mock_drm;
1160 ::testing::NiceMock<mtd::MockGBM> mock_gbm;
1161+ mtf::UdevEnvironment fake_devices;
1162 #endif
1163 };
1164
1165
1166=== modified file 'tools/setup-partial-armhf-chroot.sh'
1167--- tools/setup-partial-armhf-chroot.sh 2013-06-17 09:31:24 +0000
1168+++ tools/setup-partial-armhf-chroot.sh 2013-07-02 07:08:27 +0000
1169@@ -62,6 +62,7 @@
1170 libboost-program-options1.49.0
1171 libhybris
1172 libhybris-dev
1173+ libandroid-properties1
1174 libgflags2
1175 libgflags-dev
1176 libgoogle-glog-dev

Subscribers

People subscribed via source and target branches