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 hostexec
4
5import (
6 "context"
7 "errors"
8 "testing"
9 "time"
10)
11
12func TestPlan14ExecutionShutdownJoinsAcquisition(t *testing.T) {
13 b, disk, remote, _, q, peer := brokerFixture(t)
14 entered, resume := make(chan struct{}), make(chan struct{})
15 remote.onPut = func(int) { close(entered); <-resume }
16 result := make(chan error, 1)
17 go func() { _, err := b.Execute(t.Context(), peer, q); result <- err }()
18 <-entered
19 closing := make(chan error, 1)
20 go func() { closing <- b.Close(t.Context()) }()
21 var early bool
22 select {
23 case <-closing:
24 early = true
25 case <-time.After(50 * time.Millisecond):
26 }
27 probe, cancel := context.WithTimeout(t.Context(), 20*time.Millisecond)
28 unlock, lockErr := disk.Lock(probe, q.Host+".lock")
29 cancel()
30 if lockErr == nil {
31 unlock()
32 }
33 close(resume)
34 if err := <-result; err == nil {
35 t.Error("acquisition returned a permit during shutdown")
36 }
37 if !early {
38 if err := <-closing; err != nil {
39 t.Fatal(err)
40 }
41 }
42 if early || !errors.Is(lockErr, context.DeadlineExceeded) {
43 t.Fatalf("shutdown released ownership before acquisition joined: early=%v lock=%v", early, lockErr)
44 }
45 r, err := b.read(q.Host)
46 if err != nil || r.Status != "lost" || r.LeaseETag == "" {
47 t.Fatalf("late acquisition evidence was lost: %+v %v", r, err)
48 }
49 probe, cancel = context.WithTimeout(t.Context(), time.Second)
50 defer cancel()
51 unlock, err = disk.Lock(probe, q.Host+".lock")
52 if err != nil {
53 t.Fatal(err)
54 }
55 unlock()
56}
57
58func TestPlan14ExecutionShutdownRevokesBeforeCleanup(t *testing.T) {
59 b, disk, _, _, q, peer := brokerFixture(t)
60 if _, err := b.Execute(t.Context(), peer, q); err != nil {
61 t.Fatal(err)
62 }
63 entered, resume := make(chan struct{}), make(chan struct{})
64 b.cfg.Cleanup = func(context.Context, ExecutionRecord) error { close(entered); <-resume; return nil }
65 closing := make(chan error, 1)
66 go func() { closing <- b.Close(t.Context()) }()
67 <-entered
68 held, err := disk.LiveHeld(q.Host + ".live")
69 close(resume)
70 if closeErr := <-closing; closeErr != nil {
71 t.Fatal(closeErr)
72 }
73 if err != nil || held {
74 t.Fatalf("cleanup began before live permission was withdrawn: %v", err)
75 }
76 q.ID = "after-shutdown"
77 if _, err := b.Execute(t.Context(), peer, q); err == nil {
78 t.Fatal("closed broker accepted new work")
79 }
80}
81
82func TestPlan14ExecutionShutdownTimeoutRetainsOwnership(t *testing.T) {
83 b, disk, remote, _, q, peer := brokerFixture(t)
84 entered, resume := make(chan struct{}), make(chan struct{})
85 remote.onPut = func(int) { close(entered); <-resume }
86 result := make(chan error, 1)
87 go func() { _, err := b.Execute(t.Context(), peer, q); result <- err }()
88 <-entered
89 bounded, cancel := context.WithTimeout(t.Context(), 20*time.Millisecond)
90 err := b.Close(bounded)
91 cancel()
92 if !errors.Is(err, context.DeadlineExceeded) {
93 close(resume)
94 <-result
95 t.Fatalf("shutdown did not retain the outstanding acquisition: %v", err)
96 }
97 probe, cancel := context.WithTimeout(t.Context(), 20*time.Millisecond)
98 unlock, lockErr := disk.Lock(probe, q.Host+".lock")
99 cancel()
100 if lockErr == nil {
101 unlock()
102 }
103 close(resume)
104 if err := <-result; err == nil {
105 t.Fatal("late acquisition returned permission")
106 }
107 if err := b.Close(t.Context()); err != nil {
108 t.Fatal(err)
109 }
110 if !errors.Is(lockErr, context.DeadlineExceeded) {
111 t.Fatalf("timeout abandoned ownership: %v", lockErr)
112 }
113}
114