Skip to content

Commit 9146ff3

Browse files
authored
Merge pull request #19 from ncode/juliano/tests
(feat): move from exit to return and Run to RunE to make things testable
2 parents afd6207 + e5e8c3a commit 9146ff3

File tree

5 files changed

+358
-21
lines changed

5 files changed

+358
-21
lines changed

cmd/cleanup.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ limitations under the License.
1616
package cmd
1717

1818
import (
19+
"fmt"
1920
"log/slog"
2021
"os"
2122

@@ -28,7 +29,7 @@ import (
2829
var cleanupCmd = &cobra.Command{
2930
Use: "cleanup",
3031
Short: "cleanup removes all services with the tag prefix from a given consul service",
31-
Run: func(cmd *cobra.Command, args []string) {
32+
RunE: func(cmd *cobra.Command, args []string) error {
3233
logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{
3334
Level: slog.LevelInfo,
3435
}))
@@ -40,7 +41,7 @@ var cleanupCmd = &cobra.Command{
4041
consulClient, err := api.NewClient(config)
4142
if err != nil {
4243
logger.Error("Failed to create Consul client", "error", err)
43-
os.Exit(1)
44+
return fmt.Errorf("failed to create Consul client: %w", err)
4445
}
4546

4647
serviceID := cmd.InheritedFlags().Lookup("service-id").Value.String()
@@ -61,10 +62,11 @@ var cleanupCmd = &cobra.Command{
6162
err = t.CleanupTags()
6263
if err != nil {
6364
logger.Error("Failed to clean up tags", "error", err)
64-
os.Exit(1)
65+
return fmt.Errorf("failed to clean up tags: %w", err)
6566
}
6667

6768
logger.Info("Tag cleanup completed successfully")
69+
return nil
6870
},
6971
}
7072

cmd/cleanup_test.go

Lines changed: 106 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ func TestCleanupCmd(t *testing.T) {
4646
testCleanupCmd := &cobra.Command{
4747
Use: "cleanup",
4848
Short: "cleanup removes all services with the tag prefix",
49-
Run: cleanupCmd.Run,
49+
RunE: cleanupCmd.RunE,
5050
}
5151
cmd.AddCommand(testCleanupCmd)
5252

@@ -124,18 +124,120 @@ func TestCleanupCmdHelp(t *testing.T) {
124124
testCleanupCmd := &cobra.Command{
125125
Use: "cleanup",
126126
Short: "cleanup removes all services with the tag prefix from a given consul service",
127-
Run: cleanupCmd.Run,
127+
RunE: cleanupCmd.RunE,
128128
}
129129
cmd.AddCommand(testCleanupCmd)
130130

131131
buf := new(bytes.Buffer)
132132
cmd.SetOut(buf)
133133
cmd.SetArgs([]string{"cleanup", "--help"})
134-
134+
135135
err := cmd.Execute()
136136
assert.NoError(t, err)
137137

138138
output := buf.String()
139139
assert.Contains(t, output, "cleanup removes all services with the tag prefix")
140140
assert.Contains(t, output, "Usage:")
141-
}
141+
}
142+
143+
func TestCleanupCmdExecution(t *testing.T) {
144+
tests := []struct {
145+
name string
146+
consulAddr string
147+
expectError bool
148+
errorContains string
149+
}{
150+
{
151+
name: "Invalid consul address",
152+
consulAddr: "invalid-consul-address",
153+
expectError: true,
154+
errorContains: "failed to clean up tags",
155+
},
156+
}
157+
158+
for _, tt := range tests {
159+
t.Run(tt.name, func(t *testing.T) {
160+
cmd := &cobra.Command{Use: "tagit"}
161+
cmd.PersistentFlags().StringP("consul-addr", "c", "127.0.0.1:8500", "consul address")
162+
cmd.PersistentFlags().StringP("service-id", "s", "", "consul service id")
163+
cmd.PersistentFlags().StringP("script", "x", "", "path to script used to generate tags")
164+
cmd.PersistentFlags().StringP("tag-prefix", "p", "tagged", "prefix to be added to tags")
165+
cmd.PersistentFlags().StringP("token", "t", "", "consul token")
166+
167+
testCleanupCmd := &cobra.Command{
168+
Use: "cleanup",
169+
Short: "cleanup removes all services with the tag prefix from a given consul service",
170+
RunE: cleanupCmd.RunE,
171+
}
172+
cmd.AddCommand(testCleanupCmd)
173+
174+
var stderr bytes.Buffer
175+
cmd.SetErr(&stderr)
176+
cmd.SetArgs([]string{
177+
"cleanup",
178+
"--service-id=test-service",
179+
"--script=/tmp/test.sh",
180+
"--consul-addr=" + tt.consulAddr,
181+
"--tag-prefix=test",
182+
})
183+
184+
err := cmd.Execute()
185+
186+
if tt.expectError {
187+
assert.Error(t, err)
188+
if tt.errorContains != "" {
189+
assert.Contains(t, err.Error(), tt.errorContains)
190+
}
191+
} else {
192+
assert.NoError(t, err)
193+
}
194+
})
195+
}
196+
}
197+
198+
func TestCleanupCmdFlagRetrieval(t *testing.T) {
199+
// Test that all flag retrievals work correctly within the RunE function
200+
cmd := &cobra.Command{Use: "tagit"}
201+
cmd.PersistentFlags().StringP("consul-addr", "c", "127.0.0.1:8500", "consul address")
202+
cmd.PersistentFlags().StringP("service-id", "s", "", "consul service id")
203+
cmd.PersistentFlags().StringP("script", "x", "", "path to script used to generate tags")
204+
cmd.PersistentFlags().StringP("tag-prefix", "p", "tagged", "prefix to be added to tags")
205+
cmd.PersistentFlags().StringP("token", "t", "", "consul token")
206+
207+
var capturedValues map[string]string
208+
209+
testCleanupCmd := &cobra.Command{
210+
Use: "cleanup",
211+
Short: "cleanup removes all services with the tag prefix from a given consul service",
212+
RunE: func(cmd *cobra.Command, args []string) error {
213+
// Test the same flag access pattern used in the actual cleanup command
214+
capturedValues = make(map[string]string)
215+
capturedValues["consul-addr"] = cmd.InheritedFlags().Lookup("consul-addr").Value.String()
216+
capturedValues["token"] = cmd.InheritedFlags().Lookup("token").Value.String()
217+
capturedValues["service-id"] = cmd.InheritedFlags().Lookup("service-id").Value.String()
218+
capturedValues["tag-prefix"] = cmd.InheritedFlags().Lookup("tag-prefix").Value.String()
219+
220+
// Don't actually try to connect to consul - just test flag access
221+
return nil
222+
},
223+
}
224+
cmd.AddCommand(testCleanupCmd)
225+
226+
cmd.SetArgs([]string{
227+
"cleanup",
228+
"--service-id=test-service",
229+
"--script=/tmp/test.sh",
230+
"--consul-addr=localhost:9500",
231+
"--tag-prefix=test-prefix",
232+
"--token=test-token",
233+
})
234+
235+
err := cmd.Execute()
236+
assert.NoError(t, err)
237+
238+
// Verify all values were captured correctly
239+
assert.Equal(t, "localhost:9500", capturedValues["consul-addr"])
240+
assert.Equal(t, "test-token", capturedValues["token"])
241+
assert.Equal(t, "test-service", capturedValues["service-id"])
242+
assert.Equal(t, "test-prefix", capturedValues["tag-prefix"])
243+
}

cmd/root_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ func TestRootCmdHelp(t *testing.T) {
189189
var buf bytes.Buffer
190190
rootCmd.SetOut(&buf)
191191
rootCmd.SetArgs([]string{"--help"})
192-
192+
193193
err := rootCmd.Execute()
194194
assert.NoError(t, err)
195195

@@ -203,4 +203,4 @@ func TestRootCmdHelp(t *testing.T) {
203203
assert.Contains(t, output, "cleanup")
204204
assert.Contains(t, output, "run")
205205
assert.Contains(t, output, "systemd")
206-
}
206+
}

cmd/run.go

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package cmd
1717

1818
import (
1919
"context"
20+
"fmt"
2021
"log/slog"
2122
"os"
2223
"os/signal"
@@ -36,60 +37,60 @@ var runCmd = &cobra.Command{
3637
3738
example: tagit run -s my-super-service -x '/tmp/tag-role.sh'
3839
`,
39-
Run: func(cmd *cobra.Command, args []string) {
40+
RunE: func(cmd *cobra.Command, args []string) error {
4041
logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{
4142
Level: slog.LevelInfo,
4243
}))
4344

4445
interval, err := cmd.InheritedFlags().GetString("interval")
4546
if err != nil {
4647
logger.Error("Failed to get interval flag", "error", err)
47-
os.Exit(1)
48+
return err
4849
}
4950

5051
if interval == "" || interval == "0" {
5152
logger.Error("Interval is required")
52-
os.Exit(1)
53+
return fmt.Errorf("interval is required and cannot be empty or zero")
5354
}
5455

5556
validInterval, err := time.ParseDuration(interval)
5657
if err != nil {
5758
logger.Error("Invalid interval", "interval", interval, "error", err)
58-
os.Exit(1)
59+
return fmt.Errorf("invalid interval %q: %w", interval, err)
5960
}
6061

6162
config := api.DefaultConfig()
6263
config.Address, err = cmd.InheritedFlags().GetString("consul-addr")
6364
if err != nil {
6465
logger.Error("Failed to get consul-addr flag", "error", err)
65-
os.Exit(1)
66+
return err
6667
}
6768
config.Token, err = cmd.InheritedFlags().GetString("token")
6869
if err != nil {
6970
logger.Error("Failed to get token flag", "error", err)
70-
os.Exit(1)
71+
return err
7172
}
7273

7374
consulClient, err := api.NewClient(config)
7475
if err != nil {
7576
logger.Error("Failed to create Consul client", "error", err)
76-
os.Exit(1)
77+
return fmt.Errorf("failed to create Consul client: %w", err)
7778
}
7879

7980
serviceID, err := cmd.InheritedFlags().GetString("service-id")
8081
if err != nil {
8182
logger.Error("Failed to get service-id flag", "error", err)
82-
os.Exit(1)
83+
return err
8384
}
8485
script, err := cmd.InheritedFlags().GetString("script")
8586
if err != nil {
8687
logger.Error("Failed to get script flag", "error", err)
87-
os.Exit(1)
88+
return err
8889
}
8990
tagPrefix, err := cmd.InheritedFlags().GetString("tag-prefix")
9091
if err != nil {
9192
logger.Error("Failed to get tag-prefix flag", "error", err)
92-
os.Exit(1)
93+
return err
9394
}
9495

9596
t := tagit.New(
@@ -124,6 +125,7 @@ example: tagit run -s my-super-service -x '/tmp/tag-role.sh'
124125
t.Run(ctx)
125126

126127
logger.Info("Tagit has stopped")
128+
return nil
127129
},
128130
}
129131

0 commit comments

Comments
 (0)