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 "github.com/carlosframework/platform/internal/hostguard"
6 "testing"
7)
8
9func TestClaimStopProducerFenceJoinsAndDenies(t *testing.T) {
10 _, req, _ := claimStopFixture(t)
11 target := hostguard.FenceTarget{Host: req.Host, Incarnation: req.Incarnation, Stamp: req.InstallationStamp, Session: req.WriterSession, Box: req.Box, Enrollment: req.Enrollment, BootID: req.BootID, ControllerID: req.ControllerID}
12 recorded := 0
13 p, err := NewClaimProducers(target, "start-42", func(context.Context, hostguard.FenceTarget, string) error { recorded++; return nil })
14 if err != nil {
15 t.Fatal(err)
16 }
17 child, finish, err := p.Register(t.Context(), target, "replication")
18 if err != nil {
19 t.Fatal(err)
20 }
21 done := make(chan struct{})
22 go func() { defer close(done); <-child.Done(); finish(nil) }()
23 ack, err := p.DrainClaim(t.Context(), req, "fence")
24 if err != nil {
25 t.Fatal(err)
26 }
27 <-done
28 if len(ack.ProducerIDs) != 1 || ack.ProducerIDs[0] != "replication" || recorded != 1 {
29 t.Fatalf("ack=%+v records=%d", ack, recorded)
30 }
31 if _, _, err := p.Register(t.Context(), target, "late"); err == nil {
32 t.Fatal("producer admitted after fence")
33 }
34}
35
36type exactFixtureInventory struct{ StopInventoryReader }
37
38func (r exactFixtureInventory) ReadExactStopInventory(ctx context.Context, target hostguard.FenceTarget) (StopInventory, error) {
39 return r.ReadStopInventory(ctx, target.Host)
40}
41func TestClaimStopCleanupUsesDurableFenceDuringOutage(t *testing.T) {
42 c, req, store := claimStopFixture(t)
43 drainer := c.Drainer
44 c.Drainer = stopDrainFunc(func(context.Context, StopRequest, string) (DrainAcknowledgement, error) {
45 return DrainAcknowledgement{}, ErrClaimStopUnavailable
46 })
47 if _, err := c.FenceAndStop(t.Context(), req); err == nil {
48 t.Fatal("initial drain should fail")
49 }
50 c.Drainer = drainer
51 c.Inventory = exactFixtureInventory{c.Inventory}
52 c.Claims = stopClaimReader{}
53 store.err = ErrClaimStopUnavailable
54 req.Cleanup = true
55 result, err := c.FenceAndStop(t.Context(), req)
56 if err != nil {
57 t.Fatal(err)
58 }
59 if len(result.Bytes) == 0 {
60 t.Fatal("missing local receipt")
61 }
62 if store.err == nil {
63 t.Fatal("cleanup attempted remote publication")
64 }
65 req.WriterSession++
66 if _, err := c.FenceAndStop(t.Context(), req); err == nil {
67 t.Fatal("cleanup widened session")
68 }
69}
70