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/cmd/safcm/config"
27 "ruderich.org/simon/safcm/frontend"
28 "ruderich.org/simon/safcm/rpc"
29 "ruderich.org/simon/safcm/testutil"
32 func TestHostsToSync(t *testing.T) {
33 cwd, err := os.Getwd()
39 err = os.Chdir("testdata/project")
43 _, allHosts, allGroups, err := LoadBaseFiles()
50 Groups depending on "detected" groups cannot be used to select hosts as these
51 are only available after the hosts were contacted.
69 []string{"unknown-host/group"},
71 fmt.Errorf("hosts/groups not found: \"unknown-host/group\""),
78 allHosts.Map["host2"],
83 "host: multiple names",
84 []string{"host2", "host1.example.org"},
86 allHosts.Map["host1.example.org"],
87 allHosts.Map["host2"],
92 "host: multiple identical names",
93 []string{"host2", "host2"},
95 allHosts.Map["host2"],
100 "host: multiple names, including unknown",
101 []string{"host2", "unknown-host"},
103 fmt.Errorf("hosts/groups not found: \"unknown-host\""),
106 "host: multiple names, including unknowns",
107 []string{"host2", "unknown-host", "unknown-host-2"},
109 fmt.Errorf("hosts/groups not found: \"unknown-host\" \"unknown-host-2\""),
113 "group: single name",
116 allHosts.Map["host1.example.org"],
121 "group: multiple names",
122 []string{"group3", "group2"},
124 allHosts.Map["host1.example.org"],
125 allHosts.Map["host2"],
130 "group: multiple identical names",
131 []string{"group3", "group2", "group3"},
133 allHosts.Map["host1.example.org"],
134 allHosts.Map["host2"],
139 "group: multiple names, including unknown",
140 []string{"group3", "group2", "unknown-group"},
142 fmt.Errorf("hosts/groups not found: \"unknown-group\""),
148 allHosts.Map["host1.example.org"],
149 allHosts.Map["host2"],
150 allHosts.Map["host3.example.net"],
156 "group: single name (detected)",
159 fmt.Errorf(`group "group" depends on "detected" groups` + errMsg),
162 "group: multiple names (detected)",
163 []string{"group", "group2"},
165 fmt.Errorf(`group "group" depends on "detected" groups` + errMsg),
170 []string{"all", "group2"},
172 allHosts.Map["host1.example.org"],
173 allHosts.Map["host2"],
174 allHosts.Map["host3.example.net"],
180 []string{"all", "group2", "host2"},
182 allHosts.Map["host1.example.org"],
183 allHosts.Map["host2"],
184 allHosts.Map["host3.example.net"],
190 for _, tc := range tests {
191 t.Run(tc.name, func(t *testing.T) {
192 res, err := hostsToSync(tc.names, allHosts, allGroups)
193 testutil.AssertEqual(t, "res", res, tc.exp)
194 testutil.AssertErrorEqual(t, "err", err, tc.expErr)
199 func TestLogEvent(t *testing.T) {
200 // Restore default logger
201 defer log.SetFlags(log.Flags())
202 defer log.SetOutput(os.Stderr)
216 Error: fmt.Errorf("fake error"),
220 "[error] [fake-host] fake error\n",
226 Error: fmt.Errorf("fake error"),
230 "[error] [\x1b[31mfake-host\x1b[0m] fake error\n",
236 Error: fmt.Errorf("\x00"),
240 "[error] [fake-host] \\x00\n",
244 "Error: escape (tty)",
246 Error: fmt.Errorf("\x00"),
250 "[error] [\x1b[31mfake-host\x1b[0m] \x1b[35m\\x00\x1b[0m\n",
258 Level: safcm.LogInfo,
264 "[info] [fake-host] info log\n",
271 Level: safcm.LogInfo,
277 "[info] [fake-host] info log\n",
284 Level: safcm.LogVerbose,
290 "[verbose] [fake-host] verbose log\n",
297 Level: safcm.LogDebug,
303 "[debug] [fake-host] debug log\n",
310 Level: safcm.LogDebug2,
316 "[debug2] [fake-host] debug2 log\n",
323 Level: safcm.LogDebug3,
329 fmt.Sprintf("[INVALID=%d] [fake-host] debug3 log\n",
337 Level: safcm.LogDebug3,
343 fmt.Sprintf("[INVALID=%d] [\x1b[31mfake-host\x1b[0m] debug3 log\n",
351 Level: safcm.LogInfo,
357 "[info] [fake-host] \\x00\n",
364 Level: safcm.LogInfo,
370 "[info] [fake-host] \x1b[35m\\x00\x1b[0m\n",
377 ConnEvent: rpc.ConnEvent{
378 Type: rpc.ConnEventStderr,
384 "[stderr] [fake-host] fake stderr\n",
388 "ConnEvent: stderr (tty)",
390 ConnEvent: rpc.ConnEvent{
391 Type: rpc.ConnEventStderr,
397 "[stderr] [fake-host] fake stderr\n",
403 ConnEvent: rpc.ConnEvent{
404 Type: rpc.ConnEventDebug,
410 "[debug3] [fake-host] conn debug\n",
416 ConnEvent: rpc.ConnEvent{
417 Type: rpc.ConnEventUpload,
422 "[info] [fake-host] remote helper upload in progress\n",
426 "ConnEvent: upload (ignored)",
428 ConnEvent: rpc.ConnEvent{
429 Type: rpc.ConnEventUpload,
438 "ConnEvent: invalid",
440 ConnEvent: rpc.ConnEvent{
447 "[INVALID=42] [fake-host] invalid\n",
451 "ConnEvent: invalid (tty)",
453 ConnEvent: rpc.ConnEvent{
460 "[INVALID=42] [\x1b[31mfake-host\x1b[0m] invalid\n",
466 ConnEvent: rpc.ConnEvent{
467 Type: rpc.ConnEventStderr,
473 "[stderr] [fake-host] \\x00\n",
477 "ConnEvent: escape (tty)",
479 ConnEvent: rpc.ConnEvent{
480 Type: rpc.ConnEventDebug,
486 "[debug3] [fake-host] \x1b[35m\\x01\x1b[0m\n",
494 Level: safcm.LogInfo,
501 "[info] [fake-host] \x00\n",
508 Level: safcm.LogInfo,
515 "[info] [fake-host] \x00\n",
524 "[INVALID=0] [fake-host] \n",
529 for _, tc := range tests {
530 t.Run(tc.name, func(t *testing.T) {
531 tc.event.Host = &Sync{
542 logEvent(tc.event, tc.level, tc.isTTY, &failed)
544 testutil.AssertEqual(t, "log",
545 buf.String(), tc.exp)
546 testutil.AssertEqual(t, "failed",
547 failed, tc.expFailed)