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()
49 Groups depending on "detected" groups cannot be used to select hosts as these
50 are only available after the hosts were contacted.
68 []string{"unknown-host/group"},
70 fmt.Errorf("hosts/groups not found: \"unknown-host/group\""),
77 allHosts.Map["host2"],
82 "host: multiple names",
83 []string{"host2", "host1.example.org"},
85 allHosts.Map["host1.example.org"],
86 allHosts.Map["host2"],
91 "host: multiple identical names",
92 []string{"host2", "host2"},
94 allHosts.Map["host2"],
99 "host: multiple names, including unknown",
100 []string{"host2", "unknown-host"},
102 fmt.Errorf("hosts/groups not found: \"unknown-host\""),
105 "host: multiple names, including unknowns",
106 []string{"host2", "unknown-host", "unknown-host-2"},
108 fmt.Errorf("hosts/groups not found: \"unknown-host\" \"unknown-host-2\""),
112 "group: single name",
115 allHosts.Map["host1.example.org"],
120 "group: multiple names",
121 []string{"group3", "group2"},
123 allHosts.Map["host1.example.org"],
124 allHosts.Map["host2"],
129 "group: multiple identical names",
130 []string{"group3", "group2", "group3"},
132 allHosts.Map["host1.example.org"],
133 allHosts.Map["host2"],
138 "group: multiple names, including unknown",
139 []string{"group3", "group2", "unknown-group"},
141 fmt.Errorf("hosts/groups not found: \"unknown-group\""),
147 allHosts.Map["host1.example.org"],
148 allHosts.Map["host2"],
149 allHosts.Map["host3.example.net"],
155 "group: single name (detected)",
158 fmt.Errorf(`group "group" depends on "detected" groups` + errMsg),
161 "group: multiple names (detected)",
162 []string{"group", "group2"},
164 fmt.Errorf(`group "group" depends on "detected" groups` + errMsg),
169 []string{"all", "group2"},
171 allHosts.Map["host1.example.org"],
172 allHosts.Map["host2"],
173 allHosts.Map["host3.example.net"],
179 []string{"all", "group2", "host2"},
181 allHosts.Map["host1.example.org"],
182 allHosts.Map["host2"],
183 allHosts.Map["host3.example.net"],
189 for _, tc := range tests {
190 t.Run(tc.name, func(t *testing.T) {
191 res, err := hostsToSync(tc.names, allHosts, allGroups)
192 testutil.AssertEqual(t, "res", res, tc.exp)
193 testutil.AssertErrorEqual(t, "err", err, tc.expErr)
198 func TestLogEvent(t *testing.T) {
199 // Restore default logger
200 defer log.SetFlags(log.Flags())
201 defer log.SetOutput(os.Stderr)
215 Error: fmt.Errorf("fake error"),
219 "[error] [fake-host] fake error\n",
225 Error: fmt.Errorf("fake error"),
229 "[error] [\x1b[31mfake-host\x1b[0m] fake error\n",
235 Error: fmt.Errorf("\x00"),
239 "[error] [fake-host] \\x00\n",
243 "Error: escape (tty)",
245 Error: fmt.Errorf("\x00"),
249 "[error] [\x1b[31mfake-host\x1b[0m] \x1b[35m\\x00\x1b[0m\n",
257 Level: safcm.LogInfo,
263 "[info] [fake-host] info log\n",
270 Level: safcm.LogInfo,
276 "[info] [fake-host] info log\n",
283 Level: safcm.LogVerbose,
289 "[verbose] [fake-host] verbose log\n",
296 Level: safcm.LogDebug,
302 "[debug] [fake-host] debug log\n",
309 Level: safcm.LogDebug2,
315 "[debug2] [fake-host] debug2 log\n",
322 Level: safcm.LogDebug3,
328 fmt.Sprintf("[INVALID=%d] [fake-host] debug3 log\n",
336 Level: safcm.LogDebug3,
342 fmt.Sprintf("[INVALID=%d] [\x1b[31mfake-host\x1b[0m] debug3 log\n",
350 Level: safcm.LogInfo,
356 "[info] [fake-host] \\x00\n",
363 Level: safcm.LogInfo,
369 "[info] [fake-host] \x1b[35m\\x00\x1b[0m\n",
376 ConnEvent: rpc.ConnEvent{
377 Type: rpc.ConnEventStderr,
383 "[stderr] [fake-host] fake stderr\n",
387 "ConnEvent: stderr (tty)",
389 ConnEvent: rpc.ConnEvent{
390 Type: rpc.ConnEventStderr,
396 "[stderr] [fake-host] fake stderr\n",
402 ConnEvent: rpc.ConnEvent{
403 Type: rpc.ConnEventDebug,
409 "[debug3] [fake-host] conn debug\n",
415 ConnEvent: rpc.ConnEvent{
416 Type: rpc.ConnEventUpload,
421 "[info] [fake-host] remote helper upload in progress\n",
425 "ConnEvent: upload (ignored)",
427 ConnEvent: rpc.ConnEvent{
428 Type: rpc.ConnEventUpload,
437 "ConnEvent: invalid",
439 ConnEvent: rpc.ConnEvent{
446 "[INVALID=42] [fake-host] invalid\n",
450 "ConnEvent: invalid (tty)",
452 ConnEvent: rpc.ConnEvent{
459 "[INVALID=42] [\x1b[31mfake-host\x1b[0m] invalid\n",
465 ConnEvent: rpc.ConnEvent{
466 Type: rpc.ConnEventStderr,
472 "[stderr] [fake-host] \\x00\n",
476 "ConnEvent: escape (tty)",
478 ConnEvent: rpc.ConnEvent{
479 Type: rpc.ConnEventDebug,
485 "[debug3] [fake-host] \x1b[35m\\x01\x1b[0m\n",
493 Level: safcm.LogInfo,
500 "[info] [fake-host] \x00\n",
507 Level: safcm.LogInfo,
514 "[info] [fake-host] \x00\n",
523 "[INVALID=0] [fake-host] \n",
528 for _, tc := range tests {
529 t.Run(tc.name, func(t *testing.T) {
530 tc.event.Host = &config.Host{
539 logEvent(tc.event, tc.level, tc.isTTY, &failed)
541 testutil.AssertEqual(t, "log",
542 buf.String(), tc.exp)
543 testutil.AssertEqual(t, "failed",
544 failed, tc.expFailed)