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/rpc"
28 "ruderich.org/simon/safcm/testutil"
31 func TestHostsToSync(t *testing.T) {
32 cwd, err := os.Getwd()
38 err = os.Chdir("testdata/project")
42 _, allHosts, allGroups, err := LoadBaseFiles()
62 []string{"unknown-host/group"},
64 fmt.Errorf("hosts/groups not found: \"unknown-host/group\""),
71 allHosts.Map["host2"],
76 "host: multiple names",
77 []string{"host2", "host1.example.org"},
79 allHosts.Map["host1.example.org"],
80 allHosts.Map["host2"],
85 "host: multiple identical names",
86 []string{"host2", "host2"},
88 allHosts.Map["host2"],
93 "host: multiple names, including unknown",
94 []string{"host2", "unknown-host"},
96 fmt.Errorf("hosts/groups not found: \"unknown-host\""),
99 "host: multiple names, including unknowns",
100 []string{"host2", "unknown-host", "unknown-host-2"},
102 fmt.Errorf("hosts/groups not found: \"unknown-host\" \"unknown-host-2\""),
106 "group: single name",
109 allHosts.Map["host1.example.org"],
114 "group: multiple names",
115 []string{"group", "group2"},
117 allHosts.Map["host1.example.org"],
118 allHosts.Map["host2"],
123 "group: multiple identical names",
124 []string{"group", "group2", "group"},
126 allHosts.Map["host1.example.org"],
127 allHosts.Map["host2"],
132 "group: multiple names, including unknown",
133 []string{"group", "group2", "unknown-group"},
135 fmt.Errorf("hosts/groups not found: \"unknown-group\""),
141 allHosts.Map["host1.example.org"],
142 allHosts.Map["host2"],
143 allHosts.Map["host3.example.net"],
150 []string{"all", "group2"},
152 allHosts.Map["host1.example.org"],
153 allHosts.Map["host2"],
154 allHosts.Map["host3.example.net"],
160 []string{"all", "group2", "host2"},
162 allHosts.Map["host1.example.org"],
163 allHosts.Map["host2"],
164 allHosts.Map["host3.example.net"],
170 for _, tc := range tests {
171 t.Run(tc.name, func(t *testing.T) {
172 res, err := hostsToSync(tc.names, allHosts, allGroups)
173 testutil.AssertEqual(t, "res", res, tc.exp)
174 testutil.AssertErrorEqual(t, "err", err, tc.expErr)
179 func TestLogEvent(t *testing.T) {
180 // Restore default logger
181 defer log.SetFlags(log.Flags())
182 defer log.SetOutput(os.Stderr)
196 Error: fmt.Errorf("fake error"),
200 "[error] [fake-host] fake error\n",
206 Error: fmt.Errorf("fake error"),
210 "[error] [\x1b[31mfake-host\x1b[0m] fake error\n",
216 Error: fmt.Errorf("\x00"),
220 "[error] [fake-host] \\x00\n",
224 "Error: escape (tty)",
226 Error: fmt.Errorf("\x00"),
230 "[error] [\x1b[31mfake-host\x1b[0m] \x1b[35m\\x00\x1b[0m\n",
238 Level: safcm.LogInfo,
244 "[info] [fake-host] info log\n",
251 Level: safcm.LogInfo,
257 "[info] [fake-host] info log\n",
264 Level: safcm.LogVerbose,
270 "[verbose] [fake-host] verbose log\n",
277 Level: safcm.LogDebug,
283 "[debug] [fake-host] debug log\n",
290 Level: safcm.LogDebug2,
296 "[debug2] [fake-host] debug2 log\n",
303 Level: safcm.LogDebug3,
309 fmt.Sprintf("[INVALID=%d] [fake-host] debug3 log\n",
317 Level: safcm.LogDebug3,
323 fmt.Sprintf("[INVALID=%d] [\x1b[31mfake-host\x1b[0m] debug3 log\n",
331 Level: safcm.LogInfo,
337 "[info] [fake-host] \\x00\n",
344 Level: safcm.LogInfo,
350 "[info] [fake-host] \x1b[35m\\x00\x1b[0m\n",
357 ConnEvent: rpc.ConnEvent{
358 Type: rpc.ConnEventStderr,
364 "[stderr] [fake-host] fake stderr\n",
368 "ConnEvent: stderr (tty)",
370 ConnEvent: rpc.ConnEvent{
371 Type: rpc.ConnEventStderr,
377 "[stderr] [fake-host] fake stderr\n",
383 ConnEvent: rpc.ConnEvent{
384 Type: rpc.ConnEventDebug,
390 "[debug3] [fake-host] conn debug\n",
396 ConnEvent: rpc.ConnEvent{
397 Type: rpc.ConnEventUpload,
402 "[info] [fake-host] remote helper upload in progress\n",
406 "ConnEvent: upload (ignored)",
408 ConnEvent: rpc.ConnEvent{
409 Type: rpc.ConnEventUpload,
418 "ConnEvent: invalid",
420 ConnEvent: rpc.ConnEvent{
427 "[INVALID=42] [fake-host] invalid\n",
431 "ConnEvent: invalid (tty)",
433 ConnEvent: rpc.ConnEvent{
440 "[INVALID=42] [\x1b[31mfake-host\x1b[0m] invalid\n",
446 ConnEvent: rpc.ConnEvent{
447 Type: rpc.ConnEventStderr,
453 "[stderr] [fake-host] \\x00\n",
457 "ConnEvent: escape (tty)",
459 ConnEvent: rpc.ConnEvent{
460 Type: rpc.ConnEventDebug,
466 "[debug3] [fake-host] \x1b[35m\\x01\x1b[0m\n",
474 Level: safcm.LogInfo,
481 "[info] [fake-host] \x00\n",
488 Level: safcm.LogInfo,
495 "[info] [fake-host] \x00\n",
504 "[INVALID=0] [fake-host] \n",
509 for _, tc := range tests {
510 t.Run(tc.name, func(t *testing.T) {
511 tc.event.Host = &config.Host{
520 logEvent(tc.event, tc.level, tc.isTTY, &failed)
522 testutil.AssertEqual(t, "log",
523 buf.String(), tc.exp)
524 testutil.AssertEqual(t, "failed",
525 failed, tc.expFailed)