package config import ( "os" "path/filepath" "testing" ) func TestLoadValid(t *testing.T) { dir := t.TempDir() path := filepath.Join(dir, "test.toml") data := ` [database] path = "/tmp/test.db" [[listeners]] addr = ":443" [[listeners.routes]] hostname = "example.com" backend = "127.0.0.1:8443" [proxy] connect_timeout = "5s" idle_timeout = "300s" shutdown_timeout = "30s" [log] level = "info" ` if err := os.WriteFile(path, []byte(data), 0600); err != nil { t.Fatalf("write config: %v", err) } cfg, err := Load(path) if err != nil { t.Fatalf("unexpected error: %v", err) } if len(cfg.Listeners) != 1 { t.Fatalf("got %d listeners, want 1", len(cfg.Listeners)) } if cfg.Listeners[0].Addr != ":443" { t.Fatalf("got listener addr %q, want %q", cfg.Listeners[0].Addr, ":443") } if len(cfg.Listeners[0].Routes) != 1 { t.Fatalf("got %d routes, want 1", len(cfg.Listeners[0].Routes)) } if cfg.Listeners[0].Routes[0].Hostname != "example.com" { t.Fatalf("got hostname %q, want %q", cfg.Listeners[0].Routes[0].Hostname, "example.com") } } func TestLoadNoDatabasePath(t *testing.T) { dir := t.TempDir() path := filepath.Join(dir, "test.toml") data := ` [[listeners]] addr = ":443" [[listeners.routes]] hostname = "example.com" backend = "127.0.0.1:8443" ` if err := os.WriteFile(path, []byte(data), 0600); err != nil { t.Fatalf("write config: %v", err) } _, err := Load(path) if err == nil { t.Fatal("expected error for missing database path") } } func TestLoadNoListenersValid(t *testing.T) { dir := t.TempDir() path := filepath.Join(dir, "test.toml") // No listeners is valid — DB may already have them. data := ` [database] path = "/tmp/test.db" [log] level = "info" ` if err := os.WriteFile(path, []byte(data), 0600); err != nil { t.Fatalf("write config: %v", err) } _, err := Load(path) if err != nil { t.Fatalf("unexpected error: %v", err) } } func TestLoadDuplicateHostnames(t *testing.T) { dir := t.TempDir() path := filepath.Join(dir, "test.toml") data := ` [database] path = "/tmp/test.db" [[listeners]] addr = ":443" [[listeners.routes]] hostname = "example.com" backend = "127.0.0.1:8443" [[listeners.routes]] hostname = "example.com" backend = "127.0.0.1:9443" ` if err := os.WriteFile(path, []byte(data), 0600); err != nil { t.Fatalf("write config: %v", err) } _, err := Load(path) if err == nil { t.Fatal("expected error for duplicate hostnames") } } func TestLoadGeoIPRequiredWithCountries(t *testing.T) { dir := t.TempDir() path := filepath.Join(dir, "test.toml") data := ` [database] path = "/tmp/test.db" [[listeners]] addr = ":443" [[listeners.routes]] hostname = "example.com" backend = "127.0.0.1:8443" [firewall] blocked_countries = ["CN"] ` if err := os.WriteFile(path, []byte(data), 0600); err != nil { t.Fatalf("write config: %v", err) } _, err := Load(path) if err == nil { t.Fatal("expected error for blocked_countries without geoip_db") } } func TestLoadMultipleListeners(t *testing.T) { dir := t.TempDir() path := filepath.Join(dir, "test.toml") data := ` [database] path = "/tmp/test.db" [[listeners]] addr = ":443" [[listeners.routes]] hostname = "public.example.com" backend = "127.0.0.1:8443" [[listeners]] addr = ":8443" [[listeners.routes]] hostname = "internal.example.com" backend = "127.0.0.1:9443" ` if err := os.WriteFile(path, []byte(data), 0600); err != nil { t.Fatalf("write config: %v", err) } cfg, err := Load(path) if err != nil { t.Fatalf("unexpected error: %v", err) } if len(cfg.Listeners) != 2 { t.Fatalf("got %d listeners, want 2", len(cfg.Listeners)) } if cfg.Listeners[0].Routes[0].Hostname != "public.example.com" { t.Fatalf("listener 0 hostname = %q, want %q", cfg.Listeners[0].Routes[0].Hostname, "public.example.com") } if cfg.Listeners[1].Routes[0].Hostname != "internal.example.com" { t.Fatalf("listener 1 hostname = %q, want %q", cfg.Listeners[1].Routes[0].Hostname, "internal.example.com") } } func TestDuration(t *testing.T) { var d Duration if err := d.UnmarshalText([]byte("5s")); err != nil { t.Fatalf("unexpected error: %v", err) } if d.Duration.Seconds() != 5 { t.Fatalf("got %v, want 5s", d.Duration) } }