Source file src/internal/gate/gate_test.go

     1  // Copyright 2024 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  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  	// WaitAndLock is canceled.
    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  	// WaitAndLock succeeds.
    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  	// WaitAndLock succeeds when the gate is set and the context is canceled.
    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