- Event model + ToJSON - EventSink interface + ChannelEventSink (non-blocking Submit) - event_repo: batch INSERT ON CONFLICT DO NOTHING dedup - event_service: 7-type whitelist + 1KB props limit + ReceivedAt auto-fill - event_flusher: 100/1s batch + sync metric_recent_level_ups on level_up - metric_weekly + metric_upcoming workers (5min/15min with pg_try_advisory_lock) - partitioner: 7-day pre-create + 30-day cleanup (00:05 create / 00:30 cleanup) - 22 unit + integration tests (model/repo/service/sink/worker) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
60 lines
1.6 KiB
Go
60 lines
1.6 KiB
Go
package sink
|
||
|
||
import (
|
||
"context"
|
||
"testing"
|
||
"time"
|
||
|
||
"github.com/topfans/backend/services/statisticService/model"
|
||
)
|
||
|
||
func TestChannelEventSink_Submit(t *testing.T) {
|
||
ch := make(chan *model.Event, 10)
|
||
s := NewChannelEventSink(ch)
|
||
e := &model.Event{EventID: "test-1"}
|
||
if err := s.Submit(context.Background(), e); err != nil {
|
||
t.Fatalf("Submit failed: %v", err)
|
||
}
|
||
select {
|
||
case got := <-ch:
|
||
if got.EventID != "test-1" {
|
||
t.Fatal("event mismatch")
|
||
}
|
||
case <-time.After(100 * time.Millisecond):
|
||
t.Fatal("no event received")
|
||
}
|
||
}
|
||
|
||
func TestChannelEventSink_SubmitBatch(t *testing.T) {
|
||
ch := make(chan *model.Event, 10)
|
||
s := NewChannelEventSink(ch)
|
||
events := []*model.Event{{EventID: "a"}, {EventID: "b"}}
|
||
if err := s.SubmitBatch(context.Background(), events); err != nil {
|
||
t.Fatalf("SubmitBatch failed: %v", err)
|
||
}
|
||
if len(ch) != 2 {
|
||
t.Fatalf("expected 2 events, got %d", len(ch))
|
||
}
|
||
}
|
||
|
||
func TestChannelEventSink_ChannelFull(t *testing.T) {
|
||
ch := make(chan *model.Event, 1)
|
||
s := NewChannelEventSink(ch)
|
||
// 第一个事件占用 channel
|
||
if err := s.Submit(context.Background(), &model.Event{EventID: "first"}); err != nil {
|
||
t.Fatalf("first submit failed: %v", err)
|
||
}
|
||
// 第二个应失败(channel 满)
|
||
if err := s.Submit(context.Background(), &model.Event{EventID: "second"}); err != ErrChannelFull {
|
||
t.Fatalf("expected ErrChannelFull, got %v", err)
|
||
}
|
||
}
|
||
|
||
func TestChannelEventSink_NilEvent(t *testing.T) {
|
||
ch := make(chan *model.Event, 10)
|
||
s := NewChannelEventSink(ch)
|
||
if err := s.Submit(context.Background(), nil); err == nil {
|
||
t.Fatal("expected error for nil event")
|
||
}
|
||
}
|