package shutdown import ( "context" "errors" "testing" "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.uber.org/zap" ) func TestNewShutdownManager(t *testing.T) { logger, _ := zap.NewDevelopment() sm := NewShutdownManager(logger) assert.NotNil(t, sm) assert.Equal(t, 0, len(sm.shutdowners)) assert.False(t, sm.shuttingDown) } func TestShutdownManager_Register(t *testing.T) { logger, _ := zap.NewDevelopment() sm := NewShutdownManager(logger) shutdowner := NewShutdownFunc("test_service", func(ctx context.Context) error { return nil }) sm.Register(shutdowner) assert.Equal(t, 1, len(sm.shutdowners)) } func TestShutdownManager_Shutdown_Success(t *testing.T) { logger, _ := zap.NewDevelopment() sm := NewShutdownManager(logger) shutdownCount := 0 shutdowner1 := NewShutdownFunc("service1", func(ctx context.Context) error { shutdownCount++ return nil }) shutdowner2 := NewShutdownFunc("service2", func(ctx context.Context) error { shutdownCount++ return nil }) sm.Register(shutdowner1) sm.Register(shutdowner2) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() err := sm.Shutdown(ctx) require.NoError(t, err) assert.Equal(t, 2, shutdownCount) } func TestShutdownManager_Shutdown_WithError(t *testing.T) { logger, _ := zap.NewDevelopment() sm := NewShutdownManager(logger) shutdowner1 := NewShutdownFunc("service1", func(ctx context.Context) error { return nil }) shutdowner2 := NewShutdownFunc("service2", func(ctx context.Context) error { return errors.New("shutdown error") }) sm.Register(shutdowner1) sm.Register(shutdowner2) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() err := sm.Shutdown(ctx) require.Error(t, err) assert.Contains(t, err.Error(), "shutdown completed with 1 errors") } func TestShutdownManager_Shutdown_Timeout(t *testing.T) { logger, _ := zap.NewDevelopment() sm := NewShutdownManager(logger) shutdowner := NewShutdownFunc("slow_service", func(ctx context.Context) error { // Simuler un service qui prend trop de temps time.Sleep(2 * time.Second) return nil }) sm.Register(shutdowner) ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) defer cancel() err := sm.Shutdown(ctx) // Le timeout devrait être atteint assert.Error(t, err) } func TestShutdownManager_RegisterDuringShutdown(t *testing.T) { logger, _ := zap.NewDevelopment() sm := NewShutdownManager(logger) shutdowner1 := NewShutdownFunc("service1", func(ctx context.Context) error { return nil }) sm.Register(shutdowner1) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() // Démarrer le shutdown dans une goroutine done := make(chan bool) go func() { sm.Shutdown(ctx) done <- true }() // Essayer d'enregistrer pendant le shutdown time.Sleep(10 * time.Millisecond) shutdowner2 := NewShutdownFunc("service2", func(ctx context.Context) error { return nil }) sm.Register(shutdowner2) <-done // Le deuxième service ne devrait pas être arrêté car enregistré pendant le shutdown assert.Equal(t, 1, len(sm.shutdowners)) } func TestShutdownFunc(t *testing.T) { shutdownFunc := NewShutdownFunc("test", func(ctx context.Context) error { return nil }) assert.Equal(t, "test", shutdownFunc.Name()) ctx := context.Background() err := shutdownFunc.Shutdown(ctx) assert.NoError(t, err) }