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 "errors"
8 "github.com/carlosframework/platform/internal/hostclaim"
9 "github.com/carlosframework/platform/internal/hostguard"
10 "github.com/carlosframework/platform/internal/hostwrite"
11 "github.com/carlosframework/platform/internal/park"
12 "testing"
13 "time"
14)
15
16func TestReconcileDryRunAndExecutorValidation(t *testing.T) {
17 source, store, obs := workFixture(t)
18 h := obs.Claim.Holder
19 selected := RecordSelection{Host: obs.Host, Key: h.Key, ETag: "record-etag", Incarnation: h.Incarnation, Family: h.Family, Layout: "flat", Paths: []string{"shop.example.db"}, DryRun: true}
20 checks, writes := 0, 0
21 r := Reconciler{Claims: store, Guard: source.Guard, Local: park.Local{Guard: source.Guard, Claims: store, DataDir: source.Guard.DataDir, Box: "box"}, Writes: hostwrite.Config{Enabled: true, Selector: source}, Box: "box", Region: "ie", Now: func() time.Time { return time.Unix(100, 0) }, CheckRecord: func(context.Context, RecordSelection) error { return nil }, CheckLocal: func(context.Context, hostclaim.Observed, RecordSelection) error { checks++; return nil }}
22 if err := r.Install(context.Background(), selected, func() error { writes++; return nil }); err != nil {
23 t.Fatal(err)
24 }
25 if writes != 0 || checks != 1 {
26 t.Fatal(writes, checks)
27 }
28 selected.DryRun = false
29 r.CheckLocal = func(context.Context, hostclaim.Observed, RecordSelection) error {
30 checks++
31 if checks >= 3 {
32 return errors.New("quarantined after precheck")
33 }
34 return nil
35 }
36 if err := r.Install(context.Background(), selected, func() error { writes++; return nil }); err == nil {
37 t.Fatal("executor bypassed fresh local check")
38 }
39 if writes != 0 {
40 t.Fatal("row materialized")
41 }
42}
43
44func TestInstallSettlesParticipationBeforeInventory(t *testing.T) {
45 for _, refuse := range []bool{false, true} {
46 t.Run(map[bool]string{false: "settled", true: "refused"}[refuse], func(t *testing.T) {
47 source, store, obs := workFixture(t)
48 h := obs.Claim.Holder
49 selected := RecordSelection{Host: obs.Host, Key: h.Key, ETag: "record-etag", Incarnation: h.Incarnation, Family: h.Family, Layout: "flat", Paths: []string{"shop.example.db"}}
50 prepared, inventory, written := false, false, false
51 denied := errors.New("participation still owns prior operation")
52 r := Reconciler{Claims: store, Guard: source.Guard, Local: park.Local{Guard: source.Guard, Claims: store, DataDir: source.Guard.DataDir, Box: "box"}, Writes: hostwrite.Config{Enabled: true, Selector: source}, Box: "box", Region: "ie", Now: func() time.Time { return time.Unix(100, 0) }, CheckRecord: func(context.Context, RecordSelection) error { return nil }, CheckLocal: func(context.Context, hostclaim.Observed, RecordSelection) error { return nil }}
53 r.Prepare = func(context.Context, hostclaim.Observed) error {
54 prepared = true
55 if refuse {
56 return denied
57 }
58 return nil
59 }
60 r.PrepareInventory = func(context.Context, RecordSelection, hostguard.Captured) error {
61 if !prepared {
62 t.Fatal("inventory preceded participation settlement")
63 }
64 inventory = true
65 return nil
66 }
67 err := r.Install(t.Context(), selected, func() error { written = true; return nil })
68 if refuse {
69 if !errors.Is(err, denied) || inventory || written {
70 t.Fatal("unsettled participation reached effects", err, inventory, written)
71 }
72 } else if err != nil || !prepared || !inventory || !written {
73 t.Fatal("settled installation", err, prepared, inventory, written)
74 }
75 })
76 }
77}
78