Branch data Line data Source code
1 : : /* SPDX-License-Identifier: LGPL-2.1+ */
2 : :
3 : : #include <stdbool.h>
4 : : #include <unistd.h>
5 : :
6 : : #include "sd-device.h"
7 : : #include "sd-event.h"
8 : :
9 : : #include "device-monitor-private.h"
10 : : #include "device-private.h"
11 : : #include "device-util.h"
12 : : #include "macro.h"
13 : : #include "string-util.h"
14 : : #include "tests.h"
15 : : #include "util.h"
16 : : #include "virt.h"
17 : :
18 : 0 : static int monitor_handler(sd_device_monitor *m, sd_device *d, void *userdata) {
19 : 0 : const char *s, *syspath = userdata;
20 : :
21 [ # # ]: 0 : assert_se(sd_device_get_syspath(d, &s) >= 0);
22 [ # # ]: 0 : assert_se(streq(s, syspath));
23 : :
24 : 0 : return sd_event_exit(sd_device_monitor_get_event(m), 100);
25 : : }
26 : :
27 : 0 : static int test_receive_device_fail(void) {
28 : 0 : _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *monitor_server = NULL, *monitor_client = NULL;
29 : 0 : _cleanup_(sd_device_unrefp) sd_device *loopback = NULL;
30 : : const char *syspath;
31 : : int r;
32 : :
33 [ # # ]: 0 : log_info("/* %s */", __func__);
34 : :
35 : : /* Try to send device with invalid action and without seqnum. */
36 [ # # ]: 0 : assert_se(sd_device_new_from_syspath(&loopback, "/sys/class/net/lo") >= 0);
37 [ # # ]: 0 : assert_se(device_add_property(loopback, "ACTION", "hoge") >= 0);
38 : :
39 [ # # ]: 0 : assert_se(sd_device_get_syspath(loopback, &syspath) >= 0);
40 : :
41 [ # # ]: 0 : assert_se(device_monitor_new_full(&monitor_server, MONITOR_GROUP_NONE, -1) >= 0);
42 [ # # ]: 0 : assert_se(sd_device_monitor_start(monitor_server, NULL, NULL) >= 0);
43 [ # # ]: 0 : assert_se(sd_event_source_set_description(sd_device_monitor_get_event_source(monitor_server), "sender") >= 0);
44 : :
45 [ # # ]: 0 : assert_se(device_monitor_new_full(&monitor_client, MONITOR_GROUP_NONE, -1) >= 0);
46 [ # # ]: 0 : assert_se(device_monitor_allow_unicast_sender(monitor_client, monitor_server) >= 0);
47 [ # # ]: 0 : assert_se(sd_device_monitor_start(monitor_client, monitor_handler, (void *) syspath) >= 0);
48 [ # # ]: 0 : assert_se(sd_event_source_set_description(sd_device_monitor_get_event_source(monitor_client), "receiver") >= 0);
49 : :
50 : : /* Do not use assert_se() here. */
51 : 0 : r = device_monitor_send_device(monitor_server, monitor_client, loopback);
52 [ # # ]: 0 : if (r < 0)
53 [ # # ]: 0 : return log_error_errno(r, "Failed to send loopback device: %m");
54 : :
55 [ # # ]: 0 : assert_se(sd_event_run(sd_device_monitor_get_event(monitor_client), 0) >= 0);
56 : :
57 : 0 : return 0;
58 : : }
59 : :
60 : 0 : static void test_send_receive_one(sd_device *device, bool subsystem_filter, bool tag_filter, bool use_bpf) {
61 : 0 : _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *monitor_server = NULL, *monitor_client = NULL;
62 : 0 : const char *syspath, *subsystem, *tag, *devtype = NULL;
63 : :
64 [ # # # # : 0 : log_device_info(device, "/* %s(subsystem_filter=%s, tag_filter=%s, use_bpf=%s) */", __func__,
# # ]
65 : : true_false(subsystem_filter), true_false(tag_filter), true_false(use_bpf));
66 : :
67 [ # # ]: 0 : assert_se(sd_device_get_syspath(device, &syspath) >= 0);
68 : :
69 [ # # ]: 0 : assert_se(device_monitor_new_full(&monitor_server, MONITOR_GROUP_NONE, -1) >= 0);
70 [ # # ]: 0 : assert_se(sd_device_monitor_start(monitor_server, NULL, NULL) >= 0);
71 [ # # ]: 0 : assert_se(sd_event_source_set_description(sd_device_monitor_get_event_source(monitor_server), "sender") >= 0);
72 : :
73 [ # # ]: 0 : assert_se(device_monitor_new_full(&monitor_client, MONITOR_GROUP_NONE, -1) >= 0);
74 [ # # ]: 0 : assert_se(device_monitor_allow_unicast_sender(monitor_client, monitor_server) >= 0);
75 [ # # ]: 0 : assert_se(sd_device_monitor_start(monitor_client, monitor_handler, (void *) syspath) >= 0);
76 [ # # ]: 0 : assert_se(sd_event_source_set_description(sd_device_monitor_get_event_source(monitor_client), "receiver") >= 0);
77 : :
78 [ # # ]: 0 : if (subsystem_filter) {
79 [ # # ]: 0 : assert_se(sd_device_get_subsystem(device, &subsystem) >= 0);
80 : 0 : (void) sd_device_get_devtype(device, &devtype);
81 [ # # ]: 0 : assert_se(sd_device_monitor_filter_add_match_subsystem_devtype(monitor_client, subsystem, devtype) >= 0);
82 : : }
83 : :
84 [ # # ]: 0 : if (tag_filter)
85 [ # # ]: 0 : FOREACH_DEVICE_TAG(device, tag)
86 [ # # ]: 0 : assert_se(sd_device_monitor_filter_add_match_tag(monitor_client, tag) >= 0);
87 : :
88 [ # # # # : 0 : if ((subsystem_filter || tag_filter) && use_bpf)
# # ]
89 [ # # ]: 0 : assert_se(sd_device_monitor_filter_update(monitor_client) >= 0);
90 : :
91 [ # # ]: 0 : assert_se(device_monitor_send_device(monitor_server, monitor_client, device) >= 0);
92 [ # # ]: 0 : assert_se(sd_event_loop(sd_device_monitor_get_event(monitor_client)) == 100);
93 : 0 : }
94 : :
95 : 0 : static void test_subsystem_filter(sd_device *device) {
96 : 0 : _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *monitor_server = NULL, *monitor_client = NULL;
97 : 0 : _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
98 : : const char *syspath, *subsystem, *p, *s;
99 : : sd_device *d;
100 : :
101 [ # # ]: 0 : log_info("/* %s */", __func__);
102 : :
103 [ # # ]: 0 : assert_se(sd_device_get_syspath(device, &syspath) >= 0);
104 [ # # ]: 0 : assert_se(sd_device_get_subsystem(device, &subsystem) >= 0);
105 : :
106 [ # # ]: 0 : assert_se(device_monitor_new_full(&monitor_server, MONITOR_GROUP_NONE, -1) >= 0);
107 [ # # ]: 0 : assert_se(sd_device_monitor_start(monitor_server, NULL, NULL) >= 0);
108 [ # # ]: 0 : assert_se(sd_event_source_set_description(sd_device_monitor_get_event_source(monitor_server), "sender") >= 0);
109 : :
110 [ # # ]: 0 : assert_se(device_monitor_new_full(&monitor_client, MONITOR_GROUP_NONE, -1) >= 0);
111 [ # # ]: 0 : assert_se(device_monitor_allow_unicast_sender(monitor_client, monitor_server) >= 0);
112 [ # # ]: 0 : assert_se(sd_device_monitor_filter_add_match_subsystem_devtype(monitor_client, subsystem, NULL) >= 0);
113 [ # # ]: 0 : assert_se(sd_device_monitor_start(monitor_client, monitor_handler, (void *) syspath) >= 0);
114 [ # # ]: 0 : assert_se(sd_event_source_set_description(sd_device_monitor_get_event_source(monitor_client), "receiver") >= 0);
115 : :
116 [ # # ]: 0 : assert_se(sd_device_enumerator_new(&e) >= 0);
117 [ # # ]: 0 : assert_se(sd_device_enumerator_add_match_subsystem(e, subsystem, false) >= 0);
118 [ # # ]: 0 : FOREACH_DEVICE(e, d) {
119 [ # # ]: 0 : assert_se(sd_device_get_syspath(d, &p) >= 0);
120 [ # # ]: 0 : assert_se(sd_device_get_subsystem(d, &s) >= 0);
121 : :
122 [ # # ]: 0 : log_info("Sending device subsystem:%s syspath:%s", s, p);
123 [ # # ]: 0 : assert_se(device_monitor_send_device(monitor_server, monitor_client, d) >= 0);
124 : : }
125 : :
126 [ # # ]: 0 : log_info("Sending device subsystem:%s syspath:%s", subsystem, syspath);
127 [ # # ]: 0 : assert_se(device_monitor_send_device(monitor_server, monitor_client, device) >= 0);
128 [ # # ]: 0 : assert_se(sd_event_loop(sd_device_monitor_get_event(monitor_client)) == 100);
129 : 0 : }
130 : :
131 : 0 : static void test_sd_device_monitor_filter_remove(sd_device *device) {
132 : 0 : _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *monitor_server = NULL, *monitor_client = NULL;
133 : : const char *syspath;
134 : :
135 [ # # # # : 0 : log_device_info(device, "/* %s */", __func__);
# # ]
136 : :
137 [ # # ]: 0 : assert_se(sd_device_get_syspath(device, &syspath) >= 0);
138 : :
139 [ # # ]: 0 : assert_se(device_monitor_new_full(&monitor_server, MONITOR_GROUP_NONE, -1) >= 0);
140 [ # # ]: 0 : assert_se(sd_device_monitor_start(monitor_server, NULL, NULL) >= 0);
141 [ # # ]: 0 : assert_se(sd_event_source_set_description(sd_device_monitor_get_event_source(monitor_server), "sender") >= 0);
142 : :
143 [ # # ]: 0 : assert_se(device_monitor_new_full(&monitor_client, MONITOR_GROUP_NONE, -1) >= 0);
144 [ # # ]: 0 : assert_se(device_monitor_allow_unicast_sender(monitor_client, monitor_server) >= 0);
145 [ # # ]: 0 : assert_se(sd_device_monitor_start(monitor_client, monitor_handler, (void *) syspath) >= 0);
146 [ # # ]: 0 : assert_se(sd_event_source_set_description(sd_device_monitor_get_event_source(monitor_client), "receiver") >= 0);
147 : :
148 [ # # ]: 0 : assert_se(sd_device_monitor_filter_add_match_subsystem_devtype(monitor_client, "hoge", NULL) >= 0);
149 [ # # ]: 0 : assert_se(sd_device_monitor_filter_update(monitor_client) >= 0);
150 : :
151 [ # # ]: 0 : assert_se(device_monitor_send_device(monitor_server, monitor_client, device) >= 0);
152 [ # # ]: 0 : assert_se(sd_event_run(sd_device_monitor_get_event(monitor_client), 0) >= 0);
153 : :
154 [ # # ]: 0 : assert_se(sd_device_monitor_filter_remove(monitor_client) >= 0);
155 : :
156 [ # # ]: 0 : assert_se(device_monitor_send_device(monitor_server, monitor_client, device) >= 0);
157 [ # # ]: 0 : assert_se(sd_event_loop(sd_device_monitor_get_event(monitor_client)) == 100);
158 : 0 : }
159 : :
160 : 0 : static void test_device_copy_properties(sd_device *device) {
161 : 0 : _cleanup_(sd_device_unrefp) sd_device *copy = NULL;
162 : :
163 [ # # ]: 0 : assert_se(device_shallow_clone(device, ©) >= 0);
164 [ # # ]: 0 : assert_se(device_copy_properties(copy, device) >= 0);
165 : :
166 : 0 : test_send_receive_one(copy, false, false, false);
167 : 0 : }
168 : :
169 : 4 : int main(int argc, char *argv[]) {
170 : 4 : _cleanup_(sd_device_unrefp) sd_device *loopback = NULL, *sda = NULL;
171 : : int r;
172 : :
173 : 4 : test_setup_logging(LOG_INFO);
174 : :
175 [ + - ]: 4 : if (getuid() != 0)
176 : 4 : return log_tests_skipped("not root");
177 : :
178 : 0 : r = test_receive_device_fail();
179 [ # # ]: 0 : if (r < 0) {
180 [ # # # # ]: 0 : assert_se(r == -EPERM && detect_container() > 0);
181 : 0 : return log_tests_skipped("Running in container? Skipping remaining tests");
182 : : }
183 : :
184 [ # # ]: 0 : assert_se(sd_device_new_from_syspath(&loopback, "/sys/class/net/lo") >= 0);
185 [ # # ]: 0 : assert_se(device_add_property(loopback, "ACTION", "add") >= 0);
186 [ # # ]: 0 : assert_se(device_add_property(loopback, "SEQNUM", "10") >= 0);
187 : :
188 : 0 : test_send_receive_one(loopback, false, false, false);
189 : 0 : test_send_receive_one(loopback, true, false, false);
190 : 0 : test_send_receive_one(loopback, false, true, false);
191 : 0 : test_send_receive_one(loopback, true, true, false);
192 : 0 : test_send_receive_one(loopback, true, false, true);
193 : 0 : test_send_receive_one(loopback, false, true, true);
194 : 0 : test_send_receive_one(loopback, true, true, true);
195 : :
196 : 0 : test_subsystem_filter(loopback);
197 : 0 : test_sd_device_monitor_filter_remove(loopback);
198 : 0 : test_device_copy_properties(loopback);
199 : :
200 : 0 : r = sd_device_new_from_subsystem_sysname(&sda, "block", "sda");
201 [ # # ]: 0 : if (r < 0) {
202 [ # # ]: 0 : log_info_errno(r, "Failed to create sd_device for sda, skipping remaining tests: %m");
203 : 0 : return 0;
204 : : }
205 : :
206 [ # # ]: 0 : assert_se(device_add_property(sda, "ACTION", "change") >= 0);
207 [ # # ]: 0 : assert_se(device_add_property(sda, "SEQNUM", "11") >= 0);
208 : :
209 : 0 : test_send_receive_one(sda, false, false, false);
210 : 0 : test_send_receive_one(sda, true, false, false);
211 : 0 : test_send_receive_one(sda, false, true, false);
212 : 0 : test_send_receive_one(sda, true, true, false);
213 : 0 : test_send_receive_one(sda, true, false, true);
214 : 0 : test_send_receive_one(sda, false, true, true);
215 : 0 : test_send_receive_one(sda, true, true, true);
216 : :
217 : 0 : return 0;
218 : : }
|