github.com/asynkron/protoactor-go@v0.0.0-20240308120642-ef91a6abee75/scheduler/timer_test.go (about) 1 package scheduler 2 3 import ( 4 "testing" 5 "time" 6 7 "github.com/asynkron/protoactor-go/actor" 8 "github.com/stretchr/testify/assert" 9 ) 10 11 var system = actor.NewActorSystem() 12 13 func TestNewTimerScheduler(t *testing.T) { 14 newActor := func(t *testing.T, n int) (pid *actor.PID, ch chan struct{}) { 15 ch = make(chan struct{}, n) 16 props := actor.PropsFromFunc(func(c actor.Context) { 17 switch c.Message().(type) { 18 case string: 19 select { 20 case ch <- struct{}{}: 21 default: 22 t.Errorf("exceeeded expected count %d", n) 23 } 24 } 25 }) 26 return system.Root.Spawn(props), ch 27 } 28 29 // check verifies the number of times ch receives a message matches exp 30 // and executes once more to ensure no further messages are received 31 check := func(t *testing.T, ch chan struct{}, cancel CancelFunc, exp int) { 32 got := 0 33 for i := 0; i < exp+1; i++ { 34 select { 35 case <-ch: 36 got++ 37 if got == exp { 38 cancel() 39 } 40 case <-time.After(3 * time.Millisecond): 41 if got != exp { 42 assert.Fail(t, "failed to receive message") 43 } 44 } 45 } 46 cancel() 47 assert.Equal(t, exp, got) 48 } 49 50 t.Run("does", func(t *testing.T) { 51 t.Run("send once", func(t *testing.T) { 52 s := NewTimerScheduler(system.Root) 53 pid, ch := newActor(t, 1) 54 tok := s.SendOnce(1*time.Millisecond, pid, "hello") 55 56 check(t, ch, tok, 1) 57 }) 58 59 t.Run("send repeatedly", func(t *testing.T) { 60 s := NewTimerScheduler(system.Root) 61 pid, ch := newActor(t, 5) 62 tok := s.SendRepeatedly(1*time.Millisecond, 1*time.Millisecond, pid, "hello") 63 check(t, ch, tok, 5) 64 }) 65 66 t.Run("request once", func(t *testing.T) { 67 s := NewTimerScheduler(system.Root) 68 pid, ch := newActor(t, 1) 69 tok := s.RequestOnce(1*time.Millisecond, pid, "hello") 70 71 check(t, ch, tok, 1) 72 }) 73 74 t.Run("request repeatedly", func(t *testing.T) { 75 s := NewTimerScheduler(system.Root) 76 pid, ch := newActor(t, 5) 77 tok := s.RequestRepeatedly(1*time.Millisecond, 1*time.Millisecond, pid, "hello") 78 check(t, ch, tok, 5) 79 }) 80 }) 81 82 t.Run("does not", func(t *testing.T) { 83 t.Run("send once", func(t *testing.T) { 84 s := NewTimerScheduler(system.Root) 85 pid, ch := newActor(t, 1) 86 cancel := s.SendOnce(1*time.Millisecond, pid, "hello") 87 cancel() 88 check(t, ch, cancel, 0) 89 }) 90 91 t.Run("send repeatedly", func(t *testing.T) { 92 s := NewTimerScheduler(system.Root) 93 pid, ch := newActor(t, 5) 94 cancel := s.SendRepeatedly(1*time.Millisecond, 1*time.Millisecond, pid, "hello") 95 cancel() 96 check(t, ch, cancel, 0) 97 }) 98 99 t.Run("request once", func(t *testing.T) { 100 s := NewTimerScheduler(system.Root) 101 pid, ch := newActor(t, 1) 102 cancel := s.RequestOnce(1*time.Millisecond, pid, "hello") 103 cancel() 104 check(t, ch, cancel, 0) 105 }) 106 107 t.Run("request repeatedly", func(t *testing.T) { 108 s := NewTimerScheduler(system.Root) 109 pid, ch := newActor(t, 5) 110 cancel := s.RequestRepeatedly(1*time.Millisecond, 1*time.Millisecond, pid, "hello") 111 cancel() 112 check(t, ch, cancel, 0) 113 }) 114 }) 115 }