251 lines
5.7 KiB
Go
251 lines
5.7 KiB
Go
|
|
package engine
|
||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"sync"
|
||
|
|
"testing"
|
||
|
|
"time"
|
||
|
|
|
||
|
|
"cellbot/internal/protocol"
|
||
|
|
"go.uber.org/zap"
|
||
|
|
)
|
||
|
|
|
||
|
|
func TestEventBus_PublishSubscribe(t *testing.T) {
|
||
|
|
logger := zap.NewNop()
|
||
|
|
eventBus := NewEventBus(logger, 100)
|
||
|
|
eventBus.Start()
|
||
|
|
defer eventBus.Stop()
|
||
|
|
|
||
|
|
// 创建测试事件
|
||
|
|
event := &protocol.BaseEvent{
|
||
|
|
Type: protocol.EventTypeMessage,
|
||
|
|
DetailType: "private",
|
||
|
|
Timestamp: time.Now().Unix(),
|
||
|
|
SelfID: "test_bot",
|
||
|
|
Data: make(map[string]interface{}),
|
||
|
|
}
|
||
|
|
|
||
|
|
// 订阅事件
|
||
|
|
eventChan := eventBus.Subscribe(protocol.EventTypeMessage, nil)
|
||
|
|
|
||
|
|
// 发布事件
|
||
|
|
eventBus.Publish(event)
|
||
|
|
|
||
|
|
// 接收事件
|
||
|
|
select {
|
||
|
|
case receivedEvent := <-eventChan:
|
||
|
|
if receivedEvent.GetType() != protocol.EventTypeMessage {
|
||
|
|
t.Errorf("Expected event type '%s', got '%s'", protocol.EventTypeMessage, receivedEvent.GetType())
|
||
|
|
}
|
||
|
|
case <-time.After(100 * time.Millisecond):
|
||
|
|
t.Error("Timeout waiting for event")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestEventBus_Filter(t *testing.T) {
|
||
|
|
logger := zap.NewNop()
|
||
|
|
eventBus := NewEventBus(logger, 100)
|
||
|
|
eventBus.Start()
|
||
|
|
defer eventBus.Stop()
|
||
|
|
|
||
|
|
// 创建测试事件
|
||
|
|
event1 := &protocol.BaseEvent{
|
||
|
|
Type: protocol.EventTypeMessage,
|
||
|
|
DetailType: "private",
|
||
|
|
Timestamp: time.Now().Unix(),
|
||
|
|
SelfID: "test_bot",
|
||
|
|
Data: make(map[string]interface{}),
|
||
|
|
}
|
||
|
|
|
||
|
|
event2 := &protocol.BaseEvent{
|
||
|
|
Type: protocol.EventTypeMessage,
|
||
|
|
DetailType: "group",
|
||
|
|
Timestamp: time.Now().Unix(),
|
||
|
|
SelfID: "test_bot",
|
||
|
|
Data: make(map[string]interface{}),
|
||
|
|
}
|
||
|
|
|
||
|
|
// 订阅并过滤:只接收private消息
|
||
|
|
filter := func(e protocol.Event) bool {
|
||
|
|
return e.GetDetailType() == "private"
|
||
|
|
}
|
||
|
|
eventChan := eventBus.Subscribe(protocol.EventTypeMessage, filter)
|
||
|
|
|
||
|
|
// 发布两个事件
|
||
|
|
eventBus.Publish(event1)
|
||
|
|
eventBus.Publish(event2)
|
||
|
|
|
||
|
|
// 应该只收到private消息
|
||
|
|
select {
|
||
|
|
case receivedEvent := <-eventChan:
|
||
|
|
if receivedEvent.GetDetailType() != "private" {
|
||
|
|
t.Errorf("Expected detail type 'private', got '%s'", receivedEvent.GetDetailType())
|
||
|
|
}
|
||
|
|
case <-time.After(100 * time.Millisecond):
|
||
|
|
t.Error("Timeout waiting for event")
|
||
|
|
}
|
||
|
|
|
||
|
|
// 不应该再收到第二个事件
|
||
|
|
select {
|
||
|
|
case <-eventChan:
|
||
|
|
t.Error("Should not receive group message")
|
||
|
|
case <-time.After(50 * time.Millisecond):
|
||
|
|
// 正确,不应该收到
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestEventBus_Concurrent(t *testing.T) {
|
||
|
|
logger := zap.NewNop()
|
||
|
|
eventBus := NewEventBus(logger, 10000)
|
||
|
|
eventBus.Start()
|
||
|
|
defer eventBus.Stop()
|
||
|
|
|
||
|
|
numSubscribers := 10
|
||
|
|
numPublishers := 10
|
||
|
|
numEvents := 100
|
||
|
|
|
||
|
|
// 创建多个订阅者
|
||
|
|
subscribers := make([]chan protocol.Event, numSubscribers)
|
||
|
|
for i := 0; i < numSubscribers; i++ {
|
||
|
|
subscribers[i] = eventBus.Subscribe(protocol.EventTypeMessage, nil)
|
||
|
|
}
|
||
|
|
|
||
|
|
var wg sync.WaitGroup
|
||
|
|
wg.Add(numPublishers)
|
||
|
|
|
||
|
|
// 多个发布者并发发布事件
|
||
|
|
for i := 0; i < numPublishers; i++ {
|
||
|
|
go func() {
|
||
|
|
defer wg.Done()
|
||
|
|
for j := 0; j < numEvents; j++ {
|
||
|
|
event := &protocol.BaseEvent{
|
||
|
|
Type: protocol.EventTypeMessage,
|
||
|
|
DetailType: "private",
|
||
|
|
Timestamp: time.Now().Unix(),
|
||
|
|
SelfID: "test_bot",
|
||
|
|
Data: make(map[string]interface{}),
|
||
|
|
}
|
||
|
|
eventBus.Publish(event)
|
||
|
|
}
|
||
|
|
}()
|
||
|
|
}
|
||
|
|
|
||
|
|
wg.Wait()
|
||
|
|
|
||
|
|
// 验证每个订阅者都收到了事件
|
||
|
|
for _, ch := range subscribers {
|
||
|
|
count := 0
|
||
|
|
for count < numPublishers*numEvents {
|
||
|
|
select {
|
||
|
|
case <-ch:
|
||
|
|
count++
|
||
|
|
case <-time.After(500 * time.Millisecond):
|
||
|
|
t.Errorf("Timeout waiting for events, received %d, expected %d", count, numPublishers*numEvents)
|
||
|
|
break
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestEventBus_Benchmark(b *testing.B) {
|
||
|
|
logger := zap.NewNop()
|
||
|
|
eventBus := NewEventBus(logger, 100000)
|
||
|
|
eventBus.Start()
|
||
|
|
defer eventBus.Stop()
|
||
|
|
|
||
|
|
eventChan := eventBus.Subscribe(protocol.EventTypeMessage, nil)
|
||
|
|
|
||
|
|
b.ResetTimer()
|
||
|
|
b.RunParallel(func(pb *testing.PB) {
|
||
|
|
for pb.Next() {
|
||
|
|
event := &protocol.BaseEvent{
|
||
|
|
Type: protocol.EventTypeMessage,
|
||
|
|
DetailType: "private",
|
||
|
|
Timestamp: time.Now().Unix(),
|
||
|
|
SelfID: "test_bot",
|
||
|
|
Data: make(map[string]interface{}),
|
||
|
|
}
|
||
|
|
eventBus.Publish(event)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
// 消耗channel避免阻塞
|
||
|
|
go func() {
|
||
|
|
for range eventChan {
|
||
|
|
}
|
||
|
|
}()
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestDispatcher_HandlerPriority(t *testing.T) {
|
||
|
|
logger := zap.NewNop()
|
||
|
|
eventBus := NewEventBus(logger, 100)
|
||
|
|
dispatcher := NewDispatcher(eventBus, logger)
|
||
|
|
|
||
|
|
// 创建测试处理器
|
||
|
|
handlers := make([]*TestHandler, 3)
|
||
|
|
priorities := []int{3, 1, 2}
|
||
|
|
|
||
|
|
for i, priority := range priorities {
|
||
|
|
handlers[i] = &TestHandler{
|
||
|
|
priority: priority,
|
||
|
|
matched: false,
|
||
|
|
executed: false,
|
||
|
|
}
|
||
|
|
dispatcher.RegisterHandler(handlers[i])
|
||
|
|
}
|
||
|
|
|
||
|
|
// 验证处理器按优先级排序
|
||
|
|
if dispatcher.GetHandlerCount() != 3 {
|
||
|
|
t.Errorf("Expected 3 handlers, got %d", dispatcher.GetHandlerCount())
|
||
|
|
}
|
||
|
|
|
||
|
|
event := &protocol.BaseEvent{
|
||
|
|
Type: protocol.EventTypeMessage,
|
||
|
|
DetailType: "private",
|
||
|
|
Timestamp: time.Now().Unix(),
|
||
|
|
SelfID: "test_bot",
|
||
|
|
Data: make(map[string]interface{}),
|
||
|
|
}
|
||
|
|
|
||
|
|
ctx := context.Background()
|
||
|
|
|
||
|
|
// 分发事件
|
||
|
|
dispatcher.handleEvent(ctx, event)
|
||
|
|
|
||
|
|
// 验证处理器是否按优先级执行
|
||
|
|
executedOrder := make([]int, 0)
|
||
|
|
for _, handler := range handlers {
|
||
|
|
if handler.executed {
|
||
|
|
executedOrder = append(executedOrder, handler.priority)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// 检查是否按升序执行
|
||
|
|
for i := 1; i < len(executedOrder); i++ {
|
||
|
|
if executedOrder[i] < executedOrder[i-1] {
|
||
|
|
t.Errorf("Handlers not executed in priority order: %v", executedOrder)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// TestHandler 测试处理器
|
||
|
|
type TestHandler struct {
|
||
|
|
priority int
|
||
|
|
matched bool
|
||
|
|
executed bool
|
||
|
|
}
|
||
|
|
|
||
|
|
func (h *TestHandler) Handle(ctx context.Context, event protocol.Event) error {
|
||
|
|
h.executed = true
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (h *TestHandler) Priority() int {
|
||
|
|
return h.priority
|
||
|
|
}
|
||
|
|
|
||
|
|
func (h *TestHandler) Match(event protocol.Event) bool {
|
||
|
|
h.matched = true
|
||
|
|
return true
|
||
|
|
}
|