]> ruderich.org/simon Gitweb - safcm/safcm.git/blob - cmd/safcm-remote/sync/services_systemd_test.go
sync: tests: use "..." instead of `...` for regular strings
[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 anything here!
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: detected systemd",
79                                 "4: sync remote: services: checking service-one service-two",
80                                 `4: sync remote: services: running "/bin/systemctl" "show" "--property=ActiveState,UnitFileState,LoadError" "--" "service-one" "service-two"`,
81                                 `5: sync remote: services: command stdout:
82 ActiveState=active
83 UnitFileState=enabled
84 LoadError=
85
86 ActiveState=active
87 UnitFileState=enabled
88 LoadError=
89 `,
90                         },
91                         safcm.MsgSyncResp{},
92                         nil,
93                 },
94
95                 {
96                         "no service change necessary (older systemd)",
97                         safcm.MsgSyncReq{
98                                 Services: []string{
99                                         "service-one",
100                                         "service-two",
101                                 },
102                         },
103                         [][]byte{
104                                 []byte(`ActiveState=active
105 UnitFileState=enabled
106 LoadError= ""
107
108 ActiveState=active
109 UnitFileState=enabled
110 LoadError= ""
111 `),
112                         },
113                         [][]byte{nil},
114                         []error{nil},
115                         []*exec.Cmd{&exec.Cmd{
116                                 Path: "/bin/systemctl",
117                                 Args: []string{
118                                         "/bin/systemctl",
119                                         "show",
120                                         "--property=ActiveState,UnitFileState,LoadError",
121                                         "--",
122                                         "service-one",
123                                         "service-two",
124                                 },
125                                 Stdout: &bytes.Buffer{},
126                                 Stderr: &bytes.Buffer{},
127                         }},
128                         []string{
129                                 "4: sync remote: services: detected systemd",
130                                 "4: sync remote: services: checking service-one service-two",
131                                 `4: sync remote: services: running "/bin/systemctl" "show" "--property=ActiveState,UnitFileState,LoadError" "--" "service-one" "service-two"`,
132                                 `5: sync remote: services: command stdout:
133 ActiveState=active
134 UnitFileState=enabled
135 LoadError= ""
136
137 ActiveState=active
138 UnitFileState=enabled
139 LoadError= ""
140 `,
141                         },
142                         safcm.MsgSyncResp{},
143                         nil,
144                 },
145
146                 {
147                         "invalid service",
148                         safcm.MsgSyncReq{
149                                 Services: []string{
150                                         "service-does-not-exist",
151                                         "service-two",
152                                 },
153                         },
154                         [][]byte{
155                                 []byte(`ActiveState=inactive
156 UnitFileState=
157 LoadError=org.freedesktop.systemd1.NoSuchUnit "Unit service-does-not-exist.service not found."
158
159 ActiveState=active
160 UnitFileState=enabled
161 LoadError=
162 `),
163                         },
164                         [][]byte{nil},
165                         []error{nil},
166                         []*exec.Cmd{&exec.Cmd{
167                                 Path: "/bin/systemctl",
168                                 Args: []string{
169                                         "/bin/systemctl",
170                                         "show",
171                                         "--property=ActiveState,UnitFileState,LoadError",
172                                         "--",
173                                         "service-does-not-exist",
174                                         "service-two",
175                                 },
176                                 Stdout: &bytes.Buffer{},
177                                 Stderr: &bytes.Buffer{},
178                         }},
179                         []string{
180                                 "4: sync remote: services: detected systemd",
181                                 "4: sync remote: services: checking service-does-not-exist service-two",
182                                 `4: sync remote: services: running "/bin/systemctl" "show" "--property=ActiveState,UnitFileState,LoadError" "--" "service-does-not-exist" "service-two"`,
183                                 `5: sync remote: services: command stdout:
184 ActiveState=inactive
185 UnitFileState=
186 LoadError=org.freedesktop.systemd1.NoSuchUnit "Unit service-does-not-exist.service not found."
187
188 ActiveState=active
189 UnitFileState=enabled
190 LoadError=
191 `,
192                         },
193                         safcm.MsgSyncResp{},
194                         fmt.Errorf("systemd unit \"service-does-not-exist\" not found"),
195                 },
196
197                 {
198                         "start/enable service",
199                         safcm.MsgSyncReq{
200                                 Services: []string{
201                                         "service-one",
202                                         "service-two",
203                                         "service-three",
204                                 },
205                         },
206                         [][]byte{
207                                 []byte(`ActiveState=inactive
208 UnitFileState=enabled
209 LoadError=
210
211 ActiveState=active
212 UnitFileState=disabled
213 LoadError=
214
215 ActiveState=failed
216 UnitFileState=disabled
217 LoadError=
218 `),
219                                 nil,
220                                 nil,
221                                 nil,
222                         },
223                         [][]byte{
224                                 nil,
225                                 nil,
226                                 nil,
227                                 []byte("fake stderr"),
228                         },
229                         []error{nil, nil, nil, nil},
230                         []*exec.Cmd{&exec.Cmd{
231                                 Path: "/bin/systemctl",
232                                 Args: []string{
233                                         "/bin/systemctl",
234                                         "show",
235                                         "--property=ActiveState,UnitFileState,LoadError",
236                                         "--",
237                                         "service-one",
238                                         "service-two",
239                                         "service-three",
240                                 },
241                                 Stdout: &bytes.Buffer{},
242                                 Stderr: &bytes.Buffer{},
243                         }, &exec.Cmd{
244                                 Path: "/bin/systemctl",
245                                 Args: []string{
246                                         "/bin/systemctl",
247                                         "daemon-reload",
248                                 },
249                                 Stdout: &bytes.Buffer{},
250                                 Stderr: &bytes.Buffer{},
251                         }, &exec.Cmd{
252                                 Path: "/bin/systemctl",
253                                 Args: []string{
254                                         "/bin/systemctl",
255                                         "start",
256                                         "--",
257                                         "service-one",
258                                         "service-three",
259                                 },
260                                 Stdout: &bytes.Buffer{},
261                                 Stderr: &bytes.Buffer{},
262                         }, &exec.Cmd{
263                                 Path: "/bin/systemctl",
264                                 Args: []string{
265                                         "/bin/systemctl",
266                                         "enable",
267                                         "--",
268                                         "service-two",
269                                         "service-three",
270                                 },
271                                 Stdout: &bytes.Buffer{},
272                                 Stderr: &bytes.Buffer{},
273                         }},
274                         []string{
275                                 "4: sync remote: services: detected systemd",
276                                 "4: sync remote: services: checking service-one service-two service-three",
277                                 `4: sync remote: services: running "/bin/systemctl" "show" "--property=ActiveState,UnitFileState,LoadError" "--" "service-one" "service-two" "service-three"`,
278                                 `5: sync remote: services: command stdout:
279 ActiveState=inactive
280 UnitFileState=enabled
281 LoadError=
282
283 ActiveState=active
284 UnitFileState=disabled
285 LoadError=
286
287 ActiveState=failed
288 UnitFileState=disabled
289 LoadError=
290 `,
291                                 `4: sync remote: services: running "/bin/systemctl" "daemon-reload"`,
292                                 "3: sync remote: services: starting service-one service-three",
293                                 `4: sync remote: services: running "/bin/systemctl" "start" "--" "service-one" "service-three"`,
294                                 "3: sync remote: services: enabling service-two service-three",
295                                 `4: sync remote: services: running "/bin/systemctl" "enable" "--" "service-two" "service-three"`,
296                                 "5: sync remote: services: command stderr:\nfake stderr",
297                         },
298                         safcm.MsgSyncResp{
299                                 ServiceChanges: []safcm.ServiceChange{
300                                         {
301                                                 Name:    "service-one",
302                                                 Started: true,
303                                         },
304                                         {
305                                                 Name:    "service-two",
306                                                 Enabled: true,
307                                         },
308                                         {
309                                                 Name:    "service-three",
310                                                 Started: true,
311                                                 Enabled: true,
312                                         },
313                                 },
314                         },
315                         nil,
316                 },
317
318                 {
319                         "start/enable service (dry-run)",
320                         safcm.MsgSyncReq{
321                                 DryRun: true,
322                                 Services: []string{
323                                         "service-one",
324                                         "service-two",
325                                         "service-three",
326                                 },
327                         },
328                         [][]byte{
329                                 []byte(`ActiveState=inactive
330 UnitFileState=enabled
331 LoadError=
332
333 ActiveState=active
334 UnitFileState=disabled
335 LoadError=
336
337 ActiveState=failed
338 UnitFileState=disabled
339 LoadError=
340 `),
341                         },
342                         [][]byte{nil},
343                         []error{nil},
344                         []*exec.Cmd{&exec.Cmd{
345                                 Path: "/bin/systemctl",
346                                 Args: []string{
347                                         "/bin/systemctl",
348                                         "show",
349                                         "--property=ActiveState,UnitFileState,LoadError",
350                                         "--",
351                                         "service-one",
352                                         "service-two",
353                                         "service-three",
354                                 },
355                                 Stdout: &bytes.Buffer{},
356                                 Stderr: &bytes.Buffer{},
357                         }},
358                         []string{
359                                 "4: sync remote: services: detected systemd",
360                                 "4: sync remote: services: checking service-one service-two service-three",
361                                 `4: sync remote: services: running "/bin/systemctl" "show" "--property=ActiveState,UnitFileState,LoadError" "--" "service-one" "service-two" "service-three"`,
362                                 `5: sync remote: services: command stdout:
363 ActiveState=inactive
364 UnitFileState=enabled
365 LoadError=
366
367 ActiveState=active
368 UnitFileState=disabled
369 LoadError=
370
371 ActiveState=failed
372 UnitFileState=disabled
373 LoadError=
374 `,
375                         },
376                         safcm.MsgSyncResp{
377                                 ServiceChanges: []safcm.ServiceChange{
378                                         {
379                                                 Name:    "service-one",
380                                                 Started: true,
381                                         },
382                                         {
383                                                 Name:    "service-two",
384                                                 Enabled: true,
385                                         },
386                                         {
387                                                 Name:    "service-three",
388                                                 Started: true,
389                                                 Enabled: true,
390                                         },
391                                 },
392                         },
393                         nil,
394                 },
395
396                 {
397                         "start/enable service (error)",
398                         safcm.MsgSyncReq{
399                                 Services: []string{
400                                         "service-one",
401                                         "service-two",
402                                         "service-three",
403                                 },
404                         },
405                         [][]byte{
406                                 []byte(`ActiveState=inactive
407 UnitFileState=enabled
408 LoadError=
409
410 ActiveState=active
411 UnitFileState=disabled
412 LoadError=
413
414 ActiveState=failed
415 UnitFileState=disabled
416 LoadError=
417 `),
418                                 nil,
419                                 nil,
420                         },
421                         [][]byte{
422                                 nil,
423                                 nil,
424                                 []byte("fake stderr"),
425                         },
426                         []error{
427                                 nil,
428                                 nil,
429                                 fmt.Errorf("fake error"),
430                         },
431                         []*exec.Cmd{&exec.Cmd{
432                                 Path: "/bin/systemctl",
433                                 Args: []string{
434                                         "/bin/systemctl",
435                                         "show",
436                                         "--property=ActiveState,UnitFileState,LoadError",
437                                         "--",
438                                         "service-one",
439                                         "service-two",
440                                         "service-three",
441                                 },
442                                 Stdout: &bytes.Buffer{},
443                                 Stderr: &bytes.Buffer{},
444                         }, &exec.Cmd{
445                                 Path: "/bin/systemctl",
446                                 Args: []string{
447                                         "/bin/systemctl",
448                                         "daemon-reload",
449                                 },
450                                 Stdout: &bytes.Buffer{},
451                                 Stderr: &bytes.Buffer{},
452                         }, &exec.Cmd{
453                                 Path: "/bin/systemctl",
454                                 Args: []string{
455                                         "/bin/systemctl",
456                                         "start",
457                                         "--",
458                                         "service-one",
459                                         "service-three",
460                                 },
461                                 Stdout: &bytes.Buffer{},
462                                 Stderr: &bytes.Buffer{},
463                         }},
464                         []string{
465                                 "4: sync remote: services: detected systemd",
466                                 "4: sync remote: services: checking service-one service-two service-three",
467                                 `4: sync remote: services: running "/bin/systemctl" "show" "--property=ActiveState,UnitFileState,LoadError" "--" "service-one" "service-two" "service-three"`,
468                                 `5: sync remote: services: command stdout:
469 ActiveState=inactive
470 UnitFileState=enabled
471 LoadError=
472
473 ActiveState=active
474 UnitFileState=disabled
475 LoadError=
476
477 ActiveState=failed
478 UnitFileState=disabled
479 LoadError=
480 `,
481                                 `4: sync remote: services: running "/bin/systemctl" "daemon-reload"`,
482                                 "3: sync remote: services: starting service-one service-three",
483                                 `4: sync remote: services: running "/bin/systemctl" "start" "--" "service-one" "service-three"`,
484                                 "5: sync remote: services: command stderr:\nfake stderr",
485                         },
486                         safcm.MsgSyncResp{
487                                 ServiceChanges: []safcm.ServiceChange{
488                                         {
489                                                 Name:    "service-one",
490                                                 Started: true,
491                                         },
492                                         {
493                                                 Name:    "service-two",
494                                                 Enabled: true,
495                                         },
496                                         {
497                                                 Name:    "service-three",
498                                                 Started: true,
499                                                 Enabled: true,
500                                         },
501                                 },
502                         },
503                         fmt.Errorf(`"/bin/systemctl" "start" "--" "service-one" "service-three" failed: fake error; stdout: "", stderr: "fake stderr"`),
504                 },
505         }
506
507         for _, tc := range tests {
508                 t.Run(tc.name, func(t *testing.T) {
509                         s, res := prepareSync(tc.req, &testRunner{
510                                 t:         t,
511                                 expCmds:   tc.expCmds,
512                                 resStdout: tc.stdout,
513                                 resStderr: tc.stderr,
514                                 resError:  tc.errors,
515                         })
516
517                         err := s.syncServicesSystemd()
518                         testutil.AssertErrorEqual(t, "err", err, tc.expErr)
519                         dbg := res.Wait()
520
521                         testutil.AssertEqual(t, "resp", s.resp, tc.expResp)
522                         testutil.AssertEqual(t, "dbg", dbg, tc.expDbg)
523                 })
524         }
525 }