Files
bl/common/utils/timer/time_wheel_test.go

190 lines
3.6 KiB
Go
Raw Normal View History

// Copyright 2020-2024 guonaihong, antlabs. All rights reserved.
//
// mit license
package timer
import (
"context"
"math"
"sync/atomic"
"testing"
"time"
)
func Test_maxVal(t *testing.T) {
if maxVal() != uint64(math.MaxUint32) {
t.Error("maxVal() != uint64(math.MaxUint32)")
}
}
func Test_LevelMax(t *testing.T) {
if levelMax(1) != uint64(1<<(nearShift+levelShift)) {
t.Error("levelMax(1) != uint64(1<<(nearShift+levelShift))")
}
if levelMax(2) != uint64(1<<(nearShift+2*levelShift)) {
t.Error("levelMax(2) != uint64(1<<(nearShift+2*levelShift))")
}
if levelMax(3) != uint64(1<<(nearShift+3*levelShift)) {
t.Error("levelMax(3) != uint64(1<<(nearShift+3*levelShift))")
}
if levelMax(4) != uint64(1<<(nearShift+4*levelShift)) {
t.Error("levelMax(4) != uint64(1<<(nearShift+4*levelShift))")
}
}
func Test_GenVersion(t *testing.T) {
if genVersionHeight(1, 0xf) != uint64(0x0001000f00000000) {
t.Error("genVersionHeight(1, 0xf) != uint64(0x0001000f00000000)")
}
if genVersionHeight(1, 64) != uint64(0x0001004000000000) {
t.Error("genVersionHeight(2, 0xf) != uint64(0x0001004000000000)")
}
}
// 测试1小时
func Test_hour(t *testing.T) {
tw := newTimeWheel()
testHour := new(bool)
done := make(chan struct{}, 1)
tw.AfterFunc(time.Hour, func() {
*testHour = true
done <- struct{}{}
})
expire := getExpire(time.Hour, 0)
for i := 0; i < int(expire)+10; i++ {
get10Ms := func() time.Duration {
return tw.curTimePoint + 1
}
tw.run(get10Ms)
}
select {
case <-done:
case <-time.After(time.Second / 100):
}
if *testHour == false {
t.Error("testHour == false")
}
}
// 测试周期性定时器, 5s
func Test_ScheduleFunc_5s(t *testing.T) {
tw := newTimeWheel()
var first5 int32
ctx, cancel := context.WithCancel(context.Background())
const total = int32(1000)
testTime := time.Second * 5
tw.ScheduleFunc(testTime, func() {
atomic.AddInt32(&first5, 1)
if atomic.LoadInt32(&first5) == total {
cancel()
}
})
expire := getExpire(testTime*time.Duration(total), 0)
for i := 0; i <= int(expire)+10; i++ {
get10Ms := func() time.Duration {
return tw.curTimePoint + 1
}
tw.run(get10Ms)
}
select {
case <-ctx.Done():
case <-time.After(time.Second / 100):
}
if total != first5 {
t.Errorf("total:%d != first5:%d\n", total, first5)
}
}
// 测试周期性定时器, 1hour
func Test_ScheduleFunc_hour(t *testing.T) {
tw := newTimeWheel()
var first5 int32
ctx, cancel := context.WithCancel(context.Background())
const total = int32(100)
testTime := time.Hour
tw.ScheduleFunc(testTime, func() {
atomic.AddInt32(&first5, 1)
if atomic.LoadInt32(&first5) == total {
cancel()
}
})
expire := getExpire(testTime*time.Duration(total), 0)
for i := 0; i <= int(expire)+10; i++ {
get10Ms := func() time.Duration {
return tw.curTimePoint + 1
}
tw.run(get10Ms)
}
select {
case <-ctx.Done():
case <-time.After(time.Second / 100):
}
if total != first5 {
t.Errorf("total:%d != first5:%d\n", total, first5)
}
}
// 测试周期性定时器, 1day
func Test_ScheduleFunc_day(t *testing.T) {
tw := newTimeWheel()
var first5 int32
ctx, cancel := context.WithCancel(context.Background())
const total = int32(10)
testTime := time.Hour * 24
tw.ScheduleFunc(testTime, func() {
atomic.AddInt32(&first5, 1)
if atomic.LoadInt32(&first5) == total {
cancel()
}
})
expire := getExpire(testTime*time.Duration(total), 0)
for i := 0; i <= int(expire)+10; i++ {
get10Ms := func() time.Duration {
return tw.curTimePoint + 1
}
tw.run(get10Ms)
}
select {
case <-ctx.Done():
case <-time.After(time.Second / 100):
}
if total != first5 {
t.Errorf("total:%d != first5:%d\n", total, first5)
}
}