- Modify unit test commands in the Makefile to include additional skip patterns for memory leak tests, improving test coverage and accuracy. - Expand benchmark and memory leak detection to include the event module, ensuring comprehensive testing across all components. - Add new design and TODO documentation files for the event module to facilitate future development.
229 lines
4.7 KiB
Go
229 lines
4.7 KiB
Go
package event_test
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"github.com/yaoapp/yao/event"
|
|
"github.com/yaoapp/yao/event/types"
|
|
)
|
|
|
|
// stubHandler is a minimal Handler for testing registration and lifecycle.
|
|
type stubHandler struct {
|
|
shutdownCalled bool
|
|
}
|
|
|
|
func (h *stubHandler) Handle(ctx context.Context, ev *types.Event, resp chan<- types.Result) {}
|
|
|
|
func (h *stubHandler) Shutdown(ctx context.Context) error {
|
|
h.shutdownCalled = true
|
|
return nil
|
|
}
|
|
|
|
// --- Register + Start/Stop lifecycle ---
|
|
|
|
func TestStartStop_Basic(t *testing.T) {
|
|
event.Reset()
|
|
defer event.Reset()
|
|
|
|
if event.IsStarted() {
|
|
t.Fatal("service should not be started initially")
|
|
}
|
|
|
|
if err := event.Start(); err != nil {
|
|
t.Fatalf("Start failed: %v", err)
|
|
}
|
|
if !event.IsStarted() {
|
|
t.Fatal("service should be started after Start")
|
|
}
|
|
|
|
if err := event.Stop(context.Background()); err != nil {
|
|
t.Fatalf("Stop failed: %v", err)
|
|
}
|
|
if event.IsStarted() {
|
|
t.Fatal("service should not be started after Stop")
|
|
}
|
|
}
|
|
|
|
func TestStart_Double(t *testing.T) {
|
|
event.Reset()
|
|
defer event.Reset()
|
|
|
|
if err := event.Start(); err != nil {
|
|
t.Fatalf("Start failed: %v", err)
|
|
}
|
|
|
|
err := event.Start()
|
|
if err != event.ErrAlreadyStart {
|
|
t.Fatalf("expected ErrAlreadyStart, got: %v", err)
|
|
}
|
|
|
|
_ = event.Stop(context.Background())
|
|
}
|
|
|
|
func TestStop_WhenNotStarted(t *testing.T) {
|
|
event.Reset()
|
|
defer event.Reset()
|
|
|
|
if err := event.Stop(context.Background()); err != nil {
|
|
t.Fatalf("Stop on non-started service should succeed, got: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestReload_WhenNotStarted(t *testing.T) {
|
|
event.Reset()
|
|
defer event.Reset()
|
|
|
|
err := event.Reload()
|
|
if err != event.ErrNotStarted {
|
|
t.Fatalf("expected ErrNotStarted, got: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestReload_WhenStarted(t *testing.T) {
|
|
event.Reset()
|
|
defer event.Reset()
|
|
|
|
_ = event.Start()
|
|
if err := event.Reload(); err != nil {
|
|
t.Fatalf("Reload failed: %v", err)
|
|
}
|
|
_ = event.Stop(context.Background())
|
|
}
|
|
|
|
// --- Register + options ---
|
|
|
|
func TestRegister_DefaultOptions(t *testing.T) {
|
|
event.Reset()
|
|
defer event.Reset()
|
|
|
|
h := &stubHandler{}
|
|
event.Register("test", h)
|
|
|
|
_ = event.Start()
|
|
defer func() { _ = event.Stop(context.Background()) }()
|
|
|
|
if !event.IsStarted() {
|
|
t.Fatal("service should be started")
|
|
}
|
|
}
|
|
|
|
func TestRegister_CustomOptions(t *testing.T) {
|
|
event.Reset()
|
|
defer event.Reset()
|
|
|
|
h := &stubHandler{}
|
|
event.Register("test", h,
|
|
event.MaxWorkers(128),
|
|
event.ReservedWorkers(5),
|
|
event.QueueSize(2048),
|
|
)
|
|
|
|
_ = event.Start()
|
|
defer func() { _ = event.Stop(context.Background()) }()
|
|
|
|
if !event.IsStarted() {
|
|
t.Fatal("service should be started")
|
|
}
|
|
}
|
|
|
|
// --- Stop calls Shutdown on handlers ---
|
|
|
|
func TestStop_CallsHandlerShutdown(t *testing.T) {
|
|
event.Reset()
|
|
defer event.Reset()
|
|
|
|
h := &stubHandler{}
|
|
event.Register("test", h)
|
|
_ = event.Start()
|
|
|
|
if err := event.Stop(context.Background()); err != nil {
|
|
t.Fatalf("Stop failed: %v", err)
|
|
}
|
|
if !h.shutdownCalled {
|
|
t.Fatal("Handler.Shutdown should have been called on Stop")
|
|
}
|
|
}
|
|
|
|
func TestStop_MultipleHandlersShutdown(t *testing.T) {
|
|
event.Reset()
|
|
defer event.Reset()
|
|
|
|
h1 := &stubHandler{}
|
|
h2 := &stubHandler{}
|
|
event.Register("alpha", h1)
|
|
event.Register("bravo", h2)
|
|
_ = event.Start()
|
|
|
|
if err := event.Stop(context.Background()); err != nil {
|
|
t.Fatalf("Stop failed: %v", err)
|
|
}
|
|
if !h1.shutdownCalled || !h2.shutdownCalled {
|
|
t.Fatal("all handlers should have been shut down")
|
|
}
|
|
}
|
|
|
|
// --- Context SID/Auth propagation ---
|
|
|
|
func TestWithSID_SIDFrom(t *testing.T) {
|
|
ctx := event.WithSID(context.Background(), "sess-123")
|
|
got := event.SIDFrom(ctx)
|
|
if got != "sess-123" {
|
|
t.Fatalf("expected sess-123, got %s", got)
|
|
}
|
|
}
|
|
|
|
func TestSIDFrom_Empty(t *testing.T) {
|
|
got := event.SIDFrom(context.Background())
|
|
if got != "" {
|
|
t.Fatalf("expected empty, got %s", got)
|
|
}
|
|
}
|
|
|
|
func TestWithAuth_AuthFrom(t *testing.T) {
|
|
auth := &types.AuthorizedInfo{UserID: "u-1", TeamID: "t-1"}
|
|
ctx := event.WithAuth(context.Background(), auth)
|
|
got := event.AuthFrom(ctx)
|
|
if got == nil {
|
|
t.Fatal("expected non-nil auth")
|
|
}
|
|
if got.UserID != "u-1" || got.TeamID != "t-1" {
|
|
t.Fatalf("unexpected auth: %+v", got)
|
|
}
|
|
}
|
|
|
|
func TestAuthFrom_Nil(t *testing.T) {
|
|
got := event.AuthFrom(context.Background())
|
|
if got != nil {
|
|
t.Fatal("expected nil auth from bare context")
|
|
}
|
|
}
|
|
|
|
func TestWithSIDAndAuth_Combined(t *testing.T) {
|
|
auth := &types.AuthorizedInfo{UserID: "u-2"}
|
|
ctx := event.WithSID(context.Background(), "sess-456")
|
|
ctx = event.WithAuth(ctx, auth)
|
|
|
|
if event.SIDFrom(ctx) != "sess-456" {
|
|
t.Fatal("SID mismatch")
|
|
}
|
|
if event.AuthFrom(ctx).UserID != "u-2" {
|
|
t.Fatal("Auth mismatch")
|
|
}
|
|
}
|
|
|
|
// --- Reset ---
|
|
|
|
func TestReset_ClearsState(t *testing.T) {
|
|
event.Reset()
|
|
|
|
h := &stubHandler{}
|
|
event.Register("test", h)
|
|
_ = event.Start()
|
|
|
|
event.Reset()
|
|
|
|
if event.IsStarted() {
|
|
t.Fatal("service should not be started after Reset")
|
|
}
|
|
}
|