feat: load explicit configuration references and remove implicit env overlays
This commit is contained in:
@@ -6,28 +6,26 @@ import (
|
||||
"example.com/configuration/internal/config"
|
||||
omniConfig "git.yuntuo.hk/k2safe/go-omni/config"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGeneratedConfiguration(t *testing.T) {
|
||||
for ext, source := range map[string]string{
|
||||
"json": `{"limit":7}`, "yaml": "limit: 7\n", "xml": "<config><limit>7</limit></config>", "custom": `{"limit":7}`,
|
||||
} {
|
||||
for ext, source := range map[string]string{"json": `{"limit":"${LIMIT:-7}"}`, "yaml": "limit: '${LIMIT:-7}'\n", "xml": "<config><limit>${LIMIT:-7}</limit></config>", "custom": `{"limit":"${LIMIT:-7}"}`} {
|
||||
t.Run(ext, func(t *testing.T) {
|
||||
t.Setenv("LIMIT", "")
|
||||
t.Setenv("GO_OMNI_LIMIT", "999")
|
||||
path := filepath.Join(t.TempDir(), "app."+ext)
|
||||
if err := os.WriteFile(path, []byte(source), 0600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cfg, err := config.Load(path)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
if err != nil || cfg.Limit != 7 {
|
||||
t.Fatal(cfg.Limit, err)
|
||||
}
|
||||
if cfg.Limit != 7 {
|
||||
t.Fatal(cfg.Limit)
|
||||
}
|
||||
t.Setenv("GO_OMNI_LIMIT", "0")
|
||||
t.Setenv("LIMIT", "0")
|
||||
cfg, err = config.Load(path)
|
||||
if err != nil || cfg.Limit != 0 {
|
||||
t.Fatal(cfg.Limit, err)
|
||||
@@ -36,24 +34,60 @@ func TestGeneratedConfiguration(t *testing.T) {
|
||||
}
|
||||
t.Setenv("GO_OMNI_LOG_OUTPUT", "stderr")
|
||||
cfg, err := config.Load("")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if cfg.Limit != 10 || cfg.Server.Log.File != "" || cfg.Server.Log.Rotation.Enabled {
|
||||
t.Fatal("defaults/log normalization", cfg, err)
|
||||
if err != nil || cfg.Limit != 10 || cfg.Server.Log.File != "./var/log/app.log" || !cfg.Server.Log.Rotation.Enabled {
|
||||
t.Fatal("implicit overlay", err)
|
||||
}
|
||||
path := filepath.Join(t.TempDir(), "bad.yaml")
|
||||
os.WriteFile(path, []byte("limit: -1\n"), 0600)
|
||||
// Validation must run before svc.Initialize; the project initializer panics
|
||||
// below if reached, so this also detects accidentally starting dependencies.
|
||||
os.WriteFile(path, []byte("limit: '${LIMIT}'\n"), 0600)
|
||||
t.Setenv("LIMIT", "-1")
|
||||
// svc.Init panics if reached. Both invalid startup and successful check must
|
||||
// stop before opening the configured file logger or project dependencies.
|
||||
err = run(context.Background(), path)
|
||||
var diagnostic *omniConfig.Error
|
||||
if !errors.As(err, &diagnostic) || diagnostic.Field != "limit" || diagnostic.File != path || diagnostic.Line != 1 {
|
||||
var d *omniConfig.Error
|
||||
if !errors.As(err, &d) || d.Field != "limit" || d.File != path || d.Line != 1 || d.Env != "LIMIT" {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Setenv("GO_OMNI_LIMIT", "private-not-a-number")
|
||||
t.Setenv("LIMIT", "private-invalid")
|
||||
_, err = config.Load(path)
|
||||
if !errors.As(err, &diagnostic) || diagnostic.Env != "GO_OMNI_LIMIT" || strings.Contains(err.Error(), "private-not-a-number") {
|
||||
if !errors.As(err, &d) || d.Env != "LIMIT" || strings.Contains(err.Error(), "private-invalid") {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
func TestConfigurationCheckProcess(t *testing.T) {
|
||||
exe := filepath.Join(t.TempDir(), "server")
|
||||
cmd := exec.Command("go", "build", "-o", exe, ".")
|
||||
if out, err := cmd.CombinedOutput(); err != nil {
|
||||
t.Fatal(err, string(out))
|
||||
}
|
||||
dir := t.TempDir()
|
||||
path := filepath.Join(dir, "selected.yaml")
|
||||
if err := os.WriteFile(path, []byte("limit: '${LIMIT:-0}'\nserver:\n address: 127.0.0.1:1\n"), 0600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// A broken neighboring default/local/test file must never be layered in.
|
||||
for _, name := range []string{"config.yaml", "config.local.yaml", "config.test.yaml"} {
|
||||
os.WriteFile(filepath.Join(dir, name), []byte("broken: ["), 0600)
|
||||
}
|
||||
cmd = exec.Command(exe, "-config", path, "-check-config")
|
||||
cmd.Dir = dir
|
||||
if out, err := cmd.CombinedOutput(); err != nil || len(out) != 0 {
|
||||
t.Fatal(err, string(out))
|
||||
}
|
||||
if _, err := os.Stat(filepath.Join(dir, "var")); !os.IsNotExist(err) {
|
||||
t.Fatal("check opened logger/dependencies")
|
||||
}
|
||||
os.WriteFile(path, []byte("limit: '${MISSING_REQUIRED}'"), 0600)
|
||||
cmd = exec.Command(exe, "-config", path, "-check-config")
|
||||
cmd.Dir = dir
|
||||
cmd.Env = append(os.Environ(), "MISSING_REQUIRED=")
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err == nil || !strings.Contains(string(out), "MISSING_REQUIRED") || strings.Contains(string(out), "panic") {
|
||||
t.Fatal(err, string(out))
|
||||
}
|
||||
cmd = exec.Command(exe, "-config", path)
|
||||
cmd.Dir = dir
|
||||
cmd.Env = append(os.Environ(), "MISSING_REQUIRED=")
|
||||
if out, err := cmd.CombinedOutput(); err == nil || strings.Contains(string(out), "panic") {
|
||||
t.Fatal(err, string(out))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user