github.com/weedge/lib@v0.0.0-20230424045628-a36dcc1d90e4/timingwheel/timingwheel_test.go (about)

     1  package timingwheel
     2  
     3  import (
     4  	"testing"
     5  	"time"
     6  )
     7  
     8  func TestTimingWheel_AfterFunc(t *testing.T) {
     9  	tw := NewTimingWheel(time.Millisecond, 20)
    10  	tw.Start()
    11  	defer tw.Stop()
    12  
    13  	durations := []time.Duration{
    14  		1 * time.Millisecond,
    15  		5 * time.Millisecond,
    16  		10 * time.Millisecond,
    17  		50 * time.Millisecond,
    18  		100 * time.Millisecond,
    19  		500 * time.Millisecond,
    20  		1 * time.Second,
    21  	}
    22  	for _, d := range durations {
    23  		t.Run("", func(t *testing.T) {
    24  			exitC := make(chan time.Time)
    25  
    26  			start := time.Now().UTC()
    27  			tw.AfterFunc(d, func() {
    28  				exitC <- time.Now().UTC()
    29  			})
    30  
    31  			got := (<-exitC).Truncate(time.Millisecond)
    32  			min := start.Add(d).Truncate(time.Millisecond)
    33  
    34  			err := 5 * time.Millisecond
    35  			if got.Before(min) || got.After(min.Add(err)) {
    36  				t.Errorf("Timer(%s) expiration: want [%s, %s], got %s", d, min, min.Add(err), got)
    37  			}
    38  		})
    39  	}
    40  }
    41  
    42  type scheduler struct {
    43  	intervals []time.Duration
    44  	current   int
    45  }
    46  
    47  func (s *scheduler) Next(prev time.Time) time.Time {
    48  	if s.current >= len(s.intervals) {
    49  		return time.Time{}
    50  	}
    51  	next := prev.Add(s.intervals[s.current])
    52  	s.current += 1
    53  	return next
    54  }
    55  
    56  func TestTimingWheel_ScheduleFunc(t *testing.T) {
    57  	tw := NewTimingWheel(time.Millisecond, 20)
    58  	tw.Start()
    59  	defer tw.Stop()
    60  
    61  	s := &scheduler{intervals: []time.Duration{
    62  		1 * time.Millisecond,   // start + 1ms
    63  		4 * time.Millisecond,   // start + 5ms
    64  		5 * time.Millisecond,   // start + 10ms
    65  		40 * time.Millisecond,  // start + 50ms
    66  		50 * time.Millisecond,  // start + 100ms
    67  		400 * time.Millisecond, // start + 500ms
    68  		500 * time.Millisecond, // start + 1s
    69  	}}
    70  
    71  	exitC := make(chan time.Time, len(s.intervals))
    72  
    73  	start := time.Now().UTC()
    74  	tw.ScheduleFunc(s, func() {
    75  		exitC <- time.Now().UTC()
    76  	})
    77  
    78  	accum := time.Duration(0)
    79  	for _, d := range s.intervals {
    80  		got := (<-exitC).Truncate(time.Millisecond)
    81  		accum += d
    82  		min := start.Add(accum).Truncate(time.Millisecond)
    83  
    84  		err := 5 * time.Millisecond
    85  		if got.Before(min) || got.After(min.Add(err)) {
    86  			t.Errorf("Timer(%s) expiration: want [%s, %s], got %s", accum, min, min.Add(err), got)
    87  		}
    88  	}
    89  }