carlos / platform Public

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

Plain git — no account needed to clone.

Download

Download this file

1package hostbox
2
3import (
4 "context"
5 "errors"
6 "reflect"
7 "testing"
8
9 "github.com/carlosframework/platform/internal/park"
10)
11
12type recordedLease struct {
13 name string
14 checks, releases int
15 closed int
16 checkErr, releaseErr error
17}
18
19func (l *recordedLease) Check(context.Context) error { l.checks++; return l.checkErr }
20func (l *recordedLease) Release(context.Context) error { l.releases++; return l.releaseErr }
21func (l *recordedLease) Close() { l.closed++ }
22
23type recordingLeases struct {
24 names []string
25 held map[string]*recordedLease
26 failAt string
27}
28
29func (l *recordingLeases) Acquire(_ context.Context, _, name string) (park.HeldLease, error) {
30 l.names = append(l.names, name)
31 if name == l.failAt {
32 return nil, errors.New("acquire failed")
33 }
34 h := &recordedLease{name: name}
35 l.held[name] = h
36 return h, nil
37}
38
39func TestAggregateLeasesOrderHealthReleaseAndClose(t *testing.T) {
40 base := &recordingLeases{held: map[string]*recordedLease{}}
41 a := AggregateLeases{Leases: base, Resolve: func(context.Context, string, string) ([]string, error) {
42 return []string{"moves/h/op", "instances/h/inc", "moves/h/op"}, nil
43 }}
44 held, err := a.Acquire(t.Context(), "data", "instances/h/inc")
45 if err != nil {
46 t.Fatal(err)
47 }
48 if want := []string{"instances/h/inc", "moves/h/op"}; !reflect.DeepEqual(base.names, want) {
49 t.Fatalf("acquire order = %v, want %v", base.names, want)
50 }
51 base.held["moves/h/op"].checkErr = errors.New("lost")
52 if err := held.Check(t.Context()); err == nil || base.held["instances/h/inc"].checks != 1 || base.held["moves/h/op"].checks != 1 {
53 t.Fatalf("aggregate check = %v", err)
54 }
55 if err := held.Release(t.Context()); err != nil {
56 t.Fatal(err)
57 }
58 held.Close()
59 for name, h := range base.held {
60 if h.releases != 1 || h.closed != 1 {
61 t.Fatalf("%s: releases=%d closes=%d", name, h.releases, h.closed)
62 }
63 }
64}
65
66func TestAggregateLeasesPartialAcquireUnwindsOnlyAcquired(t *testing.T) {
67 base := &recordingLeases{held: map[string]*recordedLease{}, failAt: "b"}
68 a := AggregateLeases{Leases: base, Resolve: func(context.Context, string, string) ([]string, error) {
69 return []string{"scope", "b", "a"}, nil
70 }}
71 if _, err := a.Acquire(t.Context(), "data", "scope"); err == nil {
72 t.Fatal("acquire succeeded")
73 }
74 if want := []string{"a", "b"}; !reflect.DeepEqual(base.names, want) {
75 t.Fatalf("attempts = %v, want %v", base.names, want)
76 }
77 if h := base.held["a"]; h.releases != 1 || h.closed != 1 {
78 t.Fatalf("acquired lease not unwound: %+v", h)
79 }
80 if _, ok := base.held["scope"]; ok {
81 t.Fatal("unattempted lease was acquired")
82 }
83}
84