X-Git-Url: https://ruderich.org/simon/gitweb/?a=blobdiff_plain;f=cmd%2Fsafcm%2Fsync_test.go;h=4744ad553cd45715bcb08313842ad2700d5af800;hb=c899e17495d4eb932e0b4f428ec91882d845f1bc;hp=753f942fe06706d123967df5d95df9a43ee7c2e7;hpb=992eaae7fec45c2d58fff89d1bc0ae920a899296;p=safcm%2Fsafcm.git diff --git a/cmd/safcm/sync_test.go b/cmd/safcm/sync_test.go index 753f942..4744ad5 100644 --- a/cmd/safcm/sync_test.go +++ b/cmd/safcm/sync_test.go @@ -16,14 +16,17 @@ package main import ( + "bytes" "fmt" + "log" "os" - "reflect" "testing" - "github.com/google/go-cmp/cmp" - + "ruderich.org/simon/safcm" "ruderich.org/simon/safcm/cmd/safcm/config" + "ruderich.org/simon/safcm/frontend" + "ruderich.org/simon/safcm/rpc" + "ruderich.org/simon/safcm/testutil" ) func TestHostsToSync(t *testing.T) { @@ -42,6 +45,12 @@ func TestHostsToSync(t *testing.T) { t.Fatal(err) } + const errMsg = ` + +Groups depending on "detected" groups cannot be used to select hosts as these +are only available after the hosts were contacted. +` + tests := []struct { name string names []string @@ -102,7 +111,7 @@ func TestHostsToSync(t *testing.T) { { "group: single name", - []string{"group"}, + []string{"group3"}, []*config.Host{ allHosts.Map["host1.example.org"], }, @@ -110,7 +119,7 @@ func TestHostsToSync(t *testing.T) { }, { "group: multiple names", - []string{"group", "group2"}, + []string{"group3", "group2"}, []*config.Host{ allHosts.Map["host1.example.org"], allHosts.Map["host2"], @@ -119,7 +128,7 @@ func TestHostsToSync(t *testing.T) { }, { "group: multiple identical names", - []string{"group", "group2", "group"}, + []string{"group3", "group2", "group3"}, []*config.Host{ allHosts.Map["host1.example.org"], allHosts.Map["host2"], @@ -128,7 +137,7 @@ func TestHostsToSync(t *testing.T) { }, { "group: multiple names, including unknown", - []string{"group", "group2", "unknown-group"}, + []string{"group3", "group2", "unknown-group"}, nil, fmt.Errorf("hosts/groups not found: \"unknown-group\""), }, @@ -143,6 +152,19 @@ func TestHostsToSync(t *testing.T) { nil, }, + { + "group: single name (detected)", + []string{"group"}, + nil, + fmt.Errorf(`group "group" depends on "detected" groups` + errMsg), + }, + { + "group: multiple names (detected)", + []string{"group", "group2"}, + nil, + fmt.Errorf(`group "group" depends on "detected" groups` + errMsg), + }, + { "\"all\" and name", []string{"all", "group2"}, @@ -167,16 +189,362 @@ func TestHostsToSync(t *testing.T) { for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { - res, err := hostsToSync(tc.names, allHosts, allGroups) - if !reflect.DeepEqual(tc.exp, res) { - t.Errorf("res: %s", - cmp.Diff(tc.exp, res)) - } - // Ugly but the simplest way to compare errors (including nil) - if fmt.Sprintf("%s", err) != fmt.Sprintf("%s", tc.expErr) { - t.Errorf("err = %#v, want %#v", - err, tc.expErr) - } + res, err := hostsToSync(tc.names, allHosts, allGroups) + testutil.AssertEqual(t, "res", res, tc.exp) + testutil.AssertErrorEqual(t, "err", err, tc.expErr) + }) + } +} + +func TestLogEvent(t *testing.T) { + // Restore default logger + defer log.SetFlags(log.Flags()) + defer log.SetOutput(os.Stderr) + + tests := []struct { + name string + event frontend.Event + level safcm.LogLevel + isTTY bool + exp string + expFailed bool + }{ + + { + "Error", + frontend.Event{ + Error: fmt.Errorf("fake error"), + }, + safcm.LogDebug3, + false, + "[error] [fake-host] fake error\n", + true, + }, + { + "Error (tty)", + frontend.Event{ + Error: fmt.Errorf("fake error"), + }, + safcm.LogDebug3, + true, + "[error] [\x1b[31mfake-host\x1b[0m] fake error\n", + true, + }, + { + "Error: escape", + frontend.Event{ + Error: fmt.Errorf("\x00"), + }, + safcm.LogDebug3, + false, + "[error] [fake-host] \\x00\n", + true, + }, + { + "Error: escape (tty)", + frontend.Event{ + Error: fmt.Errorf("\x00"), + }, + safcm.LogDebug3, + true, + "[error] [\x1b[31mfake-host\x1b[0m] \x1b[35m\\x00\x1b[0m\n", + true, + }, + + { + "Log: info", + frontend.Event{ + Log: frontend.Log{ + Level: safcm.LogInfo, + Text: "info log", + }, + }, + safcm.LogDebug3, + false, + "[info] [fake-host] info log\n", + false, + }, + { + "Log: info (tty)", + frontend.Event{ + Log: frontend.Log{ + Level: safcm.LogInfo, + Text: "info log", + }, + }, + safcm.LogDebug3, + true, + "[info] [fake-host] info log\n", + false, + }, + { + "Log: verbose", + frontend.Event{ + Log: frontend.Log{ + Level: safcm.LogVerbose, + Text: "verbose log", + }, + }, + safcm.LogDebug3, + false, + "[verbose] [fake-host] verbose log\n", + false, + }, + { + "Log: debug", + frontend.Event{ + Log: frontend.Log{ + Level: safcm.LogDebug, + Text: "debug log", + }, + }, + safcm.LogDebug3, + false, + "[debug] [fake-host] debug log\n", + false, + }, + { + "Log: debug2", + frontend.Event{ + Log: frontend.Log{ + Level: safcm.LogDebug2, + Text: "debug2 log", + }, + }, + safcm.LogDebug3, + false, + "[debug2] [fake-host] debug2 log\n", + false, + }, + { + "Log: debug3", + frontend.Event{ + Log: frontend.Log{ + Level: safcm.LogDebug3, + Text: "debug3 log", + }, + }, + safcm.LogDebug3, + false, + fmt.Sprintf("[INVALID=%d] [fake-host] debug3 log\n", + safcm.LogDebug3), + false, + }, + { + "Log: debug3 (tty)", + frontend.Event{ + Log: frontend.Log{ + Level: safcm.LogDebug3, + Text: "debug3 log", + }, + }, + safcm.LogDebug3, + true, + fmt.Sprintf("[INVALID=%d] [\x1b[31mfake-host\x1b[0m] debug3 log\n", + safcm.LogDebug3), + false, + }, + { + "Log: escape", + frontend.Event{ + Log: frontend.Log{ + Level: safcm.LogInfo, + Text: "\x00", + }, + }, + safcm.LogDebug3, + false, + "[info] [fake-host] \\x00\n", + false, + }, + { + "Log: escape (tty)", + frontend.Event{ + Log: frontend.Log{ + Level: safcm.LogInfo, + Text: "\x00", + }, + }, + safcm.LogDebug3, + true, + "[info] [fake-host] \x1b[35m\\x00\x1b[0m\n", + false, + }, + + { + "ConnEvent: stderr", + frontend.Event{ + ConnEvent: rpc.ConnEvent{ + Type: rpc.ConnEventStderr, + Data: "fake stderr", + }, + }, + safcm.LogDebug3, + false, + "[stderr] [fake-host] fake stderr\n", + false, + }, + { + "ConnEvent: stderr (tty)", + frontend.Event{ + ConnEvent: rpc.ConnEvent{ + Type: rpc.ConnEventStderr, + Data: "fake stderr", + }, + }, + safcm.LogDebug3, + true, + "[stderr] [fake-host] fake stderr\n", + false, + }, + { + "ConnEvent: debug", + frontend.Event{ + ConnEvent: rpc.ConnEvent{ + Type: rpc.ConnEventDebug, + Data: "conn debug", + }, + }, + safcm.LogDebug3, + false, + "[debug3] [fake-host] conn debug\n", + false, + }, + { + "ConnEvent: upload", + frontend.Event{ + ConnEvent: rpc.ConnEvent{ + Type: rpc.ConnEventUpload, + }, + }, + safcm.LogDebug3, + false, + "[info] [fake-host] remote helper upload in progress\n", + false, + }, + { + "ConnEvent: upload (ignored)", + frontend.Event{ + ConnEvent: rpc.ConnEvent{ + Type: rpc.ConnEventUpload, + }, + }, + safcm.LogError, + false, + "", + false, + }, + { + "ConnEvent: invalid", + frontend.Event{ + ConnEvent: rpc.ConnEvent{ + Type: 42, + Data: "invalid", + }, + }, + safcm.LogError, + false, + "[INVALID=42] [fake-host] invalid\n", + false, + }, + { + "ConnEvent: invalid (tty)", + frontend.Event{ + ConnEvent: rpc.ConnEvent{ + Type: 42, + Data: "invalid", + }, + }, + safcm.LogError, + true, + "[INVALID=42] [\x1b[31mfake-host\x1b[0m] invalid\n", + false, + }, + { + "ConnEvent: escape", + frontend.Event{ + ConnEvent: rpc.ConnEvent{ + Type: rpc.ConnEventStderr, + Data: "\x00", + }, + }, + safcm.LogDebug3, + false, + "[stderr] [fake-host] \\x00\n", + false, + }, + { + "ConnEvent: escape (tty)", + frontend.Event{ + ConnEvent: rpc.ConnEvent{ + Type: rpc.ConnEventDebug, + Data: "\x01", + }, + }, + safcm.LogDebug3, + true, + "[debug3] [fake-host] \x1b[35m\\x01\x1b[0m\n", + false, + }, + + { + "Escaped", + frontend.Event{ + Log: frontend.Log{ + Level: safcm.LogInfo, + Text: "\x00", + }, + Escaped: true, + }, + safcm.LogDebug3, + false, + "[info] [fake-host] \x00\n", + false, + }, + { + "Escaped (tty)", + frontend.Event{ + Log: frontend.Log{ + Level: safcm.LogInfo, + Text: "\x00", + }, + Escaped: true, + }, + safcm.LogDebug3, + true, + "[info] [fake-host] \x00\n", + false, + }, + + { + "empty (invalid)", + frontend.Event{}, + safcm.LogDebug3, + false, + "[INVALID=0] [fake-host] \n", + false, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + tc.event.Host = &Sync{ + host: &config.Host{ + Name: "fake-host", + }, + } + + var buf bytes.Buffer + log.SetFlags(0) + log.SetOutput(&buf) + + var failed bool + logEvent(tc.event, tc.level, tc.isTTY, &failed) + + testutil.AssertEqual(t, "log", + buf.String(), tc.exp) + testutil.AssertEqual(t, "failed", + failed, tc.expFailed) }) } }