feat: publish Gamertan Tend preview source

Sanitized root snapshot from private source commit a72903c63e1753f9e6ffbf40453c0830bdfc05c5 and tree 295641e67eef5979da76746d8ae271249568263e. Private development history and workflows are excluded by the exact allowlist.

AI-assisted: OpenAI Codex helped implement, test, and audit this preview.
Signed-off-by: Cole Speelman <crspeelman@gmail.com>
This commit is contained in:
2026-08-14 14:01:02 -04:00
commit b68fa2487d
46 changed files with 4067 additions and 0 deletions
+213
View File
@@ -0,0 +1,213 @@
// SPDX-License-Identifier: AGPL-3.0-only
package deploy
import (
"context"
"errors"
"os"
"path/filepath"
"strings"
"testing"
"time"
"gamertan.com/tend/internal/config"
"gamertan.com/tend/internal/state"
)
type fakeOperator struct {
failReload bool
failRestartUnit string
rejectMarkers bool
active map[string]bool
starts, stops, restarts []string
probes []string
}
func (f *fakeOperator) Restart(_ context.Context, unit string) error {
f.restarts = append(f.restarts, unit)
if unit == f.failRestartUnit {
return errors.New("injected restart failure")
}
f.active[unit] = true
return nil
}
func (f *fakeOperator) Stop(_ context.Context, unit string) error {
f.stops = append(f.stops, unit)
f.active[unit] = false
return nil
}
func (f *fakeOperator) IsActive(_ context.Context, unit string) (bool, error) {
return f.active[unit], nil
}
func (f *fakeOperator) StartCandidate(_ context.Context, unit, binary string, env map[string]string) error {
if !filepath.IsAbs(binary) || len(env) == 0 {
return errors.New("bad candidate")
}
f.starts = append(f.starts, unit)
f.active[unit] = true
return nil
}
func (f *fakeOperator) ValidateCaddy(context.Context, string) error { return nil }
func (f *fakeOperator) ReloadCaddy(context.Context) error {
if f.failReload {
return errors.New("injected reload failure")
}
return nil
}
func (f *fakeOperator) Probe(_ context.Context, address, host, path, contains string) error {
f.probes = append(f.probes, address+path)
if f.rejectMarkers && contains != "" {
return errors.New("unexpected future-release smoke marker")
}
return nil
}
func baseConfig(t *testing.T, strategy string) (config.Config, string, string) {
t.Helper()
root := filepath.Join(t.TempDir(), "service")
if err := os.MkdirAll(filepath.Join(root, "releases"), 0o755); err != nil {
t.Fatal(err)
}
old := filepath.Join(root, "releases", "legacy-old")
fresh := filepath.Join(root, "releases", "sha256-"+strings.Repeat("a", 64))
for _, dir := range []string{old, fresh} {
if err := os.Mkdir(dir, 0o755); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(filepath.Join(dir, "app"), []byte("x"), 0o755); err != nil {
t.Fatal(err)
}
}
cfg := config.Config{SchemaVersion: 1, Service: config.Service{Name: "example-site", AllowedHost: "example.test"}, Build: config.Build{Package: "./cmd/site", Binary: "app", Branch: "main"}, Deployment: config.Deployment{Strategy: strategy, Root: root, LockFile: filepath.Join(root, "deploy.lock"), StateFile: filepath.Join(root, "state.json"), HealthPath: "/healthz", ReadinessPath: "/readyz", CandidateTimeoutSecs: 2, Smoke: []config.Smoke{{Path: "/", Contains: "Example"}}}}
return cfg, old, fresh
}
func manager(operator Operator, fresh string) Manager {
return Manager{Operator: operator, Now: func() time.Time { return time.Unix(100, 0).UTC() }, Prepare: func(config.Config, string, string, string) (string, error) { return fresh, nil }, Inspect: func(config.Config, string, string, string) error { return nil }}
}
func TestBlueGreenActivationAndRollback(t *testing.T) {
cfg, old, fresh := baseConfig(t, "blue_green")
handler := filepath.Join(cfg.Deployment.Root, "handler.caddy")
template := filepath.Join(cfg.Deployment.Root, "handler.template")
if err := os.WriteFile(handler, []byte("reverse_proxy 127.0.0.1:8090\n"), 0o640); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(template, []byte("reverse_proxy {{UPSTREAM}}\n"), 0o644); err != nil {
t.Fatal(err)
}
blue := filepath.Join(cfg.Deployment.Root, "slots", "blue")
green := filepath.Join(cfg.Deployment.Root, "slots", "green")
if err := replaceSymlink(blue, old); err != nil {
t.Fatal(err)
}
if err := replaceSymlink(green, old); err != nil {
t.Fatal(err)
}
cfg.Deployment.BlueGreen = &config.BlueGreen{CaddyConfig: filepath.Join(cfg.Deployment.Root, "Caddyfile"), CaddyHandler: handler, CaddyHandlerTemplate: template, BootstrapActive: "blue", Blue: config.Slot{Unit: "example-blue.service", Address: "127.0.0.1:8090", Link: blue}, Green: config.Slot{Unit: "example-green.service", Address: "127.0.0.1:8091", Link: green}}
if err := cfg.Validate(); err != nil {
t.Fatal(err)
}
operator := &fakeOperator{active: map[string]bool{"example-blue.service": true, "example-green.service": true}}
m := manager(operator, fresh)
report, err := m.Deploy(context.Background(), cfg, Request{Activate: true})
if err != nil {
t.Fatal(err)
}
if report.ActiveRelease != fresh || report.PreviousRelease != old {
t.Fatalf("report=%+v", report)
}
if info, err := os.Stat(handler); err != nil || info.Mode().Perm() != 0o640 {
t.Fatalf("handler mode=%v err=%v", info.Mode().Perm(), err)
}
if target, err := resolveReleaseLink(cfg.Deployment.Root, green); err != nil || target != fresh {
t.Fatalf("green=%q err=%v", target, err)
}
operator.rejectMarkers = true
operator.probes = nil
record, err := m.Rollback(context.Background(), cfg)
if err != nil {
t.Fatal(err)
}
if record.ActiveRelease != old || record.PreviousRelease != fresh {
t.Fatalf("rollback=%+v", record)
}
if len(operator.probes) != 4 {
t.Fatalf("rollback probes=%#v", operator.probes)
}
for _, probe := range operator.probes {
if !strings.HasSuffix(probe, "/healthz") && !strings.HasSuffix(probe, "/readyz") {
t.Fatalf("rollback applied future-release smoke checks: %#v", operator.probes)
}
}
}
func TestBlueGreenCaddyFailureRestoresHandlerAndSlot(t *testing.T) {
cfg, old, fresh := baseConfig(t, "blue_green")
handler := filepath.Join(cfg.Deployment.Root, "handler.caddy")
template := filepath.Join(cfg.Deployment.Root, "handler.template")
original := []byte("reverse_proxy 127.0.0.1:8090\n")
_ = os.WriteFile(handler, original, 0o644)
_ = os.WriteFile(template, []byte("reverse_proxy {{UPSTREAM}}\n"), 0o644)
blue := filepath.Join(cfg.Deployment.Root, "slots", "blue")
green := filepath.Join(cfg.Deployment.Root, "slots", "green")
_ = replaceSymlink(blue, old)
_ = replaceSymlink(green, old)
cfg.Deployment.BlueGreen = &config.BlueGreen{CaddyConfig: filepath.Join(cfg.Deployment.Root, "Caddyfile"), CaddyHandler: handler, CaddyHandlerTemplate: template, BootstrapActive: "blue", Blue: config.Slot{Unit: "example-blue.service", Address: "127.0.0.1:8090", Link: blue}, Green: config.Slot{Unit: "example-green.service", Address: "127.0.0.1:8091", Link: green}}
operator := &fakeOperator{active: map[string]bool{}, failReload: true}
m := manager(operator, fresh)
if _, err := m.Deploy(context.Background(), cfg, Request{Activate: true}); err == nil {
t.Fatal("expected failure")
}
body, _ := os.ReadFile(handler)
if string(body) != string(original) {
t.Fatalf("handler not restored: %q", body)
}
target, err := resolveReleaseLink(cfg.Deployment.Root, green)
if err != nil || target != old {
t.Fatalf("green=%q err=%v", target, err)
}
if _, err := os.Stat(cfg.Deployment.StateFile); !os.IsNotExist(err) {
t.Fatal("failed activation wrote state")
}
}
func TestSingletonRestartFailureRestoresPointers(t *testing.T) {
cfg, old, fresh := baseConfig(t, "singleton_candidate")
previous := filepath.Join(cfg.Deployment.Root, "previous")
current := filepath.Join(cfg.Deployment.Root, "current")
_ = replaceSymlink(current, old)
cfg.Deployment.Singleton = &config.Singleton{Unit: "example-site.service", Address: "127.0.0.1:8092", CandidateAddress: "127.0.0.1:18092", ListenEnv: "EXAMPLE_LISTEN", CurrentLink: current, PreviousLink: previous}
operator := &fakeOperator{active: map[string]bool{}, failRestartUnit: "example-site.service"}
m := manager(operator, fresh)
if _, err := m.Deploy(context.Background(), cfg, Request{Activate: true}); err == nil {
t.Fatal("expected failure")
}
target, err := resolveReleaseLink(cfg.Deployment.Root, current)
if err != nil || target != old {
t.Fatalf("current=%q err=%v", target, err)
}
if _, err := os.Lstat(previous); !os.IsNotExist(err) {
t.Fatal("previous pointer was not restored")
}
}
func TestStatePersistsOnlyAfterSuccessfulActivation(t *testing.T) {
cfg, old, fresh := baseConfig(t, "singleton_candidate")
current := filepath.Join(cfg.Deployment.Root, "current")
previous := filepath.Join(cfg.Deployment.Root, "previous")
_ = replaceSymlink(current, old)
cfg.Deployment.Singleton = &config.Singleton{Unit: "example-site.service", Address: "127.0.0.1:8092", CandidateAddress: "127.0.0.1:18092", ListenEnv: "EXAMPLE_LISTEN", CurrentLink: current, PreviousLink: previous}
operator := &fakeOperator{active: map[string]bool{}}
m := manager(operator, fresh)
if _, err := m.Deploy(context.Background(), cfg, Request{Activate: true}); err != nil {
t.Fatal(err)
}
record, err := state.Load(cfg.Deployment.StateFile, cfg.Deployment.Root, cfg.Deployment.Strategy)
if err != nil {
t.Fatal(err)
}
if record.ActiveRelease != fresh || record.PreviousRelease != old {
t.Fatalf("state=%+v", record)
}
}