1
0
mirror of https://blitiri.com.ar/repos/chasquid synced 2026-10-28 15:02:28 +00:00
Files
go-chasquid-smtp/internal/config/config_test.go
T
Alberto Bertogli 8b19760f4e test: Use modern testing features instead of custom helpers
Many of our tests rely on helpers that predate features which are now
available in the standard library.

This patch replaces them with the standard equivalents:

- MustTempDir/RemoveIfOk -> t.ArtifactDir() or t.TempDir() (depending on
  whether it is useful to keep the data on request).
- GetFreePort + waitForServer -> opening the listeners before starting
  the servers. To support this, localrpc.Server gains a Serve method. We
  may re-introduce these in the future if more use cases appear.
- WaitFor and real-time timing checks -> testing/synctest.
- context.Background() -> t.Context().
- Benchmark b.N loops -> b.Loop().
- reflect.DeepEqual -> cmp.Diff, and proto.Equal for protobufs.
2026-10-03 10:34:35 +01:00

160 lines
3.3 KiB
Go

package config
import (
"io"
"os"
"testing"
"blitiri.com.ar/go/log"
"github.com/google/go-cmp/cmp"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/testing/protocmp"
)
func mustCreateConfig(t *testing.T, contents string) string {
t.Helper()
path := t.ArtifactDir() + "/chasquid.conf"
err := os.WriteFile(path, []byte(contents), 0600)
if err != nil {
t.Fatalf("Failed to write tmp config: %v", err)
}
return path
}
func TestEmptyStruct(t *testing.T) {
testLogConfig(&Config{})
}
func TestEmptyConfig(t *testing.T) {
path := mustCreateConfig(t, "")
c, err := Load(path, "")
if err != nil {
t.Fatalf("error loading empty config: %v", err)
}
// Test the default values are set.
defaults := proto.Clone(defaultConfig).(*Config)
hostname, _ := os.Hostname()
defaults.Hostname = hostname
diff := cmp.Diff(defaults, c, protocmp.Transform())
if diff != "" {
t.Errorf("Load() mismatch (-want +got):\n%s", diff)
}
testLogConfig(c)
}
func TestFullConfig(t *testing.T) {
confStr := `
hostname: "joust"
smtp_address: ":1234"
smtp_address: ":5678"
submission_address: ":10001"
submission_address: ":10002"
monitoring_address: ":1111"
max_data_size_mb: 26
suffix_separators: ""
max_queue_items: 345
`
path := mustCreateConfig(t, confStr)
overrideStr := `
hostname: "proust"
submission_address: ":999"
dovecot_auth: true
drop_characters: ""
give_up_send_after: "7h"
`
expected := &Config{
Hostname: "proust",
MaxDataSizeMb: 26,
SmtpAddress: []string{":1234", ":5678"},
SubmissionAddress: []string{":999"},
SubmissionOverTlsAddress: []string{"systemd"},
MonitoringAddress: ":1111",
MailDeliveryAgentBin: "maildrop",
MailDeliveryAgentArgs: []string{"-f", "%from%", "-d", "%to_user%"},
DataDir: "/var/lib/chasquid",
SuffixSeparators: new(""),
DropCharacters: new(""),
MailLogPath: "<syslog>",
DovecotAuth: true,
MaxQueueItems: 345,
GiveUpSendAfter: "7h",
}
c, err := Load(path, overrideStr)
if err != nil {
t.Fatalf("error loading non-existent config: %v", err)
}
diff := cmp.Diff(expected, c, protocmp.Transform())
if diff != "" {
t.Errorf("Load() mismatch (-want +got):\n%s", diff)
}
testLogConfig(c)
}
func TestErrorLoading(t *testing.T) {
c, err := Load("/does/not/exist", "")
if err == nil {
t.Fatalf("loaded a non-existent config: %v", c)
}
}
func TestBrokenConfig(t *testing.T) {
path := mustCreateConfig(
t, "<invalid> this is not a valid protobuf")
c, err := Load(path, "")
if err == nil {
t.Fatalf("loaded an invalid config: %v", c)
}
}
func TestBrokenOverride(t *testing.T) {
path := mustCreateConfig(
t, `hostname: "test"`)
c, err := Load(path, "broken override")
if err == nil {
t.Fatalf("loaded an invalid config: %v", c)
}
}
func TestInvalidGiveUpSendingAfter(t *testing.T) {
path := mustCreateConfig(
t, `give_up_send_after: "10"`)
c, err := Load(path, "")
if err == nil {
t.Fatalf("loaded an invalid config: %v", c)
}
}
// Run LogConfig, overriding the default logger first. This exercises the
// code, we don't yet validate the output, but it is an useful sanity check.
func testLogConfig(c *Config) {
l := log.New(nopWCloser{io.Discard})
log.Default = l
LogConfig(c)
}
type nopWCloser struct {
io.Writer
}
func (nopWCloser) Close() error { return nil }