| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- package config_test
- import (
- "os"
- "path/filepath"
- "testing"
- "workflow/config"
- )
- func TestLoad_Defaults(t *testing.T) {
- // No file, no env vars — should return built-in defaults
- cfg := config.Load("/nonexistent/path/that/does/not/exist")
- if cfg.LLM.URL != "http://localhost:4000" {
- t.Errorf("LLM.URL = %q, want default", cfg.LLM.URL)
- }
- if cfg.LLM.Model != "gpt-4o" {
- t.Errorf("LLM.Model = %q, want default", cfg.LLM.Model)
- }
- if cfg.Workspace.Root != "./workspace" {
- t.Errorf("Workspace.Root = %q, want default", cfg.Workspace.Root)
- }
- if cfg.Server.Port != "8080" {
- t.Errorf("Server.Port = %q, want default", cfg.Server.Port)
- }
- }
- func TestLoad_FromFile(t *testing.T) {
- content := `
- # comment
- LLM_URL=http://my-llm:5000
- LLM_KEY=sk-test-key
- LLM_MODEL=gpt-4-turbo
- WORKSPACE_ROOT=/tmp/ws
- PORT=9090
- `
- f := filepath.Join(t.TempDir(), "test.env")
- if err := os.WriteFile(f, []byte(content), 0600); err != nil {
- t.Fatal(err)
- }
- cfg := config.Load(f)
- if cfg.LLM.URL != "http://my-llm:5000" {
- t.Errorf("LLM.URL = %q", cfg.LLM.URL)
- }
- if cfg.LLM.Key != "sk-test-key" {
- t.Errorf("LLM.Key = %q", cfg.LLM.Key)
- }
- if cfg.LLM.Model != "gpt-4-turbo" {
- t.Errorf("LLM.Model = %q", cfg.LLM.Model)
- }
- if cfg.Workspace.Root != "/tmp/ws" {
- t.Errorf("Workspace.Root = %q", cfg.Workspace.Root)
- }
- if cfg.Server.Port != "9090" {
- t.Errorf("Server.Port = %q", cfg.Server.Port)
- }
- }
- func TestLoad_QuotedValues(t *testing.T) {
- content := `LLM_KEY="sk-quoted-key"` + "\n" + `LLM_MODEL='gpt-4o'` + "\n"
- f := filepath.Join(t.TempDir(), "test.env")
- os.WriteFile(f, []byte(content), 0600)
- cfg := config.Load(f)
- if cfg.LLM.Key != "sk-quoted-key" {
- t.Errorf("quoted double: LLM.Key = %q, want sk-quoted-key", cfg.LLM.Key)
- }
- if cfg.LLM.Model != "gpt-4o" {
- t.Errorf("quoted single: LLM.Model = %q, want gpt-4o", cfg.LLM.Model)
- }
- }
- func TestLoad_EnvVarOverridesFile(t *testing.T) {
- content := "LLM_KEY=from-file\nLLM_MODEL=from-file-model\n"
- f := filepath.Join(t.TempDir(), "test.env")
- os.WriteFile(f, []byte(content), 0600)
- // Set env var that should override file
- t.Setenv("LLM_KEY", "from-env")
- cfg := config.Load(f)
- if cfg.LLM.Key != "from-env" {
- t.Errorf("env var should win: LLM.Key = %q, want from-env", cfg.LLM.Key)
- }
- // Non-overridden field still comes from file
- if cfg.LLM.Model != "from-file-model" {
- t.Errorf("file value: LLM.Model = %q, want from-file-model", cfg.LLM.Model)
- }
- }
- func TestLoad_WorkflowConfigEnv(t *testing.T) {
- content := "LLM_KEY=from-workflow-config\n"
- f := filepath.Join(t.TempDir(), "custom.env")
- os.WriteFile(f, []byte(content), 0600)
- t.Setenv("WORKFLOW_CONFIG", f)
- cfg := config.Load("") // empty explicit path — should use WORKFLOW_CONFIG
- if cfg.LLM.Key != "from-workflow-config" {
- t.Errorf("WORKFLOW_CONFIG: LLM.Key = %q, want from-workflow-config", cfg.LLM.Key)
- }
- }
- func TestLoad_MissingFileUsesDefaults(t *testing.T) {
- cfg := config.Load("")
- // Should not panic; returns defaults
- if cfg.LLM.URL == "" {
- t.Error("LLM.URL should not be empty")
- }
- }
- func TestMaskKey(t *testing.T) {
- got := config.MaskKey("")
- if got != "(not set)" {
- t.Errorf("MaskKey(\"\") = %q, want \"(not set)\"", got)
- }
- got = config.MaskKey("sk-1234567890abcdef")
- if got == "sk-1234567890abcdef" {
- t.Error("MaskKey should not return plaintext key")
- }
- if len(got) == 0 {
- t.Error("MaskKey should not return empty string")
- }
- // Short key (≤ 8 chars) → all stars
- got = config.MaskKey("abc")
- for _, c := range got {
- if c != '*' {
- t.Errorf("MaskKey(short): expected all stars, got %q", got)
- break
- }
- }
- }
|