76 lines
2.2 KiB
Go
76 lines
2.2 KiB
Go
package rpc
|
||
|
||
import (
|
||
"context"
|
||
"sync"
|
||
"testing"
|
||
"time"
|
||
|
||
"go.uber.org/zap/zaptest"
|
||
)
|
||
|
||
// TestBotAPIEnqueueDispatcherSynchronousBeforeRun 锁定未启动时的同步回退:
|
||
// 测试/未装配场景下 enqueue 行为与旧版完全一致(job 在调用方 goroutine 内即时执行)。
|
||
func TestBotAPIEnqueueDispatcherSynchronousBeforeRun(t *testing.T) {
|
||
d := newBotAPIEnqueueDispatcher(zaptest.NewLogger(t), 4)
|
||
ran := false
|
||
d.Enqueue(context.Background(), func(context.Context) { ran = true })
|
||
if !ran {
|
||
t.Fatal("job must run synchronously before Run is called")
|
||
}
|
||
}
|
||
|
||
// TestBotAPIEnqueueDispatcherFIFOOrder 锁定启动后单 worker FIFO:同一 bot 的
|
||
// update_id 顺序必须与 enqueue 顺序一致(乱序会让 bot 侧 getUpdates 看到错序消息)。
|
||
func TestBotAPIEnqueueDispatcherFIFOOrder(t *testing.T) {
|
||
d := newBotAPIEnqueueDispatcher(zaptest.NewLogger(t), 16)
|
||
ctx, cancel := context.WithCancel(context.Background())
|
||
defer cancel()
|
||
go d.Run(ctx)
|
||
for !d.started.Load() {
|
||
time.Sleep(time.Millisecond)
|
||
}
|
||
|
||
var mu sync.Mutex
|
||
var order []int
|
||
done := make(chan struct{})
|
||
for i := 0; i < 5; i++ {
|
||
i := i
|
||
d.Enqueue(context.Background(), func(context.Context) {
|
||
mu.Lock()
|
||
order = append(order, i)
|
||
if len(order) == 5 {
|
||
close(done)
|
||
}
|
||
mu.Unlock()
|
||
})
|
||
}
|
||
select {
|
||
case <-done:
|
||
case <-time.After(2 * time.Second):
|
||
t.Fatal("jobs did not complete")
|
||
}
|
||
mu.Lock()
|
||
defer mu.Unlock()
|
||
for i, got := range order {
|
||
if got != i {
|
||
t.Fatalf("order = %v, want FIFO", order)
|
||
}
|
||
}
|
||
}
|
||
|
||
// TestBotAPIEnqueueDispatcherFallsBackWhenFull 锁定队列满时的同步回退:Bot API 队列行
|
||
// 是投递真值(无 getDifference 类兜底),满时发送者多等一次 INSERT,绝不丢。
|
||
func TestBotAPIEnqueueDispatcherFallsBackWhenFull(t *testing.T) {
|
||
d := newBotAPIEnqueueDispatcher(zaptest.NewLogger(t), 1)
|
||
d.started.Store(true) // 模拟已启动但 worker 不消费(阻塞场景)
|
||
|
||
// 塞满容量 1 的队列。
|
||
d.Enqueue(context.Background(), func(context.Context) {})
|
||
|
||
ran := false
|
||
d.Enqueue(context.Background(), func(context.Context) { ran = true })
|
||
if !ran {
|
||
t.Fatal("job must fall back to synchronous execution when queue is full")
|
||
}
|
||
}
|