mox/autotls/autotls_test.go
Mechiel Lukkien a2c79e25c1
check and log errors more often in deferred cleanup calls, and log remote-induced errors at lower priority
We normally check errors for all operations. But for some cleanup calls, eg
"defer file.Close()", we didn't. Now we also check and log most of those.
Partially because those errors can point to some mishandling or unexpected code
paths (eg file unexpected already closed). And in part to make it easier to use
"errcheck" to find the real missing error checks, there is too much noise now.

The log.Check function can now be used unconditionally for checking and logging
about errors. It adjusts the log level if the error is caused by a network
connection being closed, or a context is canceled or its deadline reached, or a
socket deadline is reached.
2025-03-24 14:06:05 +01:00

109 lines
4.0 KiB
Go

package autotls
import (
"context"
"crypto"
"errors"
"fmt"
"os"
"reflect"
"testing"
"github.com/mjl-/autocert"
"github.com/mjl-/mox/dns"
"github.com/mjl-/mox/mlog"
)
func TestAutotls(t *testing.T) {
log := mlog.New("autotls", nil)
os.RemoveAll("../testdata/autotls")
os.MkdirAll("../testdata/autotls", 0770)
shutdown := make(chan struct{})
getPrivateKey := func(host string, keyType autocert.KeyType) (crypto.Signer, error) {
return nil, fmt.Errorf("not used")
}
m, err := Load(log, "test", "../testdata/autotls", "mox@localhost", "https://localhost/", "", nil, getPrivateKey, shutdown)
if err != nil {
t.Fatalf("load manager: %v", err)
}
l := m.Hostnames()
if len(l) != 0 {
t.Fatalf("hostnames, got %v, expected empty list", l)
}
if err := m.HostPolicy(context.Background(), "mox.example"); err == nil || !errors.Is(err, errHostNotAllowed) {
t.Fatalf("hostpolicy, got err %v, expected errHostNotAllowed", err)
}
m.SetAllowedHostnames(log, dns.MockResolver{}, map[dns.Domain]struct{}{{ASCII: "mox.example"}: {}}, nil, false)
l = m.Hostnames()
if !reflect.DeepEqual(l, []dns.Domain{{ASCII: "mox.example"}}) {
t.Fatalf("hostnames, got %v, expected single mox.example", l)
}
if err := m.HostPolicy(context.Background(), "mox.example"); err != nil {
t.Fatalf("hostpolicy, got err %v, expected no error", err)
}
if err := m.HostPolicy(context.Background(), "mox.example:80"); err != nil {
t.Fatalf("hostpolicy, got err %v, expected no error", err)
}
if err := m.HostPolicy(context.Background(), "other.mox.example"); err == nil || !errors.Is(err, errHostNotAllowed) {
t.Fatalf("hostpolicy, got err %v, expected errHostNotAllowed", err)
}
ctx := context.Background()
cache := m.Manager.Cache
if _, err := cache.Get(ctx, "mox.example"); err == nil || !errors.Is(err, autocert.ErrCacheMiss) {
t.Fatalf("cache get for absent entry: got err %v, expected autocert.ErrCacheMiss", err)
}
if err := cache.Put(ctx, "mox.example", []byte("test")); err != nil {
t.Fatalf("cache put for absent entry: got err %v, expected error", err)
}
if data, err := cache.Get(ctx, "mox.example"); err != nil || string(data) != "test" {
t.Fatalf("cache get: got err %v data %q, expected nil, 'test'", err, data)
}
if err := cache.Put(ctx, "mox.example", []byte("test2")); err != nil {
t.Fatalf("cache put for absent entry: got err %v, expected error", err)
}
if data, err := cache.Get(ctx, "mox.example"); err != nil || string(data) != "test2" {
t.Fatalf("cache get: got err %v data %q, expected nil, 'test2'", err, data)
}
if err := cache.Delete(ctx, "mox.example"); err != nil {
t.Fatalf("cache delete: got err %v, expected no error", err)
}
if _, err := cache.Get(ctx, "mox.example"); err == nil || !errors.Is(err, autocert.ErrCacheMiss) {
t.Fatalf("cache get for absent entry: got err %v, expected autocert.ErrCacheMiss", err)
}
close(shutdown)
if err := m.HostPolicy(context.Background(), "mox.example"); err == nil {
t.Fatalf("hostpolicy, got err %v, expected error due to shutdown", err)
}
key0 := m.Manager.Client.Key
m, err = Load(log, "test", "../testdata/autotls", "mox@localhost", "https://localhost/", "", nil, getPrivateKey, shutdown)
if err != nil {
t.Fatalf("load manager again: %v", err)
}
if !reflect.DeepEqual(m.Manager.Client.Key, key0) {
t.Fatalf("private key changed after reload")
}
m.shutdown = make(chan struct{})
m.SetAllowedHostnames(log, dns.MockResolver{}, map[dns.Domain]struct{}{{ASCII: "mox.example"}: {}}, nil, false)
if err := m.HostPolicy(context.Background(), "mox.example"); err != nil {
t.Fatalf("hostpolicy, got err %v, expected no error", err)
}
m2, err := Load(log, "test2", "../testdata/autotls", "mox@localhost", "https://localhost/", "", nil, nil, shutdown)
if err != nil {
t.Fatalf("load another manager: %v", err)
}
if reflect.DeepEqual(m.Manager.Client.Key, m2.Manager.Client.Key) {
t.Fatalf("private key reused between managers")
}
// Only remove in case of success.
os.RemoveAll("../testdata/autotls")
}