]> ruderich.org/simon Gitweb - safcm/safcm.git/blob - cmd/safcm-remote/sync/services_systemd_test.go
sync: remove "detected" log message in packages/services
[safcm/safcm.git] / cmd / safcm-remote / sync / services_systemd_test.go
1 // Copyright (C) 2021  Simon Ruderich
2 //
3 // This program is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, either version 3 of the License, or
6 // (at your option) any later version.
7 //
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
15
16 package sync
17
18 import (
19         "bytes"
20         "fmt"
21         "os/exec"
22         "testing"
23
24         "ruderich.org/simon/safcm"
25         "ruderich.org/simon/safcm/testutil"
26 )
27
28 func TestSyncServicesSystemd(t *testing.T) {
29         tests := []struct {
30                 name    string
31                 req     safcm.MsgSyncReq
32                 stdout  [][]byte
33                 stderr  [][]byte
34                 errors  []error
35                 expCmds []*exec.Cmd
36                 expDbg  []string
37                 expResp safcm.MsgSyncResp
38                 expErr  error
39         }{
40
41                 // NOTE: Also update MsgSyncResp in safcm test cases when
42                 // changing the MsgSyncResp struct!
43
44                 {
45                         "no service change necessary",
46                         safcm.MsgSyncReq{
47                                 Services: []string{
48                                         "service-one",
49                                         "service-two",
50                                 },
51                         },
52                         [][]byte{
53                                 []byte(`ActiveState=active
54 UnitFileState=enabled
55 LoadError=
56
57 ActiveState=active
58 UnitFileState=enabled
59 LoadError=
60 `),
61                         },
62                         [][]byte{nil},
63                         []error{nil},
64                         []*exec.Cmd{&exec.Cmd{
65                                 Path: "/bin/systemctl",
66                                 Args: []string{
67                                         "/bin/systemctl",
68                                         "show",
69                                         "--property=ActiveState,UnitFileState,LoadError",
70                                         "--",
71                                         "service-one",
72                                         "service-two",
73                                 },
74                                 Stdout: &bytes.Buffer{},
75                                 Stderr: &bytes.Buffer{},
76                         }},
77                         []string{
78                                 "4: sync remote: services: checking service-one service-two (systemd detected)",
79                                 `4: sync remote: services: running "/bin/systemctl" "show" "--property=ActiveState,UnitFileState,LoadError" "--" "service-one" "service-two"`,
80                                 `5: sync remote: services: command stdout:
81 ActiveState=active
82 UnitFileState=enabled
83 LoadError=
84
85 ActiveState=active
86 UnitFileState=enabled
87 LoadError=
88 `,
89                         },
90                         safcm.MsgSyncResp{},
91                         nil,
92                 },
93
94                 {
95                         "no service change necessary (older systemd)",
96                         safcm.MsgSyncReq{
97                                 Services: []string{
98                                         "service-one",
99                                         "service-two",
100                                 },
101                         },
102                         [][]byte{
103                                 []byte(`ActiveState=active
104 UnitFileState=enabled
105 LoadError= ""
106
107 ActiveState=active
108 UnitFileState=enabled
109 LoadError= ""
110 `),
111                         },
112                         [][]byte{nil},
113                         []error{nil},
114                         []*exec.Cmd{&exec.Cmd{
115                                 Path: "/bin/systemctl",
116                                 Args: []string{
117                                         "/bin/systemctl",
118                                         "show",
119                                         "--property=ActiveState,UnitFileState,LoadError",
120                                         "--",
121                                         "service-one",
122                                         "service-two",
123                                 },
124                                 Stdout: &bytes.Buffer{},
125                                 Stderr: &bytes.Buffer{},
126                         }},
127                         []string{
128                                 "4: sync remote: services: checking service-one service-two (systemd detected)",
129                                 `4: sync remote: services: running "/bin/systemctl" "show" "--property=ActiveState,UnitFileState,LoadError" "--" "service-one" "service-two"`,
130                                 `5: sync remote: services: command stdout:
131 ActiveState=active
132 UnitFileState=enabled
133 LoadError= ""
134
135 ActiveState=active
136 UnitFileState=enabled
137 LoadError= ""
138 `,
139                         },
140                         safcm.MsgSyncResp{},
141                         nil,
142                 },
143
144                 {
145                         "invalid service",
146                         safcm.MsgSyncReq{
147                                 Services: []string{
148                                         "service-does-not-exist",
149                                         "service-two",
150                                 },
151                         },
152                         [][]byte{
153                                 []byte(`ActiveState=inactive
154 UnitFileState=
155 LoadError=org.freedesktop.systemd1.NoSuchUnit "Unit service-does-not-exist.service not found."
156
157 ActiveState=active
158 UnitFileState=enabled
159 LoadError=
160 `),
161                         },
162                         [][]byte{nil},
163                         []error{nil},
164                         []*exec.Cmd{&exec.Cmd{
165                                 Path: "/bin/systemctl",
166                                 Args: []string{
167                                         "/bin/systemctl",
168                                         "show",
169                                         "--property=ActiveState,UnitFileState,LoadError",
170                                         "--",
171                                         "service-does-not-exist",
172                                         "service-two",
173                                 },
174                                 Stdout: &bytes.Buffer{},
175                                 Stderr: &bytes.Buffer{},
176                         }},
177                         []string{
178                                 "4: sync remote: services: checking service-does-not-exist service-two (systemd detected)",
179                                 `4: sync remote: services: running "/bin/systemctl" "show" "--property=ActiveState,UnitFileState,LoadError" "--" "service-does-not-exist" "service-two"`,
180                                 `5: sync remote: services: command stdout:
181 ActiveState=inactive
182 UnitFileState=
183 LoadError=org.freedesktop.systemd1.NoSuchUnit "Unit service-does-not-exist.service not found."
184
185 ActiveState=active
186 UnitFileState=enabled
187 LoadError=
188 `,
189                         },
190                         safcm.MsgSyncResp{},
191                         fmt.Errorf("systemd unit \"service-does-not-exist\" not found"),
192                 },
193
194                 {
195                         "start/enable service",
196                         safcm.MsgSyncReq{
197                                 Services: []string{
198                                         "service-one",
199                                         "service-two",
200                                         "service-three",
201                                 },
202                         },
203                         [][]byte{
204                                 []byte(`ActiveState=inactive
205 UnitFileState=enabled
206 LoadError=
207
208 ActiveState=active
209 UnitFileState=disabled
210 LoadError=
211
212 ActiveState=failed
213 UnitFileState=disabled
214 LoadError=
215 `),
216                                 nil,
217                                 nil,
218                                 nil,
219                         },
220                         [][]byte{
221                                 nil,
222                                 nil,
223                                 nil,
224                                 []byte("fake stderr"),
225                         },
226                         []error{nil, nil, nil, nil},
227                         []*exec.Cmd{&exec.Cmd{
228                                 Path: "/bin/systemctl",
229                                 Args: []string{
230                                         "/bin/systemctl",
231                                         "show",
232                                         "--property=ActiveState,UnitFileState,LoadError",
233                                         "--",
234                                         "service-one",
235                                         "service-two",
236                                         "service-three",
237                                 },
238                                 Stdout: &bytes.Buffer{},
239                                 Stderr: &bytes.Buffer{},
240                         }, &exec.Cmd{
241                                 Path: "/bin/systemctl",
242                                 Args: []string{
243                                         "/bin/systemctl",
244                                         "daemon-reload",
245                                 },
246                                 Stdout: &bytes.Buffer{},
247                                 Stderr: &bytes.Buffer{},
248                         }, &exec.Cmd{
249                                 Path: "/bin/systemctl",
250                                 Args: []string{
251                                         "/bin/systemctl",
252                                         "start",
253                                         "--",
254                                         "service-one",
255                                         "service-three",
256                                 },
257                                 Stdout: &bytes.Buffer{},
258                                 Stderr: &bytes.Buffer{},
259                         }, &exec.Cmd{
260                                 Path: "/bin/systemctl",
261                                 Args: []string{
262                                         "/bin/systemctl",
263                                         "enable",
264                                         "--",
265                                         "service-two",
266                                         "service-three",
267                                 },
268                                 Stdout: &bytes.Buffer{},
269                                 Stderr: &bytes.Buffer{},
270                         }},
271                         []string{
272                                 "4: sync remote: services: checking service-one service-two service-three (systemd detected)",
273                                 `4: sync remote: services: running "/bin/systemctl" "show" "--property=ActiveState,UnitFileState,LoadError" "--" "service-one" "service-two" "service-three"`,
274                                 `5: sync remote: services: command stdout:
275 ActiveState=inactive
276 UnitFileState=enabled
277 LoadError=
278
279 ActiveState=active
280 UnitFileState=disabled
281 LoadError=
282
283 ActiveState=failed
284 UnitFileState=disabled
285 LoadError=
286 `,
287                                 `4: sync remote: services: running "/bin/systemctl" "daemon-reload"`,
288                                 "3: sync remote: services: starting service-one service-three",
289                                 `4: sync remote: services: running "/bin/systemctl" "start" "--" "service-one" "service-three"`,
290                                 "3: sync remote: services: enabling service-two service-three",
291                                 `4: sync remote: services: running "/bin/systemctl" "enable" "--" "service-two" "service-three"`,
292                                 "5: sync remote: services: command stderr:\nfake stderr",
293                         },
294                         safcm.MsgSyncResp{
295                                 ServiceChanges: []safcm.ServiceChange{
296                                         {
297                                                 Name:    "service-one",
298                                                 Started: true,
299                                         },
300                                         {
301                                                 Name:    "service-two",
302                                                 Enabled: true,
303                                         },
304                                         {
305                                                 Name:    "service-three",
306                                                 Started: true,
307                                                 Enabled: true,
308                                         },
309                                 },
310                         },
311                         nil,
312                 },
313
314                 {
315                         "start/enable service (dry-run)",
316                         safcm.MsgSyncReq{
317                                 DryRun: true,
318                                 Services: []string{
319                                         "service-one",
320                                         "service-two",
321                                         "service-three",
322                                 },
323                         },
324                         [][]byte{
325                                 []byte(`ActiveState=inactive
326 UnitFileState=enabled
327 LoadError=
328
329 ActiveState=active
330 UnitFileState=disabled
331 LoadError=
332
333 ActiveState=failed
334 UnitFileState=disabled
335 LoadError=
336 `),
337                         },
338                         [][]byte{nil},
339                         []error{nil},
340                         []*exec.Cmd{&exec.Cmd{
341                                 Path: "/bin/systemctl",
342                                 Args: []string{
343                                         "/bin/systemctl",
344                                         "show",
345                                         "--property=ActiveState,UnitFileState,LoadError",
346                                         "--",
347                                         "service-one",
348                                         "service-two",
349                                         "service-three",
350                                 },
351                                 Stdout: &bytes.Buffer{},
352                                 Stderr: &bytes.Buffer{},
353                         }},
354                         []string{
355                                 "4: sync remote: services: checking service-one service-two service-three (systemd detected)",
356                                 `4: sync remote: services: running "/bin/systemctl" "show" "--property=ActiveState,UnitFileState,LoadError" "--" "service-one" "service-two" "service-three"`,
357                                 `5: sync remote: services: command stdout:
358 ActiveState=inactive
359 UnitFileState=enabled
360 LoadError=
361
362 ActiveState=active
363 UnitFileState=disabled
364 LoadError=
365
366 ActiveState=failed
367 UnitFileState=disabled
368 LoadError=
369 `,
370                         },
371                         safcm.MsgSyncResp{
372                                 ServiceChanges: []safcm.ServiceChange{
373                                         {
374                                                 Name:    "service-one",
375                                                 Started: true,
376                                         },
377                                         {
378                                                 Name:    "service-two",
379                                                 Enabled: true,
380                                         },
381                                         {
382                                                 Name:    "service-three",
383                                                 Started: true,
384                                                 Enabled: true,
385                                         },
386                                 },
387                         },
388                         nil,
389                 },
390
391                 {
392                         "start/enable service (error)",
393                         safcm.MsgSyncReq{
394                                 Services: []string{
395                                         "service-one",
396                                         "service-two",
397                                         "service-three",
398                                 },
399                         },
400                         [][]byte{
401                                 []byte(`ActiveState=inactive
402 UnitFileState=enabled
403 LoadError=
404
405 ActiveState=active
406 UnitFileState=disabled
407 LoadError=
408
409 ActiveState=failed
410 UnitFileState=disabled
411 LoadError=
412 `),
413                                 nil,
414                                 nil,
415                         },
416                         [][]byte{
417                                 nil,
418                                 nil,
419                                 []byte("fake stderr"),
420                         },
421                         []error{
422                                 nil,
423                                 nil,
424                                 fmt.Errorf("fake error"),
425                         },
426                         []*exec.Cmd{&exec.Cmd{
427                                 Path: "/bin/systemctl",
428                                 Args: []string{
429                                         "/bin/systemctl",
430                                         "show",
431                                         "--property=ActiveState,UnitFileState,LoadError",
432                                         "--",
433                                         "service-one",
434                                         "service-two",
435                                         "service-three",
436                                 },
437                                 Stdout: &bytes.Buffer{},
438                                 Stderr: &bytes.Buffer{},
439                         }, &exec.Cmd{
440                                 Path: "/bin/systemctl",
441                                 Args: []string{
442                                         "/bin/systemctl",
443                                         "daemon-reload",
444                                 },
445                                 Stdout: &bytes.Buffer{},
446                                 Stderr: &bytes.Buffer{},
447                         }, &exec.Cmd{
448                                 Path: "/bin/systemctl",
449                                 Args: []string{
450                                         "/bin/systemctl",
451                                         "start",
452                                         "--",
453                                         "service-one",
454                                         "service-three",
455                                 },
456                                 Stdout: &bytes.Buffer{},
457                                 Stderr: &bytes.Buffer{},
458                         }},
459                         []string{
460                                 "4: sync remote: services: checking service-one service-two service-three (systemd detected)",
461                                 `4: sync remote: services: running "/bin/systemctl" "show" "--property=ActiveState,UnitFileState,LoadError" "--" "service-one" "service-two" "service-three"`,
462                                 `5: sync remote: services: command stdout:
463 ActiveState=inactive
464 UnitFileState=enabled
465 LoadError=
466
467 ActiveState=active
468 UnitFileState=disabled
469 LoadError=
470
471 ActiveState=failed
472 UnitFileState=disabled
473 LoadError=
474 `,
475                                 `4: sync remote: services: running "/bin/systemctl" "daemon-reload"`,
476                                 "3: sync remote: services: starting service-one service-three",
477                                 `4: sync remote: services: running "/bin/systemctl" "start" "--" "service-one" "service-three"`,
478                                 "5: sync remote: services: command stderr:\nfake stderr",
479                         },
480                         safcm.MsgSyncResp{
481                                 ServiceChanges: []safcm.ServiceChange{
482                                         {
483                                                 Name:    "service-one",
484                                                 Started: true,
485                                         },
486                                         {
487                                                 Name:    "service-two",
488                                                 Enabled: true,
489                                         },
490                                         {
491                                                 Name:    "service-three",
492                                                 Started: true,
493                                                 Enabled: true,
494                                         },
495                                 },
496                         },
497                         fmt.Errorf(`"/bin/systemctl" "start" "--" "service-one" "service-three" failed: fake error; stdout: "", stderr: "fake stderr"`),
498                 },
499         }
500
501         for _, tc := range tests {
502                 t.Run(tc.name, func(t *testing.T) {
503                         s, res := prepareSync(tc.req, &testRunner{
504                                 t:         t,
505                                 expCmds:   tc.expCmds,
506                                 resStdout: tc.stdout,
507                                 resStderr: tc.stderr,
508                                 resError:  tc.errors,
509                         })
510
511                         err := s.syncServicesSystemd()
512                         testutil.AssertErrorEqual(t, "err", err, tc.expErr)
513                         dbg := res.Wait()
514
515                         testutil.AssertEqual(t, "resp", s.resp, tc.expResp)
516                         testutil.AssertEqual(t, "dbg", dbg, tc.expDbg)
517                 })
518         }
519 }