package smtp2shoutrrr import ( "context" "fmt" "net" "testing" "time" "github.com/stretchr/testify/require" ) func dialSMTP(t *testing.T, port int) (net.Conn, error) { t.Helper() return net.DialTimeout("tcp", fmt.Sprintf("localhost:%d", port), 200*time.Millisecond) } func TestServerShutsDownOnContextCancel(t *testing.T) { config := &Config{Port: 2530, Username: "testuser", Password: "testpass"} server := NewSMTPServer(config) ctx, cancel := context.WithCancel(context.Background()) t.Cleanup(cancel) stopped := make(chan error, 1) go func() { stopped <- server.Start(ctx) }() require.Eventually(t, func() bool { conn, err := dialSMTP(t, config.Port) if err != nil { return false } require.NoError(t, conn.Close()) return true }, 5*time.Second, 20*time.Millisecond, "server never started listening") cancel() select { case err := <-stopped: require.NoError(t, err) case <-time.After(shutdownTimeout + time.Second): t.Fatal("server did not shut down after context cancellation") } _, err := dialSMTP(t, config.Port) require.Error(t, err, "listener should be released once Start returns") } func TestServerStartReturnsListenError(t *testing.T) { config := &Config{Port: 2531, Username: "testuser", Password: "testpass"} blocker, err := net.Listen("tcp", fmt.Sprintf(":%d", config.Port)) require.NoError(t, err) t.Cleanup(func() { _ = blocker.Close() }) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) t.Cleanup(cancel) require.Error(t, NewSMTPServer(config).Start(ctx)) }