github.com/haraldrudell/parl@v0.4.176/win-or-waiter-core_test.go (about) 1 /* 2 © 2022–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/) 3 ISC License 4 */ 5 6 package parl 7 8 import ( 9 "testing" 10 "time" 11 ) 12 13 func TestNewWinOrWaiterCore(t *testing.T) { 14 var winOrWaiterStrategy = WinOrWaiterAnyValue 15 var shortTime = time.Millisecond 16 17 var calculatorInvoked = NewMutexWait() 18 var completeCalculation = NewMutexWait() 19 var calculator = func() (err error) { 20 calculatorInvoked.Unlock() 21 completeCalculation.Wait() 22 return 23 } 24 var calculationReference *Future[time.Time] 25 var result time.Time 26 var isValid bool 27 28 var winOrWaiter *WinOrWaiterCore = NewWinOrWaiterCore(winOrWaiterStrategy, calculator) 29 30 if winOrWaiter.strategy != winOrWaiterStrategy { 31 t.Errorf("bad startegy: %d exp %d", winOrWaiter.strategy, winOrWaiterStrategy) 32 } 33 if winOrWaiter.isCalculationPut.Load() { 34 t.Error("winOrWaiter.isCalculationPut true") 35 } 36 if winOrWaiter.calculation.Load() != nil { 37 t.Error("winOrWaiter.calculation not nil") 38 } 39 if winOrWaiter.winnerPicker.Load() { 40 t.Error("winOrWaiter.winnerPicker true") 41 } 42 43 // first thread gets stuck in calculator func 44 var calculatorThread = NewMutexWait() 45 go func() { 46 defer calculatorThread.Unlock() 47 48 winOrWaiter.WinOrWait() 49 }() 50 t.Log("waiting for calculator invocation…") 51 calculatorInvoked.Wait() 52 53 if !winOrWaiter.isCalculationPut.Load() { 54 t.Error("2 winOrWaiter.isCalculationPut false") 55 } 56 if winOrWaiter.calculation.Load() == nil { 57 t.Error("2 winOrWaiter.calculation nil") 58 } 59 if !winOrWaiter.winnerPicker.Load() { 60 t.Error("2 winOrWaiter.winnerPicker false") 61 } 62 63 // second thread gets stuck in at ww.calculator.RWMutex 64 var loserThread = NewMutexWait() 65 var loserThreadUp = NewMutexWait() 66 go func() { 67 defer loserThread.Unlock() 68 69 loserThreadUp.Unlock() 70 winOrWaiter.WinOrWait() 71 }() 72 t.Log("waiting for loser thread…") 73 loserThreadUp.Wait() 74 75 time.Sleep(shortTime) 76 77 if calculatorThread.IsUnlocked() { 78 t.Error("calculatorThread exited too soon") 79 } 80 if loserThread.IsUnlocked() { 81 t.Error("loserThread exited too soon") 82 } 83 84 completeCalculation.Unlock() 85 86 calculatorThread.Wait() 87 loserThread.Wait() 88 89 calculationReference = winOrWaiter.calculation.Load() 90 if calculationReference == nil { 91 t.Error("3 winOrWaiter.calculation.Get nil") 92 t.FailNow() 93 } 94 if !calculationReference.IsCompleted() { 95 t.Error("3 calculationReference.IsCompleted false") 96 } 97 result, isValid = calculationReference.Result() 98 if !isValid { 99 t.Error("3 isValid false") 100 } 101 if result.IsZero() { 102 t.Error("3 result IsZero") 103 } 104 if winOrWaiter.winnerPicker.Load() { 105 t.Error("3 winOrWaiter.winnerPicker true") 106 } 107 }