feat: 支持从 config.yaml 读取 MySQL 配置 (#83)

This commit is contained in:
chengma
2026-08-10 09:24:04 +08:00
parent ad44c3ee86
commit 04a777dc8e
9 changed files with 222 additions and 35 deletions
+89
View File
@@ -36,6 +36,95 @@ func TestLoadDatabaseFromEnv_缺少必填项时只报变量名(t *testing.T) {
}
}
func TestLoadDatabaseFromPath_可以只用YAML配置(t *testing.T) {
clearDatabaseEnv(t)
path := writeConfigFile(t, `
database:
host: 127.0.0.1
port: "13307"
name: autobuy
user: buy
password: "yaml-secret"
`)
cfg, err := loadDatabaseFromPath(path)
if err != nil {
t.Fatal(err)
}
if cfg.Host != "127.0.0.1" || cfg.Port != "13307" || cfg.Name != "autobuy" || cfg.User != "buy" {
t.Fatalf("YAML 数据库配置读取错误:%s", cfg)
}
if cfg.Password != "yaml-secret" {
t.Fatal("YAML 数据库密码没有原样读出")
}
}
func TestLoadDatabaseFromPath_环境变量按字段覆盖YAML(t *testing.T) {
clearDatabaseEnv(t)
t.Setenv(databasePortEnv, "23307")
t.Setenv(databaseUserEnv, "env-user")
t.Setenv(databasePasswordEnv, "env-secret")
path := writeConfigFile(t, `
database:
host: 127.0.0.1
port: "13307"
name: autobuy
user: yaml-user
password: "yaml-secret"
`)
cfg, err := loadDatabaseFromPath(path)
if err != nil {
t.Fatal(err)
}
if cfg.Host != "127.0.0.1" || cfg.Name != "autobuy" {
t.Fatalf("未覆盖字段应该保留 YAML 值:%s", cfg)
}
if cfg.Port != "23307" || cfg.User != "env-user" || cfg.Password != "env-secret" {
t.Fatalf("环境变量没有按字段覆盖 YAML:%s", cfg)
}
if strings.Contains(cfg.String(), "env-secret") || strings.Contains(cfg.String(), "yaml-secret") {
t.Fatalf("配置字符串泄露密码:%s", cfg)
}
}
func TestLoadDatabaseFromPath_文件不存在时完整环境变量仍可启动(t *testing.T) {
clearDatabaseEnv(t)
t.Setenv(databaseNameEnv, "autobuy")
t.Setenv(databaseUserEnv, "buy")
t.Setenv(databasePasswordEnv, "env-secret")
cfg, err := loadDatabaseFromPath(filepath.Join(t.TempDir(), "missing.yaml"))
if err != nil {
t.Fatal(err)
}
if cfg.Host != "127.0.0.1" || cfg.Port != "3307" {
t.Fatalf("线上环境变量模式应该保留安全默认地址,实际:%s", cfg)
}
}
func clearDatabaseEnv(t *testing.T) {
t.Helper()
for _, name := range []string{
databaseHostEnv,
databasePortEnv,
databaseNameEnv,
databaseUserEnv,
databasePasswordEnv,
} {
t.Setenv(name, "")
}
}
func writeConfigFile(t *testing.T, yamlText string) string {
t.Helper()
path := filepath.Join(t.TempDir(), configFileName)
if err := os.WriteFile(path, []byte(yamlText), 0o600); err != nil {
t.Fatalf("写测试配置文件失败: %v", err)
}
return path
}
// loadFrom 是测试专用的小工具:把一段 YAML 文本写到临时目录里的
// config.yaml,绕开 ConfigPath()(它依赖 os.Executable,测试环境里
// 不可控),直接测 Load 里"读文件 + 解析"这段逻辑。