timer/timer_test.go

138 lines
2.7 KiB
Go

package timer
import (
"errors"
"testing"
"time"
)
func TestTracker(t *testing.T) {
tk := Start()
time.Sleep(10 * time.Millisecond)
tk.Record("step1")
time.Sleep(20 * time.Millisecond)
tk.Record("step2")
laps := tk.Summarize()
if len(laps) != 2 {
t.Errorf("expected 2 laps, got %d", len(laps))
}
if laps[0].Label != "step1" || laps[1].Label != "step2" {
t.Errorf("invalid lap labels")
}
desc := tk.Describe()
if desc == "" {
t.Error("description should not be empty")
}
t.Log(desc)
}
func TestRetry(t *testing.T) {
count := 0
err := Retry(func() error {
count++
if count < 3 {
return errors.New("fail")
}
return nil
}, WithMaxRetries(3), WithBackoff(10*time.Millisecond, 2.0))
if err != nil {
t.Errorf("expected success, got %v", err)
}
if count != 3 {
t.Errorf("expected 3 attempts, got %d", count)
}
count = 0
err = Retry(func() error {
count++
return errors.New("always fail")
}, WithMaxRetries(2), WithBackoff(5*time.Millisecond, 2.0))
if err == nil {
t.Error("expected error, got nil")
}
if count != 3 { // 0, 1, 2 = 3 times
t.Errorf("expected 3 attempts, got %d", count)
}
}
func TestTimeWheel(t *testing.T) {
tw := NewTimeWheel(10*time.Millisecond, 10)
tw.Start()
defer tw.Stop()
done := make(chan bool)
start := time.Now()
tw.AfterFunc(50*time.Millisecond, func() {
duration := time.Since(start)
if duration < 40*time.Millisecond {
t.Errorf("too early: %v", duration)
}
done <- true
})
select {
case <-done:
// success
case <-time.After(200 * time.Millisecond):
t.Fatal("timeout")
}
}
func TestFlow(t *testing.T) {
// Debounce test
count := 0
d := NewDebouncer(20*time.Millisecond, func() {
count++
})
d.Trigger()
d.Trigger()
d.Trigger()
time.Sleep(50 * time.Millisecond)
if count != 1 {
t.Errorf("debounce failed, count: %d", count)
}
// Throttle test
count = 0
tr := NewThrottler(20*time.Millisecond, func() {
count++
})
tr.Trigger()
tr.Trigger()
tr.Trigger()
time.Sleep(10 * time.Millisecond)
if count != 1 {
t.Errorf("throttle initial failed, count: %d", count)
}
time.Sleep(30 * time.Millisecond)
tr.Trigger()
time.Sleep(10 * time.Millisecond)
if count != 2 {
t.Errorf("throttle interval failed, count: %d", count)
}
}
func TestRunTimeout(t *testing.T) {
res, err := RunTimeout(50*time.Millisecond, func(tk *Tracker) (string, error) {
tk.Record("start")
time.Sleep(10 * time.Millisecond)
tk.Record("middle")
return "ok", nil
})
if err != nil || res != "ok" {
t.Errorf("RunTimeout failed: %v, %v", res, err)
}
_, err = RunTimeout(20*time.Millisecond, func(tk *Tracker) (string, error) {
time.Sleep(50 * time.Millisecond)
return "late", nil
})
if err != ErrTimeout {
t.Errorf("expected ErrTimeout, got %v", err)
}
}