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 linux
2
3package host
4
5import (
6 "context"
7 "errors"
8 "fmt"
9 "io"
10 "os"
11 "path/filepath"
12 "reflect"
13 "testing"
14 "time"
15
16 "github.com/carlosframework/platform/internal/hostclaim"
17 "github.com/carlosframework/platform/internal/hostfiles"
18 "github.com/carlosframework/platform/internal/lease"
19 "github.com/carlosframework/platform/internal/lease/leasetest"
20 "github.com/carlosframework/platform/internal/provision"
21 "github.com/carlosframework/platform/internal/registry"
22)
23
24type filesEvidenceMetadata struct {
25 lease.VersionedStore
26 lists, reads int
27}
28
29func (s *filesEvidenceMetadata) ListVersions(ctx context.Context, b, k string) ([]lease.ObjectVersion, error) {
30 s.lists++
31 return s.VersionedStore.ListVersions(ctx, b, k)
32}
33func (s *filesEvidenceMetadata) GetVersion(context.Context, string, string, string) ([]byte, error) {
34 s.reads++
35 return nil, hostfiles.ErrNoEvidence
36}
37func (s *filesEvidenceMetadata) OpenVersion(context.Context, string, string, string) (io.ReadCloser, error) {
38 s.reads++
39 return nil, hostfiles.ErrNoEvidence
40}
41
42func TestUnseededServingRequestsSpendNoRetry(t *testing.T) {
43 for _, state := range []string{"none", "attempting", "open", "failed"} {
44 t.Run(state, func(t *testing.T) {
45 f := newServingRootFixture(t, true)
46 count := 0
47 if state != "none" {
48 count = 1
49 }
50 if state == "failed" {
51 count = 5
52 }
53 for i := 0; i < count; i++ {
54 o := f.f.read()
55 attempt := hostclaim.WakeRetryAttempt{ID: fmt.Sprint("attempt-", i), Box: f.actor.Box, Enrollment: f.actor.Enrollment, BootID: "old-boot", ControllerID: "old-controller", InvocationID: fmt.Sprint("invocation-", i), LaunchInputs: "inputs"}
56 reserved, err := hostclaim.Update(t.Context(), f.f.claims, o, hostclaim.ReserveWakeRetryAttempt(hostclaim.WakeRetryReservation{HolderIncarnation: o.Claim.Holder.Incarnation, EpisodeID: "episode", Attempt: attempt, Now: f.f.now}))
57 if err != nil {
58 t.Fatal(err)
59 }
60 if state != "attempting" {
61 if _, err := hostclaim.Update(t.Context(), f.f.claims, reserved, hostclaim.FailWakeRetryAttempt(hostclaim.WakeRetryResult{HolderIncarnation: o.Claim.Holder.Incarnation, EpisodeID: "episode", Attempt: attempt, Now: f.f.now})); err != nil {
62 t.Fatal(err)
63 }
64 f.f.now = f.f.now.Add(time.Minute)
65 }
66 }
67 bucket := leasetest.NewVersionedBucket()
68 bucket.AddBucket("data")
69 data := &filesEvidenceMetadata{VersionedStore: bucket}
70 provider := &movesFiles{Data: data, Bucket: "data", Box: f.actor.Box, Region: f.actor.Region, DataDir: f.f.guard.DataDir, EnvFile: func(host, db string) (claimEnvFile, error) {
71 return claimEnvFile{Dir: filepath.Dir(db), Name: host + ".env", Nested: true}, nil
72 }}
73 p := newServingPreparation(t, f, "boot", "controller", func(w *ClaimWakeAssembly) { w.ServingPrerequisites = servingFilesPrerequisites(f.f.claims, provider) })
74 before := f.f.read()
75 disk := servingBootSnapshot(t, f.disk.dir)
76 roots := servingBootSnapshot(t, f.rootDisk.dir)
77 for i := 0; i < 12; i++ {
78 f.f.now = f.f.now.Add(time.Minute)
79 err := p.runtime.Prerequisites(t.Context(), registry.Route{Host: before.Host, DBPath: provision.NestedDBPath(f.f.guard.DataDir, before.Host)}, before, recoveryPolicy)
80 if !errors.Is(err, hostfiles.ErrNoEvidence) {
81 t.Fatal(err)
82 }
83 }
84 after := f.f.read()
85 if !reflect.DeepEqual(before, after) || !reflect.DeepEqual(disk, servingBootSnapshot(t, f.disk.dir)) || !reflect.DeepEqual(roots, servingBootSnapshot(t, f.rootDisk.dir)) || len(p.events) != 0 {
86 t.Fatal("missing evidence spent retries or changed root state", p.events)
87 }
88 if data.reads != 0 || data.lists < 12 {
89 t.Fatal("guard did not use metadata only", data.lists, data.reads)
90 }
91 })
92 }
93}
94
95func TestServingEmptyBootstrapNeedsNoExistingInstanceDirectory(t *testing.T) {
96 f := newFilesSeedFixture(t)
97 if err := os.RemoveAll(filepath.Dir(f.route.DBPath)); err != nil {
98 t.Fatal(err)
99 }
100 o := f.observed
101 o.Claim.Holder.Generation = ""
102 o.Claim.Holder.Session = 0
103 o.Claim.Holder.Admissions = nil
104 o.Claim.Holder.WriterBox = ""
105 // Match the production empty-authority predicate, not absence of a manifest.
106 if !claimEmptyBootstrap(o.Claim.Holder) {
107 t.Fatal("fixture not bootstrap")
108 }
109 if err := f.files.checkServingFilesEvidence(t.Context(), o, f.route); err != nil {
110 t.Fatal(err)
111 }
112}
113