diff --git a/internal/updates/manager_test.go b/internal/updates/manager_test.go index f95ea0902..35ff0f3da 100644 --- a/internal/updates/manager_test.go +++ b/internal/updates/manager_test.go @@ -6,6 +6,7 @@ import ( "compress/gzip" "context" "encoding/json" + "errors" "net/http" "net/http/httptest" "os" @@ -483,3 +484,91 @@ func TestInferVersionFromDownloadURL(t *testing.T) { }) } } + +func TestSanitizeError(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + err error + expected string + }{ + { + name: "nil error", + err: nil, + expected: "", + }, + { + name: "simple error", + err: errors.New("connection refused"), + expected: "connection refused", + }, + { + name: "error with newlines preserved", + err: errors.New("line1\nline2"), + expected: "line1\nline2", + }, + { + name: "error at max length", + err: errors.New(strings.Repeat("a", 500)), + expected: strings.Repeat("a", 500), + }, + { + name: "error over max length truncated", + err: errors.New(strings.Repeat("a", 501)), + expected: strings.Repeat("a", 500) + "...", + }, + { + name: "error way over max length", + err: errors.New(strings.Repeat("a", 1000)), + expected: strings.Repeat("a", 500) + "...", + }, + } + + for _, tc := range tests { + tc := tc + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + if got := sanitizeError(tc.err); got != tc.expected { + t.Fatalf("sanitizeError() = %q (len %d), expected %q (len %d)", + got, len(got), tc.expected, len(tc.expected)) + } + }) + } +} + +func TestStatusDelayForStage(t *testing.T) { + // This test verifies the stage delay logic without actually configuring a delay + // since configuredStageDelay uses sync.Once and reads from environment + + tests := []struct { + name string + status string + }{ + // Stages that should return configured delay (if any) + {name: "downloading", status: "downloading"}, + {name: "verifying", status: "verifying"}, + {name: "extracting", status: "extracting"}, + {name: "backing-up", status: "backing-up"}, + {name: "applying", status: "applying"}, + + // Stages that should always return 0 + {name: "idle", status: "idle"}, + {name: "completed", status: "completed"}, + {name: "failed", status: "failed"}, + {name: "unknown", status: "unknown"}, + {name: "empty", status: ""}, + } + + for _, tc := range tests { + tc := tc + t.Run(tc.name, func(t *testing.T) { + // Without PULSE_UPDATE_STAGE_DELAY_MS set, all should return 0 + got := statusDelayForStage(tc.status) + if got != 0 { + t.Fatalf("statusDelayForStage(%q) = %v, expected 0 (no delay configured)", + tc.status, got) + } + }) + } +} diff --git a/internal/updates/version_test.go b/internal/updates/version_test.go index c50f09bc8..c8eec84b8 100644 --- a/internal/updates/version_test.go +++ b/internal/updates/version_test.go @@ -523,3 +523,92 @@ func TestSanitizePrereleaseIdentifier(t *testing.T) { }) } } + +func TestNormalizeGitDescribeVersion(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + input string + expected string + ok bool + }{ + // Valid git describe outputs + { + name: "basic git describe", + input: "4.24.0-45-gabcdef", + expected: "4.24.0+git.45.gabcdef", + ok: true, + }, + { + name: "with prerelease", + input: "4.24.0-rc.3-45-gABCDEF", + expected: "4.24.0-rc.3+git.45.gabcdef", + ok: true, + }, + { + name: "with dirty flag", + input: "4.24.0-rc.3-45-gabc123-dirty", + expected: "4.24.0-rc.3+git.45.gabc123.dirty", + ok: true, + }, + { + name: "uppercase hash normalized", + input: "4.24.0-1-gABCDEF", + expected: "4.24.0+git.1.gabcdef", + ok: true, + }, + { + name: "dirty without prerelease", + input: "4.24.0-10-g1234567-dirty", + expected: "4.24.0+git.10.g1234567.dirty", + ok: true, + }, + + // Invalid inputs + { + name: "plain version", + input: "4.24.0", + expected: "", + ok: false, + }, + { + name: "version with prerelease only", + input: "4.24.0-rc.1", + expected: "", + ok: false, + }, + { + name: "empty string", + input: "", + expected: "", + ok: false, + }, + { + name: "branch name", + input: "feature-branch", + expected: "", + ok: false, + }, + { + name: "invalid base version", + input: "invalid-45-gabcdef", + expected: "", + ok: false, + }, + } + + for _, tc := range tests { + tc := tc + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + got, ok := normalizeGitDescribeVersion(tc.input) + if ok != tc.ok { + t.Fatalf("normalizeGitDescribeVersion(%q) ok = %v, expected %v", tc.input, ok, tc.ok) + } + if got != tc.expected { + t.Fatalf("normalizeGitDescribeVersion(%q) = %q, expected %q", tc.input, got, tc.expected) + } + }) + } +}