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 "encoding/json"
6 "testing"
7 "time"
8
9 "github.com/carlosframework/platform/internal/hostbox"
10 "github.com/carlosframework/platform/internal/hostclaim"
11 execlease "github.com/carlosframework/platform/internal/hostexec"
12 "github.com/carlosframework/platform/internal/hostguard"
13)
14
15func TestPlan14OrdinaryDeleteParticipation(t *testing.T) {
16 t.Parallel()
17 for _, mode := range []string{"live", "stopped", "parking", "retired", "serving stopped", "pending", "record present", "delete absent", "etag", "key", "enrollment", "foreign home", "session", "stamp", "op", "box", "inventory"} {
18 t.Run(mode, func(t *testing.T) {
19 f, root, iq := plan14InstallRegistration(t, hostclaim.KindServing, "")
20 if _, err := root.commitRootInventory(t.Context(), iq); err != nil {
21 t.Fatal(err)
22 }
23 actor, _ := root.InventoryActor(t.Context())
24 actor.FleetHomeRegion, actor.HomeRegion = "ie", "ie"
25 root.InventoryActor = func(context.Context) (hostbox.Actor, error) { return actor, nil }
26 o, err := hostclaim.Update(t.Context(), f.claims, f.read(), hostclaim.AdmitWriter(hostclaim.Admission{ObservedSession: f.read().Claim.Holder.Session, ObservedGeneration: f.read().Claim.Holder.Generation, Box: actor.Box, Region: "ie", Mode: "cold", NewGeneration: "delete-generation", KeepStamp: true}))
27 if err != nil {
28 t.Fatal(err)
29 }
30 target := iq.Target
31 target.Session, target.ClaimETag, target.ClaimGen = o.Claim.Holder.Session, o.ETag, o.Claim.Gen
32 target.FenceID, target.Region, target.BootID, target.ControllerID, target.DirectoryRevision, target.RosterRevision = "delete-stop", "ie", "boot", "controller", "1", 1
33 if mode != "live" {
34 if target, err = root.Stop.Coordinator.Guard.BeginFence(t.Context(), target); err != nil {
35 t.Fatal(err)
36 }
37 if mode != "pending" {
38 at := time.Now().UTC()
39 receipt := StopReceipt{V: 1, Kind: "stopped", ID: "delete-stop-receipt", FenceID: target.FenceID, Host: target.Host, Incarnation: target.Incarnation, InstallationStamp: target.Stamp, WriterSession: target.Session, Region: target.Region, ClaimETag: target.ClaimETag, ClaimGen: target.ClaimGen, Box: target.Box, Enrollment: target.Enrollment, BootID: target.BootID, ControllerID: target.ControllerID, DirectoryRevision: testReceiptNumeral(target), Binding: target.DirectoryRevision, EvidenceAt: at}
40 raw, _ := json.Marshal(receipt)
41 if err = root.Stop.Coordinator.Guard.CompleteFence(t.Context(), target, raw, at, func(ctx context.Context, t hostguard.FenceTarget, b []byte, at time.Time) error {
42 return verifyRetirementReceipt(ctx, hostguard.FenceReceipt{Target: t, Bytes: b, EvidenceAt: at})
43 }); err != nil {
44 t.Fatal(err)
45 }
46 }
47 }
48 if mode != "serving stopped" {
49 o, err = hostclaim.Update(t.Context(), f.claims, f.read(), hostclaim.BeginDelete("delete", "console", iq.RecordETag, time.Now(), []string{"ie"}, []string{actor.Box}, ""))
50 if err != nil {
51 t.Fatal(err)
52 }
53 }
54 if mode == "parking" || mode == "retired" || mode == "record present" {
55 o, err = hostclaim.Update(t.Context(), f.claims, o, hostclaim.ToScopedParking("delete", []string{"ie"}, []string{actor.Box}, f.newID))
56 if err != nil {
57 t.Fatal(err)
58 }
59 }
60 if mode == "parking" || mode == "retired" || mode == "delete absent" {
61 if err = f.claims.Delete(t.Context(), iq.RecordKey); err != nil {
62 t.Fatal(err)
63 }
64 }
65 if mode == "retired" {
66 if err = root.Stop.Coordinator.Guard.RetireInstallationWith(t.Context(), o.Host, hostguard.Captured{Incarnation: target.Incarnation, Stamp: target.Stamp}, func(*hostclaim.Claim) error { return nil }, func() error { return nil }); err != nil {
67 t.Fatal(err)
68 }
69 }
70 if mode == "etag" || mode == "key" {
71 o, err = hostclaim.Update(t.Context(), f.claims, o, func(c *hostclaim.Claim) error { c.Op.Intent[mode] = "forged"; return nil })
72 if err != nil {
73 t.Fatal(err)
74 }
75 }
76 q := execlease.ExecutionRequest{Schema: 1, ID: "delete-participation", Operation: "executionBegin", Host: o.Host, Incarnation: target.Incarnation, Stamp: target.Stamp, Session: target.Session, Op: o.Claim.Op.ID}
77 switch mode {
78 case "enrollment":
79 actor.Enrollment = "foreign"
80 case "foreign home":
81 actor.FleetHomeRegion = "uk"
82 case "session":
83 q.Session++
84 case "stamp":
85 q.Stamp++
86 case "op":
87 q.Op = "foreign"
88 case "box":
89 actor.Box = "foreign"
90 case "inventory":
91 if err = root.Journals.Inventory.WriteStopInventory(t.Context(), iq.Inventory); err != nil {
92 t.Fatal(err)
93 }
94 }
95 a, err := root.executionAuthority(t.Context(), q, execlease.ControllerProcess{})
96 want := mode == "live" || mode == "stopped" || mode == "parking" || mode == "retired" || mode == "delete absent"
97 if want {
98 if err != nil || !a.ParticipationOnly || a.Installation == "" || a.RecordRevision != iq.RecordETag {
99 t.Fatalf("participation: %+v %v", a, err)
100 }
101 } else if err == nil {
102 t.Fatalf("unsafe participation: %+v", a)
103 }
104 if mode == "retired" {
105 root.Stop.Coordinator.Kernel = f.kernel
106 f.kernel.noProcess = true
107 if err := root.cleanupExecution(t.Context(), execlease.ExecutionRecord{Request: q, Authority: a}); err != nil || f.kernel.noProcessCalls != 1 {
108 t.Fatalf("retired participation cleanup: %v, kernel calls=%d", err, f.kernel.noProcessCalls)
109 }
110 a.Enrollment = "foreign"
111 if err := root.cleanupExecution(t.Context(), execlease.ExecutionRecord{Request: q, Authority: a}); err == nil || f.kernel.noProcessCalls != 1 {
112 t.Fatalf("foreign retired cleanup: %v, kernel calls=%d", err, f.kernel.noProcessCalls)
113 }
114 }
115 })
116 }
117}
118