carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1package release
2
3import (
4 "encoding/json"
5 "os"
6 "testing"
7)
8
9func TestPlan14HistoryReconstructionCompletion(t *testing.T) {
10 for _, boundary := range []string{"before", "intent", "complete", "unsynced"} {
11 t.Run(boundary, func(t *testing.T) {
12 h, s, b, pub, wire, now := reconstructionCrashFixture(t)
13 var g HistoryReconstruction
14 if err := VerifyRootEnvelope(pub, wire, &g); err != nil {
15 t.Fatal(err)
16 }
17 raw, _ := json.Marshal(g)
18 resolve := func(HistoryBinding) (string, error) { return "canonical", nil }
19 if boundary != "before" {
20 if boundary == "intent" {
21 h.Store = &reconstructionCrashStore{healthyRetryStore: s, stage: "intent", fail: true}
22 }
23 err := h.Reconstruct(pub, wire, b.Account, b.App, now, resolve)
24 if (boundary == "intent") != (err != nil) {
25 t.Fatalf("reconstruct: %v", err)
26 }
27 }
28 h = &RootHistory{Store: s}
29 if boundary == "unsynced" {
30 s.fail = 1
31 }
32 view, err := h.MigrationStatus(b, resolve)
33 if boundary == "unsynced" {
34 if err == nil {
35 t.Fatal("unsynced completion published")
36 }
37 view, err = h.MigrationStatus(b, resolve)
38 }
39 if err != nil {
40 t.Fatal(err)
41 }
42 want := ""
43 if boundary == "complete" || boundary == "unsynced" {
44 want = reconstructionDigest(raw)
45 }
46 if view.LastReconstructionDigest != want {
47 t.Fatalf("completion=%q want %q", view.LastReconstructionDigest, want)
48 }
49 })
50 }
51}
52
53func TestPlan14HistoryRetirementCompletion(t *testing.T) {
54 for _, fault := range []string{"valid", "missing", "unsynced", "changed outcome", "pending original", "changed source"} {
55 t.Run(fault, func(t *testing.T) {
56 h, s, old, _, g, pub, key := retirementFixture(t)
57 if fault != "missing" {
58 if err := retireForTest(h, g, pub, key); err != nil {
59 t.Fatal(err)
60 }
61 }
62 raw, _ := json.Marshal(g)
63 if fault == "changed outcome" {
64 old.Verified = true
65 if err := h.RetainRecovery(old); err != nil {
66 t.Fatal(err)
67 }
68 }
69 if fault == "unsynced" {
70 h.Store = &retirementSyncStore{Store: s, fail: true}
71 }
72 source := "canonical"
73 if fault == "changed source" {
74 source = "changed"
75 }
76 sources := HistoryRecoverySources{Known: true}
77 if fault == "pending original" {
78 old.Settled = false
79 sources.Unresolved = []HistoryRecovery{old}
80 }
81 view, err := h.MigrationStatusWithSources(old.Binding, func(HistoryBinding) (string, error) { return source, nil }, sources)
82 if fault == "unsynced" {
83 if err == nil {
84 t.Fatal("unsynced retirement published")
85 }
86 h.Store = s
87 view, err = h.MigrationStatusWithSources(old.Binding, func(HistoryBinding) (string, error) { return source, nil }, sources)
88 }
89 if err != nil {
90 t.Fatal(err)
91 }
92 want := ""
93 if fault == "valid" || fault == "unsynced" {
94 want = reconstructionDigest(raw)
95 }
96 if len(view.Hosts) != 1 || view.Hosts[0].RetirementDigests[old.Attempt.ID] != want {
97 t.Fatalf("status=%+v want %q", view, want)
98 }
99 if fault == "pending original" {
100 if len(view.RecoverySources.Unresolved) != 1 {
101 t.Fatal("lost original")
102 }
103 }
104 if _, err := s.Read(historyRecoveryKey(old)); os.IsNotExist(err) {
105 t.Fatal("deleted retained outcome")
106 }
107 })
108 }
109}
110