1
2
3
4
5 package gate_test
6
7 import (
8 "context"
9 "internal/gate"
10 "testing"
11 "time"
12 )
13
14 func TestGateLockAndUnlock(t *testing.T) {
15 g := gate.New(false)
16 if set := g.Lock(); set {
17 t.Errorf("g.Lock of never-locked gate: true, want false")
18 }
19 unlockedc := make(chan struct{})
20 donec := make(chan struct{})
21 go func() {
22 defer close(donec)
23 if set := g.Lock(); !set {
24 t.Errorf("g.Lock of set gate: false, want true")
25 }
26 select {
27 case <-unlockedc:
28 default:
29 t.Errorf("g.Lock succeeded while gate was held")
30 }
31 g.Unlock(false)
32 }()
33 time.Sleep(1 * time.Millisecond)
34 close(unlockedc)
35 g.Unlock(true)
36 <-donec
37 if set := g.Lock(); set {
38 t.Errorf("g.Lock of unset gate: true, want false")
39 }
40 }
41
42 func TestGateWaitAndLock(t *testing.T) {
43 g := gate.New(false)
44
45 ctx, cancel := context.WithTimeout(context.Background(), 1*time.Millisecond)
46 defer cancel()
47 if err := g.WaitAndLock(ctx); err != context.DeadlineExceeded {
48 t.Fatalf("g.WaitAndLock = %v, want context.DeadlineExceeded", err)
49 }
50
51 set := false
52 go func() {
53 time.Sleep(1 * time.Millisecond)
54 g.Lock()
55 set = true
56 g.Unlock(true)
57 }()
58 if err := g.WaitAndLock(context.Background()); err != nil {
59 t.Fatalf("g.WaitAndLock = %v, want nil", err)
60 }
61 if !set {
62 t.Fatalf("g.WaitAndLock returned before gate was set")
63 }
64 g.Unlock(true)
65
66 if err := g.WaitAndLock(ctx); err != nil {
67 t.Fatalf("g.WaitAndLock = %v, want nil", err)
68 }
69 }
70
71 func TestGateLockIfSet(t *testing.T) {
72 g := gate.New(false)
73 if locked := g.LockIfSet(); locked {
74 t.Fatalf("g.LockIfSet of unset gate = %v, want false", locked)
75 }
76 g.Lock()
77 if locked := g.LockIfSet(); locked {
78 t.Fatalf("g.LockIfSet of locked gate = %v, want false", locked)
79 }
80 g.Unlock(true)
81 if locked := g.LockIfSet(); !locked {
82 t.Fatalf("g.LockIfSet of set gate = %v, want true", locked)
83 }
84 }
85
View as plain text