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/>.
25 "ruderich.org/simon/safcm"
26 "ruderich.org/simon/safcm/testutil"
29 func TestSyncCommands(t *testing.T) {
30 exe, err := os.Executable()
34 env := append(os.Environ(),
36 "SAFCM_GROUPS=all group1 group2 host.example.org",
37 "SAFCM_GROUP_all=all",
38 "SAFCM_GROUP_group1=group1",
39 "SAFCM_GROUP_group2=group2",
40 "SAFCM_GROUP_host.example.org=host.example.org",
52 expResp safcm.MsgSyncResp
56 // NOTE: Also update MsgSyncResp in safcm test cases when
57 // changing the MsgSyncResp struct!
68 Commands: []*safcm.Command{
71 Cmd: "echo; env | grep SAFCM_",
76 [][]byte{[]byte("fake stdout/stderr")},
83 "echo; env | grep SAFCM_",
88 `3: sync remote: commands: running "/bin/sh" "-c" "echo; env | grep SAFCM_" (group)`,
89 "5: sync remote: commands: command output:\nfake stdout/stderr",
92 CommandChanges: []safcm.CommandChange{
94 Command: "echo; env | grep SAFCM_",
95 Output: "fake stdout/stderr",
102 "successful command (dry-run)",
111 Commands: []*safcm.Command{
114 Cmd: "echo; env | grep SAFCM_",
125 CommandChanges: []safcm.CommandChange{
127 Command: "echo; env | grep SAFCM_",
143 Commands: []*safcm.Command{
146 Cmd: "echo hi; false",
151 [][]byte{[]byte("fake stdout/stderr")},
153 []error{fmt.Errorf("fake error")},
163 `3: sync remote: commands: running "/bin/sh" "-c" "echo hi; false" (group)`,
164 "5: sync remote: commands: command output:\nfake stdout/stderr",
167 CommandChanges: []safcm.CommandChange{
169 Command: "echo hi; false",
170 Output: "fake stdout/stderr",
175 fmt.Errorf("\"echo hi; false\" failed: fake error"),
178 "failed command (dry-run)",
187 Commands: []*safcm.Command{
190 Cmd: "echo hi; false",
201 CommandChanges: []safcm.CommandChange{
203 Command: "echo hi; false",
211 "multiple commands, abort on first failed",
219 Commands: []*safcm.Command{
237 []byte("fake stdout/stderr first"),
238 []byte("fake stdout/stderr second"),
249 fmt.Errorf("fake error"),
274 `3: sync remote: commands: running "/bin/sh" "-c" "echo first" (group1)`,
275 "5: sync remote: commands: command output:\nfake stdout/stderr first",
276 `3: sync remote: commands: running "/bin/sh" "-c" "echo second" (group2)`,
277 "5: sync remote: commands: command output:\nfake stdout/stderr second",
278 `3: sync remote: commands: running "/bin/sh" "-c" "false" (group3)`,
281 CommandChanges: []safcm.CommandChange{
283 Command: "echo first",
284 Output: "fake stdout/stderr first",
287 Command: "echo second",
288 Output: "fake stdout/stderr second",
297 fmt.Errorf("\"false\" failed: fake error"),
309 Files: map[string]*safcm.File{
312 Mode: fs.ModeDir | 0700,
316 TriggerCommands: []string{
322 Mode: fs.ModeDir | 0755,
326 TriggerCommands: []string{
335 Data: []byte("content\n"),
337 TriggerCommands: []string{
338 "echo trigger dir/file",
342 Commands: []*safcm.Command{
345 Cmd: "echo; env | grep SAFCM_",
354 []byte("fake stdout/stderr ."),
355 []byte("fake stdout/stderr dir"),
356 []byte("fake stdout/stderr"),
386 "echo; env | grep SAFCM_",
391 `3: sync remote: commands: running "/bin/sh" "-c" "echo trigger ." (".")`,
392 "5: sync remote: commands: command output:\nfake stdout/stderr .",
393 `3: sync remote: commands: running "/bin/sh" "-c" "echo trigger dir" ("dir")`,
394 "5: sync remote: commands: command output:\nfake stdout/stderr dir",
395 `3: sync remote: commands: running "/bin/sh" "-c" "echo; env | grep SAFCM_" (group)`,
396 "5: sync remote: commands: command output:\nfake stdout/stderr",
399 CommandChanges: []safcm.CommandChange{
401 Command: "echo trigger .",
403 Output: "fake stdout/stderr .",
406 Command: "echo trigger dir",
408 Output: "fake stdout/stderr dir",
411 Command: "echo; env | grep SAFCM_",
412 Output: "fake stdout/stderr",
428 Files: map[string]*safcm.File{
431 Mode: fs.ModeDir | 0700,
435 TriggerCommands: []string{
441 Mode: fs.ModeDir | 0755,
445 TriggerCommands: []string{
454 Data: []byte("content\n"),
456 TriggerCommands: []string{
457 "echo trigger dir/file",
461 Commands: []*safcm.Command{
464 Cmd: "echo; env | grep SAFCM_",
473 []byte("fake stdout/stderr ."),
474 []byte("fake stdout/stderr dir"),
482 fmt.Errorf("fake error"),
500 `3: sync remote: commands: running "/bin/sh" "-c" "echo trigger ." (".")`,
501 "5: sync remote: commands: command output:\nfake stdout/stderr .",
502 `3: sync remote: commands: running "/bin/sh" "-c" "false" ("dir")`,
503 "5: sync remote: commands: command output:\nfake stdout/stderr dir",
506 CommandChanges: []safcm.CommandChange{
508 Command: "echo trigger .",
510 Output: "fake stdout/stderr .",
515 Output: "fake stdout/stderr dir",
520 fmt.Errorf("\"false\" failed: fake error"),
524 for _, tc := range tests {
525 t.Run(tc.name, func(t *testing.T) {
526 s, res := prepareSync(tc.req, &testRunner{
529 resStdout: tc.stdout,
530 resStderr: tc.stderr,
533 s.triggers = tc.triggers
535 err := s.syncCommands()
536 testutil.AssertErrorEqual(t, "err", err, tc.expErr)
539 testutil.AssertEqual(t, "resp", s.resp, tc.expResp)
540 testutil.AssertEqual(t, "dbg", dbg, tc.expDbg)