main pico / pkg / shared / router / router_test.go
Antonio Mika  ·  2026-10-10
 1package router
 2
 3import (
 4	"errors"
 5	"net"
 6	"net/http"
 7	"net/http/httptest"
 8	"testing"
 9)
10
11func TestGetCustomDomainCachesMisses(t *testing.T) {
12	records := map[string][]string{}
13	var lookups int
14	var fail error
15	lookupTXT = func(name string) ([]string, error) {
16		lookups++
17		if fail != nil {
18			return nil, fail
19		}
20		if r, ok := records[name]; ok {
21			return r, nil
22		}
23		return nil, &net.DNSError{Err: "no such host", Name: name, IsNotFound: true}
24	}
25	t.Cleanup(func() {
26		lookupTXT = net.LookupTXT
27		txtCache.Purge()
28		txtMissCache.Purge()
29	})
30
31	if got := GetCustomDomain("example.com", "pgs"); got != "" || lookups != 1 {
32		t.Fatalf("got %q after %d lookups", got, lookups)
33	}
34	if got := GetCustomDomain("example.com", "pgs"); got != "" || lookups != 1 {
35		t.Fatalf("missing record was looked up again: %q after %d lookups", got, lookups)
36	}
37
38	// The uncached lookup sees a record as soon as it exists.
39	records["_pgs.example.com"] = []string{" antonio-blog "}
40	if got, err := LookupCustomDomain("example.com", "pgs"); got != "antonio-blog" || err != nil {
41		t.Fatalf("LookupCustomDomain = %q, %v", got, err)
42	}
43
44	// Failures other than a missing record are not cached.
45	fail = errors.New("i/o timeout")
46	if got := GetCustomDomain("other.com", "pgs"); got != "" {
47		t.Fatalf("got %q", got)
48	}
49	fail = nil
50	records["_pgs.other.com"] = []string{"antonio-other"}
51	if got := GetCustomDomain("other.com", "pgs"); got != "antonio-other" {
52		t.Fatalf("lookup after a transient failure got %q", got)
53	}
54}
55
56func TestNewHostRouter(t *testing.T) {
57	serve := func(name string) http.Handler {
58		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
59			_, _ = w.Write([]byte(name + ":" + GetSubdomain(r)))
60		})
61	}
62	get := func(h http.Handler, url string) string {
63		res := httptest.NewRecorder()
64		h.ServeHTTP(res, httptest.NewRequest(http.MethodGet, url, nil))
65		return res.Body.String()
66	}
67
68	h := NewHostRouter("pico.test", "prose", serve("main"), serve("sites"))
69	if got := get(h, "https://pico.test/"); got != "main:" {
70		t.Errorf("main domain = %q", got)
71	}
72	if got := get(h, "https://tester.pico.test/"); got != "sites:tester" {
73		t.Errorf("subdomain = %q", got)
74	}
75	if got := get(NewHostRouter("pico.test", "prose", serve("main"), nil), "https://tester.pico.test/"); got != "main:" {
76		t.Errorf("subdomain without sites = %q", got)
77	}
78}
79
80func TestCreatePProfRoutesMux(t *testing.T) {
81	mux := http.NewServeMux()
82	CreatePProfRoutesMux(mux)
83	for _, path := range []string{"/debug/pprof/", "/debug/pprof/heap", "/debug/pprof/cmdline"} {
84		res := httptest.NewRecorder()
85		mux.ServeHTTP(res, httptest.NewRequest(http.MethodGet, path, nil))
86		if res.Code != http.StatusOK {
87			t.Errorf("%s = %d", path, res.Code)
88		}
89	}
90}