1 // Copyright (C) 2021 Simon Ruderich
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.
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.
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/>.
24 "ruderich.org/simon/safcm"
25 "ruderich.org/simon/safcm/testutil"
28 func TestSyncServicesSystemd(t *testing.T) {
37 expResp safcm.MsgSyncResp
41 // NOTE: Also update MsgSyncResp in safcm test cases when
42 // changing the MsgSyncResp struct!
45 "no service change necessary",
53 []byte(`ActiveState=active
64 []*exec.Cmd{&exec.Cmd{
65 Path: "/bin/systemctl",
69 "--property=ActiveState,UnitFileState,LoadError",
74 Stdout: &bytes.Buffer{},
75 Stderr: &bytes.Buffer{},
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:
96 "no service change necessary (older systemd)",
104 []byte(`ActiveState=active
105 UnitFileState=enabled
109 UnitFileState=enabled
115 []*exec.Cmd{&exec.Cmd{
116 Path: "/bin/systemctl",
120 "--property=ActiveState,UnitFileState,LoadError",
125 Stdout: &bytes.Buffer{},
126 Stderr: &bytes.Buffer{},
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:
134 UnitFileState=enabled
138 UnitFileState=enabled
150 "service-does-not-exist",
155 []byte(`ActiveState=inactive
157 LoadError=org.freedesktop.systemd1.NoSuchUnit "Unit service-does-not-exist.service not found."
160 UnitFileState=enabled
166 []*exec.Cmd{&exec.Cmd{
167 Path: "/bin/systemctl",
171 "--property=ActiveState,UnitFileState,LoadError",
173 "service-does-not-exist",
176 Stdout: &bytes.Buffer{},
177 Stderr: &bytes.Buffer{},
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:
186 LoadError=org.freedesktop.systemd1.NoSuchUnit "Unit service-does-not-exist.service not found."
189 UnitFileState=enabled
194 fmt.Errorf("systemd unit \"service-does-not-exist\" not found"),
198 "start/enable service",
207 []byte(`ActiveState=inactive
208 UnitFileState=enabled
212 UnitFileState=disabled
216 UnitFileState=disabled
227 []byte("fake stderr"),
229 []error{nil, nil, nil, nil},
230 []*exec.Cmd{&exec.Cmd{
231 Path: "/bin/systemctl",
235 "--property=ActiveState,UnitFileState,LoadError",
241 Stdout: &bytes.Buffer{},
242 Stderr: &bytes.Buffer{},
244 Path: "/bin/systemctl",
249 Stdout: &bytes.Buffer{},
250 Stderr: &bytes.Buffer{},
252 Path: "/bin/systemctl",
260 Stdout: &bytes.Buffer{},
261 Stderr: &bytes.Buffer{},
263 Path: "/bin/systemctl",
271 Stdout: &bytes.Buffer{},
272 Stderr: &bytes.Buffer{},
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:
280 UnitFileState=enabled
284 UnitFileState=disabled
288 UnitFileState=disabled
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",
299 ServiceChanges: []safcm.ServiceChange{
309 Name: "service-three",
319 "start/enable service (dry-run)",
329 []byte(`ActiveState=inactive
330 UnitFileState=enabled
334 UnitFileState=disabled
338 UnitFileState=disabled
344 []*exec.Cmd{&exec.Cmd{
345 Path: "/bin/systemctl",
349 "--property=ActiveState,UnitFileState,LoadError",
355 Stdout: &bytes.Buffer{},
356 Stderr: &bytes.Buffer{},
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:
364 UnitFileState=enabled
368 UnitFileState=disabled
372 UnitFileState=disabled
377 ServiceChanges: []safcm.ServiceChange{
387 Name: "service-three",
397 "start/enable service (error)",
406 []byte(`ActiveState=inactive
407 UnitFileState=enabled
411 UnitFileState=disabled
415 UnitFileState=disabled
424 []byte("fake stderr"),
429 fmt.Errorf("fake error"),
431 []*exec.Cmd{&exec.Cmd{
432 Path: "/bin/systemctl",
436 "--property=ActiveState,UnitFileState,LoadError",
442 Stdout: &bytes.Buffer{},
443 Stderr: &bytes.Buffer{},
445 Path: "/bin/systemctl",
450 Stdout: &bytes.Buffer{},
451 Stderr: &bytes.Buffer{},
453 Path: "/bin/systemctl",
461 Stdout: &bytes.Buffer{},
462 Stderr: &bytes.Buffer{},
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:
470 UnitFileState=enabled
474 UnitFileState=disabled
478 UnitFileState=disabled
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",
487 ServiceChanges: []safcm.ServiceChange{
497 Name: "service-three",
503 fmt.Errorf(`"/bin/systemctl" "start" "--" "service-one" "service-three" failed: fake error; stdout: "", stderr: "fake stderr"`),
507 for _, tc := range tests {
508 t.Run(tc.name, func(t *testing.T) {
509 s, res := prepareSync(tc.req, &testRunner{
512 resStdout: tc.stdout,
513 resStderr: tc.stderr,
517 err := s.syncServicesSystemd()
518 testutil.AssertErrorEqual(t, "err", err, tc.expErr)
521 testutil.AssertEqual(t, "resp", s.resp, tc.expResp)
522 testutil.AssertEqual(t, "dbg", dbg, tc.expDbg)