You've already forked coredns-powerdns-api-wrapper
114 lines
3.2 KiB
Go
114 lines
3.2 KiB
Go
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
// Copyright (C) 2026 Bryan Joshua Pedini
|
|
|
|
package main
|
|
|
|
import (
|
|
"os"
|
|
"os/exec"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// TestLoadConfigDefaults exercises the success path in-process: all required
|
|
// vars set, defaults left unset, and asserts the documented defaults.
|
|
func TestLoadConfigDefaults(t *testing.T) {
|
|
t.Setenv("PDNS_API_KEY", "k")
|
|
t.Setenv("MYSQL_DSN", "user:pass@tcp(127.0.0.1:3306)/db")
|
|
t.Setenv("PUID", "1000")
|
|
t.Setenv("PGID", "1000")
|
|
os.Unsetenv("LISTEN_ADDR")
|
|
os.Unsetenv("TABLE_PREFIX")
|
|
os.Unsetenv("DEFAULT_TTL")
|
|
os.Unsetenv("PDNS_SERVER_ID")
|
|
os.Unsetenv("LOG_LEVEL")
|
|
|
|
cfg := LoadConfig()
|
|
|
|
if cfg.ListenAddr != ":3000" {
|
|
t.Errorf("ListenAddr = %q, want :3000", cfg.ListenAddr)
|
|
}
|
|
if cfg.TablePrefix != "coredns_" {
|
|
t.Errorf("TablePrefix = %q, want coredns_", cfg.TablePrefix)
|
|
}
|
|
if cfg.DefaultTTL != 120 {
|
|
t.Errorf("DefaultTTL = %d, want 120", cfg.DefaultTTL)
|
|
}
|
|
if cfg.PDNSServerID != "localhost" {
|
|
t.Errorf("PDNSServerID = %q, want localhost", cfg.PDNSServerID)
|
|
}
|
|
if cfg.LogLevel != "info" {
|
|
t.Errorf("LogLevel = %q, want info", cfg.LogLevel)
|
|
}
|
|
}
|
|
|
|
// TestLoadConfigFatal exercises the os.Exit(1) paths of LoadConfig via a
|
|
// re-exec subprocess, since LoadConfig calls os.Exit directly and cannot be
|
|
// asserted in-process.
|
|
func TestLoadConfigFatal(t *testing.T) {
|
|
baseEnv := map[string]string{
|
|
"PDNS_API_KEY": "k",
|
|
"MYSQL_DSN": "user:pass@tcp(127.0.0.1:3306)/db",
|
|
"PUID": "1000",
|
|
"PGID": "1000",
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
mutate map[string]string // overrides/additions to baseEnv; "" value means unset
|
|
wantInErr string
|
|
}{
|
|
{"missing PDNS_API_KEY", map[string]string{"PDNS_API_KEY": ""}, "PDNS_API_KEY"},
|
|
{"missing MYSQL_DSN", map[string]string{"MYSQL_DSN": ""}, "MYSQL_DSN"},
|
|
{"missing PUID", map[string]string{"PUID": ""}, "PUID"},
|
|
{"missing PGID", map[string]string{"PGID": ""}, "PGID"},
|
|
{"PUID zero rejected", map[string]string{"PUID": "0"}, "root"},
|
|
{"PGID zero rejected", map[string]string{"PGID": "0"}, "root"},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
env := map[string]string{}
|
|
for k, v := range baseEnv {
|
|
env[k] = v
|
|
}
|
|
for k, v := range tt.mutate {
|
|
env[k] = v
|
|
}
|
|
|
|
cmd := exec.Command(os.Args[0], "-test.run=TestConfigFatalHelper")
|
|
cmd.Env = []string{"GO_CONFIG_CRASH=1"}
|
|
for k, v := range env {
|
|
if v != "" {
|
|
cmd.Env = append(cmd.Env, k+"="+v)
|
|
}
|
|
}
|
|
|
|
out, err := cmd.CombinedOutput()
|
|
if err == nil {
|
|
t.Fatalf("expected non-zero exit, got success. output: %s", out)
|
|
}
|
|
exitErr, ok := err.(*exec.ExitError)
|
|
if !ok {
|
|
t.Fatalf("expected *exec.ExitError, got %T: %v", err, err)
|
|
}
|
|
if exitErr.ExitCode() == 0 {
|
|
t.Fatalf("expected non-zero exit code")
|
|
}
|
|
if !strings.Contains(string(out), tt.wantInErr) {
|
|
t.Fatalf("stderr output = %q, want substring %q", out, tt.wantInErr)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestConfigFatalHelper is not a real test; it's invoked as a subprocess by
|
|
// TestLoadConfigFatal via -test.run, guarded by GO_CONFIG_CRASH so it never
|
|
// runs (and never touches the DB) under a normal `go test` invocation.
|
|
func TestConfigFatalHelper(t *testing.T) {
|
|
if os.Getenv("GO_CONFIG_CRASH") == "" {
|
|
t.Skip("only runs as a re-exec subprocess")
|
|
}
|
|
LoadConfig()
|
|
}
|