carlos / platform Public

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

Plain git — no account needed to clone.

Download

Download this file

1//go:build unix
2
3package hostbox
4
5import (
6 "context"
7 "testing"
8
9 "github.com/carlosframework/platform/internal/hostclaim"
10 "github.com/carlosframework/platform/internal/hostwrite"
11 "github.com/carlosframework/platform/internal/release"
12)
13
14// plan9D1Probe turns the adopted fixture into a landing op at probing with the
15// fixture box executing, keeping the holder's stamp so the local record stays
16// active, then selects the probe's spawn work there.
17func plan9D1Probe(t *testing.T, continues func(string, string, string) bool) (hostwrite.Work, release.Store, func(func(*hostclaim.Claim) error)) {
18 t.Helper()
19 source, store, obs := workFixture(t)
20 source.Continue = continues
21 source.Policy = func(context.Context, *hostclaim.Claim, Selection, hostwrite.Identity) error { return nil }
22 ctx := context.Background()
23 update := func(fn func(*hostclaim.Claim) error) {
24 t.Helper()
25 current, err := hostclaim.Read(ctx, store, "shop.example")
26 if err != nil {
27 t.Fatal(err)
28 }
29 if _, err = hostclaim.Update(ctx, store, current, fn); err != nil {
30 t.Fatal(err)
31 }
32 }
33 obs, err := hostclaim.Update(ctx, store, obs, func(c *hostclaim.Claim) error {
34 c.Op = hostclaim.Op{Kind: hostclaim.KindLanding, ID: "m1", Phase: hostclaim.PhaseLandingProbing, Exec: "box", Participants: []string{"source", "box"}, Intent: map[string]string{"to": "ie", "source": "source", "target": "box"}}
35 return nil
36 })
37 if err != nil {
38 t.Fatal(err)
39 }
40 work, err := source.Select(ctx, obs.Host, "spawn")
41 if err != nil {
42 t.Fatal(err)
43 }
44 return work, store, update
45}
46
47func plan9D1Write(work hostwrite.Work) error {
48 return work.With(context.Background(), hostwrite.Identity{Config: "c", Release: "r"}, func() error { return nil })
49}
50
51func TestPlan9D1ProbeSessionSurvivesForwardSteps(t *testing.T) {
52 work, _, update := plan9D1Probe(t, hostclaim.SessionContinues)
53 if err := plan9D1Write(work); err != nil {
54 t.Fatal(err)
55 }
56 update(hostclaim.SetMovePhase("m1", hostclaim.KindLanding, hostclaim.PhaseLandingProbing, hostclaim.PhaseLandingProbed))
57 if err := plan9D1Write(work); err != nil {
58 t.Fatalf("probed ended the probe's session: %v", err)
59 }
60 update(hostclaim.KeepWriterSession("m1", hostclaim.SetMovePhase("m1", hostclaim.KindLanding, hostclaim.PhaseLandingProbed, hostclaim.PhaseLandingCommitted)))
61 if err := plan9D1Write(work); err != nil {
62 t.Fatalf("committed ended the probe's session: %v", err)
63 }
64}
65
66func TestPlan9D1ProbeSessionEndsOnEveryOtherChange(t *testing.T) {
67 for name, change := range map[string]func(*hostclaim.Claim) error{
68 // A landing failure reverts the op: the claim moves to restoring
69 // under the same op id (moves §7.8).
70 "rollback": func(c *hostclaim.Claim) error {
71 c.Op.Kind, c.Op.Phase = hostclaim.KindRestoring, "releasing"
72 return nil
73 },
74 "backward": func(c *hostclaim.Claim) error { c.Op.Phase = "restored"; return nil },
75 "release": func(c *hostclaim.Claim) error {
76 c.Op = hostclaim.Op{Kind: hostclaim.KindServing, Exec: "box"}
77 return nil
78 },
79 "other-op": func(c *hostclaim.Claim) error { c.Op.ID = "m2"; return nil },
80 "session": func(c *hostclaim.Claim) error { c.Holder.Session++; return nil },
81 "generation": func(c *hostclaim.Claim) error {
82 c.Holder.Generation = "fresh"
83 return nil
84 },
85 } {
86 t.Run(name, func(t *testing.T) {
87 work, _, update := plan9D1Probe(t, hostclaim.SessionContinues)
88 update(change)
89 if err := plan9D1Write(work); err == nil {
90 t.Fatalf("%s kept the probe's session", name)
91 }
92 })
93 }
94}
95
96// Without the moves C1 table (either flag off) main's phase equality stands.
97func TestPlan9D1PhaseEqualityStandsWithoutTheTable(t *testing.T) {
98 work, _, update := plan9D1Probe(t, nil)
99 update(hostclaim.SetMovePhase("m1", hostclaim.KindLanding, hostclaim.PhaseLandingProbing, hostclaim.PhaseLandingProbed))
100 if err := plan9D1Write(work); err == nil {
101 t.Fatal("a phase step kept the session without the table")
102 }
103}
104