carlos / platform Public

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

Plain git — no account needed to clone.

Download

Download this file

1package host
2
3import (
4 "context"
5 "testing"
6
7 "github.com/carlosframework/platform/internal/hostclaim"
8 "github.com/carlosframework/platform/internal/hostguard"
9 "github.com/carlosframework/platform/internal/release"
10)
11
12func TestPlan14GenerationRetirementRetainedRebind(t *testing.T) {
13 for _, change := range []string{"none", "open-writers", "unsettled", "wrong-installation", "wrong-incarnation", "wrong-stamp", "wrong-account", "wrong-enrollment"} {
14 t.Run(change, func(t *testing.T) {
15 f, disk, _ := generationLaunchFixture(t)
16 if _, err := f.root.Serve(t.Context(), f.peer, f.req); err != nil {
17 t.Fatal(err)
18 }
19 r := readGenerationLaunch(t, disk)
20 if change != "unsettled" {
21 if err := f.root.stop(t.Context(), f.peer, *f.req.Reservation); err != nil {
22 t.Fatal(err)
23 }
24 }
25 if change != "open-writers" {
26 if err := f.journal.CloseWriters(t.Context(), f.target); err != nil {
27 t.Fatal(err)
28 }
29 }
30 prior := hostguard.Captured{Incarnation: f.target.Incarnation, Stamp: f.target.Stamp}
31 in, err := f.root.Guard.Root.Installation(t.Context(), f.target.Host, prior)
32 if err != nil {
33 t.Fatal(err)
34 }
35 next := in
36 next.Stamp += 3
37 next.InventoryRevision++
38 f.claims.set(func(c *hostclaim.Claim) { c.Holder.Stamp = next.Stamp })
39 if err := f.root.Guard.RebindRootInventory(t.Context(), prior, in.InventoryRevision, next, []byte("root-verified-rebind"), func(*hostclaim.Claim) error { return nil }, func() error { return nil }); err != nil {
40 t.Fatal(err)
41 }
42 switch change {
43 case "wrong-installation":
44 r.Binding.Installation = "other"
45 case "wrong-incarnation":
46 r.Binding.Target.Incarnation = "other"
47 case "wrong-stamp":
48 r.Binding.Target.Stamp++
49 case "wrong-account":
50 r.Binding.Binding.Account = "other"
51 case "wrong-enrollment":
52 r.Binding.Target.Enrollment = "other"
53 }
54 calls := 0
55 verifier := generationRetirement{guard: f.root.Guard, journal: f.journal, kernel: func(context.Context, release.GenerationReservation) (string, error) {
56 calls++
57 return r.Binding.Digest, nil
58 }}
59 _, err = verifier.verify(t.Context(), r)
60 if change != "none" {
61 if err == nil || calls != 0 {
62 t.Fatalf("rebind erased old obligation: %v kernel=%d", err, calls)
63 }
64 return
65 }
66 if err != nil || calls != 1 {
67 t.Fatalf("retained predecessor refused: %v kernel=%d", err, calls)
68 }
69 if err := verifier.retire(t.Context(), &release.RootGenerations{Store: disk}, r); err != nil {
70 t.Fatal(err)
71 }
72 got := readGenerationLaunch(t, disk)
73 if got.Retirement == "" {
74 t.Fatal("exact old reservation retained after verified retirement")
75 }
76 current, err := f.root.Guard.Root.Installation(t.Context(), next.Host, hostguard.Captured{Incarnation: next.Incarnation, Stamp: next.Stamp})
77 if err != nil || current != next {
78 t.Fatal("retirement changed successor installation", err)
79 }
80 })
81 }
82}
83