Export the reviewed allowlisted snapshot from private source commit 07c1655921f21ee5e4fc4d85639d199e8867b17d. This records the Docker Compose activation, schema-compatible rollback, and stateful migration resource findings from Observatory Preview 19 dogfooding. AI-Assisted: OpenAI Codex Signed-off-by: Cole Speelman <crspeelman@gmail.com>
90 lines
3.7 KiB
Go
90 lines
3.7 KiB
Go
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
package state
|
|
|
|
import (
|
|
"bytes"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestCandidateLeaseRoundTripAndRemoval(t *testing.T) {
|
|
root := filepath.Join(t.TempDir(), "service")
|
|
release := filepath.Join(root, "releases", "sha256-"+strings.Repeat("a", 64))
|
|
if err := os.MkdirAll(release, 0o755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
path := CandidateLeasePath(filepath.Join(root, "state.json"))
|
|
operation := strings.Repeat("d", 32)
|
|
lease := CandidateLease{SchemaVersion: CandidateLeaseSchemaVersion, Service: "example-site", OperationID: operation, Release: release, Unit: "example-site-tend-candidate-" + operation[:12] + ".service", Address: "127.0.0.1:18092", StartedAt: time.Unix(1, 0).UTC().Format(time.RFC3339)}
|
|
if err := StoreCandidateLease(path, root, lease); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
loaded, err := LoadCandidateLease(path, root, "example-site")
|
|
if err != nil || loaded != lease {
|
|
t.Fatalf("loaded=%+v err=%v", loaded, err)
|
|
}
|
|
if err := RemoveCandidateLease(path); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := os.Lstat(path); !os.IsNotExist(err) {
|
|
t.Fatalf("lease remains: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestCandidateLeaseRejectsCrossServiceAndSymlink(t *testing.T) {
|
|
root := filepath.Join(t.TempDir(), "service")
|
|
release := filepath.Join(root, "releases", "sha256-"+strings.Repeat("a", 64))
|
|
if err := os.MkdirAll(release, 0o755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
operation := strings.Repeat("d", 32)
|
|
lease := CandidateLease{SchemaVersion: CandidateLeaseSchemaVersion, Service: "example-site", OperationID: operation, Release: release, Unit: "example-site-tend-candidate-" + operation[:12] + ".service", Address: "127.0.0.1:18092", StartedAt: time.Unix(1, 0).UTC().Format(time.RFC3339)}
|
|
if err := lease.Validate(root, "other-site"); err == nil {
|
|
t.Fatal("expected service mismatch")
|
|
}
|
|
path := CandidateLeasePath(filepath.Join(root, "state.json"))
|
|
if err := os.Symlink(filepath.Join(root, "elsewhere"), path); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := StoreCandidateLease(path, root, lease); err == nil {
|
|
t.Fatal("expected symlink refusal")
|
|
}
|
|
if err := RemoveCandidateLease(path); err == nil {
|
|
t.Fatal("expected symlink removal refusal")
|
|
}
|
|
}
|
|
|
|
func TestCandidateLeasePreservesSchemaOneDeploymentState(t *testing.T) {
|
|
root := filepath.Join(t.TempDir(), "service")
|
|
release := filepath.Join(root, "releases", "sha256-"+strings.Repeat("a", 64))
|
|
if err := os.MkdirAll(release, 0o755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
at := time.Unix(1, 0).UTC().Format(time.RFC3339)
|
|
statePath := filepath.Join(root, "state.json")
|
|
record := Record{SchemaVersion: SchemaVersion, Strategy: "singleton_candidate", DesiredRelease: release, CandidateRelease: release, ActiveSlot: "singleton", ActiveRelease: release, LastAttemptRelease: release, LastAttemptOutcome: "running", LastAttemptAt: at, UpdatedAt: at}
|
|
if err := Store(statePath, root, record); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
operation := strings.Repeat("d", 32)
|
|
lease := CandidateLease{SchemaVersion: CandidateLeaseSchemaVersion, Service: "example-site", OperationID: operation, Release: release, Unit: "example-site-tend-candidate-" + operation[:12] + ".service", Address: "127.0.0.1:18092", StartedAt: at}
|
|
if err := StoreCandidateLease(CandidateLeasePath(statePath), root, lease); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
body, err := os.ReadFile(statePath)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !bytes.Contains(body, []byte(`"schema_version": 1`)) || bytes.Contains(body, []byte("candidate_operation_id")) || bytes.Contains(body, []byte("candidate_unit")) {
|
|
t.Fatalf("deployment state contract changed: %s", body)
|
|
}
|
|
loaded, err := Load(statePath, root, "singleton_candidate")
|
|
if err != nil || loaded.SchemaVersion != 1 || loaded.CandidateRelease != release {
|
|
t.Fatalf("loaded=%+v err=%v", loaded, err)
|
|
}
|
|
}
|