carlos / platform Public

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

Plain git — no account needed to clone.

Download

Download this file

1package hostexec
2
3import (
4 "context"
5 "encoding/json"
6 "errors"
7 "github.com/carlosframework/platform/internal/release"
8 "os"
9 "testing"
10 "time"
11)
12
13func TestPlan14Fix2RenewReplyLostSettlesAfterExpiry(t *testing.T) {
14 b, _, remote, clock, q, p := brokerFixture(t)
15 out, err := b.Execute(t.Context(), p, q)
16 if err != nil {
17 t.Fatal(err)
18 }
19 r, err := b.read(q.Host)
20 if err != nil {
21 t.Fatal(err)
22 }
23 key, _ := Key(q.Host, r.Authority.Box)
24 r.Expires = r.Expires.Add(Renewal)
25 raw, _ := json.Marshal(Record{Op: q.Op, Expires: r.Expires})
26 if _, err := remote.Store.Put(t.Context(), key, raw, r.LeaseETag); err != nil {
27 t.Fatal(err)
28 }
29 r.Status = "pending"
30 if err := b.write(r); err != nil {
31 t.Fatal(err)
32 }
33 q.Operation, q.Token, q.ID = "executionSettle", out.Token, "settle-lost-response"
34 if _, err := b.Execute(t.Context(), p, q); err == nil {
35 t.Fatal("unexpired unknown ETag deleted")
36 }
37 clock.advance(TTL + Renewal + time.Second)
38 if _, err := b.Execute(t.Context(), p, q); err != nil {
39 t.Fatal(err)
40 }
41 if _, _, err := remote.Get(t.Context(), key); !errors.Is(err, os.ErrNotExist) {
42 t.Fatal("remote lease retained", err)
43 }
44}
45func TestPlan14Fix2TransientRenewalRetries(t *testing.T) {
46 for _, kind := range []string{"authority", "put"} {
47 t.Run(kind, func(t *testing.T) {
48 b, _, remote, _, q, p := brokerFixture(t)
49 out, err := b.Execute(t.Context(), p, q)
50 if err != nil {
51 t.Fatal(err)
52 }
53 q.Operation, q.Token, q.ID = "executionRenew", out.Token, "renew"
54 calls := 0
55 orig := b.cfg.Authority
56 if kind == "authority" {
57 b.cfg.Authority = func(ctx context.Context, q ExecutionRequest, p ControllerProcess) (ExecutionAuthority, error) {
58 calls++
59 if calls == 1 {
60 return ExecutionAuthority{}, errors.New("transient transport")
61 }
62 return orig(ctx, q, p)
63 }
64 } else {
65 remote.failAt = 2
66 }
67 renewed, err := b.Execute(t.Context(), p, q)
68 if err != nil {
69 t.Fatal(err)
70 }
71 if renewed.Status != "active" || renewed.Token == out.Token {
72 t.Fatal("renewal not committed", renewed)
73 }
74 })
75 }
76}
77func TestPlan14Fix2LostMonitorBacksOff(t *testing.T) {
78 b, d, _, clock, q, p := brokerFixture(t)
79 if _, err := b.Execute(t.Context(), p, q); err != nil {
80 t.Fatal(err)
81 }
82 r, err := b.read(q.Host)
83 if err != nil {
84 t.Fatal(err)
85 }
86 if err := b.deny(t.Context(), r, nil); err != nil {
87 t.Fatal(err)
88 }
89 attempts := 0
90 b.cfg.Settle = func(context.Context, ExecutionRecord) error { attempts++; return release.ErrCASConflict }
91 _ = b.Monitor(t.Context())
92 writes := d.writes
93 for i := 0; i < 9; i++ {
94 clock.advance(100 * time.Millisecond)
95 _ = b.Monitor(t.Context())
96 }
97 if attempts != 1 || d.writes != writes {
98 t.Fatal("lost record hot-loop", attempts, d.writes, writes)
99 }
100 clock.advance(101 * time.Millisecond)
101 _ = b.Monitor(t.Context())
102 if attempts != 2 {
103 t.Fatal("backoff never retried", attempts)
104 }
105}
106