Some checks failed
CI / Run tests and lints (push) Failing after 29s
CI / Build CLI docs (push) Has been skipped
CI / Run Playwright end-to-end tests (mysql) (push) Failing after 3s
CI / Run Playwright end-to-end tests (postgres) (push) Failing after 2s
CI / Run Playwright end-to-end tests (sqlite) (push) Failing after 3s
CodeQL / Analyze (go) (push) Failing after 4s
CodeQL / Analyze (javascript) (push) Failing after 3s
Docker Image Scanners / scanners (push) Failing after 4s
Synchronize Issue Labels / Synchronize Issue Labels (push) Has been skipped
CI / Run end-to-end tests (postgres) (push) Failing after 19s
CI / Run end-to-end tests (sqlite) (push) Failing after 2s
CI / Run Playwright end-to-end tests (cockroach) (push) Failing after 2s
CI / Draft newsletter (push) Has been skipped
CI / Generate release (push) Has been skipped
CI / Pending approval Slack notification (push) Has been skipped
CI / Send newsletter (push) Has been skipped
107 lines
2.5 KiB
Go
107 lines
2.5 KiB
Go
// Copyright © 2023 Ory Corp
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package testhelpers
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
stdlog "log"
|
|
"net"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"github.com/gorilla/pat"
|
|
"github.com/ian-kent/go-log/levels"
|
|
"github.com/ian-kent/go-log/log"
|
|
"github.com/mailhog/MailHog-Server/api"
|
|
mailhogconf "github.com/mailhog/MailHog-Server/config"
|
|
"github.com/mailhog/MailHog-Server/monkey"
|
|
"github.com/mailhog/MailHog-Server/smtp"
|
|
"github.com/mailhog/data"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
xmailhog "github.com/ory/x/mailhog"
|
|
)
|
|
|
|
// StartMailhog starts a MailHog server for testing purposes.
|
|
// It returns the SMTP connection URL and the API URL.
|
|
// If withChaosMonkey is true, the SMTP server will randomly drop connections and simulate network issues.
|
|
func StartMailhog(t testing.TB, withChaosMonkey bool) (smtpAddr, apiAddr string) {
|
|
t.Helper()
|
|
|
|
// hacky but should silence most MailHog logs during tests
|
|
log.Logger().SetLevel(levels.FATAL)
|
|
stdlog.Default().SetOutput(io.Discard)
|
|
|
|
apiconf := &mailhogconf.Config{
|
|
Storage: xmailhog.NewInMemory(),
|
|
MessageChan: make(chan *data.Message),
|
|
}
|
|
if withChaosMonkey {
|
|
jim := &monkey.Jim{
|
|
DisconnectChance: 0.005,
|
|
AcceptChance: 0.99,
|
|
LinkSpeedAffect: 0.05,
|
|
LinkSpeedMin: 1250,
|
|
LinkSpeedMax: 12500,
|
|
RejectAuthChance: 0.05,
|
|
|
|
// important: set to 0 to avoid flakes in tests, because those errors are not retryable
|
|
RejectSenderChance: 0,
|
|
RejectRecipientChance: 0,
|
|
}
|
|
jim.Configure(t.Logf)
|
|
apiconf.Monkey = jim
|
|
}
|
|
|
|
ln, err := net.Listen("tcp", "127.0.0.1:0")
|
|
require.NoError(t, err)
|
|
t.Cleanup(func() { _ = ln.Close() })
|
|
go serveSMTP(t.Context(), ln, apiconf)
|
|
|
|
r := pat.New()
|
|
api.CreateAPI(apiconf, r)
|
|
s := httptest.NewServer(r)
|
|
t.Cleanup(s.Close)
|
|
|
|
return fmt.Sprintf("smtp://%s?disable_starttls=true", ln.Addr().String()), s.URL
|
|
}
|
|
|
|
func serveSMTP(ctx context.Context, ln net.Listener, cfg *mailhogconf.Config) {
|
|
for {
|
|
select {
|
|
case <-ctx.Done():
|
|
return
|
|
default:
|
|
conn, err := ln.Accept()
|
|
if errors.Is(err, net.ErrClosed) {
|
|
return
|
|
}
|
|
if err != nil {
|
|
fmt.Printf("[SMTP] Error accepting connection: %s\n", err)
|
|
continue
|
|
}
|
|
|
|
if cfg.Monkey != nil {
|
|
ok := cfg.Monkey.Accept(conn)
|
|
if !ok {
|
|
_ = conn.Close()
|
|
continue
|
|
}
|
|
}
|
|
|
|
go smtp.Accept(
|
|
conn.(*net.TCPConn).RemoteAddr().String(),
|
|
io.ReadWriteCloser(conn),
|
|
cfg.Storage,
|
|
cfg.MessageChan,
|
|
cfg.Hostname,
|
|
cfg.Monkey,
|
|
)
|
|
}
|
|
}
|
|
}
|