smtp2shoutrrr/server_test.go
Full-Stack Developer 8c12783e95
Some checks failed
CI / goreleaser-lint (pull_request) Failing after 37s
CI / format (pull_request) Successful in 1m20s
CI / test (pull_request) Successful in 2m36s
CI / lint (pull_request) Successful in 3m34s
CI / build (pull_request) Has been cancelled
deps: upgrade Go to 1.27.1, refresh dependencies and drop gotoolkit
Replaces the gotoolkit helpers with the standard library and the
libraries they wrapped:

- gotoolkit/encoding TOML wrapper -> pelletier/go-toml/v2 directly,
  behind a new smtp2shoutrrr.LoadConfig shared by both commands.
- gotoolkit/service + gotoolkit/model.Server -> signal.NotifyContext
  and a concrete *Server whose Start shuts the listener down
  gracefully when its context is cancelled.

Also drops the unused ANONYMOUS SASL client from cmd/sendmail, bumps
alpine, golangci-lint and the CI actions, and adds coverage for config
loading and the server lifecycle.

Closes FMG-2

Co-authored-by: multica-agent <github@multica.ai>
2026-09-07 16:28:11 +00:00

64 lines
1.5 KiB
Go

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))
}