307 lines
7.2 KiB
Go
307 lines
7.2 KiB
Go
package config
|
|
|
|
import (
|
|
"os"
|
|
"testing"
|
|
|
|
"github.com/spf13/afero"
|
|
)
|
|
|
|
func TestNewManager(t *testing.T) {
|
|
manager := NewManager()
|
|
if manager == nil {
|
|
t.Fatal("NewManager returned nil")
|
|
}
|
|
if manager.config == nil {
|
|
t.Error("Manager config map is nil")
|
|
}
|
|
if manager.loader == nil {
|
|
t.Error("Manager loader is nil")
|
|
}
|
|
if manager.resolvedCache == nil {
|
|
t.Error("Manager resolvedCache is nil")
|
|
}
|
|
if manager.fs == nil {
|
|
t.Error("Manager fs is nil")
|
|
}
|
|
}
|
|
|
|
func TestLoader_FindConfigFile(t *testing.T) {
|
|
// Create an in-memory filesystem for testing
|
|
fs := afero.NewMemMapFs()
|
|
loader := NewLoader(fs)
|
|
|
|
// Create a config file in the filesystem
|
|
configContent := `
|
|
environments:
|
|
test:
|
|
config:
|
|
testKey: testValue
|
|
secrets:
|
|
testSecret: secretValue
|
|
configDefaults:
|
|
defaultKey: defaultValue
|
|
`
|
|
// Create the file in the current directory
|
|
if err := afero.WriteFile(fs, "config.yaml", []byte(configContent), 0644); err != nil {
|
|
t.Fatalf("Failed to write test config: %v", err)
|
|
}
|
|
|
|
// Test finding the config file
|
|
foundPath, err := loader.FindConfigFile("config.yaml")
|
|
if err != nil {
|
|
t.Errorf("FindConfigFile failed: %v", err)
|
|
}
|
|
|
|
// In memory fs, the path should be exactly what we created
|
|
if foundPath != "config.yaml" {
|
|
t.Errorf("Expected config.yaml, got %s", foundPath)
|
|
}
|
|
}
|
|
|
|
func TestLoader_LoadYAML(t *testing.T) {
|
|
fs := afero.NewMemMapFs()
|
|
loader := NewLoader(fs)
|
|
|
|
// Create a test config file
|
|
testConfig := `
|
|
environments:
|
|
test:
|
|
config:
|
|
testKey: testValue
|
|
configDefaults:
|
|
defaultKey: defaultValue
|
|
`
|
|
if err := afero.WriteFile(fs, "test-config.yaml", []byte(testConfig), 0644); err != nil {
|
|
t.Fatalf("Failed to write test config: %v", err)
|
|
}
|
|
|
|
// Load the YAML
|
|
config, err := loader.LoadYAML("test-config.yaml")
|
|
if err != nil {
|
|
t.Fatalf("LoadYAML failed: %v", err)
|
|
}
|
|
|
|
// Verify the structure
|
|
envs, ok := config["environments"].(map[string]interface{})
|
|
if !ok {
|
|
t.Fatal("environments not found or wrong type")
|
|
}
|
|
|
|
testEnv, ok := envs["test"].(map[string]interface{})
|
|
if !ok {
|
|
t.Fatal("test environment not found")
|
|
}
|
|
|
|
testConfig2, ok := testEnv["config"].(map[string]interface{})
|
|
if !ok {
|
|
t.Fatal("test config not found")
|
|
}
|
|
|
|
if testConfig2["testKey"] != "testValue" {
|
|
t.Errorf("Expected testKey=testValue, got %v", testConfig2["testKey"])
|
|
}
|
|
}
|
|
|
|
func TestResolver_ResolveEnv(t *testing.T) {
|
|
fs := afero.NewMemMapFs()
|
|
resolver := NewResolver("", "", fs)
|
|
|
|
// Set a test environment variable
|
|
os.Setenv("TEST_CONFIG_VAR", "test-value")
|
|
defer os.Unsetenv("TEST_CONFIG_VAR")
|
|
|
|
// Test resolving environment variable
|
|
result := resolver.Resolve("$ENV:TEST_CONFIG_VAR")
|
|
if result != "test-value" {
|
|
t.Errorf("Expected 'test-value', got %v", result)
|
|
}
|
|
|
|
// Test non-existent env var
|
|
result = resolver.Resolve("$ENV:NON_EXISTENT_VAR")
|
|
if result != nil {
|
|
t.Errorf("Expected nil for non-existent env var, got %v", result)
|
|
}
|
|
}
|
|
|
|
func TestResolver_ResolveFile(t *testing.T) {
|
|
fs := afero.NewMemMapFs()
|
|
resolver := NewResolver("", "", fs)
|
|
|
|
// Create a test file
|
|
secretContent := "my-secret-value"
|
|
if err := afero.WriteFile(fs, "/test-secret.txt", []byte(secretContent+"\n"), 0644); err != nil {
|
|
t.Fatalf("Failed to write test file: %v", err)
|
|
}
|
|
|
|
// Test resolving file
|
|
result := resolver.Resolve("$FILE:/test-secret.txt")
|
|
if result != secretContent {
|
|
t.Errorf("Expected '%s', got %v", secretContent, result)
|
|
}
|
|
|
|
// Test non-existent file
|
|
result = resolver.Resolve("$FILE:/non/existent/file")
|
|
if result != nil {
|
|
t.Errorf("Expected nil for non-existent file, got %v", result)
|
|
}
|
|
}
|
|
|
|
func TestManager_GetAndSet(t *testing.T) {
|
|
// Create an in-memory filesystem
|
|
fs := afero.NewMemMapFs()
|
|
|
|
// Create a test config file
|
|
testConfig := `
|
|
environments:
|
|
dev:
|
|
config:
|
|
apiURL: http://dev.example.com
|
|
timeout: 30
|
|
debug: true
|
|
secrets:
|
|
apiKey: dev-key-123
|
|
prod:
|
|
config:
|
|
apiURL: https://prod.example.com
|
|
timeout: 10
|
|
debug: false
|
|
secrets:
|
|
apiKey: $ENV:PROD_API_KEY
|
|
configDefaults:
|
|
appName: TestApp
|
|
timeout: 20
|
|
port: 8080
|
|
`
|
|
if err := afero.WriteFile(fs, "config.yaml", []byte(testConfig), 0644); err != nil {
|
|
t.Fatalf("Failed to write test config: %v", err)
|
|
}
|
|
|
|
// Create manager and set the filesystem
|
|
manager := NewManager()
|
|
manager.SetFs(fs)
|
|
|
|
// Load config should find the file automatically
|
|
manager.SetEnvironment("dev")
|
|
|
|
// Test getting config values
|
|
if v := manager.Get("apiURL", ""); v != "http://dev.example.com" {
|
|
t.Errorf("Expected dev apiURL, got %v", v)
|
|
}
|
|
|
|
if v := manager.Get("timeout", 0); v != 30 {
|
|
t.Errorf("Expected timeout=30, got %v", v)
|
|
}
|
|
|
|
if v := manager.Get("debug", false); v != true {
|
|
t.Errorf("Expected debug=true, got %v", v)
|
|
}
|
|
|
|
// Test default values
|
|
if v := manager.Get("appName", ""); v != "TestApp" {
|
|
t.Errorf("Expected appName from defaults, got %v", v)
|
|
}
|
|
|
|
// Test getting secrets
|
|
if v := manager.GetSecret("apiKey", ""); v != "dev-key-123" {
|
|
t.Errorf("Expected dev apiKey, got %v", v)
|
|
}
|
|
|
|
// Switch to prod environment
|
|
manager.SetEnvironment("prod")
|
|
|
|
if v := manager.Get("apiURL", ""); v != "https://prod.example.com" {
|
|
t.Errorf("Expected prod apiURL, got %v", v)
|
|
}
|
|
|
|
// Test environment variable resolution in secrets
|
|
os.Setenv("PROD_API_KEY", "prod-key-456")
|
|
defer os.Unsetenv("PROD_API_KEY")
|
|
|
|
if v := manager.GetSecret("apiKey", ""); v != "prod-key-456" {
|
|
t.Errorf("Expected resolved env var for apiKey, got %v", v)
|
|
}
|
|
}
|
|
|
|
func TestGlobalAPI(t *testing.T) {
|
|
// Create an in-memory filesystem
|
|
fs := afero.NewMemMapFs()
|
|
|
|
// Create a test config file
|
|
testConfig := `
|
|
environments:
|
|
test:
|
|
config:
|
|
stringVal: hello
|
|
intVal: 42
|
|
boolVal: true
|
|
secrets:
|
|
secret1: test-secret
|
|
configDefaults:
|
|
defaultString: world
|
|
`
|
|
if err := afero.WriteFile(fs, "config.yaml", []byte(testConfig), 0644); err != nil {
|
|
t.Fatalf("Failed to write test config: %v", err)
|
|
}
|
|
|
|
// Use the global API with the test filesystem
|
|
SetFs(fs)
|
|
SetEnvironment("test")
|
|
|
|
// Test type-safe getters
|
|
if v := GetString("stringVal"); v != "hello" {
|
|
t.Errorf("Expected 'hello', got %v", v)
|
|
}
|
|
|
|
if v := GetInt("intVal"); v != 42 {
|
|
t.Errorf("Expected 42, got %v", v)
|
|
}
|
|
|
|
if v := GetBool("boolVal"); v != true {
|
|
t.Errorf("Expected true, got %v", v)
|
|
}
|
|
|
|
if v := GetSecretString("secret1"); v != "test-secret" {
|
|
t.Errorf("Expected 'test-secret', got %v", v)
|
|
}
|
|
|
|
// Test defaults
|
|
if v := GetString("defaultString"); v != "world" {
|
|
t.Errorf("Expected 'world', got %v", v)
|
|
}
|
|
}
|
|
|
|
func TestManager_SetFs(t *testing.T) {
|
|
// Create manager with default OS filesystem
|
|
manager := NewManager()
|
|
|
|
// Create an in-memory filesystem
|
|
memFs := afero.NewMemMapFs()
|
|
|
|
// Write a config file to the memory fs
|
|
testConfig := `
|
|
environments:
|
|
test:
|
|
config:
|
|
testKey: fromMemory
|
|
configDefaults:
|
|
defaultKey: memoryDefault
|
|
`
|
|
if err := afero.WriteFile(memFs, "config.yaml", []byte(testConfig), 0644); err != nil {
|
|
t.Fatalf("Failed to write test config: %v", err)
|
|
}
|
|
|
|
// Set the filesystem
|
|
manager.SetFs(memFs)
|
|
manager.SetEnvironment("test")
|
|
|
|
// Test that it reads from the memory filesystem
|
|
if v := manager.Get("testKey", ""); v != "fromMemory" {
|
|
t.Errorf("Expected 'fromMemory', got %v", v)
|
|
}
|
|
|
|
if v := manager.Get("defaultKey", ""); v != "memoryDefault" {
|
|
t.Errorf("Expected 'memoryDefault', got %v", v)
|
|
}
|
|
}
|