- server.Config + DefaultConfig + LoadConfig/ParseConfig (yaml.v3) - all operator knobs now configurable: listen addr, audience, data dir, log level, per-IP rate limits, per-subject quota, challenge/session TTLs, max body bytes - server.New takes Config; flags (-addr/-audience/-data/-config) override the file; missing config.yaml falls back to defaults - config.yaml.example committed as template; config.yaml git-ignored - tests for config defaults/parsing/partial override
72 lines
2 KiB
Go
72 lines
2 KiB
Go
package server
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestDefaultConfig(t *testing.T) {
|
|
c := DefaultConfig()
|
|
if c.ListenAddr != ":8080" || c.Audience != "trust.n1ko.dev" {
|
|
t.Fatalf("unexpected defaults: %+v", c)
|
|
}
|
|
if c.PutLimit != 60 || c.PutWindow != time.Minute {
|
|
t.Fatalf("unexpected rate-limit defaults: %+v", c)
|
|
}
|
|
if c.MaxPerSubject != 1000 || c.ChallengeTTL != 5*time.Minute || c.SessionTTL != 30*time.Minute {
|
|
t.Fatalf("unexpected auth defaults: %+v", c)
|
|
}
|
|
}
|
|
|
|
func TestParseConfig(t *testing.T) {
|
|
yaml := []byte(`
|
|
listen_addr: ":9090"
|
|
audience: "relay.example"
|
|
data_dir: "/var/lib/trust"
|
|
log_level: "debug"
|
|
put_limit: 10
|
|
put_window: "2m"
|
|
challenge_limit: 5
|
|
challenge_window: "30s"
|
|
max_per_subject: 50
|
|
challenge_ttl: "1m"
|
|
session_ttl: "10m"
|
|
max_body_bytes: 2048
|
|
`)
|
|
c, err := ParseConfig(yaml)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if c.ListenAddr != ":9090" || c.Audience != "relay.example" || c.DataDir != "/var/lib/trust" || c.LogLevel != "debug" {
|
|
t.Fatalf("scalars not overridden: %+v", c)
|
|
}
|
|
if c.PutLimit != 10 || c.PutWindow != 2*time.Minute {
|
|
t.Fatalf("put limit not parsed: %+v", c)
|
|
}
|
|
if c.ChallengeLimit != 5 || c.ChallengeWindow != 30*time.Second {
|
|
t.Fatalf("challenge limit not parsed: %+v", c)
|
|
}
|
|
if c.MaxPerSubject != 50 || c.ChallengeTTL != time.Minute || c.SessionTTL != 10*time.Minute {
|
|
t.Fatalf("auth knobs not parsed: %+v", c)
|
|
}
|
|
if c.MaxBodyBytes != 2048 {
|
|
t.Fatalf("max_body_bytes not parsed: %+v", c)
|
|
}
|
|
}
|
|
|
|
func TestParseConfigPartial(t *testing.T) {
|
|
// Unset keys fall back to defaults; badly-formatted durations are ignored.
|
|
c, err := ParseConfig([]byte("put_limit: 7\nput_window: \"not-a-duration\"\n"))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if c.PutLimit != 7 {
|
|
t.Fatalf("put_limit should be 7, got %d", c.PutLimit)
|
|
}
|
|
if c.PutWindow != time.Minute {
|
|
t.Fatalf("invalid duration should fall back to default, got %v", c.PutWindow)
|
|
}
|
|
if c.MaxPerSubject != 1000 {
|
|
t.Fatalf("unset max_per_subject should keep default, got %d", c.MaxPerSubject)
|
|
}
|
|
}
|