528a09ca90
Split release.sh into release-client.sh and release-engine.sh for independent release cadences. Client checks engine version on first API call and hard-fails if engine is below MinEngineVersion. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
137 lines
3.0 KiB
Go
137 lines
3.0 KiB
Go
package api
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
)
|
|
|
|
func TestSemverAtLeast(t *testing.T) {
|
|
tests := []struct {
|
|
version string
|
|
minimum string
|
|
expected bool
|
|
}{
|
|
{"2.1.0", "2.0.0", true},
|
|
{"2.0.0", "2.0.0", true},
|
|
{"2.0.5", "2.0.0", true},
|
|
{"2.1.5", "2.1.0", true},
|
|
{"2.0.9", "2.1.0", false},
|
|
{"1.9.9", "2.0.0", false},
|
|
{"3.0.0", "2.9.9", true},
|
|
{"2.0.0", "2.0.1", false},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.version+">="+tt.minimum, func(t *testing.T) {
|
|
got := semverAtLeast(tt.version, tt.minimum)
|
|
if got != tt.expected {
|
|
t.Errorf("semverAtLeast(%q, %q) = %v, want %v", tt.version, tt.minimum, got, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCheckEngineVersion_Compatible(t *testing.T) {
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
json.NewEncoder(w).Encode(map[string]string{"version": "2.1.0"})
|
|
}))
|
|
defer srv.Close()
|
|
|
|
clientVersion = "2.2.0"
|
|
minEngineVersion = "2.1.0"
|
|
defer func() { clientVersion = ""; minEngineVersion = "" }()
|
|
|
|
c := &Client{
|
|
baseURL: srv.URL,
|
|
httpClient: &http.Client{},
|
|
}
|
|
|
|
// Should not panic or exit
|
|
c.checkEngineVersion()
|
|
|
|
if !c.versionChecked {
|
|
t.Error("versionChecked should be true after check")
|
|
}
|
|
}
|
|
|
|
func TestCheckEngineVersion_SkipsWhenDev(t *testing.T) {
|
|
clientVersion = "dev"
|
|
minEngineVersion = "dev"
|
|
defer func() { clientVersion = ""; minEngineVersion = "" }()
|
|
|
|
c := &Client{
|
|
baseURL: "http://localhost:99999",
|
|
httpClient: &http.Client{},
|
|
}
|
|
|
|
// Should not attempt connection
|
|
c.checkEngineVersion()
|
|
|
|
if !c.versionChecked {
|
|
t.Error("versionChecked should be true after skipping")
|
|
}
|
|
}
|
|
|
|
func TestCheckEngineVersion_SkipsWhenEmpty(t *testing.T) {
|
|
clientVersion = "1.0.0"
|
|
minEngineVersion = ""
|
|
defer func() { clientVersion = ""; minEngineVersion = "" }()
|
|
|
|
c := &Client{
|
|
baseURL: "http://localhost:99999",
|
|
httpClient: &http.Client{},
|
|
}
|
|
|
|
c.checkEngineVersion()
|
|
|
|
if !c.versionChecked {
|
|
t.Error("versionChecked should be true after skipping")
|
|
}
|
|
}
|
|
|
|
func TestCheckEngineVersion_SkipsWhenUnreachable(t *testing.T) {
|
|
clientVersion = "2.0.0"
|
|
minEngineVersion = "2.0.0"
|
|
defer func() { clientVersion = ""; minEngineVersion = "" }()
|
|
|
|
c := &Client{
|
|
baseURL: "http://localhost:99999",
|
|
httpClient: &http.Client{},
|
|
}
|
|
|
|
// Should not panic — just skip
|
|
c.checkEngineVersion()
|
|
|
|
if !c.versionChecked {
|
|
t.Error("versionChecked should be true even when unreachable")
|
|
}
|
|
}
|
|
|
|
func TestCheckEngineVersion_CachedAfterFirstCall(t *testing.T) {
|
|
callCount := 0
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
callCount++
|
|
json.NewEncoder(w).Encode(map[string]string{"version": "2.1.0"})
|
|
}))
|
|
defer srv.Close()
|
|
|
|
clientVersion = "2.1.0"
|
|
minEngineVersion = "2.0.0"
|
|
defer func() { clientVersion = ""; minEngineVersion = "" }()
|
|
|
|
c := &Client{
|
|
baseURL: srv.URL,
|
|
httpClient: &http.Client{},
|
|
}
|
|
|
|
c.checkEngineVersion()
|
|
c.checkEngineVersion()
|
|
c.checkEngineVersion()
|
|
|
|
if callCount != 1 {
|
|
t.Errorf("expected 1 status call, got %d", callCount)
|
|
}
|
|
}
|