feat: mail service
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"galaxy/mail/internal/config"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestAppRunStopsComponentsOnContextCancellation(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
component := &blockingComponent{}
|
||||
app := New(config.Config{ShutdownTimeout: time.Second}, component)
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
done := make(chan error, 1)
|
||||
go func() {
|
||||
done <- app.Run(ctx)
|
||||
}()
|
||||
|
||||
require.Eventually(t, func() bool {
|
||||
component.mu.Lock()
|
||||
defer component.mu.Unlock()
|
||||
return component.runStarted
|
||||
}, time.Second, 10*time.Millisecond)
|
||||
|
||||
cancel()
|
||||
|
||||
require.Eventually(t, func() bool {
|
||||
select {
|
||||
case err := <-done:
|
||||
return err == nil
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}, time.Second, 10*time.Millisecond)
|
||||
require.Equal(t, 1, component.shutdownCalls)
|
||||
}
|
||||
|
||||
func TestAppRunReportsEarlyComponentExit(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
app := New(config.Config{ShutdownTimeout: time.Second}, componentFunc(func(context.Context) error {
|
||||
return nil
|
||||
}))
|
||||
|
||||
err := app.Run(context.Background())
|
||||
require.Error(t, err)
|
||||
require.Contains(t, err.Error(), "exited without error before shutdown")
|
||||
}
|
||||
|
||||
type blockingComponent struct {
|
||||
mu sync.Mutex
|
||||
runStarted bool
|
||||
shutdownCalls int
|
||||
}
|
||||
|
||||
func (component *blockingComponent) Run(ctx context.Context) error {
|
||||
component.mu.Lock()
|
||||
component.runStarted = true
|
||||
component.mu.Unlock()
|
||||
|
||||
<-ctx.Done()
|
||||
return ctx.Err()
|
||||
}
|
||||
|
||||
func (component *blockingComponent) Shutdown(context.Context) error {
|
||||
component.shutdownCalls++
|
||||
return nil
|
||||
}
|
||||
|
||||
type componentFunc func(context.Context) error
|
||||
|
||||
func (fn componentFunc) Run(ctx context.Context) error {
|
||||
return fn(ctx)
|
||||
}
|
||||
|
||||
func (fn componentFunc) Shutdown(context.Context) error {
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user