carlos / platform Public

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

Plain git — no account needed to clone.

Download

Download this file

1package hostfence
2
3import (
4 "context"
5 "encoding/json"
6 "testing"
7 "time"
8
9 "github.com/aws/aws-sdk-go-v2/service/ec2/types"
10 "github.com/carlosframework/platform/internal/awsinv"
11 "github.com/carlosframework/platform/internal/hostclaim"
12 "github.com/carlosframework/platform/internal/release"
13)
14
15// M1-5: journal evidence requires current writer authority.
16func TestPlan9ClaimFenceRequiresWriterUnfencedNow(t *testing.T) {
17 for _, tc := range []struct {
18 name string
19 offset time.Duration
20 valid bool
21 }{
22 {"writer-unfenced", 0, true},
23 {"writer-fenced-before", -time.Minute, false},
24 {"writer-fenced-same-instant", 0, false},
25 {"writer-fenced-after", time.Minute, false},
26 {"writer-fence-malformed", 0, false},
27 } {
28 t.Run(tc.name, func(t *testing.T) {
29 ctx := context.Background()
30 w, s := terminationFixture(t)
31 w.Reader = func(context.Context, string) (awsinv.ExactEC2API, error) {
32 return terminatedEC2{state: types.InstanceStateNameTerminated, owner: "123"}, nil
33 }
34 got, err := w.Describe(ctx, "dead")
35 if err != nil {
36 t.Fatal(err)
37 }
38 raw, _, err := s.Get(ctx, got.Key)
39 if err != nil {
40 t.Fatal(err)
41 }
42 var seen Termination
43 if err := json.Unmarshal(raw, &seen); err != nil {
44 t.Fatal(err)
45 }
46 observed, err := time.Parse(time.RFC3339Nano, seen.ObservedAt)
47 if err != nil {
48 t.Fatal(err)
49 }
50 o, err := w.Directory.Read(ctx)
51 if err != nil {
52 t.Fatal(err)
53 }
54 self, dead := o.Roster.Boxes["worker"], o.Roster.Boxes["dead"]
55 if tc.name != "writer-unfenced" {
56 body := []byte("{")
57 if tc.name != "writer-fence-malformed" {
58 f := Termination{V: 1, Box: "worker", Enrollment: self.Enrollment, Cloud: self.Cloud, State: "terminated", ObservedAt: observed.Add(tc.offset).Format(time.RFC3339Nano), Via: "describe", RequestID: "request", WrittenBy: Worker{Box: "dead", Enrollment: dead.Enrollment}}
59 if body, err = json.Marshal(f); err != nil {
60 t.Fatal(err)
61 }
62 }
63 if err := release.CreateExact(ctx, s, FenceKey(self.Enrollment), body); err != nil {
64 t.Fatal(err)
65 }
66 }
67 _, err = hostclaim.VerifyFence(ctx, s, ClaimFenceAuthority{Directory: w.Directory, Now: w.Now}, ClaimFenceRef(got))
68 if (err == nil) != tc.valid {
69 t.Fatalf("%s: verify = %v; want valid = %v", tc.name, err, tc.valid)
70 }
71 })
72 }
73}
74