Files
zzet--gortex/cmd/gortex/daemon_controller_proxy_test.go
T
wehub-resource-sync a06f331eb8
CI / benchmark (push) Has been skipped
install-script / posix-syntax (push) Successful in 6m1s
CI / build-onnx (push) Failing after 6m43s
init-smoke / dry-run (push) Failing after 15m57s
security / govulncheck (push) Has been cancelled
security / trivy-fs (push) Has been cancelled
CI / test (1.26, ubuntu-latest) (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
CI / test (1.26, macos-latest) (push) Has been cancelled
CI / build-windows (push) Has been cancelled
CI / lint (push) Has been cancelled
install-script / powershell-syntax (push) Has been cancelled
install-script / install (macos-14) (push) Has been cancelled
install-script / install (ubuntu-latest) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:33:42 +08:00

84 lines
2.5 KiB
Go

package main
import (
"context"
"encoding/json"
"os"
"path/filepath"
"testing"
"go.uber.org/zap"
"github.com/zzet/gortex/internal/daemon"
)
// TestReloadServers_BuildSwapTeardown drives the live-reload lifecycle:
// build a router when the first remote appears, swap it in place when the
// roster changes, and tear it down when the last remote is removed.
func TestReloadServers_BuildSwapTeardown(t *testing.T) {
dir := t.TempDir()
path := filepath.Join(dir, "servers.toml")
t.Setenv("GORTEX_DAEMON_SERVERS", path)
var published []*daemon.Router // nil entries == teardown
c := &realController{
logger: zap.NewNop(),
localExecute: func(context.Context, string, []byte) ([]byte, int, error) { return []byte(`{}`), 200, nil },
}
c.publishRouter = func(r *daemon.Router) { published = append(published, r) }
write := func(body string) {
if err := os.WriteFile(path, []byte(body), 0o600); err != nil {
t.Fatal(err)
}
}
reload := func() map[string]any {
raw, err := c.ReloadServers(context.Background())
if err != nil {
t.Fatalf("ReloadServers: %v", err)
}
var m map[string]any
_ = json.Unmarshal(raw, &m)
return m
}
// 1. First remote added => router built + published.
write("[[server]]\nslug = \"r2\"\nurl = \"https://r2:4747\"\n")
m := reload()
if m["router_wired"] != true || m["servers"].(float64) != 1 {
t.Fatalf("first add should wire 1 server, got %v", m)
}
if c.liveRouter == nil {
t.Fatal("liveRouter should be built")
}
if len(published) != 1 || published[0] == nil {
t.Fatalf("a non-nil router should have been published, got %v", published)
}
// 2. Roster grows to 2 => in-place swap, no re-publish, new count visible.
write("[[server]]\nslug = \"r2\"\nurl = \"https://r2:4747\"\n[[server]]\nslug = \"r3\"\nurl = \"https://r3:4747\"\n")
m = reload()
if m["servers"].(float64) != 2 {
t.Fatalf("swap should reflect 2 servers, got %v", m)
}
if len(published) != 1 {
t.Fatal("an in-place swap must not re-publish the router")
}
if got := len(c.liveRouter.CurrentConfig().Server); got != 2 {
t.Fatalf("liveRouter should serve 2 servers after swap, got %d", got)
}
// 3. All remotes removed => router torn down (nil published).
write("")
m = reload()
if m["router_wired"] != false || m["servers"].(float64) != 0 {
t.Fatalf("teardown should report 0/false, got %v", m)
}
if c.liveRouter != nil {
t.Fatal("liveRouter should be nil after teardown")
}
if len(published) != 2 || published[1] != nil {
t.Fatalf("teardown should publish a nil router, got %v", published)
}
}