Files
go-omni/cmd/go-omni/apigen/testdata/configuration/consumer_test.go

114 lines
4.1 KiB
Go

package main
import (
"context"
"errors"
"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":"${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 || cfg.Limit != 7 {
t.Fatal(cfg.Limit, err)
}
t.Setenv("LIMIT", "0")
cfg, err = config.Load(path)
if err != nil || cfg.Limit != 0 {
t.Fatal(cfg.Limit, err)
}
})
}
t.Setenv("GO_OMNI_LOG_OUTPUT", "stderr")
cfg, err := config.Load("")
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: '${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 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("LIMIT", "private-invalid")
_, err = config.Load(path)
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))
}
}
func TestGeneratedModuleFieldDiagnostic(t *testing.T) {
path := filepath.Join(t.TempDir(), "config.yaml")
t.Setenv("EXAMPLE_LOG_LEVEL", "invalid-private-level")
if err := os.WriteFile(path, []byte("server:\n log:\n level: '${EXAMPLE_LOG_LEVEL}'\n"), 0600); err != nil {
t.Fatal(err)
}
err := run(context.Background(), path)
var d *omniConfig.Error
if !errors.As(err, &d) || d.Field != "server.log.level" || d.Line != 3 || d.Env != "EXAMPLE_LOG_LEVEL" || !strings.Contains(d.Reason, "debug") || strings.Contains(err.Error(), "invalid-private-level") {
t.Fatal(err)
}
if err := os.WriteFile(path, []byte("server:\n log:\n timeZone: Asia/Shanghai\n"), 0600); err != nil {
t.Fatal(err)
}
cfg, err := config.Load(path)
if err != nil || cfg.Server.Log.TimeZone != "Asia/Shanghai" {
t.Fatal(err)
}
}