34
34
namespace mg=mir::graphics;
35
namespace mgg=mir::graphics::gbm;
35
namespace mgm=mir::graphics::mesa;
36
36
namespace mtf=mir::mir_test_framework;
38
38
class UdevWrapperTest : public ::testing::Test
49
49
udev_environment.add_device("drm", "fakedev4", NULL, {}, {});
50
50
udev_environment.add_device("drm", "fakedev5", NULL, {}, {});
52
auto ctx = std::make_shared<mgg::UdevContext>();
53
mgg::UdevEnumerator enumerator(ctx);
52
auto ctx = std::make_shared<mgm::UdevContext>();
53
mgm::UdevEnumerator enumerator(ctx);
55
55
enumerator.scan_devices();
73
73
udev_environment.add_device("usb", "fakeusb1", NULL, {}, {});
74
74
udev_environment.add_device("usb", "fakeusb2", NULL, {}, {});
76
auto ctx = std::make_shared<mgg::UdevContext>();
77
mgg::UdevEnumerator devices(ctx);
76
auto ctx = std::make_shared<mgm::UdevContext>();
77
mgm::UdevEnumerator devices(ctx);
79
79
devices.match_subsystem("drm");
80
80
devices.scan_devices();
89
89
auto sysfs_path = udev_environment.add_device("drm", "card0", NULL, {}, {"DEVTYPE", "drm_minor"});
91
mgg::UdevDevice dev(mgg::UdevContext(), sysfs_path);
91
mgm::UdevDevice dev(mgm::UdevContext(), sysfs_path);
92
92
ASSERT_STREQ("drm_minor", dev.devtype());
97
97
auto sysfs_path = udev_environment.add_device("drm", "card0", NULL, {}, {});
99
mgg::UdevDevice dev(mgg::UdevContext(), sysfs_path);
99
mgm::UdevDevice dev(mgm::UdevContext(), sysfs_path);
100
100
ASSERT_STREQ("/devices/card0", dev.devpath());
105
105
auto sysfs_path = udev_environment.add_device("drm", "card0", NULL, {}, {"DEVNAME", "/dev/dri/card0"});
107
mgg::UdevDevice card0(mgg::UdevContext(), sysfs_path);
107
mgm::UdevDevice card0(mgm::UdevContext(), sysfs_path);
109
109
ASSERT_STREQ("/dev/dri/card0", card0.devnode());
114
114
auto sysfs_path = udev_environment.add_device("drm", "card0", NULL, {}, {});
116
mgg::UdevDevice dev(mgg::UdevContext(), sysfs_path);
116
mgm::UdevDevice dev(mgm::UdevContext(), sysfs_path);
118
118
EXPECT_TRUE(dev == dev);
123
123
auto sysfs_path = udev_environment.add_device("drm", "card0", NULL, {}, {});
125
mgg::UdevContext ctx;
126
mgg::UdevDevice same_one(ctx, sysfs_path);
127
mgg::UdevDevice same_two(ctx, sysfs_path);
125
mgm::UdevContext ctx;
126
mgm::UdevDevice same_one(ctx, sysfs_path);
127
mgm::UdevDevice same_two(ctx, sysfs_path);
129
129
EXPECT_TRUE(same_one == same_two);
130
130
EXPECT_TRUE(same_two == same_one);
135
135
auto path_one = udev_environment.add_device("drm", "card0", NULL, {}, {});
136
136
auto path_two = udev_environment.add_device("drm", "card1", NULL, {}, {});
138
mgg::UdevContext ctx;
139
mgg::UdevDevice dev_one(ctx, path_one);
140
mgg::UdevDevice dev_two(ctx, path_two);
138
mgm::UdevContext ctx;
139
mgm::UdevDevice dev_one(ctx, path_one);
140
mgm::UdevDevice dev_two(ctx, path_two);
142
142
EXPECT_FALSE(dev_one == dev_two);
143
143
EXPECT_FALSE(dev_two == dev_one);
148
148
auto path_one = udev_environment.add_device("drm", "card0", NULL, {}, {});
149
149
auto path_two = udev_environment.add_device("drm", "card1", NULL, {}, {});
151
mgg::UdevContext ctx;
152
mgg::UdevDevice dev_one(ctx, path_one);
153
mgg::UdevDevice dev_two(ctx, path_two);
151
mgm::UdevContext ctx;
152
mgm::UdevDevice dev_one(ctx, path_one);
153
mgm::UdevDevice dev_two(ctx, path_two);
155
155
EXPECT_TRUE(dev_one != dev_two);
156
EXPECT_TRUE(dev_two != dev_one);
156
EXPECT_TRUE(dev_two != dev_one);
159
159
TEST_F(UdevWrapperTest, UdevDeviceSameDeviceIsNotNotEqual)
161
161
auto sysfs_path = udev_environment.add_device("drm", "card0", NULL, {}, {});
163
mgg::UdevContext ctx;
164
mgg::UdevDevice same_one(ctx, sysfs_path);
165
mgg::UdevDevice same_two(ctx, sysfs_path);
163
mgm::UdevContext ctx;
164
mgm::UdevDevice same_one(ctx, sysfs_path);
165
mgm::UdevDevice same_two(ctx, sysfs_path);
167
167
EXPECT_FALSE(same_one != same_two);
168
168
EXPECT_FALSE(same_two != same_one);
177
177
udev_environment.add_device("drm", "card0-VGA1", "/sys/devices/card0", {}, {});
178
178
udev_environment.add_device("drm", "card0-LVDS1", "/sys/devices/card0", {}, {});
180
auto ctx = std::make_shared<mgg::UdevContext>();
180
auto ctx = std::make_shared<mgm::UdevContext>();
182
mgg::UdevEnumerator devices(ctx);
183
mgg::UdevDevice drm_device(*ctx, card0_syspath);
182
mgm::UdevEnumerator devices(ctx);
183
mgm::UdevDevice drm_device(*ctx, card0_syspath);
185
185
devices.match_parent(drm_device);
186
186
devices.scan_devices();
197
197
TEST_F(UdevWrapperTest, EnumeratorThrowsLogicErrorIfIteratedBeforeScanned)
199
auto ctx = std::make_shared<mgg::UdevContext>();
199
auto ctx = std::make_shared<mgm::UdevContext>();
201
mgg::UdevEnumerator devices(ctx);
201
mgm::UdevEnumerator devices(ctx);
203
203
EXPECT_THROW({ devices.begin(); },
204
204
std::logic_error);
207
207
TEST_F(UdevWrapperTest, EnumeratorLogicErrorHasSensibleMessage)
209
auto ctx = std::make_shared<mgg::UdevContext>();
209
auto ctx = std::make_shared<mgm::UdevContext>();
211
mgg::UdevEnumerator devices(ctx);
211
mgm::UdevEnumerator devices(ctx);
212
212
std::string error_msg;
225
225
TEST_F(UdevWrapperTest, EnumeratorEnumeratesEmptyList)
227
auto ctx = std::make_shared<mgg::UdevContext>();
227
auto ctx = std::make_shared<mgm::UdevContext>();
229
mgg::UdevEnumerator devices(ctx);
229
mgm::UdevEnumerator devices(ctx);
231
231
devices.scan_devices();
241
241
udev_environment.add_device("drm", "card0-LVDS1", drm_sysfspath.c_str(), {}, {});
242
242
udev_environment.add_device("drm", "card1", NULL, {}, {});
244
auto ctx = std::make_shared<mgg::UdevContext>();
244
auto ctx = std::make_shared<mgm::UdevContext>();
246
mgg::UdevEnumerator devices(ctx);
246
mgm::UdevEnumerator devices(ctx);
248
248
devices.match_sysname("card[0-9]");
249
249
devices.scan_devices();
257
257
TEST_F(UdevWrapperTest, UdevMonitorDoesNotTriggerBeforeEnabling)
259
auto monitor = mgg::UdevMonitor(mgg::UdevContext());
259
auto monitor = mgm::UdevMonitor(mgm::UdevContext());
260
260
bool event_handler_called = false;
262
262
udev_environment.add_device("drm", "control64D", NULL, {}, {});
264
monitor.process_events([&event_handler_called](mgg::UdevMonitor::EventType,
265
mgg::UdevDevice const&) {event_handler_called = true;});
264
monitor.process_events([&event_handler_called](mgm::UdevMonitor::EventType,
265
mgm::UdevDevice const&) {event_handler_called = true;});
267
267
EXPECT_FALSE(event_handler_called);
270
270
TEST_F(UdevWrapperTest, UdevMonitorTriggersAfterEnabling)
272
auto monitor = mgg::UdevMonitor(mgg::UdevContext());
272
auto monitor = mgm::UdevMonitor(mgm::UdevContext());
273
273
bool event_handler_called = false;
275
275
monitor.enable();
277
277
udev_environment.add_device("drm", "control64D", NULL, {}, {});
279
monitor.process_events([&event_handler_called](mgg::UdevMonitor::EventType,
280
mgg::UdevDevice const&) {event_handler_called = true;});
279
monitor.process_events([&event_handler_called](mgm::UdevMonitor::EventType,
280
mgm::UdevDevice const&) {event_handler_called = true;});
282
282
EXPECT_TRUE(event_handler_called);
285
285
TEST_F(UdevWrapperTest, UdevMonitorSendsRemoveEvent)
287
auto monitor = mgg::UdevMonitor(mgg::UdevContext());
287
auto monitor = mgm::UdevMonitor(mgm::UdevContext());
288
288
bool remove_event_received = false;
290
290
monitor.enable();
293
293
udev_environment.remove_device(test_sysfspath);
295
295
monitor.process_events([&remove_event_received]
296
(mgg::UdevMonitor::EventType action, mgg::UdevDevice const&)
296
(mgm::UdevMonitor::EventType action, mgm::UdevDevice const&)
298
if (action == mgg::UdevMonitor::EventType::REMOVED)
298
if (action == mgm::UdevMonitor::EventType::REMOVED)
299
299
remove_event_received = true;
305
305
TEST_F(UdevWrapperTest, UdevMonitorSendsChangedEvent)
307
auto monitor = mgg::UdevMonitor(mgg::UdevContext());
307
auto monitor = mgm::UdevMonitor(mgm::UdevContext());
308
308
bool changed_event_received = false;
310
310
monitor.enable();
313
313
udev_environment.emit_device_changed(test_sysfspath);
315
315
monitor.process_events([&changed_event_received]
316
(mgg::UdevMonitor::EventType action, mgg::UdevDevice const&)
316
(mgm::UdevMonitor::EventType action, mgm::UdevDevice const&)
318
if (action == mgg::UdevMonitor::EventType::CHANGED)
318
if (action == mgm::UdevMonitor::EventType::CHANGED)
319
319
changed_event_received = true;
322
EXPECT_TRUE(changed_event_received);
322
EXPECT_TRUE(changed_event_received);
325
325
TEST_F(UdevWrapperTest, UdevMonitorEventHasCorrectDeviceDetails)
327
mgg::UdevContext ctx;
327
mgm::UdevContext ctx;
329
auto monitor = mgg::UdevMonitor(ctx);
329
auto monitor = mgm::UdevMonitor(ctx);
330
330
bool event_handler_called = false;
332
332
monitor.enable();
334
334
auto sysfs_path = udev_environment.add_device("drm", "control64D", NULL, {}, {});
335
mgg::UdevDevice device(ctx, sysfs_path);
335
mgm::UdevDevice device(ctx, sysfs_path);
337
337
monitor.process_events(
338
[&event_handler_called, &device](mgg::UdevMonitor::EventType, mgg::UdevDevice const& dev)
338
[&event_handler_called, &device](mgm::UdevMonitor::EventType, mgm::UdevDevice const& dev)
340
340
event_handler_called = true;
341
341
EXPECT_EQ(device, dev);
359
359
ASSERT_GT(poll(&fds, 1, 0), 0);
361
EXPECT_TRUE(fds.revents & POLLIN);
361
EXPECT_TRUE(fds.revents & POLLIN);
364
364
TEST_F(UdevWrapperTest, UdevMonitorFdIsUnreadableAfterProcessingEvents)
366
auto monitor = mgg::UdevMonitor(mgg::UdevContext());
366
auto monitor = mgm::UdevMonitor(mgm::UdevContext());
368
368
monitor.enable();
376
376
fds.events = POLLIN;
378
378
ASSERT_GT(poll(&fds, 1, 0), 0);
379
ASSERT_TRUE(fds.revents & POLLIN);
379
ASSERT_TRUE(fds.revents & POLLIN);
381
monitor.process_events([](mgg::UdevMonitor::EventType, mgg::UdevDevice const&){});
381
monitor.process_events([](mgm::UdevMonitor::EventType, mgm::UdevDevice const&){});
383
383
EXPECT_EQ(poll(&fds, 1, 0), 0);
386
386
TEST_F(UdevWrapperTest, UdevMonitorFiltersByPathAndType)
388
mgg::UdevContext ctx;
388
mgm::UdevContext ctx;
390
auto monitor = mgg::UdevMonitor(ctx);
390
auto monitor = mgm::UdevMonitor(ctx);
391
391
bool event_received = false;
393
393
monitor.filter_by_subsystem_and_type("drm", "drm_minor");
395
395
monitor.enable();
397
397
auto test_sysfspath = udev_environment.add_device("drm", "control64D", NULL, {}, {"DEVTYPE", "drm_minor"});
398
mgg::UdevDevice minor_device(ctx, test_sysfspath);
398
mgm::UdevDevice minor_device(ctx, test_sysfspath);
399
399
udev_environment.add_device("drm", "card0-LVDS1", test_sysfspath.c_str(), {}, {});
400
400
udev_environment.add_device("usb", "mightymouse", NULL, {}, {});
402
402
monitor.process_events([&event_received, &minor_device]
403
(mgg::UdevMonitor::EventType, mgg::UdevDevice const& dev)
403
(mgm::UdevMonitor::EventType, mgm::UdevDevice const& dev)
405
405
EXPECT_EQ(dev, minor_device);
406
406
event_received = true;
412
412
TEST_F(UdevWrapperTest, UdevMonitorFiltersAreAdditive)
414
mgg::UdevContext ctx;
414
mgm::UdevContext ctx;
416
auto monitor = mgg::UdevMonitor(ctx);
416
auto monitor = mgm::UdevMonitor(ctx);
417
417
bool usb_event_received = false, drm_event_recieved = false;
419
419
monitor.filter_by_subsystem_and_type("drm", "drm_minor");
422
422
monitor.enable();
424
424
auto drm_sysfspath = udev_environment.add_device("drm", "control64D", NULL, {}, {"DEVTYPE", "drm_minor"});
425
mgg::UdevDevice drm_device(ctx, drm_sysfspath);
425
mgm::UdevDevice drm_device(ctx, drm_sysfspath);
426
426
udev_environment.add_device("drm", "card0-LVDS1", drm_sysfspath.c_str(), {}, {});
427
427
auto usb_sysfspath = udev_environment.add_device("usb", "mightymouse", NULL, {}, {"DEVTYPE", "hid"});
428
mgg::UdevDevice usb_device(ctx, usb_sysfspath);
428
mgm::UdevDevice usb_device(ctx, usb_sysfspath);
430
430
monitor.process_events([&drm_event_recieved, &drm_device, &usb_event_received, &usb_device]
431
(mgg::UdevMonitor::EventType, mgg::UdevDevice const& dev)
431
(mgm::UdevMonitor::EventType, mgm::UdevDevice const& dev)
433
433
if (dev == drm_device)
434
434
drm_event_recieved = true;
443
443
TEST_F(UdevWrapperTest, UdevMonitorFiltersApplyAfterEnable)
445
mgg::UdevContext ctx;
445
mgm::UdevContext ctx;
447
auto monitor = mgg::UdevMonitor(ctx);
447
auto monitor = mgm::UdevMonitor(ctx);
448
448
bool event_received = false;
450
450
monitor.enable();
452
452
monitor.filter_by_subsystem_and_type("drm", "drm_minor");
454
454
auto test_sysfspath = udev_environment.add_device("drm", "control64D", NULL, {}, {"DEVTYPE", "drm_minor"});
455
mgg::UdevDevice minor_device(ctx, test_sysfspath);
455
mgm::UdevDevice minor_device(ctx, test_sysfspath);
456
456
udev_environment.add_device("drm", "card0-LVDS1", test_sysfspath.c_str(), {}, {});
457
457
udev_environment.add_device("usb", "mightymouse", NULL, {}, {});
459
459
monitor.process_events([&event_received, &minor_device]
460
(mgg::UdevMonitor::EventType, mgg::UdevDevice const& dev)
460
(mgm::UdevMonitor::EventType, mgm::UdevDevice const& dev)
462
462
EXPECT_EQ(dev, minor_device);
463
463
event_received = true;