github.com/mutagen-io/mutagen@v0.18.0-rc1/pkg/state/tracker_test.go (about) 1 package state 2 3 import ( 4 "context" 5 "testing" 6 "time" 7 ) 8 9 // trackerTestTimeout prevents tracker tests from timing out. It also sets an 10 // indirect performance boundary on update detection time. 11 const trackerTestTimeout = 1 * time.Second 12 13 // TestTracker tests Tracker. 14 func TestTracker(t *testing.T) { 15 // Create a tracker. 16 tracker := NewTracker() 17 18 // Create a channel for Goroutine communication. 19 handoff := make(chan bool) 20 21 // Create a cancellable context that we can use to tracking testing. Ensure 22 // that it's cancelled by the time we return, just in case it isn't 23 // cancelled during testing. 24 ctx, cancel := context.WithCancel(context.Background()) 25 defer cancel() 26 27 // Start a Goroutine with which we'll coordinate. 28 go func() { 29 // Wait indefinitely for a successful change from the initial tracker 30 // state (1). 31 firstState, err := tracker.WaitForChange(context.Background(), 1) 32 if err != nil || firstState != 2 { 33 handoff <- false 34 return 35 } 36 handoff <- true 37 38 // Perform a preempted wait and ensure that the state doesn't change. 39 secondState, err := tracker.WaitForChange(ctx, firstState) 40 if err != context.Canceled || secondState != firstState { 41 handoff <- false 42 return 43 } 44 handoff <- true 45 46 // Wait for termination and ensure that the state doesn't change. 47 finalState, err := tracker.WaitForChange(context.Background(), secondState) 48 handoff <- (finalState == firstState && err == ErrTrackingTerminated) 49 }() 50 51 // Notify of a change and wait for a response. 52 tracker.NotifyOfChange() 53 select { 54 case value := <-handoff: 55 if !value { 56 t.Fatal("received failure on state tracking") 57 } 58 case <-time.After(trackerTestTimeout): 59 t.Fatal("timeout failure on state tracking") 60 } 61 62 // Cancel the polling context and wait for a response. 63 cancel() 64 select { 65 case value := <-handoff: 66 if !value { 67 t.Fatal("received failure on state tracking with cancellation") 68 } 69 case <-time.After(trackerTestTimeout): 70 t.Fatal("timeout failure on state tracking with cancellation") 71 } 72 73 // Terminate tracking and wait for a response. 74 tracker.Terminate() 75 select { 76 case value := <-handoff: 77 if !value { 78 t.Fatal("received failure on tracking termination") 79 } 80 case <-time.After(trackerTestTimeout): 81 t.Fatal("timeout failure on tracking termination") 82 } 83 }