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  }