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 anything here!
68 Commands: []*safcm.Command{
70 Cmd: "echo; env | grep SAFCM_",
75 [][]byte{[]byte("fake stdout/stderr")},
82 "echo; env | grep SAFCM_",
87 `3: sync remote: commands: running "/bin/sh" "-c" "echo; env | grep SAFCM_"`,
88 "5: sync remote: commands: command output:\nfake stdout/stderr",
91 CommandChanges: []safcm.CommandChange{
93 Command: "echo; env | grep SAFCM_",
94 Output: "fake stdout/stderr",
101 "successful command (dry-run)",
110 Commands: []*safcm.Command{
112 Cmd: "echo; env | grep SAFCM_",
123 CommandChanges: []safcm.CommandChange{
125 Command: "echo; env | grep SAFCM_",
141 Commands: []*safcm.Command{
143 Cmd: "echo hi; false",
148 [][]byte{[]byte("fake stdout/stderr")},
150 []error{fmt.Errorf("fake error")},
160 `3: sync remote: commands: running "/bin/sh" "-c" "echo hi; false"`,
161 "5: sync remote: commands: command output:\nfake stdout/stderr",
164 CommandChanges: []safcm.CommandChange{
166 Command: "echo hi; false",
167 Output: "fake stdout/stderr",
172 fmt.Errorf("\"echo hi; false\" failed: fake error"),
175 "failed command (dry-run)",
184 Commands: []*safcm.Command{
186 Cmd: "echo hi; false",
197 CommandChanges: []safcm.CommandChange{
199 Command: "echo hi; false",
207 "multiple commands, abort on first failed",
215 Commands: []*safcm.Command{
229 []byte("fake stdout/stderr first"),
230 []byte("fake stdout/stderr second"),
241 fmt.Errorf("fake error"),
266 `3: sync remote: commands: running "/bin/sh" "-c" "echo first"`,
267 "5: sync remote: commands: command output:\nfake stdout/stderr first",
268 `3: sync remote: commands: running "/bin/sh" "-c" "echo second"`,
269 "5: sync remote: commands: command output:\nfake stdout/stderr second",
270 `3: sync remote: commands: running "/bin/sh" "-c" "false"`,
273 CommandChanges: []safcm.CommandChange{
275 Command: "echo first",
276 Output: "fake stdout/stderr first",
279 Command: "echo second",
280 Output: "fake stdout/stderr second",
289 fmt.Errorf("\"false\" failed: fake error"),
301 Files: map[string]*safcm.File{
304 Mode: fs.ModeDir | 0700,
308 TriggerCommands: []string{
314 Mode: fs.ModeDir | 0755,
318 TriggerCommands: []string{
327 Data: []byte("content\n"),
329 TriggerCommands: []string{
330 "echo trigger dir/file",
334 Commands: []*safcm.Command{
336 Cmd: "echo; env | grep SAFCM_",
345 []byte("fake stdout/stderr ."),
346 []byte("fake stdout/stderr dir"),
347 []byte("fake stdout/stderr"),
377 "echo; env | grep SAFCM_",
382 `3: sync remote: commands: running "/bin/sh" "-c" "echo trigger ."`,
383 "5: sync remote: commands: command output:\nfake stdout/stderr .",
384 `3: sync remote: commands: running "/bin/sh" "-c" "echo trigger dir"`,
385 "5: sync remote: commands: command output:\nfake stdout/stderr dir",
386 `3: sync remote: commands: running "/bin/sh" "-c" "echo; env | grep SAFCM_"`,
387 "5: sync remote: commands: command output:\nfake stdout/stderr",
390 CommandChanges: []safcm.CommandChange{
392 Command: "echo trigger .",
394 Output: "fake stdout/stderr .",
397 Command: "echo trigger dir",
399 Output: "fake stdout/stderr dir",
402 Command: "echo; env | grep SAFCM_",
403 Output: "fake stdout/stderr",
419 Files: map[string]*safcm.File{
422 Mode: fs.ModeDir | 0700,
426 TriggerCommands: []string{
432 Mode: fs.ModeDir | 0755,
436 TriggerCommands: []string{
445 Data: []byte("content\n"),
447 TriggerCommands: []string{
448 "echo trigger dir/file",
452 Commands: []*safcm.Command{
454 Cmd: "echo; env | grep SAFCM_",
463 []byte("fake stdout/stderr ."),
464 []byte("fake stdout/stderr dir"),
472 fmt.Errorf("fake error"),
490 `3: sync remote: commands: running "/bin/sh" "-c" "echo trigger ."`,
491 "5: sync remote: commands: command output:\nfake stdout/stderr .",
492 `3: sync remote: commands: running "/bin/sh" "-c" "false"`,
493 "5: sync remote: commands: command output:\nfake stdout/stderr dir",
496 CommandChanges: []safcm.CommandChange{
498 Command: "echo trigger .",
500 Output: "fake stdout/stderr .",
505 Output: "fake stdout/stderr dir",
510 fmt.Errorf("\"false\" failed: fake error"),
514 for _, tc := range tests {
515 t.Run(tc.name, func(t *testing.T) {
516 s, res := prepareSync(tc.req, &testRunner{
519 resStdout: tc.stdout,
520 resStderr: tc.stderr,
523 s.triggers = tc.triggers
525 err := s.syncCommands()
526 testutil.AssertErrorEqual(t, "err", err, tc.expErr)
529 testutil.AssertEqual(t, "resp", s.resp, tc.expResp)
530 testutil.AssertEqual(t, "dbg", dbg, tc.expDbg)