carlos / platform Public

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

Plain git — no account needed to clone.

Download

Download this file

1package activator
2
3import (
4 "context"
5 "errors"
6 "testing"
7 "time"
8)
9
10func TestFenceInitialAdmissionTimeoutHasNoFence(t *testing.T) {
11 t.Parallel()
12 a := &Service{}
13 a.mu.Lock()
14 ctx, cancel := context.WithTimeout(context.Background(), 20*time.Millisecond)
15 proof, err := a.FenceAndStop(ctx, "timeout.example.com", 1)
16 cancel()
17 if proof != nil || !errors.Is(err, ErrFenceNotInstalled) {
18 a.mu.Unlock()
19 t.Fatalf("uninstalled fence reported as installed: proof=%v err=%v", proof != nil, err)
20 }
21 if a.fences["timeout.example.com"] != 0 {
22 a.mu.Unlock()
23 t.Fatal("fence installed while mutex held")
24 }
25 a.mu.Unlock()
26 if !a.wakeAllowed("timeout.example.com") {
27 t.Fatal("unexpected admission state")
28 }
29}
30
31func TestScheduledTokenSlowHostDoesNotBlockSiblingFence(t *testing.T) {
32 a := &Service{}
33 entered, release := make(chan struct{}), make(chan struct{})
34 done := make(chan error, 1)
35 go func() {
36 _, e := a.PrepareScheduledToken("slow.example.com", func() (string, error) { close(entered); <-release; return "token", nil })
37 done <- e
38 }()
39 <-entered
40 defer func() { close(release); <-done }()
41 ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
42 defer cancel()
43 proof, err := a.FenceAndStop(ctx, "sibling.example.com", 1)
44 if proof != nil || !errors.Is(err, ErrStopUnproven) {
45 t.Fatalf("sibling fence blocked by unrelated IO: %v", err)
46 }
47 callback := make(chan error, 1)
48 go func() {
49 _, e := a.PrepareScheduledToken("fast.example.com", func() (string, error) { return "fast", nil })
50 callback <- e
51 }()
52 select {
53 case e := <-callback:
54 if e != nil {
55 t.Fatal(e)
56 }
57 case <-time.After(time.Second):
58 t.Fatal("sibling token callback blocked")
59 }
60 // A separate goroutine detects the former global mutex hold without hanging the test.
61 result := make(chan bool, 1)
62 go func() { result <- a.wakeAllowed("third.example.com") }()
63 select {
64 case allowed := <-result:
65 if !allowed {
66 t.Fatal("unrelated admission refused")
67 }
68 case <-time.After(time.Second):
69 t.Fatal("unrelated admission blocked")
70 }
71}
72