From 81f2ac475e93815f079a28d9c61b4690ca8adef4 Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Mon, 5 Apr 2021 12:05:56 +0200 Subject: [PATCH 1/1] changes: add tests for output with terminal --- cmd/safcm/sync_changes_test.go | 439 +++++++++++++++++++++++++++++++++ 1 file changed, 439 insertions(+) diff --git a/cmd/safcm/sync_changes_test.go b/cmd/safcm/sync_changes_test.go index e5efe1d..c6dd0f8 100644 --- a/cmd/safcm/sync_changes_test.go +++ b/cmd/safcm/sync_changes_test.go @@ -28,6 +28,7 @@ func TestFormatFileChanges(t *testing.T) { tests := []struct { name string dryRun bool + isTTY bool changes []safcm.FileChange exp string }{ @@ -35,6 +36,7 @@ func TestFormatFileChanges(t *testing.T) { { "regular", false, + false, []safcm.FileChange{ { Path: "created: file", @@ -214,9 +216,173 @@ func TestFormatFileChanges(t *testing.T) { `, }, + { + "regular (tty)", + false, + true, + []safcm.FileChange{ + { + Path: "created: file", + Created: true, + New: safcm.FileChangeInfo{ + Mode: 0644, + User: "user", + Uid: 1000, + Group: "group", + Gid: 2000, + }, + }, + { + Path: "created: link", + Created: true, + New: safcm.FileChangeInfo{ + Mode: fs.ModeSymlink | 0777, + User: "user", + Uid: 1000, + Group: "group", + Gid: 2000, + }, + }, + { + Path: "type change: file -> dir", + Old: safcm.FileChangeInfo{ + Mode: 0751, + User: "user", + Uid: 1000, + Group: "group", + Gid: 2000, + }, + New: safcm.FileChangeInfo{ + Mode: fs.ModeDir | 0751, + User: "user", + Uid: 1000, + Group: "group", + Gid: 2000, + }, + DataDiff: `@@ -1,2 +1 @@ +-content + +`, + }, + { + Path: "user change", + Old: safcm.FileChangeInfo{ + Mode: 0755, + User: "user", + Uid: 1000, + Group: "group", + Gid: 2000, + }, + New: safcm.FileChangeInfo{ + Mode: 0755, + User: "user2", + Uid: 1001, + Group: "group", + Gid: 2000, + }, + }, + { + Path: "group change", + Old: safcm.FileChangeInfo{ + Mode: 0755, + User: "user", + Uid: 1000, + Group: "group", + Gid: 2000, + }, + New: safcm.FileChangeInfo{ + Mode: 0755, + User: "user", + Uid: 1000, + Group: "group2", + Gid: 2001, + }, + }, + { + Path: "mode change", + Old: safcm.FileChangeInfo{ + Mode: 0755, + User: "user", + Uid: 1000, + Group: "group", + Gid: 2000, + }, + New: safcm.FileChangeInfo{ + Mode: 0750, + User: "user", + Uid: 1000, + Group: "group", + Gid: 2000, + }, + }, + { + Path: "mode change (setuid)", + Old: safcm.FileChangeInfo{ + Mode: 0755, + User: "user", + Uid: 1000, + Group: "group", + Gid: 2000, + }, + New: safcm.FileChangeInfo{ + Mode: 0755 | fs.ModeSetuid, + User: "user", + Uid: 1000, + Group: "group", + Gid: 2000, + }, + }, + { + Path: "content change", + Old: safcm.FileChangeInfo{ + Mode: 0644, + User: "user", + Uid: 1000, + Group: "group", + Gid: 2000, + }, + New: safcm.FileChangeInfo{ + Mode: 0644, + User: "user", + Uid: 1000, + Group: "group", + Gid: 2000, + }, + DataDiff: `@@ -1,2 +1,2 @@ +-old content ++content + +`, + }, + { + Path: "multiple changes", + Old: safcm.FileChangeInfo{ + Mode: 0644, + User: "user", + Uid: 1000, + Group: "group", + Gid: 2000, + }, + New: safcm.FileChangeInfo{ + Mode: fs.ModeDir | 0755, + User: "user2", + Uid: 1001, + Group: "group2", + Gid: 2001, + }, + DataDiff: `@@ -1,2 +1 @@ +-content + +`, + }, + }, + "changed 9 file(s):\n\x1b[36m\"created: file\"\x1b[0m: \x1b[32mcreated\x1b[0m, file, user(1000) group(2000), 0644\n\x1b[36m\"created: link\"\x1b[0m: \x1b[32mcreated\x1b[0m, symlink, user(1000) group(2000), 0777\n\x1b[36m\"type change: file -> dir\"\x1b[0m: file -> dir\n @@ -1,2 +1 @@\n\x1b[31m -content\x1b[0m\n \n\x1b[36m\"user change\"\x1b[0m: user(1000) group(2000) -> user2(1001) group(2000)\n\x1b[36m\"group change\"\x1b[0m: user(1000) group(2000) -> user(1000) group2(2001)\n\x1b[36m\"mode change\"\x1b[0m: 0755 -> 0750\n\x1b[36m\"mode change (setuid)\"\x1b[0m: 0755 -> 04755\n\x1b[36m\"content change\"\x1b[0m:\n @@ -1,2 +1,2 @@\n\x1b[31m -old content\x1b[0m\n\x1b[32m +content\x1b[0m\n \n\x1b[36m\"multiple changes\"\x1b[0m: file -> dir, user(1000) group(2000) -> user2(1001) group2(2001), 0644 -> 0755\n @@ -1,2 +1 @@\n\x1b[31m -content\x1b[0m\n \n", + }, + { "dry-run", true, + false, []safcm.FileChange{ { Path: "file", @@ -235,9 +401,30 @@ func TestFormatFileChanges(t *testing.T) { `, }, + { + "dry-run (tty)", + true, + true, + []safcm.FileChange{ + { + Path: "file", + Created: true, + New: safcm.FileChangeInfo{ + Mode: 0644, + User: "user", + Uid: 1000, + Group: "group", + Gid: 2000, + }, + }, + }, + "changed 1 file(s): (dry-run)\n\x1B[36m\"file\"\x1B[0m: \x1B[32mcreated\x1B[0m, file, user(1000) group(2000), 0644\n", + }, + { "escaping", false, + false, []safcm.FileChange{ { Path: "\x00", @@ -279,6 +466,45 @@ func TestFormatFileChanges(t *testing.T) { \ No newline at end of file `, }, + + { + "escaping (tty)", + false, + true, + []safcm.FileChange{ + { + Path: "\x00", + Created: true, + New: safcm.FileChangeInfo{ + Mode: 0xFFFFFFFF, + User: "\x01", + Uid: -1, + Group: "\x02", + Gid: -2, + }, + DataDiff: "\x03", + }, + { + Path: "\x00", + Old: safcm.FileChangeInfo{ + Mode: 0x00000000, + User: "\x01", + Uid: -1, + Group: "\x02", + Gid: -2, + }, + New: safcm.FileChangeInfo{ + Mode: 0xFFFFFFFF, + User: "\x03", + Uid: -3, + Group: "\x04", + Gid: -4, + }, + DataDiff: "\x05", + }, + }, + "changed 2 file(s):\n\x1b[36m\"\\x00\"\x1b[0m: \x1b[32mcreated\x1b[0m, invalid type dLDpSc?---------, \\x01(-1) \\x02(-2), 07777\n \\x03\n \\ No newline at end of file\n\x1b[36m\"\\x00\"\x1b[0m: file -> invalid type dLDpSc?---------, \\x01(-1) \\x02(-2) -> \\x03(-3) \\x04(-4), 0 -> 07777\n \\x05\n \\ No newline at end of file\n", + }, } for _, tc := range tests { @@ -287,6 +513,7 @@ func TestFormatFileChanges(t *testing.T) { config: &config.Config{ DryRun: tc.dryRun, }, + isTTY: tc.isTTY, } res := s.formatFileChanges(tc.changes) @@ -299,6 +526,7 @@ func TestFormatPackageChanges(t *testing.T) { tests := []struct { name string dryRun bool + isTTY bool changes []safcm.PackageChange exp string }{ @@ -306,6 +534,7 @@ func TestFormatPackageChanges(t *testing.T) { { "regular", false, + false, []safcm.PackageChange{ { Name: "package-one", @@ -320,9 +549,25 @@ func TestFormatPackageChanges(t *testing.T) { `, }, + { + "regular (tty)", + false, + true, + []safcm.PackageChange{ + { + Name: "package-one", + }, + { + Name: "package-two", + }, + }, + "installed 2 package(s):\n\x1b[36m\"package-one\"\x1b[0m\n\x1b[36m\"package-two\"\x1b[0m\n", + }, + { "dry-run", true, + false, []safcm.PackageChange{ { Name: "package-one", @@ -337,9 +582,25 @@ func TestFormatPackageChanges(t *testing.T) { `, }, + { + "dry-run (tty)", + true, + true, + []safcm.PackageChange{ + { + Name: "package-one", + }, + { + Name: "package-two", + }, + }, + "installed 2 package(s): (dry-run)\n\x1b[36m\"package-one\"\x1b[0m\n\x1b[36m\"package-two\"\x1b[0m\n", + }, + { "escaping", false, + false, []safcm.PackageChange{ { Name: "\x00", @@ -349,6 +610,18 @@ func TestFormatPackageChanges(t *testing.T) { "\x00" `, }, + + { + "escaping (tty)", + false, + true, + []safcm.PackageChange{ + { + Name: "\x00", + }, + }, + "installed 1 package(s):\n\x1b[36m\"\\x00\"\x1b[0m\n", + }, } for _, tc := range tests { @@ -357,6 +630,7 @@ func TestFormatPackageChanges(t *testing.T) { config: &config.Config{ DryRun: tc.dryRun, }, + isTTY: tc.isTTY, } res := s.formatPackageChanges(tc.changes) @@ -369,6 +643,7 @@ func TestFormatServiceChanges(t *testing.T) { tests := []struct { name string dryRun bool + isTTY bool changes []safcm.ServiceChange exp string }{ @@ -376,6 +651,7 @@ func TestFormatServiceChanges(t *testing.T) { { "regular", false, + false, []safcm.ServiceChange{ { Name: "service-one", @@ -398,9 +674,32 @@ func TestFormatServiceChanges(t *testing.T) { `, }, + { + "regular (tty)", + false, + true, + []safcm.ServiceChange{ + { + Name: "service-one", + Started: true, + }, + { + Name: "service-two", + Enabled: true, + }, + { + Name: "service-three", + Started: true, + Enabled: true, + }, + }, + "modified 3 service(s):\n\x1b[36m\"service-one\"\x1b[0m: started\n\x1b[36m\"service-two\"\x1b[0m: enabled\n\x1b[36m\"service-three\"\x1b[0m: started, enabled\n", + }, + { "dry-run", true, + false, []safcm.ServiceChange{ { Name: "service-one", @@ -423,9 +722,32 @@ func TestFormatServiceChanges(t *testing.T) { `, }, + { + "dry-run (tty)", + true, + true, + []safcm.ServiceChange{ + { + Name: "service-one", + Started: true, + }, + { + Name: "service-two", + Enabled: true, + }, + { + Name: "service-three", + Started: true, + Enabled: true, + }, + }, + "modified 3 service(s): (dry-run)\n\x1b[36m\"service-one\"\x1b[0m: started\n\x1b[36m\"service-two\"\x1b[0m: enabled\n\x1b[36m\"service-three\"\x1b[0m: started, enabled\n", + }, + { "escaping", false, + false, []safcm.ServiceChange{ { Name: "\x00", @@ -441,6 +763,23 @@ func TestFormatServiceChanges(t *testing.T) { "\x01": started, enabled `, }, + + { + "escaping (tty)", + false, + true, + []safcm.ServiceChange{ + { + Name: "\x00", + }, + { + Name: "\x01", + Started: true, + Enabled: true, + }, + }, + "modified 2 service(s):\n\x1b[36m\"\\x00\"\x1b[0m: \n\x1b[36m\"\\x01\"\x1b[0m: started, enabled\n", + }, } for _, tc := range tests { @@ -449,6 +788,7 @@ func TestFormatServiceChanges(t *testing.T) { config: &config.Config{ DryRun: tc.dryRun, }, + isTTY: tc.isTTY, } res := s.formatServiceChanges(tc.changes) @@ -462,6 +802,7 @@ func TestFormatCommandChanges(t *testing.T) { name string dryRun bool quiet bool + isTTY bool changes []safcm.CommandChange exp string }{ @@ -470,6 +811,7 @@ func TestFormatCommandChanges(t *testing.T) { "regular", false, false, + false, []safcm.CommandChange{ { Command: "fake command", @@ -509,10 +851,41 @@ func TestFormatCommandChanges(t *testing.T) { `, }, + { + "regular (tty)", + false, + false, + true, + []safcm.CommandChange{ + { + Command: "fake command", + Output: "fake output", + }, + { + Command: "fake command with no output", + }, + { + Command: "fake command with newline", + Output: "fake output\n", + }, + { + Command: "fake command with more output", + Output: "fake out\nfake put\nfake\n", + }, + { + Command: "fake failed command", + Output: "fake output", + Error: "fake error", + }, + }, + "executed 5 command(s):\n\x1b[36m\"fake command\"\x1b[0m:\n > fake output\n > \\ No newline at end of file\n\x1b[36m\"fake command with no output\"\x1b[0m\n\x1b[36m\"fake command with newline\"\x1b[0m:\n > fake output\n\x1b[36m\"fake command with more output\"\x1b[0m:\n > fake out\n > fake put\n > fake\n\x1b[36m\"fake failed command\"\x1b[0m, failed: \"fake error\":\n > fake output\n > \\ No newline at end of file\n", + }, + { "dry-run", true, false, + false, []safcm.CommandChange{ { Command: "fake command", @@ -526,10 +899,25 @@ func TestFormatCommandChanges(t *testing.T) { `, }, + { + "dry-run (tty)", + true, + false, + true, + []safcm.CommandChange{ + { + Command: "fake command", + Output: "fake output", + }, + }, + "executed 1 command(s): (dry-run)\n\x1b[36m\"fake command\"\x1b[0m:\n > fake output\n > \\ No newline at end of file\n", + }, + { "quiet", false, true, + false, []safcm.CommandChange{ { Command: "fake command", @@ -568,10 +956,41 @@ func TestFormatCommandChanges(t *testing.T) { `, }, + { + "quiet (tty)", + false, + true, + true, + []safcm.CommandChange{ + { + Command: "fake command", + Output: "fake output", + }, + { + Command: "fake command with no output", + }, + { + Command: "fake command with newline", + Output: "fake output\n", + }, + { + Command: "fake command with more output", + Output: "fake out\nfake put\nfake\n", + }, + { + Command: "fake failed command", + Output: "fake output", + Error: "fake error", + }, + }, + "executed 5 command(s), 1 with no output:\n\x1b[36m\"fake command\"\x1b[0m:\n > fake output\n > \\ No newline at end of file\n\x1b[36m\"fake command with newline\"\x1b[0m:\n > fake output\n\x1b[36m\"fake command with more output\"\x1b[0m:\n > fake out\n > fake put\n > fake\n\x1b[36m\"fake failed command\"\x1b[0m, failed: \"fake error\":\n > fake output\n > \\ No newline at end of file\n", + }, + { "quiet (only quiet commands)", false, true, + false, []safcm.CommandChange{ { Command: "fake command with no output", @@ -588,6 +1007,7 @@ func TestFormatCommandChanges(t *testing.T) { "quiet (quiet with errors)", false, true, + false, []safcm.CommandChange{ { Command: "fake command with no output but error", @@ -606,6 +1026,7 @@ func TestFormatCommandChanges(t *testing.T) { "quiet & dry-run", true, true, + false, []safcm.CommandChange{ { Command: "fake command", @@ -636,6 +1057,7 @@ func TestFormatCommandChanges(t *testing.T) { "escaping", false, false, + false, []safcm.CommandChange{ { Command: "\x00", @@ -650,6 +1072,22 @@ func TestFormatCommandChanges(t *testing.T) { > \ No newline at end of file `, }, + + { + "escaping (tty)", + false, + false, + true, + []safcm.CommandChange{ + { + Command: "\x00", + Trigger: "\x01", + Output: "\x02", + Error: "\x03", + }, + }, + "executed 1 command(s):\n\x1b[36m\"\\x00\"\x1b[0m, trigger for \"\\x01\", failed: \"\\x03\":\n > \x1b[35m\\x02\x1b[0m\n > \\ No newline at end of file\n", + }, } for _, tc := range tests { @@ -659,6 +1097,7 @@ func TestFormatCommandChanges(t *testing.T) { DryRun: tc.dryRun, Quiet: tc.quiet, }, + isTTY: tc.isTTY, } res := s.formatCommandChanges(tc.changes) -- 2.45.2