Skip to content

Commit 48aee0d

Browse files
committed
adds tests fir systemd command
1 parent aca12ec commit 48aee0d

File tree

1 file changed

+296
-0
lines changed

1 file changed

+296
-0
lines changed

cmd/systemd_test.go

Lines changed: 296 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,296 @@
1+
package cmd
2+
3+
import (
4+
"bytes"
5+
"io"
6+
"os"
7+
"strings"
8+
"testing"
9+
10+
"github.com/spf13/cobra"
11+
"github.com/spf13/pflag"
12+
"github.com/stretchr/testify/assert"
13+
)
14+
15+
// setupSystemdCmd creates and returns a properly configured systemd command
16+
func setupSystemdCmd() *cobra.Command {
17+
rootCmd := &cobra.Command{Use: "tagit"}
18+
systCmd := &cobra.Command{
19+
Use: "systemd",
20+
Short: "Generate a systemd service file for TagIt",
21+
Run: systemdCmd.Run,
22+
}
23+
24+
systCmd.Flags().String("service-id", "", "ID of the service (required)")
25+
systCmd.Flags().String("script", "", "Path to the script to execute (required)")
26+
systCmd.Flags().String("tag-prefix", "", "Prefix for tags (required)")
27+
systCmd.Flags().String("interval", "", "Interval for script execution (required)")
28+
systCmd.Flags().String("token", "", "Consul token (optional)")
29+
systCmd.Flags().String("consul-addr", "", "Consul address (optional)")
30+
systCmd.Flags().String("user", "", "User to run the service as (required)")
31+
systCmd.Flags().String("group", "", "Group to run the service as (required)")
32+
33+
systCmd.MarkFlagRequired("service-id")
34+
systCmd.MarkFlagRequired("script")
35+
systCmd.MarkFlagRequired("tag-prefix")
36+
systCmd.MarkFlagRequired("interval")
37+
systCmd.MarkFlagRequired("user")
38+
systCmd.MarkFlagRequired("group")
39+
40+
rootCmd.AddCommand(systCmd)
41+
return rootCmd
42+
}
43+
44+
func TestSystemdCmd(t *testing.T) {
45+
tests := []struct {
46+
name string
47+
args []string
48+
expectedOutput []string
49+
expectedError string
50+
}{
51+
{
52+
name: "All required flags provided",
53+
args: []string{
54+
"--service-id=test-service",
55+
"--script=/path/to/script.sh",
56+
"--tag-prefix=test",
57+
"--interval=30s",
58+
"--user=testuser",
59+
"--group=testgroup",
60+
},
61+
expectedOutput: []string{
62+
"[Unit]",
63+
"Description=Tagit test-service",
64+
"After=network.target",
65+
"After=network-online.target",
66+
"Wants=network-online.target",
67+
"",
68+
"[Service]",
69+
"Type=simple",
70+
"ExecStart=/usr/bin/tagit run -s test-service -x /path/to/script.sh -p test -i 30s",
71+
"Environment=HOME=/var/run/tagit/test-service",
72+
"Restart=always",
73+
"User=testuser",
74+
"Group=testgroup",
75+
"",
76+
"[Install]",
77+
"WantedBy=multi-user.target",
78+
},
79+
},
80+
{
81+
name: "All flags provided including optional",
82+
args: []string{
83+
"--service-id=test-service",
84+
"--script=/path/to/script.sh",
85+
"--tag-prefix=test",
86+
"--interval=30s",
87+
"--user=testuser",
88+
"--group=testgroup",
89+
"--token=test-token",
90+
"--consul-addr=localhost:8500",
91+
},
92+
expectedOutput: []string{
93+
"[Unit]",
94+
"Description=Tagit test-service",
95+
"After=network.target",
96+
"After=network-online.target",
97+
"Wants=network-online.target",
98+
"",
99+
"[Service]",
100+
"Type=simple",
101+
"ExecStart=/usr/bin/tagit run -s test-service -x /path/to/script.sh -p test -i 30s -t test-token -c localhost:8500",
102+
"Environment=HOME=/var/run/tagit/test-service",
103+
"Restart=always",
104+
"User=testuser",
105+
"Group=testgroup",
106+
"",
107+
"[Install]",
108+
"WantedBy=multi-user.target",
109+
},
110+
},
111+
{
112+
name: "Missing required flag",
113+
args: []string{
114+
"--service-id=test-service",
115+
"--script=/path/to/script.sh",
116+
"--tag-prefix=test",
117+
"--interval=30s",
118+
"--user=testuser",
119+
// missing --group flag
120+
},
121+
expectedError: "required flag(s) \"group\" not set",
122+
},
123+
}
124+
125+
for _, tt := range tests {
126+
t.Run(tt.name, func(t *testing.T) {
127+
cmd := setupSystemdCmd()
128+
cmd.SetArgs(append([]string{"systemd"}, tt.args...))
129+
130+
t.Logf("Test case: %s", tt.name)
131+
t.Logf("Command args: %v", tt.args)
132+
133+
// Capture stdout and stderr
134+
oldStdout := os.Stdout
135+
oldStderr := os.Stderr
136+
r, w, _ := os.Pipe()
137+
os.Stdout = w
138+
os.Stderr = w
139+
140+
err := cmd.Execute()
141+
142+
// Restore stdout and stderr
143+
w.Close()
144+
os.Stdout = oldStdout
145+
os.Stderr = oldStderr
146+
147+
var buf bytes.Buffer
148+
io.Copy(&buf, r)
149+
output := buf.String()
150+
151+
t.Logf("Command execution completed. Error: %v", err)
152+
t.Logf("Command output:\n%s", output)
153+
154+
if tt.expectedError != "" {
155+
assert.Error(t, err)
156+
assert.Contains(t, err.Error(), tt.expectedError)
157+
assert.Contains(t, output, tt.expectedError)
158+
} else {
159+
assert.NoError(t, err)
160+
for _, expectedLine := range tt.expectedOutput {
161+
assert.Contains(t, output, expectedLine, "Output should contain %q", expectedLine)
162+
}
163+
}
164+
165+
// Check if all required flags are set
166+
systCmd, _, _ := cmd.Find([]string{"systemd"})
167+
requiredFlags := []string{"service-id", "script", "tag-prefix", "interval", "user", "group"}
168+
for _, flagName := range requiredFlags {
169+
flag := systCmd.Flags().Lookup(flagName)
170+
assert.NotNil(t, flag, "Required flag %q is not defined", flagName)
171+
t.Logf("Flag %q value: %q", flagName, flag.Value.String())
172+
173+
if tt.expectedError == "" {
174+
assert.NotEmpty(t, flag.Value.String(), "Required flag %q is not set", flagName)
175+
}
176+
}
177+
178+
// Print all set flags
179+
t.Log("All set flags:")
180+
systCmd.Flags().VisitAll(func(f *pflag.Flag) {
181+
t.Logf(" %s: %s", f.Name, f.Value.String())
182+
})
183+
})
184+
}
185+
}
186+
187+
func TestSystemdCmdFlagDefinitions(t *testing.T) {
188+
cmd := setupSystemdCmd()
189+
systCmd, _, err := cmd.Find([]string{"systemd"})
190+
assert.NoError(t, err)
191+
192+
expectedFlags := map[string]struct {
193+
expectedRequired bool
194+
flagType string
195+
}{
196+
"service-id": {true, "string"},
197+
"script": {true, "string"},
198+
"tag-prefix": {true, "string"},
199+
"interval": {true, "string"},
200+
"token": {false, "string"},
201+
"consul-addr": {false, "string"},
202+
"user": {true, "string"},
203+
"group": {true, "string"},
204+
}
205+
206+
for flagName, details := range expectedFlags {
207+
t.Run(flagName, func(t *testing.T) {
208+
flag := systCmd.Flags().Lookup(flagName)
209+
assert.NotNil(t, flag, "Flag %q should be defined", flagName)
210+
211+
t.Logf("Checking flag: %s", flagName)
212+
t.Logf("Flag found: %v", flag != nil)
213+
if flag != nil {
214+
t.Logf("Flag value: %s", flag.Value.String())
215+
t.Logf("Flag type: %s", flag.Value.Type())
216+
}
217+
218+
assert.Equal(t, details.flagType, flag.Value.Type(), "Flag %q should be of type %s", flagName, details.flagType)
219+
220+
// Try to mark the flag as required
221+
err := cobra.MarkFlagRequired(systCmd.Flags(), flagName)
222+
223+
if details.expectedRequired {
224+
assert.NoError(t, err, "Flag %q should be able to be marked as required", flagName)
225+
} else {
226+
if err == nil {
227+
t.Logf("Warning: Flag %q was expected to be optional but can be marked as required", flagName)
228+
} else {
229+
t.Logf("Flag %q behaves as expected (optional)", flagName)
230+
}
231+
}
232+
233+
// Check if the flag is actually marked as required in the command definition
234+
isRequired := systCmd.Flags().Lookup(flagName).Annotations != nil &&
235+
len(systCmd.Flags().Lookup(flagName).Annotations[cobra.BashCompOneRequiredFlag]) > 0
236+
237+
t.Logf("Flag %q is%s marked as required in the command definition", flagName, map[bool]string{true: "", false: " not"}[isRequired])
238+
239+
if details.expectedRequired != isRequired {
240+
t.Logf("Warning: Flag %q required status (%v) does not match expected (%v)", flagName, isRequired, details.expectedRequired)
241+
}
242+
})
243+
}
244+
}
245+
246+
func TestSystemdCmdHelp(t *testing.T) {
247+
cmd := setupSystemdCmd()
248+
buf := new(bytes.Buffer)
249+
cmd.SetOut(buf)
250+
cmd.SetArgs([]string{"systemd", "--help"})
251+
err := cmd.Execute()
252+
assert.NoError(t, err)
253+
254+
output := buf.String()
255+
assert.Contains(t, output, "Generate a systemd service file for TagIt")
256+
assert.Contains(t, output, "Usage:")
257+
assert.Contains(t, output, "Flags:")
258+
}
259+
260+
func TestSystemdCmdInvalidFlag(t *testing.T) {
261+
cmd := setupSystemdCmd()
262+
cmd.SetArgs([]string{"systemd", "--invalid-flag=value"})
263+
err := cmd.Execute()
264+
assert.Error(t, err)
265+
assert.Contains(t, err.Error(), "unknown flag: --invalid-flag")
266+
}
267+
268+
func TestSystemdCmdFlagParsing(t *testing.T) {
269+
cmd := setupSystemdCmd()
270+
args := []string{
271+
"systemd",
272+
"--service-id=test-service",
273+
"--script=/path/to/script.sh",
274+
"--tag-prefix=test",
275+
"--interval=30s",
276+
"--user=testuser",
277+
"--group=testgroup",
278+
"--token=test-token",
279+
"--consul-addr=localhost:8500",
280+
}
281+
282+
cmd.SetArgs(args)
283+
err := cmd.Execute()
284+
assert.NoError(t, err)
285+
286+
systCmd, _, _ := cmd.Find([]string{"systemd"})
287+
for _, arg := range args[1:] { // Skip "systemd"
288+
parts := strings.SplitN(arg, "=", 2)
289+
flagName := strings.TrimLeft(parts[0], "-")
290+
expectedValue := parts[1]
291+
292+
flag := systCmd.Flags().Lookup(flagName)
293+
assert.NotNil(t, flag)
294+
assert.Equal(t, expectedValue, flag.Value.String())
295+
}
296+
}

0 commit comments

Comments
 (0)