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>
64 lines
1.5 KiB
Go
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))
|
|
}
|