签入版本
This commit is contained in:
@@ -1,2 +0,0 @@
|
|||||||
*
|
|
||||||
!.gitignore
|
|
||||||
Binary file not shown.
BIN
Binary file not shown.
@@ -1,125 +0,0 @@
|
|||||||
package config
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"os"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/gogf/gf/v2/os/gcfg"
|
|
||||||
)
|
|
||||||
|
|
||||||
// fakeBase 模拟文件适配器,返回固定配置树
|
|
||||||
type fakeBase struct {
|
|
||||||
data map[string]any
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *fakeBase) Available(ctx context.Context, resource ...string) bool { return true }
|
|
||||||
|
|
||||||
func (f *fakeBase) Get(ctx context.Context, pattern string) (any, error) {
|
|
||||||
if pattern == "" || pattern == "." {
|
|
||||||
return f.data, nil
|
|
||||||
}
|
|
||||||
var cur any = f.data
|
|
||||||
for _, part := range splitPattern(pattern) {
|
|
||||||
m, ok := cur.(map[string]any)
|
|
||||||
if !ok {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
cur = m[part]
|
|
||||||
}
|
|
||||||
return cur, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *fakeBase) Data(ctx context.Context) (map[string]any, error) { return f.data, nil }
|
|
||||||
|
|
||||||
func splitPattern(pattern string) []string {
|
|
||||||
var parts []string
|
|
||||||
start := 0
|
|
||||||
for i := 0; i < len(pattern); i++ {
|
|
||||||
if pattern[i] == '.' {
|
|
||||||
parts = append(parts, pattern[start:i])
|
|
||||||
start = i + 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return append(parts, pattern[start:])
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestAdapterEnvFirst 覆盖优先级核心行为:
|
|
||||||
// - 设置 GF_ 环境变量 → 覆盖文件值(含 map 整节点逐叶叠加)
|
|
||||||
// - 未设置 → 回落文件值
|
|
||||||
// - 空值环境变量 → 视为未设置,不清空文件值
|
|
||||||
func TestAdapterEnvFirst(t *testing.T) {
|
|
||||||
ctx := context.Background()
|
|
||||||
base := &fakeBase{data: map[string]any{
|
|
||||||
"database": map[string]any{
|
|
||||||
"default": map[string]any{
|
|
||||||
"type": "mysql",
|
|
||||||
"link": "file-link",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"jwt": map[string]any{"secret": "file-secret"},
|
|
||||||
}}
|
|
||||||
a := &adapterEnvFirst{base: base}
|
|
||||||
|
|
||||||
// 1. 未设置环境变量:文件值原样返回
|
|
||||||
if v, _ := a.Get(ctx, "database.default.link"); v != "file-link" {
|
|
||||||
t.Fatalf("未设环境变量时应返回文件值,得到: %v", v)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. 标量覆盖
|
|
||||||
os.Setenv("GF_JWT_SECRET", "env-secret")
|
|
||||||
defer os.Unsetenv("GF_JWT_SECRET")
|
|
||||||
if v, _ := a.Get(ctx, "jwt.secret"); v != "env-secret" {
|
|
||||||
t.Fatalf("环境变量应覆盖文件值,得到: %v", v)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. map 整节点逐叶叠加(gdb 读 database 整节点的场景)
|
|
||||||
os.Setenv("GF_DATABASE_DEFAULT_LINK", "env-link")
|
|
||||||
defer os.Unsetenv("GF_DATABASE_DEFAULT_LINK")
|
|
||||||
v, _ := a.Get(ctx, "database")
|
|
||||||
m, ok := v.(map[string]any)
|
|
||||||
if !ok {
|
|
||||||
t.Fatalf("database 节点应返回 map,得到: %T", v)
|
|
||||||
}
|
|
||||||
def := m["default"].(map[string]any)
|
|
||||||
if def["link"] != "env-link" {
|
|
||||||
t.Fatalf("整节点读取时 link 应被环境变量覆盖,得到: %v", def["link"])
|
|
||||||
}
|
|
||||||
if def["type"] != "mysql" {
|
|
||||||
t.Fatalf("未覆盖的键应保持文件值,得到: %v", def["type"])
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. 空值环境变量视为未设置(不清空文件值)
|
|
||||||
os.Setenv("GF_DATABASE_DEFAULT_TYPE", "")
|
|
||||||
defer os.Unsetenv("GF_DATABASE_DEFAULT_TYPE")
|
|
||||||
if v, _ := a.Get(ctx, "database.default.type"); v != "mysql" {
|
|
||||||
t.Fatalf("空环境变量应视为未设置,得到: %v", v)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 5. Data 全量叠加
|
|
||||||
data, _ := a.Data(ctx)
|
|
||||||
defData := data["database"].(map[string]any)["default"].(map[string]any)
|
|
||||||
if defData["link"] != "env-link" {
|
|
||||||
t.Fatalf("Data 应叠加环境变量覆盖,得到: %v", defData["link"])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestRegisterEnvOverride 注册后 g.Cfg() 读取链路获得覆盖能力
|
|
||||||
func TestRegisterEnvOverride(t *testing.T) {
|
|
||||||
adapter, err := gcfg.NewAdapterContent(`database:
|
|
||||||
default:
|
|
||||||
link: file-link
|
|
||||||
`)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("构造内容适配器失败: %v", err)
|
|
||||||
}
|
|
||||||
gcfg.Instance().SetAdapter(adapter)
|
|
||||||
RegisterEnvOverride()
|
|
||||||
ctx := context.Background()
|
|
||||||
|
|
||||||
os.Setenv("GF_DATABASE_DEFAULT_LINK", "env-link")
|
|
||||||
defer os.Unsetenv("GF_DATABASE_DEFAULT_LINK")
|
|
||||||
if v := gcfg.Instance().MustGet(ctx, "database.default.link").String(); v != "env-link" {
|
|
||||||
t.Fatalf("注册后 g.Cfg 读取应获得环境变量覆盖,得到: %v", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user