220 lines
4.0 KiB
Go
220 lines
4.0 KiB
Go
// Copyright 2020-2024 guonaihong, antlabs. All rights reserved.
|
|
//
|
|
// mit license
|
|
package timer
|
|
|
|
import (
|
|
"log"
|
|
"sync"
|
|
"sync/atomic"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func Test_ScheduleFunc(t *testing.T) {
|
|
tm := NewTimer()
|
|
|
|
log.SetFlags(log.Ldate | log.Lmicroseconds)
|
|
count := uint32(0)
|
|
log.Printf("start\n")
|
|
|
|
tm.ScheduleFunc(time.Millisecond*100, func() {
|
|
log.Printf("schedule\n")
|
|
atomic.AddUint32(&count, 1)
|
|
})
|
|
|
|
go func() {
|
|
time.Sleep(570 * time.Millisecond)
|
|
log.Printf("stop\n")
|
|
tm.Stop()
|
|
}()
|
|
|
|
tm.Run()
|
|
if count != 5 {
|
|
t.Errorf("count:%d != 5\n", count)
|
|
}
|
|
|
|
}
|
|
|
|
func Test_AfterFunc(t *testing.T) {
|
|
tm := NewTimer()
|
|
go tm.Run()
|
|
log.Printf("start\n")
|
|
|
|
count := uint32(0)
|
|
tm.AfterFunc(time.Millisecond*20, func() {
|
|
log.Printf("after Millisecond * 20")
|
|
atomic.AddUint32(&count, 1)
|
|
})
|
|
|
|
tm.AfterFunc(time.Second, func() {
|
|
log.Printf("after second")
|
|
atomic.AddUint32(&count, 1)
|
|
})
|
|
|
|
/*
|
|
tm.AfterFunc(time.Minute, func() {
|
|
log.Printf("after Minute")
|
|
})
|
|
*/
|
|
/*
|
|
tm.AfterFunc(time.Hour, nil)
|
|
tm.AfterFunc(time.Hour*24, nil)
|
|
tm.AfterFunc(time.Hour*24*365, nil)
|
|
tm.AfterFunc(time.Hour*24*365*12, nil)
|
|
*/
|
|
|
|
time.Sleep(time.Second + time.Millisecond*100)
|
|
tm.Stop()
|
|
|
|
if count != 2 {
|
|
t.Errorf("count:%d != 2\n", count)
|
|
}
|
|
|
|
}
|
|
|
|
func Test_Node_Stop_1(t *testing.T) {
|
|
tm := NewTimer()
|
|
count := uint32(0)
|
|
node := tm.AfterFunc(time.Millisecond*10, func() {
|
|
atomic.AddUint32(&count, 1)
|
|
})
|
|
go func() {
|
|
time.Sleep(time.Millisecond * 30)
|
|
node.Stop()
|
|
tm.Stop()
|
|
}()
|
|
|
|
tm.Run()
|
|
if count != 1 {
|
|
t.Errorf("count:%d == 1\n", count)
|
|
}
|
|
}
|
|
|
|
func Test_Node_Stop(t *testing.T) {
|
|
tm := NewTimer()
|
|
count := uint32(0)
|
|
node := tm.AfterFunc(time.Millisecond*100, func() {
|
|
atomic.AddUint32(&count, 1)
|
|
})
|
|
node.Stop()
|
|
go func() {
|
|
time.Sleep(time.Millisecond * 200)
|
|
tm.Stop()
|
|
}()
|
|
tm.Run()
|
|
|
|
if count == 1 {
|
|
t.Errorf("count:%d == 1\n", count)
|
|
}
|
|
|
|
}
|
|
|
|
// 测试重置定时器
|
|
func Test_Reset(t *testing.T) {
|
|
t.Run("min heap reset", func(t *testing.T) {
|
|
|
|
tm := NewTimer(WithMinHeap())
|
|
|
|
go tm.Run()
|
|
count := int32(0)
|
|
|
|
tc := make(chan time.Duration, 2)
|
|
|
|
var mu sync.Mutex
|
|
isClose := false
|
|
now := time.Now()
|
|
node1 := tm.AfterFunc(time.Millisecond*100, func() {
|
|
|
|
mu.Lock()
|
|
atomic.AddInt32(&count, 1)
|
|
if atomic.LoadInt32(&count) <= 2 && !isClose {
|
|
tc <- time.Since(now)
|
|
}
|
|
mu.Unlock()
|
|
})
|
|
|
|
node2 := tm.AfterFunc(time.Millisecond*100, func() {
|
|
mu.Lock()
|
|
atomic.AddInt32(&count, 1)
|
|
if atomic.LoadInt32(&count) <= 2 && !isClose {
|
|
tc <- time.Since(now)
|
|
}
|
|
mu.Unlock()
|
|
})
|
|
node1.Reset(time.Millisecond)
|
|
node2.Reset(time.Millisecond)
|
|
|
|
time.Sleep(time.Millisecond * 3)
|
|
mu.Lock()
|
|
isClose = true
|
|
close(tc)
|
|
node1.Stop()
|
|
node2.Stop()
|
|
mu.Unlock()
|
|
for tv := range tc {
|
|
if tv < time.Millisecond || tv > 2*time.Millisecond {
|
|
t.Errorf("tc < time.Millisecond tc > 2*time.Millisecond")
|
|
|
|
}
|
|
}
|
|
if atomic.LoadInt32(&count) != 2 {
|
|
t.Errorf("count:%d != 2", atomic.LoadInt32(&count))
|
|
}
|
|
|
|
})
|
|
|
|
t.Run("time wheel reset", func(t *testing.T) {
|
|
tm := NewTimer()
|
|
|
|
go func() {
|
|
tm.Run()
|
|
}()
|
|
|
|
count := int32(0)
|
|
|
|
tc := make(chan time.Duration, 2)
|
|
|
|
var mu sync.Mutex
|
|
isClose := false
|
|
now := time.Now()
|
|
node1 := tm.AfterFunc(time.Millisecond*10, func() {
|
|
|
|
mu.Lock()
|
|
atomic.AddInt32(&count, 1)
|
|
if atomic.LoadInt32(&count) <= 2 && !isClose {
|
|
tc <- time.Since(now)
|
|
}
|
|
mu.Unlock()
|
|
})
|
|
|
|
node2 := tm.AfterFunc(time.Millisecond*10, func() {
|
|
mu.Lock()
|
|
atomic.AddInt32(&count, 1)
|
|
if atomic.LoadInt32(&count) <= 2 && !isClose {
|
|
tc <- time.Since(now)
|
|
}
|
|
mu.Unlock()
|
|
})
|
|
|
|
node1.Reset(time.Millisecond * 20)
|
|
node2.Reset(time.Millisecond * 20)
|
|
|
|
time.Sleep(time.Millisecond * 40)
|
|
mu.Lock()
|
|
isClose = true
|
|
close(tc)
|
|
node1.Stop()
|
|
node2.Stop()
|
|
mu.Unlock()
|
|
for tv := range tc {
|
|
if tv < time.Millisecond*20 || tv > 2*time.Millisecond*20 {
|
|
t.Errorf("tc < time.Millisecond tc > 2*time.Millisecond")
|
|
}
|
|
}
|
|
if atomic.LoadInt32(&count) != 2 {
|
|
t.Errorf("count:%d != 2", atomic.LoadInt32(&count))
|
|
}
|
|
})
|
|
}
|