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 }