package release import ( "bytes" "encoding/json" "errors" "fmt" "github.com/carlosframework/platform/internal/rootstate" "os" "path/filepath" "strings" "testing" "time" ) func rootHistoryFixture(t *testing.T) (*RootHistory, *healthyRetryStore, HistoryBinding) { t.Helper() s := &healthyRetryStore{dir: t.TempDir(), fault: errors.New("injected sync failure")} b := HistoryBinding{Host: proofHost, Account: "bab", App: "console"} h := &RootHistory{Store: s} r := historyRecord{Schema: 1, Binding: b, Revision: 1, Programs: historyPrograms{Revision: 1, Complete: true, Values: []string{"old/program"}}, Refusals: historyRefusals{Revision: 1, Complete: true}} if err := h.write(r); err != nil { t.Fatal(err) } return h, s, b } func TestPlan14RootHistoryMissingIsUnknown(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.Programs(b); err == nil { t.Fatal("missing program history granted fresh installation") } if _, err := h.Refusals(b); err == nil { t.Fatal("missing refusal history granted permission") } } func TestPlan14RootHistoryObservedProgramDoesNotInitializeRefusals(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.RecordInstalledProgram(b, "observed/program"); err != nil { t.Fatal(err) } programs, err := h.Programs(b) if err != nil || len(programs) != 1 || programs[0] != "observed/program" { t.Fatalf("observed programs: %v, %v", programs, err) } if _, err := h.Refusals(b); err == nil { t.Fatal("current service proved absence of historical failures") } } func TestPlan14RootHistoryRejectsMalformed(t *testing.T) { h, s, b := rootHistoryFixture(t) good, err := s.Read(historyKey(b)) if err != nil { t.Fatal(err) } for _, attack := range []string{"schema", "identity", "revision", "programs", "refusals", "trailing", "extra"} { t.Run(attack, func(t *testing.T) { var r historyRecord if err := json.Unmarshal(good, &r); err != nil { t.Fatal(err) } var raw []byte switch attack { case "schema": r.Schema = 2 case "identity": r.Binding.Account = "bap" case "revision": r.Refusals.Revision = r.Revision + 1 case "programs": r.Programs.Complete = false case "refusals": r.Refusals.Complete = false } raw, _ = json.Marshal(r) if attack == "trailing" { raw = append(raw, []byte(" {}")...) } if attack == "extra" { raw = append(raw[:len(raw)-1], []byte(`,"allow":true}`)...) } if err := s.Write(historyKey(b), raw); err != nil { t.Fatal(err) } if attack != "refusals" { if _, err := h.Programs(b); err == nil { t.Fatal("accepted unavailable program history") } } if attack != "programs" { if _, err := h.Refusals(b); err == nil { t.Fatal("accepted unavailable refusal history") } } }) } } func TestPlan14RootHistoryLegacyTampering(t *testing.T) { for _, attack := range []string{"delete", "rename", "forge"} { t.Run(attack, func(t *testing.T) { h, _, b := rootHistoryFixture(t) legacy := t.TempDir() at := time.Date(2026, 10, 13, 0, 0, 0, 0, time.UTC) r := Refusal{Schema: 1, Host: b.Host, App: b.App, Version: "new", PointerPromotedAt: at, RefusedAt: at, Reason: "failed"} if err := WriteRefusal(legacy, r); err != nil { t.Fatal(err) } if err := RecordProgram(legacy, b.Host, "foreign/program"); err != nil { t.Fatal(err) } if err := h.AddRefusal(b, r); err != nil { t.Fatal(err) } switch attack { case "delete": if err := os.Remove(filepath.Join(RefusalDir(legacy), b.Host+".json")); err != nil { t.Fatal(err) } case "rename": if err := os.Rename(legacy, legacy+"-old"); err != nil { t.Fatal(err) } t.Cleanup(func() { os.RemoveAll(legacy + "-old") }) if err := os.Mkdir(legacy, 0700); err != nil { t.Fatal(err) } case "forge": r.Recovered = true r.Version = "old" if err := WriteRefusal(legacy, r); err != nil { t.Fatal(err) } } programs, err := h.Programs(b) if err != nil || len(programs) != 1 || programs[0] != "old/program" { t.Fatalf("program exception from legacy: %v %v", programs, err) } refs, err := h.Refusals(b) if err != nil || len(refs) != 1 || refs[0].Version != "new" { t.Fatalf("refusal lost: %v %v", refs, err) } }) } } func TestPlan14RootHistoryVisibleWriteNeedsSync(t *testing.T) { h, s, b := rootHistoryFixture(t) r := Refusal{Schema: 1, Host: b.Host, App: b.App, Version: "new", RefusedAt: time.Now(), Reason: "failed"} h.Store = &historyFailNewStore{healthyRetryStore: s, remaining: 2} if err := h.AddRefusal(b, r); !errors.Is(err, s.fault) { t.Fatalf("write: %v", err) } if _, err := h.Refusals(b); !errors.Is(err, s.fault) { t.Fatalf("visible unsynced state authorized read: %v", err) } refs, err := h.Refusals(b) if err != nil || len(refs) != 1 { t.Fatalf("durable retry: %v %v", refs, err) } } func TestPlan14RootHistoryRefusalKinds(t *testing.T) { for _, kind := range []string{RefusalNotUp, RefusalWrongProgram, RefusalNotProven} { t.Run("kind="+kind, func(t *testing.T) { h, _, b := rootHistoryFixture(t) at := time.Date(2026, 10, 13, 0, 0, 0, 0, time.UTC) r := Refusal{Schema: 1, Kind: kind, Host: b.Host, App: b.App, Version: "new", PointerPromotedAt: at, RefusedAt: at, Reason: "failed"} if err := h.AddRefusal(b, r); err != nil { t.Fatal(err) } blocked, err := h.Blocks(b, &ChannelPointer{Version: "new", PromotedAt: at.Add(time.Second)}) if err != nil || blocked != (kind != RefusalNotUp) { t.Fatalf("retry clears wrong kind: blocked=%v err=%v", blocked, err) } }) } } func TestPlan14RootHistoryAttemptSurvivesReopen(t *testing.T) { h, s, b := rootHistoryFixture(t) a := HistoryAttempt{ID: "attempt-1", Version: "new", Source: "record-etag", Started: time.Now().UTC()} if err := h.Begin(b, a); err != nil { t.Fatal(err) } h = &RootHistory{Store: s} if err := h.Begin(b, HistoryAttempt{ID: "attempt-2", Version: "new", Source: "record-etag", Started: a.Started}); err == nil { t.Fatal("unresolved attempt retried") } if err := h.Begin(b, a); err == nil { t.Fatal("pending intent replay granted another forward attempt") } if _, err := h.Refusals(b); err == nil { t.Fatal("pending attempt asserted a complete mint refusal list") } if err := h.Settle(b, "attempt-2", nil); err == nil { t.Fatal("wrong attempt settled") } if err := h.Settle(b, a.ID, nil); err != nil { t.Fatal(err) } } type historyFailNewStore struct { *healthyRetryStore remaining int } func (s *historyFailNewStore) Write(name string, raw []byte) error { var r historyRecord if err := json.Unmarshal(raw, &r); err != nil { return err } if len(r.Refusals.Values) > 0 && s.remaining > 0 { s.fail = 1 s.remaining-- } return s.healthyRetryStore.Write(name, raw) } func TestPlan14RootHistoryCategoryIsolation(t *testing.T) { h, _, b := rootHistoryFixture(t) r, err := h.read(b) if err != nil { t.Fatal(err) } r.Refusals.Complete = false if err := h.write(r); err != nil { t.Fatal(err) } if _, err := h.Programs(b); err != nil { t.Fatalf("known programs lost: %v", err) } if _, err := h.Refusals(b); err == nil { t.Fatal("unknown refusals allowed") } if err := h.Begin(b, HistoryAttempt{ID: "a", Version: "new", Source: "record", Started: time.Now()}); err == nil { t.Fatal("incomplete category allowed an attempt") } } func TestPlan14RootHistoryDenyImportUnknown(t *testing.T) { h, s, b := rootHistoryFixture(t) if err := os.Remove(filepath.Join(s.dir, historyKey(b))); err != nil { t.Fatal(err) } r := Refusal{Host: b.Host, App: b.App, Version: "new", RefusedAt: time.Now(), Reason: "failed", Recovered: true} if err := h.AddRefusal(b, r); err != nil { t.Fatal(err) } saved, err := h.read(b) if err != nil { t.Fatal(err) } if saved.Programs.Complete || saved.Refusals.Complete || len(saved.Refusals.Values) != 1 { t.Fatalf("import invented completeness: %+v", saved) } if _, err := h.Refusals(b); err == nil { t.Fatal("legacy recovery asserted absence") } } func TestPlan14RootHistoryOverflowQuarantines(t *testing.T) { h, _, b := rootHistoryFixture(t) for i := 0; i < historyLimit; i++ { r := Refusal{Host: b.Host, App: b.App, Version: fmt.Sprint(i), RefusedAt: time.Now(), Reason: "failed"} if err := h.AddRefusal(b, r); err != nil { t.Fatal(err) } } extra := Refusal{Host: b.Host, App: b.App, Version: "overflow", RefusedAt: time.Now(), Reason: "failed"} if err := h.AddRefusal(b, extra); err == nil { t.Fatal("overflow succeeded") } if _, err := h.Refusals(b); err == nil { t.Fatal("overflow retained completeness and dropped a deny") } r, err := h.read(b) if err != nil || len(r.Refusals.Values) != historyLimit { t.Fatalf("lost retained denies: %v %v", len(r.Refusals.Values), err) } } func TestPlan14RootHistoryRejectsCrossBinding(t *testing.T) { h, s, b := rootHistoryFixture(t) raw, err := s.Read(historyKey(b)) if err != nil { t.Fatal(err) } for _, field := range []string{"host", "account", "app"} { other := b switch field { case "host": other.Host = "other.example" case "account": other.Account = "bap" case "app": other.App = "other" } if err := s.Write(historyKey(other), raw); err != nil { t.Fatal(err) } if _, err := h.Programs(other); err == nil { t.Fatalf("reused another %s's programs", field) } if _, err := h.Refusals(other); err == nil { t.Fatalf("reused another %s's refusals", field) } } } func TestPlan14RootHistoryDuplicateRefusal(t *testing.T) { h, _, b := rootHistoryFixture(t) r := Refusal{Host: b.Host, App: b.App, Version: "new", RefusedAt: time.Now(), Reason: "failed"} if err := h.AddRefusal(b, r); err != nil { t.Fatal(err) } if err := h.AddRefusal(b, r); err != nil { t.Fatal(err) } refs, err := h.Refusals(b) if err != nil || len(refs) != 1 { t.Fatalf("duplicate deny changed revision/content: %d %v", len(refs), err) } } func TestPlan14RootHistoryOversizedDenyQuarantines(t *testing.T) { h, _, b := rootHistoryFixture(t) r := Refusal{Host: b.Host, App: b.App, Version: "new", RefusedAt: time.Now(), Reason: strings.Repeat("x", rootstate.MaxRecord)} if err := h.AddRefusal(b, r); err == nil { t.Fatal("oversized deny succeeded") } if _, err := h.Refusals(b); err == nil { t.Fatal("oversized deny silently discarded") } } func TestPlan14RootHistoryDuplicateJSONRefused(t *testing.T) { h, s, b := rootHistoryFixture(t) raw, err := s.Read(historyKey(b)) if err != nil { t.Fatal(err) } raw = bytes.Replace(raw, []byte(`"complete":true`), []byte(`"complete":false,"complete":true`), 1) if err := s.Write(historyKey(b), raw); err != nil { t.Fatal(err) } if _, err := h.Programs(b); err == nil { t.Fatal("duplicate complete field accepted") } } func TestPlan14RootHistoryMissingTargetRefuses(t *testing.T) { h, _, b := rootHistoryFixture(t) for _, p := range []*ChannelPointer{nil, {}} { if blocked, err := h.Blocks(b, p); err == nil || !blocked { t.Fatal("missing target granted permission") } } } func TestPlan14RootHistoryPendingCannotMint(t *testing.T) { h, _, b := rootHistoryFixture(t) if err := h.Begin(b, HistoryAttempt{ID: "pending", Version: "new", Source: "etag", Started: time.Now()}); err != nil { t.Fatal(err) } if _, err := h.Refusals(b); err == nil { t.Fatal("pending update asserted a complete mint refusal list") } }