mox/autotls/autotls_test.go
Mechiel Lukkien 6706c5c84a
add basic webserver that can do most of what i need
- serve static files, serving index.html or optionally listings for directories
- redirects
- reverse-proxy, forwarding requests to a backend

these are configurable through the config file. a domain and path regexp have to
be configured. path prefixes can be stripped.  configured domains are added to
the autotls allowlist, so acme automatically fetches certificates for them.

all webserver requests now have (access) logging, metrics, rate limiting.
on http errors, the error message prints an encrypted cid for relating with log files.

this also adds a new mechanism for example config files.
2023-02-28 22:19:24 +01:00

97 lines
3.5 KiB
Go

package autotls
import (
"context"
"errors"
"os"
"reflect"
"testing"
"golang.org/x/crypto/acme/autocert"
"github.com/mjl-/mox/dns"
)
func TestAutotls(t *testing.T) {
os.RemoveAll("../testdata/autotls")
os.MkdirAll("../testdata/autotls", 0770)
shutdown := make(chan struct{})
m, err := Load("test", "../testdata/autotls", "mox@localhost", "https://localhost/", 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(map[dns.Domain]struct{}{{ASCII: "mox.example"}: {}})
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(), "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("test", "../testdata/autotls", "mox@localhost", "https://localhost/", 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(map[dns.Domain]struct{}{{ASCII: "mox.example"}: {}})
if err := m.HostPolicy(context.Background(), "mox.example"); err != nil {
t.Fatalf("hostpolicy, got err %v, expected no error", err)
}
m2, err := Load("test2", "../testdata/autotls", "mox@localhost", "https://localhost/", 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")
}