274 lines
6.4 KiB
Go
274 lines
6.4 KiB
Go
package main
|
|
|
|
import (
|
|
"os"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestLoadConfig(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
yamlContent string
|
|
wantError bool
|
|
checkFields func(*testing.T, Config)
|
|
}{
|
|
{
|
|
name: "valid config with all fields",
|
|
yamlContent: `listen:
|
|
- ":8080"
|
|
checkpoints: "checkpoints"
|
|
roots: "roots.pem"
|
|
logs:
|
|
- shortname: "test-log"
|
|
inception: "2024-01-01T00:00:00Z"
|
|
period: 300
|
|
poolsize: 1000
|
|
submissionprefix: "https://example.com/submit"
|
|
monitoringprefix: "https://example.com/monitor"
|
|
secret: "test.key"
|
|
localdirectory: "test-dir"
|
|
notafterstart: "2024-01-01T00:00:00Z"
|
|
notafterlimit: "2025-01-01T00:00:00Z"`,
|
|
wantError: false,
|
|
checkFields: func(t *testing.T, config Config) {
|
|
if len(config.Listen) != 1 || config.Listen[0] != ":8080" {
|
|
t.Errorf("Expected Listen [\":8080\"], got %v", config.Listen)
|
|
}
|
|
if config.Checkpoints != "checkpoints" {
|
|
t.Errorf("Expected Checkpoints \"checkpoints\", got %s", config.Checkpoints)
|
|
}
|
|
if len(config.Logs) != 1 {
|
|
t.Errorf("Expected 1 log, got %d", len(config.Logs))
|
|
}
|
|
log := config.Logs[0]
|
|
if log.ShortName != "test-log" {
|
|
t.Errorf("Expected ShortName \"test-log\", got %s", log.ShortName)
|
|
}
|
|
if log.Period != 300 {
|
|
t.Errorf("Expected Period 300, got %d", log.Period)
|
|
}
|
|
if log.PoolSize != 1000 {
|
|
t.Errorf("Expected PoolSize 1000, got %d", log.PoolSize)
|
|
}
|
|
if log.Origin != "example.com" {
|
|
t.Errorf("Expected Origin \"example.com\", got %s", log.Origin)
|
|
}
|
|
},
|
|
},
|
|
{
|
|
name: "config with defaults",
|
|
yamlContent: `logs:
|
|
- shortname: "minimal-log"
|
|
submissionprefix: "https://test.example.com/submit"
|
|
secret: "test.key"
|
|
localdirectory: "test-dir"`,
|
|
wantError: false,
|
|
checkFields: func(t *testing.T, config Config) {
|
|
if len(config.Listen) != 1 || config.Listen[0] != ":8080" {
|
|
t.Errorf("Expected default Listen [\":8080\"], got %v", config.Listen)
|
|
}
|
|
if len(config.Logs) != 1 {
|
|
t.Errorf("Expected 1 log, got %d", len(config.Logs))
|
|
}
|
|
log := config.Logs[0]
|
|
if log.Period != 200 {
|
|
t.Errorf("Expected default Period 200, got %d", log.Period)
|
|
}
|
|
if log.PoolSize != 750 {
|
|
t.Errorf("Expected default PoolSize 750, got %d", log.PoolSize)
|
|
}
|
|
if log.Origin != "test.example.com" {
|
|
t.Errorf("Expected Origin \"test.example.com\", got %s", log.Origin)
|
|
}
|
|
},
|
|
},
|
|
{
|
|
name: "invalid yaml",
|
|
yamlContent: `invalid: yaml: content:
|
|
- malformed`,
|
|
wantError: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
tmpfile, err := os.CreateTemp("", "test-config-*.yaml")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer os.Remove(tmpfile.Name())
|
|
|
|
_, err = tmpfile.WriteString(tt.yamlContent)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
tmpfile.Close()
|
|
|
|
if tt.wantError {
|
|
// Can't easily test log.Fatalf without subprocess
|
|
t.Skip("Cannot easily test log.Fatalf without subprocess")
|
|
} else {
|
|
config := loadConfig(tmpfile.Name())
|
|
if tt.checkFields != nil {
|
|
tt.checkFields(t, config)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestExtractHostname(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
urlStr string
|
|
want string
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "https URL",
|
|
urlStr: "https://example.com/path",
|
|
want: "example.com",
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "http URL",
|
|
urlStr: "http://test.example.com:8080/path",
|
|
want: "test.example.com:8080",
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "URL with port",
|
|
urlStr: "https://log.example.com:9090/monitor",
|
|
want: "log.example.com:9090",
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "invalid URL",
|
|
urlStr: "://invalid-url",
|
|
want: "",
|
|
wantErr: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got, err := extractHostname(tt.urlStr)
|
|
if (err != nil) != tt.wantErr {
|
|
t.Errorf("extractHostname() error = %v, wantErr %v", err, tt.wantErr)
|
|
return
|
|
}
|
|
if got != tt.want {
|
|
t.Errorf("extractHostname() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestExtractPort(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
listenAddr string
|
|
want string
|
|
}{
|
|
{
|
|
name: "port only",
|
|
listenAddr: ":8080",
|
|
want: "8080",
|
|
},
|
|
{
|
|
name: "localhost with port",
|
|
listenAddr: "localhost:9090",
|
|
want: "9090",
|
|
},
|
|
{
|
|
name: "IPv6 with port",
|
|
listenAddr: "[::]:8080",
|
|
want: "8080",
|
|
},
|
|
{
|
|
name: "no port",
|
|
listenAddr: "localhost",
|
|
want: "",
|
|
},
|
|
{
|
|
name: "empty string",
|
|
listenAddr: "",
|
|
want: "",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := extractPort(tt.listenAddr)
|
|
if got != tt.want {
|
|
t.Errorf("extractPort() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestColorizeUnifiedDiff(t *testing.T) {
|
|
diff := `--- file1.txt
|
|
+++ file2.txt
|
|
@@ -1,3 +1,3 @@
|
|
line1
|
|
-old line
|
|
+new line
|
|
line3`
|
|
|
|
result := colorizeUnifiedDiff(diff)
|
|
|
|
if !strings.Contains(result, colorCyan) {
|
|
t.Error("Expected diff to contain cyan color codes")
|
|
}
|
|
if !strings.Contains(result, colorYellow) {
|
|
t.Error("Expected diff to contain yellow color codes")
|
|
}
|
|
if !strings.Contains(result, colorRed) {
|
|
t.Error("Expected diff to contain red color codes")
|
|
}
|
|
if !strings.Contains(result, colorGreen) {
|
|
t.Error("Expected diff to contain green color codes")
|
|
}
|
|
if !strings.Contains(result, colorReset) {
|
|
t.Error("Expected diff to contain reset color codes")
|
|
}
|
|
}
|
|
|
|
func TestWriteFileWithStatus(t *testing.T) {
|
|
tmpDir := t.TempDir()
|
|
testFile := tmpDir + "/test.txt"
|
|
content := []byte("test content")
|
|
|
|
err := writeFileWithStatus(testFile, content, false, true, false)
|
|
if err != nil {
|
|
t.Errorf("writeFileWithStatus() error = %v", err)
|
|
}
|
|
|
|
writtenContent, err := os.ReadFile(testFile)
|
|
if err != nil {
|
|
t.Fatalf("Failed to read written file: %v", err)
|
|
}
|
|
|
|
if string(writtenContent) != string(content) {
|
|
t.Errorf("Written content = %s, want %s", string(writtenContent), string(content))
|
|
}
|
|
|
|
err = writeFileWithStatus(testFile, content, false, false, false)
|
|
if err != nil {
|
|
t.Errorf("writeFileWithStatus() with allowWrite=false should not error: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestTimeFormats(t *testing.T) {
|
|
testTime := time.Date(2024, 1, 1, 12, 0, 0, 0, time.UTC)
|
|
expected := "2024-01-01T12:00:00Z"
|
|
|
|
formatted := testTime.Format("2006-01-02T15:04:05Z")
|
|
if formatted != expected {
|
|
t.Errorf("Time format = %s, want %s", formatted, expected)
|
|
}
|
|
}
|