| 1 | //go:build linux |
| 2 | |
| 3 | package host |
| 4 | |
| 5 | import ( |
| 6 | "os" |
| 7 | "reflect" |
| 8 | "testing" |
| 9 | ) |
| 10 | |
| 11 | func TestPlan14ServingSameBootNamespace(t *testing.T) { |
| 12 | f, r := servingRebootRecordFixture(t, "complete") |
| 13 | f.fs.boot = func() (string, error) { return r.Source.BootID, nil } |
| 14 | oldMount := r.Source.Parent.Mount + 123 |
| 15 | for _, d := range []*servingArtifactDirectory{&r.Source.Parent, &r.Source.Directory, &r.Authorization.Directory, &r.Namespace, &r.Event} { |
| 16 | if d.Inode != 0 { |
| 17 | d.Mount = oldMount |
| 18 | } |
| 19 | } |
| 20 | for i := range r.Source.Files { |
| 21 | if r.Source.Files[i].Present { |
| 22 | r.Source.Files[i].Mount = oldMount |
| 23 | } |
| 24 | } |
| 25 | if err := f.ledger.save(r); err != nil { |
| 26 | t.Fatal(err) |
| 27 | } |
| 28 | p, err := f.fs.historicalNamespaceParent() |
| 29 | if err != nil { |
| 30 | t.Fatal(err) |
| 31 | } |
| 32 | p.Parent.Mount = oldMount |
| 33 | if err := f.ledger.write("namespace-parent.json", p); err != nil { |
| 34 | t.Fatal(err) |
| 35 | } |
| 36 | var n servingParkNamespace |
| 37 | body, err := f.disk.Read("namespace.json") |
| 38 | if err != nil || servingParkDecode(body, &n) != nil { |
| 39 | t.Fatal(err) |
| 40 | } |
| 41 | n.Parent.Mount, n.Root.Mount = oldMount, oldMount |
| 42 | if err := f.ledger.write("namespace.json", n); err != nil { |
| 43 | t.Fatal(err) |
| 44 | } |
| 45 | if r.Authorization.Legacy { |
| 46 | c, err := f.ledger.legacyConsumption(r.Authorization.Successor) |
| 47 | if err != nil { |
| 48 | t.Fatal(err) |
| 49 | } |
| 50 | if c != nil { |
| 51 | c.Source, c.Authorization = r.Source, r.Authorization |
| 52 | if err := f.ledger.write(servingLegacyKey("legacy", r.Authorization.Successor), c); err != nil { |
| 53 | t.Fatal(err) |
| 54 | } |
| 55 | } |
| 56 | } |
| 57 | historicalLedger := *f.ledger |
| 58 | historicalLedger.historical = true |
| 59 | for i := 0; i < 2; i++ { |
| 60 | if err := historicalLedger.prepareRebootLocked(t.Context(), r, nil); err != nil { |
| 61 | t.Fatal("prepare same-boot namespace", err) |
| 62 | } |
| 63 | if err := historicalLedger.commitRebootLocked(t.Context(), r, nil); err != nil { |
| 64 | t.Fatal("commit same-boot namespace", err) |
| 65 | } |
| 66 | } |
| 67 | if err := f.fs.recoverRecordedNamespace(t.Context()); err != nil { |
| 68 | t.Fatal(err) |
| 69 | } |
| 70 | current, err := f.ledger.read(r.Authorization.ID) |
| 71 | if err != nil || current.Source.Parent.Mount == oldMount { |
| 72 | t.Fatal("binding", err) |
| 73 | } |
| 74 | if err := f.ledger.save(current); err != nil { |
| 75 | t.Fatal(err) |
| 76 | } |
| 77 | historical, err := f.ledger.readHistorical(r.Authorization.ID) |
| 78 | if err != nil || !reflect.DeepEqual(historical, r) { |
| 79 | t.Fatal("history changed", err) |
| 80 | } |
| 81 | if _, err := os.Stat(f.fs.data); err != nil { |
| 82 | t.Fatal(err) |
| 83 | } |
| 84 | } |
| 85 | |
| 86 | func TestPlan14ServingNamespaceMountReuse(t *testing.T) { |
| 87 | f, r := servingRebootRecordFixture(t, "complete") |
| 88 | f.fs.boot = func() (string, error) { return r.Source.BootID, nil } |
| 89 | p, e := f.fs.historicalNamespaceParent() |
| 90 | if e != nil { |
| 91 | t.Fatal(e) |
| 92 | } |
| 93 | stale := p.Parent |
| 94 | stale.Mount += 123 |
| 95 | if e = f.ledger.write("current-namespace.json", servingParkBootBinding{Version: 1, ID: "namespace", BeforeBoot: p.BootID, BootID: p.BootID, BeforeParent: p.Parent, Parent: stale}); e != nil { |
| 96 | t.Fatal(e) |
| 97 | } |
| 98 | if e = f.ledger.write("current-retirement-"+r.Authorization.ID+".json", servingParkBootBinding{Version: 1, ID: "retirement-" + r.Authorization.ID, BeforeBoot: r.Source.BootID, BootID: r.Source.BootID, BeforeParent: r.Source.Parent, Parent: stale}); e != nil { |
| 99 | t.Fatal(e) |
| 100 | } |
| 101 | h := *f.ledger |
| 102 | h.historical = true |
| 103 | if e = h.prepareRebootLocked(t.Context(), r, nil); e != nil { |
| 104 | t.Fatal("prepare reused mount", e) |
| 105 | } |
| 106 | if e = h.commitRebootLocked(t.Context(), r, nil); e != nil { |
| 107 | t.Fatal("commit reused mount", e) |
| 108 | } |
| 109 | if e = f.fs.recoverRecordedNamespace(t.Context()); e != nil { |
| 110 | t.Fatal(e) |
| 111 | } |
| 112 | current, e := f.ledger.read(r.Authorization.ID) |
| 113 | if e != nil || current.Source.Parent != r.Source.Parent { |
| 114 | t.Fatal("return to original mount", e) |
| 115 | } |
| 116 | original, e := f.ledger.readHistorical(r.Authorization.ID) |
| 117 | if e != nil || !reflect.DeepEqual(original, r) { |
| 118 | t.Fatal("history changed", e) |
| 119 | } |
| 120 | } |
| 121 | |