This commit is contained in:
Yangxt
2026-09-21 16:46:55 +08:00
parent 01842c59c6
commit ad2b0a7d3e
58 changed files with 6906 additions and 3 deletions
+154
View File
@@ -0,0 +1,154 @@
package config
import (
"os"
"path/filepath"
"strings"
"testing"
)
func writeTempConfig(t *testing.T, body string) string {
t.Helper()
dir := t.TempDir()
path := filepath.Join(dir, "config.yaml")
if err := os.WriteFile(path, []byte(body), 0o600); err != nil {
t.Fatal(err)
}
return path
}
func TestLoadValidConfig(t *testing.T) {
path := writeTempConfig(t, `
listen:
host: 127.0.0.1
port: 13306
local_auth:
username: root
password: "local-secret"
tunnel:
url: "https://example.invalid/ntunnel?token=abc"
remote:
host: mysql
port: 3306
username: remote-root
password: "remote-secret"
database: app
charset: utf8mb4
options:
request_timeout: 15
max_connections: 3
log_level: debug
log_sql: false
`)
cfg, err := Load(path, Overrides{})
if err != nil {
t.Fatalf("Load: %v", err)
}
if cfg.ListenHost != "127.0.0.1" || cfg.ListenPort != 13306 {
t.Fatalf("listen = %s:%d", cfg.ListenHost, cfg.ListenPort)
}
if cfg.RemoteHost != "mysql" || cfg.RemoteUsername != "remote-root" {
t.Fatalf("remote mismatch")
}
if cfg.RequestTimeout.Seconds() != 15 {
t.Fatalf("timeout = %s", cfg.RequestTimeout)
}
}
func TestRejectUnspecifiedListen(t *testing.T) {
path := writeTempConfig(t, `
listen:
host: 0.0.0.0
port: 13306
local_auth:
username: root
password: x
tunnel:
url: "https://example.invalid/?token=t"
remote:
host: mysql
username: root
password: x
`)
_, err := Load(path, Overrides{})
if err == nil || !strings.Contains(err.Error(), "0.0.0.0") {
t.Fatalf("expected unspecified listen error, got %v", err)
}
}
func TestMissingTunnelURL(t *testing.T) {
path := writeTempConfig(t, `
local_auth:
username: root
password: x
remote:
host: mysql
username: root
password: x
`)
_, err := Load(path, Overrides{})
if err == nil || !strings.Contains(err.Error(), "tunnel.url") {
t.Fatalf("expected tunnel.url error, got %v", err)
}
}
func TestCLIOverrides(t *testing.T) {
path := writeTempConfig(t, `
listen:
host: 127.0.0.1
port: 13306
local_auth:
username: root
password: x
tunnel:
url: "https://example.invalid/?token=t"
remote:
host: mysql
username: root
password: x
`)
cfg, err := Load(path, Overrides{ListenHost: "127.0.0.1", ListenPort: 23306})
if err != nil {
t.Fatal(err)
}
if cfg.ListenPort != 23306 {
t.Fatalf("port override failed: %d", cfg.ListenPort)
}
}
func TestRedactedTunnelURL(t *testing.T) {
got := RedactedTunnelURL("https://bth-ntunnel.example/?token=super-secret&x=1")
if strings.Contains(got, "super-secret") {
t.Fatalf("token leaked: %s", got)
}
if !strings.Contains(got, "token=%2A%2A%2A") && !strings.Contains(got, "token=***") {
t.Fatalf("token not redacted: %s", got)
}
}
func TestWarnWhenTokenMissing(t *testing.T) {
path := writeTempConfig(t, `
local_auth:
username: root
password: x
tunnel:
url: "https://example.invalid/ntunnel"
remote:
host: mysql
username: root
password: x
`)
cfg, err := Load(path, Overrides{})
if err != nil {
t.Fatal(err)
}
found := false
for _, w := range cfg.Warnings {
if strings.Contains(w, "token") {
found = true
}
}
if !found {
t.Fatalf("expected token warning, got %#v", cfg.Warnings)
}
}