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!
69 "echo; env | grep SAFCM_",
73 [][]byte{[]byte("fake stdout/stderr")},
80 "echo; env | grep SAFCM_",
85 `3: sync remote: commands: running "/bin/sh" "-c" "echo; env | grep SAFCM_"`,
86 "5: sync remote: commands: command output:\nfake stdout/stderr",
89 CommandChanges: []safcm.CommandChange{
91 Command: "echo; env | grep SAFCM_",
92 Output: "fake stdout/stderr",
99 "successful command (dry-run)",
109 "echo; env | grep SAFCM_",
119 CommandChanges: []safcm.CommandChange{
121 Command: "echo; env | grep SAFCM_",
142 [][]byte{[]byte("fake stdout/stderr")},
144 []error{fmt.Errorf("fake error")},
154 `3: sync remote: commands: running "/bin/sh" "-c" "echo hi; false"`,
155 "5: sync remote: commands: command output:\nfake stdout/stderr",
158 CommandChanges: []safcm.CommandChange{
160 Command: "echo hi; false",
161 Output: "fake stdout/stderr",
166 fmt.Errorf("\"echo hi; false\" failed: fake error"),
169 "failed command (dry-run)",
189 CommandChanges: []safcm.CommandChange{
191 Command: "echo hi; false",
199 "multiple commands, abort on first failed",
216 []byte("fake stdout/stderr first"),
217 []byte("fake stdout/stderr second"),
228 fmt.Errorf("fake error"),
253 `3: sync remote: commands: running "/bin/sh" "-c" "echo first"`,
254 "5: sync remote: commands: command output:\nfake stdout/stderr first",
255 `3: sync remote: commands: running "/bin/sh" "-c" "echo second"`,
256 "5: sync remote: commands: command output:\nfake stdout/stderr second",
257 `3: sync remote: commands: running "/bin/sh" "-c" "false"`,
260 CommandChanges: []safcm.CommandChange{
262 Command: "echo first",
263 Output: "fake stdout/stderr first",
266 Command: "echo second",
267 Output: "fake stdout/stderr second",
276 fmt.Errorf("\"false\" failed: fake error"),
288 Files: map[string]*safcm.File{
291 Mode: fs.ModeDir | 0700,
295 TriggerCommands: []string{
301 Mode: fs.ModeDir | 0755,
305 TriggerCommands: []string{
314 Data: []byte("content\n"),
316 TriggerCommands: []string{
317 "echo trigger dir/file",
322 "echo; env | grep SAFCM_",
330 []byte("fake stdout/stderr ."),
331 []byte("fake stdout/stderr dir"),
332 []byte("fake stdout/stderr"),
362 "echo; env | grep SAFCM_",
367 `3: sync remote: commands: running "/bin/sh" "-c" "echo trigger ."`,
368 "5: sync remote: commands: command output:\nfake stdout/stderr .",
369 `3: sync remote: commands: running "/bin/sh" "-c" "echo trigger dir"`,
370 "5: sync remote: commands: command output:\nfake stdout/stderr dir",
371 `3: sync remote: commands: running "/bin/sh" "-c" "echo; env | grep SAFCM_"`,
372 "5: sync remote: commands: command output:\nfake stdout/stderr",
375 CommandChanges: []safcm.CommandChange{
377 Command: "echo trigger .",
379 Output: "fake stdout/stderr .",
382 Command: "echo trigger dir",
384 Output: "fake stdout/stderr dir",
387 Command: "echo; env | grep SAFCM_",
388 Output: "fake stdout/stderr",
404 Files: map[string]*safcm.File{
407 Mode: fs.ModeDir | 0700,
411 TriggerCommands: []string{
417 Mode: fs.ModeDir | 0755,
421 TriggerCommands: []string{
430 Data: []byte("content\n"),
432 TriggerCommands: []string{
433 "echo trigger dir/file",
438 "echo; env | grep SAFCM_",
446 []byte("fake stdout/stderr ."),
447 []byte("fake stdout/stderr dir"),
455 fmt.Errorf("fake error"),
473 `3: sync remote: commands: running "/bin/sh" "-c" "echo trigger ."`,
474 "5: sync remote: commands: command output:\nfake stdout/stderr .",
475 `3: sync remote: commands: running "/bin/sh" "-c" "false"`,
476 "5: sync remote: commands: command output:\nfake stdout/stderr dir",
479 CommandChanges: []safcm.CommandChange{
481 Command: "echo trigger .",
483 Output: "fake stdout/stderr .",
488 Output: "fake stdout/stderr dir",
493 fmt.Errorf("\"false\" failed: fake error"),
497 for _, tc := range tests {
498 t.Run(tc.name, func(t *testing.T) {
499 s, res := prepareSync(tc.req, &testRunner{
502 resStdout: tc.stdout,
503 resStderr: tc.stderr,
506 s.triggers = tc.triggers
508 err := s.syncCommands()
509 testutil.AssertErrorEqual(t, "err", err, tc.expErr)
512 testutil.AssertEqual(t, "resp", s.resp, tc.expResp)
513 testutil.AssertEqual(t, "dbg", dbg, tc.expDbg)