]> ruderich.org/simon Gitweb - safcm/safcm.git/blobdiff - cmd/safcm/sync_test.go
Move synchronization loop into new package frontend
[safcm/safcm.git] / cmd / safcm / sync_test.go
index 4616f716a28d75f5967e3654b02f2ede81331c84..4744ad553cd45715bcb08313842ad2700d5af800 100644 (file)
 package main
 
 import (
+       "bytes"
        "fmt"
+       "log"
        "os"
        "testing"
 
+       "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"
 )
 
@@ -40,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
@@ -100,7 +111,7 @@ func TestHostsToSync(t *testing.T) {
 
                {
                        "group: single name",
-                       []string{"group"},
+                       []string{"group3"},
                        []*config.Host{
                                allHosts.Map["host1.example.org"],
                        },
@@ -108,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"],
@@ -117,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"],
@@ -126,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\""),
                },
@@ -141,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"},
@@ -171,3 +195,356 @@ func TestHostsToSync(t *testing.T) {
                })
        }
 }
+
+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)
+               })
+       }
+}