golang.org/x/net@v0.25.1-0.20240516223405-c87a5b62e243/quic/gate_test.go (about) 1 // Copyright 2023 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build go1.21 6 7 package quic 8 9 import ( 10 "context" 11 "testing" 12 "time" 13 ) 14 15 func TestGateLockAndUnlock(t *testing.T) { 16 g := newGate() 17 if set := g.lock(); set { 18 t.Errorf("g.lock() of never-locked gate: true, want false") 19 } 20 unlockedc := make(chan struct{}) 21 donec := make(chan struct{}) 22 go func() { 23 defer close(donec) 24 set := g.lock() 25 select { 26 case <-unlockedc: 27 default: 28 t.Errorf("g.lock() succeeded while gate was held") 29 } 30 if !set { 31 t.Errorf("g.lock() of set gate: false, want true") 32 } 33 g.unlock(false) 34 }() 35 time.Sleep(1 * time.Millisecond) 36 close(unlockedc) 37 g.unlock(true) 38 <-donec 39 if set := g.lock(); set { 40 t.Errorf("g.lock() of unset gate: true, want false") 41 } 42 } 43 44 func TestGateWaitAndLockContext(t *testing.T) { 45 g := newGate() 46 // waitAndLock is canceled 47 ctx, cancel := context.WithCancel(context.Background()) 48 go func() { 49 time.Sleep(1 * time.Millisecond) 50 cancel() 51 }() 52 if err := g.waitAndLock(ctx, nil); err != context.Canceled { 53 t.Errorf("g.waitAndLock() = %v, want context.Canceled", err) 54 } 55 // waitAndLock succeeds 56 set := false 57 go func() { 58 time.Sleep(1 * time.Millisecond) 59 g.lock() 60 set = true 61 g.unlock(true) 62 }() 63 if err := g.waitAndLock(context.Background(), nil); err != nil { 64 t.Errorf("g.waitAndLock() = %v, want nil", err) 65 } 66 if !set { 67 t.Errorf("g.waitAndLock() returned before gate was set") 68 } 69 g.unlock(true) 70 // waitAndLock succeeds when the gate is set and the context is canceled 71 if err := g.waitAndLock(ctx, nil); err != nil { 72 t.Errorf("g.waitAndLock() = %v, want nil", err) 73 } 74 } 75 76 func TestGateLockIfSet(t *testing.T) { 77 g := newGate() 78 if locked := g.lockIfSet(); locked { 79 t.Errorf("g.lockIfSet() of unset gate = %v, want false", locked) 80 } 81 g.lock() 82 g.unlock(true) 83 if locked := g.lockIfSet(); !locked { 84 t.Errorf("g.lockIfSet() of set gate = %v, want true", locked) 85 } 86 } 87 88 func TestGateUnlockFunc(t *testing.T) { 89 g := newGate() 90 go func() { 91 g.lock() 92 defer g.unlockFunc(func() bool { return true }) 93 }() 94 g.waitAndLock(context.Background(), nil) 95 }