package release import ( "context" "encoding/json" "github.com/carlosframework/platform/internal/registry" "os" "path/filepath" "testing" "time" ) func TestPlan14FreshInstallEvidence(t *testing.T) { for _, state := range []string{"fresh", "empty", "observed", "refused", "attempted", "changed", "corrupt", "sync"} { t.Run(state, func(t *testing.T) { h, s, b := rootHistoryFixture(t) if err := os.Remove(filepath.Join(s.dir, historyKey(b))); err != nil { t.Fatal(err) } if state == "empty" { if err := h.RecordInstalledProgram(b, ""); err != nil { t.Fatal(err) } } else { if err := h.RecordCreation(b, "installation"); err != nil { t.Fatal(err) } } switch state { case "observed": if err := h.RecordInstalledProgram(b, ""); err != nil { t.Fatal(err) } case "refused": if err := h.AddRefusal(b, Refusal{Host: b.Host, App: b.App, Version: "v1", RefusedAt: time.Now()}); err != nil { t.Fatal(err) } case "attempted": if err := h.Begin(b, HistoryAttempt{ID: "attempt", Version: "v1", Source: "record", Started: time.Now()}); err != nil { t.Fatal(err) } case "corrupt": if err := os.WriteFile(filepath.Join(s.dir, historyKey(b)), []byte("{"), 0600); err != nil { t.Fatal(err) } case "sync": s.fail = 1 } identity := "installation" if state == "changed" { identity = "successor" } fresh, err := h.FreshInstallation(b, identity) if state == "fresh" { if err != nil || !fresh { t.Fatalf("fresh=%v: %v", fresh, err) } } else if err == nil && fresh { t.Fatal("invented fresh installation", state) } }) } } func TestPlan14CreationKeepsHistory(t *testing.T) { h, _, b := rootHistoryFixture(t) if err := h.RecordCreation(b, "installation"); err != nil { t.Fatal(err) } p, err := h.Programs(b) if err != nil || len(p) != 1 || p[0] != "old/program" { t.Fatalf("lost history: %v %v", p, err) } if fresh, err := h.FreshInstallation(b, "installation"); err != nil || fresh { t.Fatalf("old history became fresh: %v %v", fresh, err) } } func TestPlan14FreshInstallProgramGate(t *testing.T) { binary := tinyProgram(t, "first/program") for _, mode := range []string{"fresh", "unproven", "changed", "consumed", "missing-provider"} { t.Run(mode, func(t *testing.T) { h, s, b := rootHistoryFixture(t) if err := os.Remove(filepath.Join(s.dir, historyKey(b))); err != nil { t.Fatal(err) } if mode == "unproven" { if err := h.RecordInstalledProgram(b, ""); err != nil { t.Fatal(err) } r, err := h.read(b) if err != nil { t.Fatal(err) } r.Refusals.Complete = true if err = h.write(r); err != nil { t.Fatal(err) } } else if err := h.RecordCreation(b, "installation"); err != nil { t.Fatal(err) } if mode == "consumed" { if err := h.ConsumeCreation(b); err != nil { t.Fatal(err) } } seedRootBake(t, h, b, time.Now().UTC().Add(-time.Hour)) st := NewDirStore(t.TempDir()) priv, pub := testKeys(t) reg := testRegistry(t) opt := t.TempDir() addRoute(t, reg, b.Host, b.App, "canary/x", false) shipRelease(t, st, b.Account, b.App, "first", adoptPlatform, binary) if err := Promote(t.Context(), st, priv, b.Account, b.App, "canary/x", "first"); err != nil { t.Fatal(err) } calls, effects := 0, 0 deps := &RootHistoryPass{History: h, Resolve: func(context.Context, registry.Route) (HistoryBinding, string, error) { return b, "record", nil }, Installed: func(context.Context, registry.Route, string) (string, error) { return "first/program", nil }, Creation: func(context.Context, registry.Route) (string, error) { calls++ if mode == "changed" && calls >= 3 { return "successor", nil } return "installation", nil }} if mode == "missing-provider" { deps.Creation = nil } err := Pass(t.Context(), reg, st, pub, opt, func(string) error { effects++; return nil }, WithRootHistory(deps)) v, _ := LiveVersion(opt, b.Host) if mode == "fresh" { if err != nil || v != "first" || effects != 1 { t.Fatalf("fresh install: %s %d %v", v, effects, err) } } else if v != "" || effects != 0 { t.Fatalf("%s installed: %s %d %v", mode, v, effects, err) } }) } } func TestPlan14FreshInstallVisibleSync(t *testing.T) { h, s, b := rootHistoryFixture(t) if err := os.Remove(filepath.Join(s.dir, historyKey(b))); err != nil { t.Fatal(err) } s.fail = 2 if err := h.RecordCreation(b, "installation"); err == nil { t.Fatal("unsynced creation succeeded") } if fresh, err := h.FreshInstallation(b, "installation"); err == nil || fresh { t.Fatal("visible unsynced creation granted") } if fresh, err := h.FreshInstallation(b, "installation"); err != nil || !fresh { t.Fatalf("durability repair: %v %v", fresh, err) } s.fail = 3 if err := h.ConsumeCreation(b); err == nil { t.Fatal("unsynced read allowed attempt") } if err := h.ConsumeCreation(b); err == nil { t.Fatal("unsynced read allowed attempt") } if err := h.ConsumeCreation(b); err == nil { t.Fatal("unsynced read allowed attempt") } if err := h.ConsumeCreation(b); err != nil { t.Fatal(err) } if fresh, err := h.FreshInstallation(b, "installation"); err != nil || fresh { t.Fatalf("attempt rearmed: %v %v", fresh, err) } } type creationSyncFailure struct { *healthyRetryStore remaining int } func (s *creationSyncFailure) Write(name string, raw []byte) error { var r historyRecord if err := json.Unmarshal(raw, &r); err != nil { return err } if !r.Fresh && s.remaining > 0 { s.fail = 1 s.remaining-- } return s.healthyRetryStore.Write(name, raw) } func TestPlan14FreshInstallConsumptionSync(t *testing.T) { h, s, b := rootHistoryFixture(t) if err := os.Remove(filepath.Join(s.dir, historyKey(b))); err != nil { t.Fatal(err) } if err := h.RecordCreation(b, "installation"); err != nil { t.Fatal(err) } h.Store = &creationSyncFailure{healthyRetryStore: s, remaining: 2} if err := h.ConsumeCreation(b); err == nil { t.Fatal("visible unsynced attempt permitted launch") } if fresh, err := h.FreshInstallation(b, "installation"); err == nil || fresh { t.Fatal("unrepaired consumption read succeeded") } if fresh, err := h.FreshInstallation(b, "installation"); err != nil || fresh { t.Fatalf("consumption not recovered: %v %v", fresh, err) } if err := h.RecordCreation(b, "successor"); err != nil { t.Fatal(err) } if fresh, err := h.FreshInstallation(b, "successor"); err != nil || fresh { t.Fatalf("replacement erased retained history: %v %v", fresh, err) } }