diff --git a/.gitignore b/.gitignore index bd76197..79fedd1 100644 --- a/.gitignore +++ b/.gitignore @@ -52,6 +52,6 @@ test-results/ packaging/test/*.deb packaging/test/*.rpm -# Binary -ja4sentinel +# Binary (root level only) +/ja4sentinel ja4sentinel-linux-amd64 diff --git a/cmd/ja4sentinel/main_test.go b/cmd/ja4sentinel/main_test.go new file mode 100644 index 0000000..c11402a --- /dev/null +++ b/cmd/ja4sentinel/main_test.go @@ -0,0 +1,126 @@ +package main + +import ( + "flag" + "strings" + "testing" +) + +func TestFormatPorts(t *testing.T) { + tests := []struct { + name string + ports []uint16 + want string + }{ + { + name: "empty slice", + ports: []uint16{}, + want: "", + }, + { + name: "single port", + ports: []uint16{443}, + want: "443", + }, + { + name: "multiple ports", + ports: []uint16{443, 8443, 9443}, + want: "443,8443,9443", + }, + { + name: "two ports", + ports: []uint16{80, 443}, + want: "80,443", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := formatPorts(tt.ports) + if got != tt.want { + t.Errorf("formatPorts() = %v, want %v", got, tt.want) + } + }) + } +} + +// TestMain_VersionFlag_VerifiesOutput tests that the version flag produces correct output +// Note: This test verifies the version variables are set correctly +func TestMain_VersionFlag_VerifiesOutput(t *testing.T) { + // Verify version variables are set + if Version == "" { + t.Error("Version should not be empty") + } + if BuildTime == "" { + t.Error("BuildTime should not be empty") + } + if GitCommit == "" { + t.Error("GitCommit should not be empty") + } + + // Verify version format + expectedPrefix := "ja4sentinel version" + got := getVersionString() + if !strings.HasPrefix(got, expectedPrefix) { + t.Errorf("getVersionString() = %v, should start with %v", got, expectedPrefix) + } +} + +// getVersionString returns the version string (helper for testing) +func getVersionString() string { + return "ja4sentinel version " + Version + " (built " + BuildTime + ", commit " + GitCommit + ")" +} + +func TestFlagParsing(t *testing.T) { + tests := []struct { + name string + args []string + wantConfig string + wantVersion bool + }{ + { + name: "config flag", + args: []string{"ja4sentinel", "-config", "/path/to/config.yml"}, + wantConfig: "/path/to/config.yml", + wantVersion: false, + }, + { + name: "version flag", + args: []string{"ja4sentinel", "-version"}, + wantConfig: "", + wantVersion: true, + }, + { + name: "no flags", + args: []string{"ja4sentinel"}, + wantConfig: "", + wantVersion: false, + }, + { + name: "config with long form", + args: []string{"ja4sentinel", "--config", "/etc/ja4sentinel/config.yml"}, + wantConfig: "/etc/ja4sentinel/config.yml", + wantVersion: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + fs := flag.NewFlagSet("test", flag.ContinueOnError) + configPath := fs.String("config", "", "Path to configuration file (YAML)") + version := fs.Bool("version", false, "Show version information") + + err := fs.Parse(tt.args[1:]) + if err != nil { + t.Fatalf("Flag parsing failed: %v", err) + } + + if *configPath != tt.wantConfig { + t.Errorf("config = %v, want %v", *configPath, tt.wantConfig) + } + if *version != tt.wantVersion { + t.Errorf("version = %v, want %v", *version, tt.wantVersion) + } + }) + } +}