github.com/mutagen-io/mutagen@v0.18.0-rc1/pkg/state/lock_test.go (about)

     1  package state
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  	"time"
     7  )
     8  
     9  func TestTrackingLock(t *testing.T) {
    10  	// Create a tracker.
    11  	tracker := NewTracker()
    12  
    13  	// Wrap it in a tracking lock.
    14  	lock := NewTrackingLock(tracker)
    15  
    16  	// Create a channel for Goroutine communication.
    17  	handoff := make(chan bool)
    18  
    19  	// Start a Goroutine with which we'll coordinate.
    20  	go func() {
    21  		// Wait for a successful change from the initial tracker state (1).
    22  		firstState, err := tracker.WaitForChange(context.Background(), 1)
    23  		if err != nil || firstState != 2 {
    24  			handoff <- false
    25  			return
    26  		}
    27  		handoff <- true
    28  
    29  		// Wait for termination and ensure that the state doesn't change.
    30  		finalState, err := tracker.WaitForChange(context.Background(), firstState)
    31  		handoff <- (finalState == firstState && err == ErrTrackingTerminated)
    32  	}()
    33  
    34  	// Acquire and release the lock in a way that will change the state, and
    35  	// then wait for a response.
    36  	lock.Lock()
    37  	lock.Unlock()
    38  	select {
    39  	case value := <-handoff:
    40  		if !value {
    41  			t.Fatal("received failure on state tracking")
    42  		}
    43  	case <-time.After(trackerTestTimeout):
    44  		t.Fatal("timeout failure on state tracking")
    45  	}
    46  
    47  	// Acquire and release the lock in a way that won't change the state. We
    48  	// don't expect a response here, but our termination response will be
    49  	// invalid if this does change the state.
    50  	lock.Lock()
    51  	lock.UnlockWithoutNotify()
    52  
    53  	// Terminate tracking and wait for a response.
    54  	tracker.Terminate()
    55  	select {
    56  	case value := <-handoff:
    57  		if !value {
    58  			t.Fatal("received failure on tracking termination")
    59  		}
    60  	case <-time.After(trackerTestTimeout):
    61  		t.Fatal("timeout failure on tracking termination")
    62  	}
    63  }