master
go 1,139 lines 60.1 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 //go:build linux
4
5 package systemdunits
6
7 import (
8 "context"
9 "errors"
10 "fmt"
11 "os"
12 "path/filepath"
13 "slices"
14 "strings"
15 "testing"
16
17 "github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/collecttest"
18
19 "github.com/coreos/go-systemd/v22/dbus"
20 "github.com/stretchr/testify/assert"
21 "github.com/stretchr/testify/require"
22 )
23
24 var (
25 dataConfigJSON, _ = os.ReadFile("testdata/config.json")
26 dataConfigYAML, _ = os.ReadFile("testdata/config.yaml")
27 )
28
29 func Test_testDataIsValid(t *testing.T) {
30 for name, data := range map[string][]byte{
31 "dataConfigJSON": dataConfigJSON,
32 "dataConfigYAML": dataConfigYAML,
33 } {
34 require.NotNil(t, data, name)
35 }
36 }
37
38 func TestCollector_ConfigurationSerialize(t *testing.T) {
39 collecttest.TestConfigurationSerialize(t, &Collector{}, dataConfigJSON, dataConfigYAML)
40 }
41
42 func TestCollector_Init(t *testing.T) {
43 tests := map[string]struct {
44 config Config
45 wantFail bool
46 }{
47 "success on default config": {
48 config: New().Config,
49 },
50 "success when 'include' option set": {
51 config: Config{
52 Include: []string{"*"},
53 },
54 },
55 "fails when 'include' option not set": {
56 wantFail: true,
57 config: Config{Include: []string{}},
58 },
59 }
60
61 for name, test := range tests {
62 t.Run(name, func(t *testing.T) {
63 collr := New()
64 collr.Config = test.config
65
66 if test.wantFail {
67 assert.Error(t, collr.Init(context.Background()))
68 } else {
69 assert.NoError(t, collr.Init(context.Background()))
70 }
71 })
72 }
73 }
74
75 func TestCollector_Check(t *testing.T) {
76 tests := map[string]struct {
77 prepare func() *Collector
78 wantFail bool
79 }{
80 "success on systemd v230+": {
81 prepare: func() *Collector {
82 collr := New()
83 collr.Include = []string{"*"}
84 collr.client = prepareOKClient(230)
85 return collr
86 },
87 },
88 "success on systemd v230-": {
89 prepare: func() *Collector {
90 collr := New()
91 collr.Include = []string{"*"}
92 collr.client = prepareOKClient(220)
93 return collr
94 },
95 },
96 "fails when all unites are filtered": {
97 wantFail: true,
98 prepare: func() *Collector {
99 collr := New()
100 collr.Include = []string{"*.not_exists"}
101 collr.client = prepareOKClient(230)
102 return collr
103 },
104 },
105 "fails on error on connect": {
106 wantFail: true,
107 prepare: func() *Collector {
108 collr := New()
109 collr.client = prepareClientErrOnConnect()
110 return collr
111 },
112 },
113 "fails on error on get manager property": {
114 wantFail: true,
115 prepare: func() *Collector {
116 collr := New()
117 collr.client = prepareClientErrOnGetManagerProperty()
118 return collr
119 },
120 },
121 "fails on error on list units": {
122 wantFail: true,
123 prepare: func() *Collector {
124 collr := New()
125 collr.client = prepareClientErrOnListUnits()
126 return collr
127 },
128 },
129 }
130
131 for name, test := range tests {
132 t.Run(name, func(t *testing.T) {
133 collr := test.prepare()
134 require.NoError(t, collr.Init(context.Background()))
135
136 if test.wantFail {
137 assert.Error(t, collr.Check(context.Background()))
138 } else {
139 assert.NoError(t, collr.Check(context.Background()))
140 }
141 })
142 }
143 }
144
145 func TestCollector_Charts(t *testing.T) {
146 collr := New()
147 require.NoError(t, collr.Init(context.Background()))
148 assert.NotNil(t, collr.Charts())
149 }
150
151 func TestCollector_Cleanup(t *testing.T) {
152 collr := New()
153 collr.Include = []string{"*"}
154 client := prepareOKClient(230)
155 collr.client = client
156
157 require.NoError(t, collr.Init(context.Background()))
158 require.NotNil(t, collr.Collect(context.Background()))
159 conn := collr.conn
160 collr.Cleanup(context.Background())
161
162 assert.Nil(t, collr.conn)
163 v, _ := conn.(*mockConn)
164 assert.True(t, v.closeCalled)
165 }
166
167 func TestCollector_Collect(t *testing.T) {
168 tests := map[string]struct {
169 prepare func() *Collector
170 wantCollected map[string]int64
171 }{
172 "success v230+ on collecting all unit type": {
173 prepare: func() *Collector {
174 collr := New()
175 collr.Include = []string{"*"}
176 collr.client = prepareOKClient(230)
177 return collr
178 },
179 wantCollected: map[string]int64{
180 "unit_dbus_socket_state_activating": 0,
181 "unit_dbus_socket_state_active": 1,
182 "unit_dbus_socket_state_deactivating": 0,
183 "unit_dbus_socket_state_failed": 0,
184 "unit_dbus_socket_state_inactive": 0,
185 "unit_dev-disk-by-uuid-DE44-CEE0_device_state_activating": 0,
186 "unit_dev-disk-by-uuid-DE44-CEE0_device_state_active": 1,
187 "unit_dev-disk-by-uuid-DE44-CEE0_device_state_deactivating": 0,
188 "unit_dev-disk-by-uuid-DE44-CEE0_device_state_failed": 0,
189 "unit_dev-disk-by-uuid-DE44-CEE0_device_state_inactive": 0,
190 "unit_dev-nvme0n1_device_state_activating": 0,
191 "unit_dev-nvme0n1_device_state_active": 1,
192 "unit_dev-nvme0n1_device_state_deactivating": 0,
193 "unit_dev-nvme0n1_device_state_failed": 0,
194 "unit_dev-nvme0n1_device_state_inactive": 0,
195 "unit_docker_socket_state_activating": 0,
196 "unit_docker_socket_state_active": 1,
197 "unit_docker_socket_state_deactivating": 0,
198 "unit_docker_socket_state_failed": 0,
199 "unit_docker_socket_state_inactive": 0,
200 "unit_getty-pre_target_state_activating": 0,
201 "unit_getty-pre_target_state_active": 0,
202 "unit_getty-pre_target_state_deactivating": 0,
203 "unit_getty-pre_target_state_failed": 0,
204 "unit_getty-pre_target_state_inactive": 1,
205 "unit_init_scope_state_activating": 0,
206 "unit_init_scope_state_active": 1,
207 "unit_init_scope_state_deactivating": 0,
208 "unit_init_scope_state_failed": 0,
209 "unit_init_scope_state_inactive": 0,
210 "unit_logrotate_timer_state_activating": 0,
211 "unit_logrotate_timer_state_active": 1,
212 "unit_logrotate_timer_state_deactivating": 0,
213 "unit_logrotate_timer_state_failed": 0,
214 "unit_logrotate_timer_state_inactive": 0,
215 "unit_lvm2-lvmetad_socket_state_activating": 0,
216 "unit_lvm2-lvmetad_socket_state_active": 1,
217 "unit_lvm2-lvmetad_socket_state_deactivating": 0,
218 "unit_lvm2-lvmetad_socket_state_failed": 0,
219 "unit_lvm2-lvmetad_socket_state_inactive": 0,
220 "unit_lvm2-lvmpolld_socket_state_activating": 0,
221 "unit_lvm2-lvmpolld_socket_state_active": 1,
222 "unit_lvm2-lvmpolld_socket_state_deactivating": 0,
223 "unit_lvm2-lvmpolld_socket_state_failed": 0,
224 "unit_lvm2-lvmpolld_socket_state_inactive": 0,
225 "unit_man-db_timer_state_activating": 0,
226 "unit_man-db_timer_state_active": 1,
227 "unit_man-db_timer_state_deactivating": 0,
228 "unit_man-db_timer_state_failed": 0,
229 "unit_man-db_timer_state_inactive": 0,
230 "unit_org.cups.cupsd_path_state_activating": 0,
231 "unit_org.cups.cupsd_path_state_active": 1,
232 "unit_org.cups.cupsd_path_state_deactivating": 0,
233 "unit_org.cups.cupsd_path_state_failed": 0,
234 "unit_org.cups.cupsd_path_state_inactive": 0,
235 "unit_pamac-cleancache_timer_state_activating": 0,
236 "unit_pamac-cleancache_timer_state_active": 1,
237 "unit_pamac-cleancache_timer_state_deactivating": 0,
238 "unit_pamac-cleancache_timer_state_failed": 0,
239 "unit_pamac-cleancache_timer_state_inactive": 0,
240 "unit_pamac-mirrorlist_timer_state_activating": 0,
241 "unit_pamac-mirrorlist_timer_state_active": 1,
242 "unit_pamac-mirrorlist_timer_state_deactivating": 0,
243 "unit_pamac-mirrorlist_timer_state_failed": 0,
244 "unit_pamac-mirrorlist_timer_state_inactive": 0,
245 "unit_proc-sys-fs-binfmt_misc_automount_state_activating": 0,
246 "unit_proc-sys-fs-binfmt_misc_automount_state_active": 1,
247 "unit_proc-sys-fs-binfmt_misc_automount_state_deactivating": 0,
248 "unit_proc-sys-fs-binfmt_misc_automount_state_failed": 0,
249 "unit_proc-sys-fs-binfmt_misc_automount_state_inactive": 0,
250 "unit_remote-fs-pre_target_state_activating": 0,
251 "unit_remote-fs-pre_target_state_active": 0,
252 "unit_remote-fs-pre_target_state_deactivating": 0,
253 "unit_remote-fs-pre_target_state_failed": 0,
254 "unit_remote-fs-pre_target_state_inactive": 1,
255 "unit_rpc_pipefs_target_state_activating": 0,
256 "unit_rpc_pipefs_target_state_active": 0,
257 "unit_rpc_pipefs_target_state_deactivating": 0,
258 "unit_rpc_pipefs_target_state_failed": 0,
259 "unit_rpc_pipefs_target_state_inactive": 1,
260 "unit_run-user-1000-gvfs_mount_state_activating": 0,
261 "unit_run-user-1000-gvfs_mount_state_active": 1,
262 "unit_run-user-1000-gvfs_mount_state_deactivating": 0,
263 "unit_run-user-1000-gvfs_mount_state_failed": 0,
264 "unit_run-user-1000-gvfs_mount_state_inactive": 0,
265 "unit_run-user-1000_mount_state_activating": 0,
266 "unit_run-user-1000_mount_state_active": 1,
267 "unit_run-user-1000_mount_state_deactivating": 0,
268 "unit_run-user-1000_mount_state_failed": 0,
269 "unit_run-user-1000_mount_state_inactive": 0,
270 "unit_session-1_scope_state_activating": 0,
271 "unit_session-1_scope_state_active": 1,
272 "unit_session-1_scope_state_deactivating": 0,
273 "unit_session-1_scope_state_failed": 0,
274 "unit_session-1_scope_state_inactive": 0,
275 "unit_session-2_scope_state_activating": 0,
276 "unit_session-2_scope_state_active": 1,
277 "unit_session-2_scope_state_deactivating": 0,
278 "unit_session-2_scope_state_failed": 0,
279 "unit_session-2_scope_state_inactive": 0,
280 "unit_session-3_scope_state_activating": 0,
281 "unit_session-3_scope_state_active": 1,
282 "unit_session-3_scope_state_deactivating": 0,
283 "unit_session-3_scope_state_failed": 0,
284 "unit_session-3_scope_state_inactive": 0,
285 "unit_session-6_scope_state_activating": 0,
286 "unit_session-6_scope_state_active": 1,
287 "unit_session-6_scope_state_deactivating": 0,
288 "unit_session-6_scope_state_failed": 0,
289 "unit_session-6_scope_state_inactive": 0,
290 "unit_shadow_timer_state_activating": 0,
291 "unit_shadow_timer_state_active": 1,
292 "unit_shadow_timer_state_deactivating": 0,
293 "unit_shadow_timer_state_failed": 0,
294 "unit_shadow_timer_state_inactive": 0,
295 "unit_sound_target_state_activating": 0,
296 "unit_sound_target_state_active": 1,
297 "unit_sound_target_state_deactivating": 0,
298 "unit_sound_target_state_failed": 0,
299 "unit_sound_target_state_inactive": 0,
300 "unit_sys-devices-virtual-net-loopback1_device_state_activating": 0,
301 "unit_sys-devices-virtual-net-loopback1_device_state_active": 1,
302 "unit_sys-devices-virtual-net-loopback1_device_state_deactivating": 0,
303 "unit_sys-devices-virtual-net-loopback1_device_state_failed": 0,
304 "unit_sys-devices-virtual-net-loopback1_device_state_inactive": 0,
305 "unit_sys-module-fuse_device_state_activating": 0,
306 "unit_sys-module-fuse_device_state_active": 1,
307 "unit_sys-module-fuse_device_state_deactivating": 0,
308 "unit_sys-module-fuse_device_state_failed": 0,
309 "unit_sys-module-fuse_device_state_inactive": 0,
310 "unit_sysinit_target_state_activating": 0,
311 "unit_sysinit_target_state_active": 1,
312 "unit_sysinit_target_state_deactivating": 0,
313 "unit_sysinit_target_state_failed": 0,
314 "unit_sysinit_target_state_inactive": 0,
315 "unit_system-getty_slice_state_activating": 0,
316 "unit_system-getty_slice_state_active": 1,
317 "unit_system-getty_slice_state_deactivating": 0,
318 "unit_system-getty_slice_state_failed": 0,
319 "unit_system-getty_slice_state_inactive": 0,
320 "unit_system-netctl_slice_state_activating": 0,
321 "unit_system-netctl_slice_state_active": 1,
322 "unit_system-netctl_slice_state_deactivating": 0,
323 "unit_system-netctl_slice_state_failed": 0,
324 "unit_system-netctl_slice_state_inactive": 0,
325 "unit_system-systemd-fsck_slice_state_activating": 0,
326 "unit_system-systemd-fsck_slice_state_active": 1,
327 "unit_system-systemd-fsck_slice_state_deactivating": 0,
328 "unit_system-systemd-fsck_slice_state_failed": 0,
329 "unit_system-systemd-fsck_slice_state_inactive": 0,
330 "unit_system_slice_state_activating": 0,
331 "unit_system_slice_state_active": 1,
332 "unit_system_slice_state_deactivating": 0,
333 "unit_system_slice_state_failed": 0,
334 "unit_system_slice_state_inactive": 0,
335 "unit_systemd-ask-password-console_path_state_activating": 0,
336 "unit_systemd-ask-password-console_path_state_active": 1,
337 "unit_systemd-ask-password-console_path_state_deactivating": 0,
338 "unit_systemd-ask-password-console_path_state_failed": 0,
339 "unit_systemd-ask-password-console_path_state_inactive": 0,
340 "unit_systemd-ask-password-wall_path_state_activating": 0,
341 "unit_systemd-ask-password-wall_path_state_active": 1,
342 "unit_systemd-ask-password-wall_path_state_deactivating": 0,
343 "unit_systemd-ask-password-wall_path_state_failed": 0,
344 "unit_systemd-ask-password-wall_path_state_inactive": 0,
345 "unit_systemd-ask-password-wall_service_state_activating": 0,
346 "unit_systemd-ask-password-wall_service_state_active": 0,
347 "unit_systemd-ask-password-wall_service_state_deactivating": 0,
348 "unit_systemd-ask-password-wall_service_state_failed": 0,
349 "unit_systemd-ask-password-wall_service_state_inactive": 1,
350 "unit_systemd-fsck-root_service_state_activating": 0,
351 "unit_systemd-fsck-root_service_state_active": 0,
352 "unit_systemd-fsck-root_service_state_deactivating": 0,
353 "unit_systemd-fsck-root_service_state_failed": 0,
354 "unit_systemd-fsck-root_service_state_inactive": 1,
355 "unit_systemd-udevd-kernel_socket_state_activating": 0,
356 "unit_systemd-udevd-kernel_socket_state_active": 1,
357 "unit_systemd-udevd-kernel_socket_state_deactivating": 0,
358 "unit_systemd-udevd-kernel_socket_state_failed": 0,
359 "unit_systemd-udevd-kernel_socket_state_inactive": 0,
360 "unit_tmp_mount_state_activating": 0,
361 "unit_tmp_mount_state_active": 1,
362 "unit_tmp_mount_state_deactivating": 0,
363 "unit_tmp_mount_state_failed": 0,
364 "unit_tmp_mount_state_inactive": 0,
365 "unit_user-runtime-dir@1000_service_state_activating": 0,
366 "unit_user-runtime-dir@1000_service_state_active": 1,
367 "unit_user-runtime-dir@1000_service_state_deactivating": 0,
368 "unit_user-runtime-dir@1000_service_state_failed": 0,
369 "unit_user-runtime-dir@1000_service_state_inactive": 0,
370 "unit_user@1000_service_state_activating": 0,
371 "unit_user@1000_service_state_active": 1,
372 "unit_user@1000_service_state_deactivating": 0,
373 "unit_user@1000_service_state_failed": 0,
374 "unit_user@1000_service_state_inactive": 0,
375 "unit_user_slice_state_activating": 0,
376 "unit_user_slice_state_active": 1,
377 "unit_user_slice_state_deactivating": 0,
378 "unit_user_slice_state_failed": 0,
379 "unit_user_slice_state_inactive": 0,
380 "unit_var-lib-nfs-rpc_pipefs_mount_state_activating": 0,
381 "unit_var-lib-nfs-rpc_pipefs_mount_state_active": 0,
382 "unit_var-lib-nfs-rpc_pipefs_mount_state_deactivating": 0,
383 "unit_var-lib-nfs-rpc_pipefs_mount_state_failed": 0,
384 "unit_var-lib-nfs-rpc_pipefs_mount_state_inactive": 1,
385 },
386 },
387 "success v230+ on collecting all unit type with skip transient": {
388 prepare: func() *Collector {
389 collr := New()
390 collr.Include = []string{"*"}
391 collr.SkipTransient = true
392 collr.client = prepareOKClient(230)
393 return collr
394 },
395 wantCollected: map[string]int64{
396 "unit_systemd-ask-password-wall_service_state_activating": 0,
397 "unit_systemd-ask-password-wall_service_state_active": 0,
398 "unit_systemd-ask-password-wall_service_state_deactivating": 0,
399 "unit_systemd-ask-password-wall_service_state_failed": 0,
400 "unit_systemd-ask-password-wall_service_state_inactive": 1,
401 "unit_systemd-fsck-root_service_state_activating": 0,
402 "unit_systemd-fsck-root_service_state_active": 0,
403 "unit_systemd-fsck-root_service_state_deactivating": 0,
404 "unit_systemd-fsck-root_service_state_failed": 0,
405 "unit_systemd-fsck-root_service_state_inactive": 1,
406 "unit_user-runtime-dir@1000_service_state_activating": 0,
407 "unit_user-runtime-dir@1000_service_state_active": 1,
408 "unit_user-runtime-dir@1000_service_state_deactivating": 0,
409 "unit_user-runtime-dir@1000_service_state_failed": 0,
410 "unit_user-runtime-dir@1000_service_state_inactive": 0,
411 "unit_user@1000_service_state_activating": 0,
412 "unit_user@1000_service_state_active": 1,
413 "unit_user@1000_service_state_deactivating": 0,
414 "unit_user@1000_service_state_failed": 0,
415 "unit_user@1000_service_state_inactive": 0,
416 },
417 },
418 "success v230- on collecting all unit types": {
419 prepare: func() *Collector {
420 collr := New()
421 collr.Include = []string{"*"}
422 collr.client = prepareOKClient(220)
423 return collr
424 },
425 wantCollected: map[string]int64{
426 "unit_dbus_socket_state_activating": 0,
427 "unit_dbus_socket_state_active": 1,
428 "unit_dbus_socket_state_deactivating": 0,
429 "unit_dbus_socket_state_failed": 0,
430 "unit_dbus_socket_state_inactive": 0,
431 "unit_dev-disk-by-uuid-DE44-CEE0_device_state_activating": 0,
432 "unit_dev-disk-by-uuid-DE44-CEE0_device_state_active": 1,
433 "unit_dev-disk-by-uuid-DE44-CEE0_device_state_deactivating": 0,
434 "unit_dev-disk-by-uuid-DE44-CEE0_device_state_failed": 0,
435 "unit_dev-disk-by-uuid-DE44-CEE0_device_state_inactive": 0,
436 "unit_dev-nvme0n1_device_state_activating": 0,
437 "unit_dev-nvme0n1_device_state_active": 1,
438 "unit_dev-nvme0n1_device_state_deactivating": 0,
439 "unit_dev-nvme0n1_device_state_failed": 0,
440 "unit_dev-nvme0n1_device_state_inactive": 0,
441 "unit_docker_socket_state_activating": 0,
442 "unit_docker_socket_state_active": 1,
443 "unit_docker_socket_state_deactivating": 0,
444 "unit_docker_socket_state_failed": 0,
445 "unit_docker_socket_state_inactive": 0,
446 "unit_getty-pre_target_state_activating": 0,
447 "unit_getty-pre_target_state_active": 0,
448 "unit_getty-pre_target_state_deactivating": 0,
449 "unit_getty-pre_target_state_failed": 0,
450 "unit_getty-pre_target_state_inactive": 1,
451 "unit_init_scope_state_activating": 0,
452 "unit_init_scope_state_active": 1,
453 "unit_init_scope_state_deactivating": 0,
454 "unit_init_scope_state_failed": 0,
455 "unit_init_scope_state_inactive": 0,
456 "unit_logrotate_timer_state_activating": 0,
457 "unit_logrotate_timer_state_active": 1,
458 "unit_logrotate_timer_state_deactivating": 0,
459 "unit_logrotate_timer_state_failed": 0,
460 "unit_logrotate_timer_state_inactive": 0,
461 "unit_lvm2-lvmetad_socket_state_activating": 0,
462 "unit_lvm2-lvmetad_socket_state_active": 1,
463 "unit_lvm2-lvmetad_socket_state_deactivating": 0,
464 "unit_lvm2-lvmetad_socket_state_failed": 0,
465 "unit_lvm2-lvmetad_socket_state_inactive": 0,
466 "unit_lvm2-lvmpolld_socket_state_activating": 0,
467 "unit_lvm2-lvmpolld_socket_state_active": 1,
468 "unit_lvm2-lvmpolld_socket_state_deactivating": 0,
469 "unit_lvm2-lvmpolld_socket_state_failed": 0,
470 "unit_lvm2-lvmpolld_socket_state_inactive": 0,
471 "unit_man-db_timer_state_activating": 0,
472 "unit_man-db_timer_state_active": 1,
473 "unit_man-db_timer_state_deactivating": 0,
474 "unit_man-db_timer_state_failed": 0,
475 "unit_man-db_timer_state_inactive": 0,
476 "unit_org.cups.cupsd_path_state_activating": 0,
477 "unit_org.cups.cupsd_path_state_active": 1,
478 "unit_org.cups.cupsd_path_state_deactivating": 0,
479 "unit_org.cups.cupsd_path_state_failed": 0,
480 "unit_org.cups.cupsd_path_state_inactive": 0,
481 "unit_pamac-cleancache_timer_state_activating": 0,
482 "unit_pamac-cleancache_timer_state_active": 1,
483 "unit_pamac-cleancache_timer_state_deactivating": 0,
484 "unit_pamac-cleancache_timer_state_failed": 0,
485 "unit_pamac-cleancache_timer_state_inactive": 0,
486 "unit_pamac-mirrorlist_timer_state_activating": 0,
487 "unit_pamac-mirrorlist_timer_state_active": 1,
488 "unit_pamac-mirrorlist_timer_state_deactivating": 0,
489 "unit_pamac-mirrorlist_timer_state_failed": 0,
490 "unit_pamac-mirrorlist_timer_state_inactive": 0,
491 "unit_proc-sys-fs-binfmt_misc_automount_state_activating": 0,
492 "unit_proc-sys-fs-binfmt_misc_automount_state_active": 1,
493 "unit_proc-sys-fs-binfmt_misc_automount_state_deactivating": 0,
494 "unit_proc-sys-fs-binfmt_misc_automount_state_failed": 0,
495 "unit_proc-sys-fs-binfmt_misc_automount_state_inactive": 0,
496 "unit_remote-fs-pre_target_state_activating": 0,
497 "unit_remote-fs-pre_target_state_active": 0,
498 "unit_remote-fs-pre_target_state_deactivating": 0,
499 "unit_remote-fs-pre_target_state_failed": 0,
500 "unit_remote-fs-pre_target_state_inactive": 1,
501 "unit_rpc_pipefs_target_state_activating": 0,
502 "unit_rpc_pipefs_target_state_active": 0,
503 "unit_rpc_pipefs_target_state_deactivating": 0,
504 "unit_rpc_pipefs_target_state_failed": 0,
505 "unit_rpc_pipefs_target_state_inactive": 1,
506 "unit_run-user-1000-gvfs_mount_state_activating": 0,
507 "unit_run-user-1000-gvfs_mount_state_active": 1,
508 "unit_run-user-1000-gvfs_mount_state_deactivating": 0,
509 "unit_run-user-1000-gvfs_mount_state_failed": 0,
510 "unit_run-user-1000-gvfs_mount_state_inactive": 0,
511 "unit_run-user-1000_mount_state_activating": 0,
512 "unit_run-user-1000_mount_state_active": 1,
513 "unit_run-user-1000_mount_state_deactivating": 0,
514 "unit_run-user-1000_mount_state_failed": 0,
515 "unit_run-user-1000_mount_state_inactive": 0,
516 "unit_session-1_scope_state_activating": 0,
517 "unit_session-1_scope_state_active": 1,
518 "unit_session-1_scope_state_deactivating": 0,
519 "unit_session-1_scope_state_failed": 0,
520 "unit_session-1_scope_state_inactive": 0,
521 "unit_session-2_scope_state_activating": 0,
522 "unit_session-2_scope_state_active": 1,
523 "unit_session-2_scope_state_deactivating": 0,
524 "unit_session-2_scope_state_failed": 0,
525 "unit_session-2_scope_state_inactive": 0,
526 "unit_session-3_scope_state_activating": 0,
527 "unit_session-3_scope_state_active": 1,
528 "unit_session-3_scope_state_deactivating": 0,
529 "unit_session-3_scope_state_failed": 0,
530 "unit_session-3_scope_state_inactive": 0,
531 "unit_session-6_scope_state_activating": 0,
532 "unit_session-6_scope_state_active": 1,
533 "unit_session-6_scope_state_deactivating": 0,
534 "unit_session-6_scope_state_failed": 0,
535 "unit_session-6_scope_state_inactive": 0,
536 "unit_shadow_timer_state_activating": 0,
537 "unit_shadow_timer_state_active": 1,
538 "unit_shadow_timer_state_deactivating": 0,
539 "unit_shadow_timer_state_failed": 0,
540 "unit_shadow_timer_state_inactive": 0,
541 "unit_sound_target_state_activating": 0,
542 "unit_sound_target_state_active": 1,
543 "unit_sound_target_state_deactivating": 0,
544 "unit_sound_target_state_failed": 0,
545 "unit_sound_target_state_inactive": 0,
546 "unit_sys-devices-virtual-net-loopback1_device_state_activating": 0,
547 "unit_sys-devices-virtual-net-loopback1_device_state_active": 1,
548 "unit_sys-devices-virtual-net-loopback1_device_state_deactivating": 0,
549 "unit_sys-devices-virtual-net-loopback1_device_state_failed": 0,
550 "unit_sys-devices-virtual-net-loopback1_device_state_inactive": 0,
551 "unit_sys-module-fuse_device_state_activating": 0,
552 "unit_sys-module-fuse_device_state_active": 1,
553 "unit_sys-module-fuse_device_state_deactivating": 0,
554 "unit_sys-module-fuse_device_state_failed": 0,
555 "unit_sys-module-fuse_device_state_inactive": 0,
556 "unit_sysinit_target_state_activating": 0,
557 "unit_sysinit_target_state_active": 1,
558 "unit_sysinit_target_state_deactivating": 0,
559 "unit_sysinit_target_state_failed": 0,
560 "unit_sysinit_target_state_inactive": 0,
561 "unit_system-getty_slice_state_activating": 0,
562 "unit_system-getty_slice_state_active": 1,
563 "unit_system-getty_slice_state_deactivating": 0,
564 "unit_system-getty_slice_state_failed": 0,
565 "unit_system-getty_slice_state_inactive": 0,
566 "unit_system-netctl_slice_state_activating": 0,
567 "unit_system-netctl_slice_state_active": 1,
568 "unit_system-netctl_slice_state_deactivating": 0,
569 "unit_system-netctl_slice_state_failed": 0,
570 "unit_system-netctl_slice_state_inactive": 0,
571 "unit_system-systemd-fsck_slice_state_activating": 0,
572 "unit_system-systemd-fsck_slice_state_active": 1,
573 "unit_system-systemd-fsck_slice_state_deactivating": 0,
574 "unit_system-systemd-fsck_slice_state_failed": 0,
575 "unit_system-systemd-fsck_slice_state_inactive": 0,
576 "unit_system_slice_state_activating": 0,
577 "unit_system_slice_state_active": 1,
578 "unit_system_slice_state_deactivating": 0,
579 "unit_system_slice_state_failed": 0,
580 "unit_system_slice_state_inactive": 0,
581 "unit_systemd-ask-password-console_path_state_activating": 0,
582 "unit_systemd-ask-password-console_path_state_active": 1,
583 "unit_systemd-ask-password-console_path_state_deactivating": 0,
584 "unit_systemd-ask-password-console_path_state_failed": 0,
585 "unit_systemd-ask-password-console_path_state_inactive": 0,
586 "unit_systemd-ask-password-wall_path_state_activating": 0,
587 "unit_systemd-ask-password-wall_path_state_active": 1,
588 "unit_systemd-ask-password-wall_path_state_deactivating": 0,
589 "unit_systemd-ask-password-wall_path_state_failed": 0,
590 "unit_systemd-ask-password-wall_path_state_inactive": 0,
591 "unit_systemd-ask-password-wall_service_state_activating": 0,
592 "unit_systemd-ask-password-wall_service_state_active": 0,
593 "unit_systemd-ask-password-wall_service_state_deactivating": 0,
594 "unit_systemd-ask-password-wall_service_state_failed": 0,
595 "unit_systemd-ask-password-wall_service_state_inactive": 1,
596 "unit_systemd-fsck-root_service_state_activating": 0,
597 "unit_systemd-fsck-root_service_state_active": 0,
598 "unit_systemd-fsck-root_service_state_deactivating": 0,
599 "unit_systemd-fsck-root_service_state_failed": 0,
600 "unit_systemd-fsck-root_service_state_inactive": 1,
601 "unit_systemd-udevd-kernel_socket_state_activating": 0,
602 "unit_systemd-udevd-kernel_socket_state_active": 1,
603 "unit_systemd-udevd-kernel_socket_state_deactivating": 0,
604 "unit_systemd-udevd-kernel_socket_state_failed": 0,
605 "unit_systemd-udevd-kernel_socket_state_inactive": 0,
606 "unit_tmp_mount_state_activating": 0,
607 "unit_tmp_mount_state_active": 1,
608 "unit_tmp_mount_state_deactivating": 0,
609 "unit_tmp_mount_state_failed": 0,
610 "unit_tmp_mount_state_inactive": 0,
611 "unit_user-runtime-dir@1000_service_state_activating": 0,
612 "unit_user-runtime-dir@1000_service_state_active": 1,
613 "unit_user-runtime-dir@1000_service_state_deactivating": 0,
614 "unit_user-runtime-dir@1000_service_state_failed": 0,
615 "unit_user-runtime-dir@1000_service_state_inactive": 0,
616 "unit_user@1000_service_state_activating": 0,
617 "unit_user@1000_service_state_active": 1,
618 "unit_user@1000_service_state_deactivating": 0,
619 "unit_user@1000_service_state_failed": 0,
620 "unit_user@1000_service_state_inactive": 0,
621 "unit_user_slice_state_activating": 0,
622 "unit_user_slice_state_active": 1,
623 "unit_user_slice_state_deactivating": 0,
624 "unit_user_slice_state_failed": 0,
625 "unit_user_slice_state_inactive": 0,
626 "unit_var-lib-nfs-rpc_pipefs_mount_state_activating": 0,
627 "unit_var-lib-nfs-rpc_pipefs_mount_state_active": 0,
628 "unit_var-lib-nfs-rpc_pipefs_mount_state_deactivating": 0,
629 "unit_var-lib-nfs-rpc_pipefs_mount_state_failed": 0,
630 "unit_var-lib-nfs-rpc_pipefs_mount_state_inactive": 1,
631 },
632 },
633 "success v230+ on collecting only 'service' units": {
634 prepare: func() *Collector {
635 collr := New()
636 collr.Include = []string{"*.service"}
637 collr.client = prepareOKClient(230)
638 return collr
639 },
640 wantCollected: map[string]int64{
641 "unit_systemd-ask-password-wall_service_state_activating": 0,
642 "unit_systemd-ask-password-wall_service_state_active": 0,
643 "unit_systemd-ask-password-wall_service_state_deactivating": 0,
644 "unit_systemd-ask-password-wall_service_state_failed": 0,
645 "unit_systemd-ask-password-wall_service_state_inactive": 1,
646 "unit_systemd-fsck-root_service_state_activating": 0,
647 "unit_systemd-fsck-root_service_state_active": 0,
648 "unit_systemd-fsck-root_service_state_deactivating": 0,
649 "unit_systemd-fsck-root_service_state_failed": 0,
650 "unit_systemd-fsck-root_service_state_inactive": 1,
651 "unit_user-runtime-dir@1000_service_state_activating": 0,
652 "unit_user-runtime-dir@1000_service_state_active": 1,
653 "unit_user-runtime-dir@1000_service_state_deactivating": 0,
654 "unit_user-runtime-dir@1000_service_state_failed": 0,
655 "unit_user-runtime-dir@1000_service_state_inactive": 0,
656 "unit_user@1000_service_state_activating": 0,
657 "unit_user@1000_service_state_active": 1,
658 "unit_user@1000_service_state_deactivating": 0,
659 "unit_user@1000_service_state_failed": 0,
660 "unit_user@1000_service_state_inactive": 0,
661 },
662 },
663 "success v230- on collecting only 'service' units": {
664 prepare: func() *Collector {
665 collr := New()
666 collr.Include = []string{"*.service"}
667 collr.client = prepareOKClient(220)
668 return collr
669 },
670 wantCollected: map[string]int64{
671 "unit_systemd-ask-password-wall_service_state_activating": 0,
672 "unit_systemd-ask-password-wall_service_state_active": 0,
673 "unit_systemd-ask-password-wall_service_state_deactivating": 0,
674 "unit_systemd-ask-password-wall_service_state_failed": 0,
675 "unit_systemd-ask-password-wall_service_state_inactive": 1,
676 "unit_systemd-fsck-root_service_state_activating": 0,
677 "unit_systemd-fsck-root_service_state_active": 0,
678 "unit_systemd-fsck-root_service_state_deactivating": 0,
679 "unit_systemd-fsck-root_service_state_failed": 0,
680 "unit_systemd-fsck-root_service_state_inactive": 1,
681 "unit_user-runtime-dir@1000_service_state_activating": 0,
682 "unit_user-runtime-dir@1000_service_state_active": 1,
683 "unit_user-runtime-dir@1000_service_state_deactivating": 0,
684 "unit_user-runtime-dir@1000_service_state_failed": 0,
685 "unit_user-runtime-dir@1000_service_state_inactive": 0,
686 "unit_user@1000_service_state_activating": 0,
687 "unit_user@1000_service_state_active": 1,
688 "unit_user@1000_service_state_deactivating": 0,
689 "unit_user@1000_service_state_failed": 0,
690 "unit_user@1000_service_state_inactive": 0,
691 },
692 },
693 "success v230+ on collecting only 'service' units and files": {
694 prepare: func() *Collector {
695 collr := New()
696 collr.Include = []string{"*.service"}
697 collr.IncludeUnitFiles = []string{"*.service", "*.slice"}
698 collr.CollectUnitFiles = true
699 collr.client = prepareOKClient(230)
700 return collr
701 },
702 wantCollected: map[string]int64{
703 "unit_file_/lib/systemd/system/machine.slice_state_alias": 0,
704 "unit_file_/lib/systemd/system/machine.slice_state_bad": 0,
705 "unit_file_/lib/systemd/system/machine.slice_state_disabled": 0,
706 "unit_file_/lib/systemd/system/machine.slice_state_enabled": 0,
707 "unit_file_/lib/systemd/system/machine.slice_state_enabled-runtime": 0,
708 "unit_file_/lib/systemd/system/machine.slice_state_generated": 0,
709 "unit_file_/lib/systemd/system/machine.slice_state_indirect": 0,
710 "unit_file_/lib/systemd/system/machine.slice_state_linked": 0,
711 "unit_file_/lib/systemd/system/machine.slice_state_linked-runtime": 0,
712 "unit_file_/lib/systemd/system/machine.slice_state_masked": 0,
713 "unit_file_/lib/systemd/system/machine.slice_state_masked-runtime": 0,
714 "unit_file_/lib/systemd/system/machine.slice_state_static": 1,
715 "unit_file_/lib/systemd/system/machine.slice_state_transient": 0,
716 "unit_file_/lib/systemd/system/system-systemd-cryptsetup.slice_state_alias": 0,
717 "unit_file_/lib/systemd/system/system-systemd-cryptsetup.slice_state_bad": 0,
718 "unit_file_/lib/systemd/system/system-systemd-cryptsetup.slice_state_disabled": 0,
719 "unit_file_/lib/systemd/system/system-systemd-cryptsetup.slice_state_enabled": 0,
720 "unit_file_/lib/systemd/system/system-systemd-cryptsetup.slice_state_enabled-runtime": 0,
721 "unit_file_/lib/systemd/system/system-systemd-cryptsetup.slice_state_generated": 0,
722 "unit_file_/lib/systemd/system/system-systemd-cryptsetup.slice_state_indirect": 0,
723 "unit_file_/lib/systemd/system/system-systemd-cryptsetup.slice_state_linked": 0,
724 "unit_file_/lib/systemd/system/system-systemd-cryptsetup.slice_state_linked-runtime": 0,
725 "unit_file_/lib/systemd/system/system-systemd-cryptsetup.slice_state_masked": 0,
726 "unit_file_/lib/systemd/system/system-systemd-cryptsetup.slice_state_masked-runtime": 0,
727 "unit_file_/lib/systemd/system/system-systemd-cryptsetup.slice_state_static": 1,
728 "unit_file_/lib/systemd/system/system-systemd-cryptsetup.slice_state_transient": 0,
729 "unit_file_/lib/systemd/system/user.slice_state_alias": 0,
730 "unit_file_/lib/systemd/system/user.slice_state_bad": 0,
731 "unit_file_/lib/systemd/system/user.slice_state_disabled": 0,
732 "unit_file_/lib/systemd/system/user.slice_state_enabled": 0,
733 "unit_file_/lib/systemd/system/user.slice_state_enabled-runtime": 0,
734 "unit_file_/lib/systemd/system/user.slice_state_generated": 0,
735 "unit_file_/lib/systemd/system/user.slice_state_indirect": 0,
736 "unit_file_/lib/systemd/system/user.slice_state_linked": 0,
737 "unit_file_/lib/systemd/system/user.slice_state_linked-runtime": 0,
738 "unit_file_/lib/systemd/system/user.slice_state_masked": 0,
739 "unit_file_/lib/systemd/system/user.slice_state_masked-runtime": 0,
740 "unit_file_/lib/systemd/system/user.slice_state_static": 1,
741 "unit_file_/lib/systemd/system/user.slice_state_transient": 0,
742 "unit_file_/lib/systemd/system/uuidd.service_state_alias": 0,
743 "unit_file_/lib/systemd/system/uuidd.service_state_bad": 0,
744 "unit_file_/lib/systemd/system/uuidd.service_state_disabled": 0,
745 "unit_file_/lib/systemd/system/uuidd.service_state_enabled": 0,
746 "unit_file_/lib/systemd/system/uuidd.service_state_enabled-runtime": 0,
747 "unit_file_/lib/systemd/system/uuidd.service_state_generated": 0,
748 "unit_file_/lib/systemd/system/uuidd.service_state_indirect": 1,
749 "unit_file_/lib/systemd/system/uuidd.service_state_linked": 0,
750 "unit_file_/lib/systemd/system/uuidd.service_state_linked-runtime": 0,
751 "unit_file_/lib/systemd/system/uuidd.service_state_masked": 0,
752 "unit_file_/lib/systemd/system/uuidd.service_state_masked-runtime": 0,
753 "unit_file_/lib/systemd/system/uuidd.service_state_static": 0,
754 "unit_file_/lib/systemd/system/uuidd.service_state_transient": 0,
755 "unit_file_/lib/systemd/system/x11-common.service_state_alias": 0,
756 "unit_file_/lib/systemd/system/x11-common.service_state_bad": 0,
757 "unit_file_/lib/systemd/system/x11-common.service_state_disabled": 0,
758 "unit_file_/lib/systemd/system/x11-common.service_state_enabled": 0,
759 "unit_file_/lib/systemd/system/x11-common.service_state_enabled-runtime": 0,
760 "unit_file_/lib/systemd/system/x11-common.service_state_generated": 0,
761 "unit_file_/lib/systemd/system/x11-common.service_state_indirect": 0,
762 "unit_file_/lib/systemd/system/x11-common.service_state_linked": 0,
763 "unit_file_/lib/systemd/system/x11-common.service_state_linked-runtime": 0,
764 "unit_file_/lib/systemd/system/x11-common.service_state_masked": 1,
765 "unit_file_/lib/systemd/system/x11-common.service_state_masked-runtime": 0,
766 "unit_file_/lib/systemd/system/x11-common.service_state_static": 0,
767 "unit_file_/lib/systemd/system/x11-common.service_state_transient": 0,
768 "unit_file_/run/systemd/generator.late/monit.service_state_alias": 0,
769 "unit_file_/run/systemd/generator.late/monit.service_state_bad": 0,
770 "unit_file_/run/systemd/generator.late/monit.service_state_disabled": 0,
771 "unit_file_/run/systemd/generator.late/monit.service_state_enabled": 0,
772 "unit_file_/run/systemd/generator.late/monit.service_state_enabled-runtime": 0,
773 "unit_file_/run/systemd/generator.late/monit.service_state_generated": 1,
774 "unit_file_/run/systemd/generator.late/monit.service_state_indirect": 0,
775 "unit_file_/run/systemd/generator.late/monit.service_state_linked": 0,
776 "unit_file_/run/systemd/generator.late/monit.service_state_linked-runtime": 0,
777 "unit_file_/run/systemd/generator.late/monit.service_state_masked": 0,
778 "unit_file_/run/systemd/generator.late/monit.service_state_masked-runtime": 0,
779 "unit_file_/run/systemd/generator.late/monit.service_state_static": 0,
780 "unit_file_/run/systemd/generator.late/monit.service_state_transient": 0,
781 "unit_file_/run/systemd/generator.late/sendmail.service_state_alias": 0,
782 "unit_file_/run/systemd/generator.late/sendmail.service_state_bad": 0,
783 "unit_file_/run/systemd/generator.late/sendmail.service_state_disabled": 0,
784 "unit_file_/run/systemd/generator.late/sendmail.service_state_enabled": 0,
785 "unit_file_/run/systemd/generator.late/sendmail.service_state_enabled-runtime": 0,
786 "unit_file_/run/systemd/generator.late/sendmail.service_state_generated": 1,
787 "unit_file_/run/systemd/generator.late/sendmail.service_state_indirect": 0,
788 "unit_file_/run/systemd/generator.late/sendmail.service_state_linked": 0,
789 "unit_file_/run/systemd/generator.late/sendmail.service_state_linked-runtime": 0,
790 "unit_file_/run/systemd/generator.late/sendmail.service_state_masked": 0,
791 "unit_file_/run/systemd/generator.late/sendmail.service_state_masked-runtime": 0,
792 "unit_file_/run/systemd/generator.late/sendmail.service_state_static": 0,
793 "unit_file_/run/systemd/generator.late/sendmail.service_state_transient": 0,
794 "unit_systemd-ask-password-wall_service_state_activating": 0,
795 "unit_systemd-ask-password-wall_service_state_active": 0,
796 "unit_systemd-ask-password-wall_service_state_deactivating": 0,
797 "unit_systemd-ask-password-wall_service_state_failed": 0,
798 "unit_systemd-ask-password-wall_service_state_inactive": 1,
799 "unit_systemd-fsck-root_service_state_activating": 0,
800 "unit_systemd-fsck-root_service_state_active": 0,
801 "unit_systemd-fsck-root_service_state_deactivating": 0,
802 "unit_systemd-fsck-root_service_state_failed": 0,
803 "unit_systemd-fsck-root_service_state_inactive": 1,
804 "unit_user-runtime-dir@1000_service_state_activating": 0,
805 "unit_user-runtime-dir@1000_service_state_active": 1,
806 "unit_user-runtime-dir@1000_service_state_deactivating": 0,
807 "unit_user-runtime-dir@1000_service_state_failed": 0,
808 "unit_user-runtime-dir@1000_service_state_inactive": 0,
809 "unit_user@1000_service_state_activating": 0,
810 "unit_user@1000_service_state_active": 1,
811 "unit_user@1000_service_state_deactivating": 0,
812 "unit_user@1000_service_state_failed": 0,
813 "unit_user@1000_service_state_inactive": 0,
814 },
815 },
816 "fails when all unites are filtered": {
817 prepare: func() *Collector {
818 collr := New()
819 collr.Include = []string{"*.not_exists"}
820 collr.client = prepareOKClient(230)
821 return collr
822 },
823 wantCollected: nil,
824 },
825 "fails on error on connect": {
826 prepare: func() *Collector {
827 collr := New()
828 collr.client = prepareClientErrOnConnect()
829 return collr
830 },
831 wantCollected: nil,
832 },
833 "fails on error on get manager property": {
834 prepare: func() *Collector {
835 collr := New()
836 collr.client = prepareClientErrOnGetManagerProperty()
837 return collr
838 },
839 wantCollected: nil,
840 },
841 "fails on error on list units": {
842 prepare: func() *Collector {
843 collr := New()
844 collr.client = prepareClientErrOnListUnits()
845 return collr
846 },
847 wantCollected: nil,
848 },
849 }
850
851 for name, test := range tests {
852 t.Run(name, func(t *testing.T) {
853 collr := test.prepare()
854 require.NoError(t, collr.Init(context.Background()))
855
856 var mx map[string]int64
857
858 for range 10 {
859 mx = collr.Collect(context.Background())
860 }
861
862 assert.Equal(t, test.wantCollected, mx)
863 if len(test.wantCollected) > 0 {
864 collecttest.TestMetricsHasAllChartsDims(t, collr.Charts(), mx)
865 }
866 })
867 }
868 }
869
870 func TestCollector_connectionReuse(t *testing.T) {
871 collr := New()
872 collr.Include = []string{"*"}
873 client := prepareOKClient(230)
874 collr.client = client
875 require.NoError(t, collr.Init(context.Background()))
876
877 var collected map[string]int64
878 for range 10 {
879 collected = collr.Collect(context.Background())
880 }
881
882 assert.NotEmpty(t, collected)
883 assert.Equal(t, 1, client.connectCalls)
884 }
885
886 func prepareOKClient(ver int) *mockClient {
887 return &mockClient{
888 conn: &mockConn{
889 version: ver,
890 units: mockSystemdUnits,
891 unitFiles: mockSystemdUnitFiles,
892 },
893 }
894 }
895
896 func prepareClientErrOnConnect() *mockClient {
897 return &mockClient{
898 errOnConnect: true,
899 }
900 }
901
902 func prepareClientErrOnGetManagerProperty() *mockClient {
903 return &mockClient{
904 conn: &mockConn{
905 version: 230,
906 errOnGetManagerProperty: true,
907 units: mockSystemdUnits,
908 },
909 }
910 }
911
912 func prepareClientErrOnListUnits() *mockClient {
913 return &mockClient{
914 conn: &mockConn{
915 version: 230,
916 errOnListUnits: true,
917 units: mockSystemdUnits,
918 },
919 }
920 }
921
922 type mockClient struct {
923 conn systemdConnection
924 connectCalls int
925 errOnConnect bool
926 }
927
928 func (m *mockClient) connect() (systemdConnection, error) {
929 m.connectCalls++
930 if m.errOnConnect {
931 return nil, errors.New("mock 'connect' error")
932 }
933 return m.conn, nil
934 }
935
936 type mockConn struct {
937 version int
938 errOnGetManagerProperty bool
939
940 units []dbus.UnitStatus
941 errOnListUnits bool
942
943 unitFiles []dbus.UnitFile
944 errOnListUnitFiles bool
945
946 closeCalled bool
947 }
948
949 func (m *mockConn) Close() {
950 m.closeCalled = true
951 }
952
953 func (m *mockConn) GetManagerProperty(prop string) (string, error) {
954 if m.errOnGetManagerProperty {
955 return "", errors.New("'GetManagerProperty' call error")
956 }
957 if prop != versionProperty {
958 return "", fmt.Errorf("'GetManagerProperty' unkown property: %s", prop)
959 }
960
961 return fmt.Sprintf("%d.6-1-manjaro", m.version), nil
962 }
963
964 func (m *mockConn) GetUnitPropertyContext(_ context.Context, unit string, propertyName string) (*dbus.Property, error) {
965 if propertyName != transientProperty {
966 return nil, fmt.Errorf("'GetUnitProperty' unkown property name: %s", propertyName)
967 }
968
969 var prop dbus.Property
970
971 if strings.HasSuffix(unit, ".service") {
972 prop = dbus.PropDescription("false")
973 } else {
974 prop = dbus.PropDescription("true")
975 }
976
977 prop.Name = propertyName
978
979 return &prop, nil
980 }
981
982 func (m *mockConn) ListUnitsContext(_ context.Context) ([]dbus.UnitStatus, error) {
983 if m.errOnListUnits {
984 return nil, errors.New("'ListUnits' call error")
985 }
986 if m.version >= 230 {
987 return nil, errors.New("'ListUnits' unsupported function error")
988 }
989
990 return append([]dbus.UnitStatus{}, m.units...), nil
991 }
992
993 func (m *mockConn) ListUnitsByPatternsContext(_ context.Context, _ []string, patterns []string) ([]dbus.UnitStatus, error) {
994 if m.errOnListUnits {
995 return nil, errors.New("'ListUnitsByPatterns' call error")
996 }
997 if m.version < 230 {
998 return nil, errors.New("'ListUnitsByPatterns' unsupported function error")
999 }
1000
1001 if len(m.units) == 0 {
1002 return nil, nil
1003 }
1004
1005 units := append([]dbus.UnitStatus{}, m.units...)
1006
1007 units = slices.DeleteFunc(units, func(u dbus.UnitStatus) bool {
1008 name := cleanUnitName(u.Name)
1009 for _, p := range patterns {
1010 if ok, _ := filepath.Match(p, name); ok {
1011 return false
1012 }
1013 }
1014 return true
1015 })
1016
1017 return units, nil
1018 }
1019
1020 func (m *mockConn) ListUnitFilesByPatternsContext(_ context.Context, _ []string, patterns []string) ([]dbus.UnitFile, error) {
1021 if m.errOnListUnitFiles {
1022 return nil, errors.New("'ListUnitFilesByPatternsContex' call error")
1023 }
1024 if m.version < 230 {
1025 return nil, errors.New("'ListUnitFilesByPatternsContex' unsupported function error")
1026 }
1027
1028 if len(m.unitFiles) == 0 {
1029 return nil, nil
1030 }
1031
1032 unitFiles := append([]dbus.UnitFile{}, m.unitFiles...)
1033
1034 unitFiles = slices.DeleteFunc(unitFiles, func(file dbus.UnitFile) bool {
1035 _, name := filepath.Split(file.Path)
1036 for _, p := range patterns {
1037 if ok, _ := filepath.Match(p, name); ok {
1038 return false
1039 }
1040 }
1041 return true
1042 })
1043
1044 return unitFiles, nil
1045 }
1046
1047 var mockSystemdUnits = []dbus.UnitStatus{
1048 {Name: `proc-sys-fs-binfmt_misc.automount`, LoadState: "loaded", ActiveState: "active"},
1049 {Name: `dev-nvme0n1.device`, LoadState: "loaded", ActiveState: "active"},
1050 {Name: `sys-devices-virtual-net-loopback1.device`, LoadState: "loaded", ActiveState: "active"},
1051 {Name: `sys-module-fuse.device`, LoadState: "loaded", ActiveState: "active"},
1052 {Name: `dev-disk-by\x2duuid-DE44\x2dCEE0.device`, LoadState: "loaded", ActiveState: "active"},
1053
1054 {Name: `var-lib-nfs-rpc_pipefs.mount`, LoadState: "loaded", ActiveState: "inactive"},
1055 {Name: `var.mount`, LoadState: "not-found", ActiveState: "inactive"},
1056 {Name: `run-user-1000.mount`, LoadState: "loaded", ActiveState: "active"},
1057 {Name: `tmp.mount`, LoadState: "loaded", ActiveState: "active"},
1058 {Name: `run-user-1000-gvfs.mount`, LoadState: "loaded", ActiveState: "active"},
1059
1060 {Name: `org.cups.cupsd.path`, LoadState: "loaded", ActiveState: "active"},
1061 {Name: `systemd-ask-password-wall.path`, LoadState: "loaded", ActiveState: "active"},
1062 {Name: `systemd-ask-password-console.path`, LoadState: "loaded", ActiveState: "active"},
1063
1064 {Name: `init.scope`, LoadState: "loaded", ActiveState: "active"},
1065 {Name: `session-3.scope`, LoadState: "loaded", ActiveState: "active"},
1066 {Name: `session-6.scope`, LoadState: "loaded", ActiveState: "active"},
1067 {Name: `session-1.scope`, LoadState: "loaded", ActiveState: "active"},
1068 {Name: `session-2.scope`, LoadState: "loaded", ActiveState: "active"},
1069
1070 {Name: `systemd-fsck-root.service`, LoadState: "loaded", ActiveState: "inactive"},
1071 {Name: `httpd.service`, LoadState: "not-found", ActiveState: "inactive"},
1072 {Name: `user-runtime-dir@1000.service`, LoadState: "loaded", ActiveState: "active"},
1073 {Name: `systemd-ask-password-wall.service`, LoadState: "loaded", ActiveState: "inactive"},
1074 {Name: `user@1000.service`, LoadState: "loaded", ActiveState: "active"},
1075
1076 {Name: `user.slice`, LoadState: "loaded", ActiveState: "active"},
1077 {Name: `system-getty.slice`, LoadState: "loaded", ActiveState: "active"},
1078 {Name: `system-netctl.slice`, LoadState: "loaded", ActiveState: "active"},
1079 {Name: `system.slice`, LoadState: "loaded", ActiveState: "active"},
1080 {Name: `system-systemd\x2dfsck.slice`, LoadState: "loaded", ActiveState: "active"},
1081
1082 {Name: `lvm2-lvmpolld.socket`, LoadState: "loaded", ActiveState: "active"},
1083 {Name: `docker.socket`, LoadState: "loaded", ActiveState: "active"},
1084 {Name: `systemd-udevd-kernel.socket`, LoadState: "loaded", ActiveState: "active"},
1085 {Name: `dbus.socket`, LoadState: "loaded", ActiveState: "active"},
1086 {Name: `lvm2-lvmetad.socket`, LoadState: "loaded", ActiveState: "active"},
1087
1088 {Name: `getty-pre.target`, LoadState: "loaded", ActiveState: "inactive"},
1089 {Name: `rpc_pipefs.target`, LoadState: "loaded", ActiveState: "inactive"},
1090 {Name: `remote-fs-pre.target`, LoadState: "loaded", ActiveState: "inactive"},
1091 {Name: `sysinit.target`, LoadState: "loaded", ActiveState: "active"},
1092 {Name: `sound.target`, LoadState: "loaded", ActiveState: "active"},
1093
1094 {Name: `man-db.timer`, LoadState: "loaded", ActiveState: "active"},
1095 {Name: `pamac-mirrorlist.timer`, LoadState: "loaded", ActiveState: "active"},
1096 {Name: `pamac-cleancache.timer`, LoadState: "loaded", ActiveState: "active"},
1097 {Name: `shadow.timer`, LoadState: "loaded", ActiveState: "active"},
1098 {Name: `logrotate.timer`, LoadState: "loaded", ActiveState: "active"},
1099 }
1100
1101 var mockSystemdUnitFiles = []dbus.UnitFile{
1102 {Path: "/lib/systemd/system/systemd-tmpfiles-clean.timer", Type: "static"},
1103 {Path: "/lib/systemd/system/sysstat-summary.timer", Type: "disabled"},
1104 {Path: "/lib/systemd/system/sysstat-collect.timer", Type: "disabled"},
1105 {Path: "/lib/systemd/system/pg_dump@.timer", Type: "disabled"},
1106
1107 {Path: "/lib/systemd/system/veritysetup.target", Type: "static"},
1108 {Path: "/lib/systemd/system/veritysetup-pre.target", Type: "static"},
1109 {Path: "/lib/systemd/system/usb-gadget.target", Type: "static"},
1110 {Path: "/lib/systemd/system/umount.target", Type: "static"},
1111
1112 {Path: "/lib/systemd/system/syslog.socket", Type: "static"},
1113 {Path: "/lib/systemd/system/ssh.socket", Type: "disabled"},
1114 {Path: "/lib/systemd/system/docker.socket", Type: "enabled"},
1115 {Path: "/lib/systemd/system/dbus.socket", Type: "static"},
1116
1117 {Path: "/lib/systemd/system/user.slice", Type: "static"},
1118 {Path: "/lib/systemd/system/system-systemd\x2dcryptsetup.slice", Type: "static"},
1119 {Path: "/lib/systemd/system/machine.slice", Type: "static"},
1120
1121 {Path: "/run/systemd/generator.late/sendmail.service", Type: "generated"},
1122 {Path: "/run/systemd/generator.late/monit.service", Type: "generated"},
1123 {Path: "/lib/systemd/system/x11-common.service", Type: "masked"},
1124 {Path: "/lib/systemd/system/uuidd.service", Type: "indirect"},
1125
1126 {Path: "/run/systemd/transient/session-144.scope", Type: "transient"},
1127 {Path: "/run/systemd/transient/session-139.scope", Type: "transient"},
1128 {Path: "/run/systemd/transient/session-132.scope", Type: "transient"},
1129
1130 {Path: "/lib/systemd/system/systemd-ask-password-wall.path", Type: "static"},
1131 {Path: "/lib/systemd/system/systemd-ask-password-console.path", Type: "static"},
1132 {Path: "/lib/systemd/system/postfix-resolvconf.path", Type: "disabled"},
1133 {Path: "/lib/systemd/system/ntpsec-systemd-netif.path", Type: "enabled"},
1134
1135 {Path: "/run/systemd/generator/media-cdrom0.mount", Type: "generated"},
1136 {Path: "/run/systemd/generator/boot.mount", Type: "generated"},
1137 {Path: "/run/systemd/generator/-.mount", Type: "generated"},
1138 {Path: "/lib/systemd/system/sys-kernel-tracing.mount", Type: "static"},
1139 }