package config import ( "os" "testing" "time" ) func TestDefaultConfig(t *testing.T) { cfg := DefaultConfig() if cfg == nil { t.Fatal("DefaultConfig() returned nil") } // Check Ollama defaults if cfg.Ollama.BaseURL != "http://localhost:11434" { t.Errorf("expected default Ollama BaseURL 'http://localhost:11434', got %q", cfg.Ollama.BaseURL) } if cfg.Ollama.Model != "gemma4:e4b" { t.Errorf("expected default Ollama Model 'gemma4:e4b', got %q", cfg.Ollama.Model) } if cfg.Ollama.Timeout != 120*time.Second { t.Errorf("expected default Ollama Timeout 120s, got %v", cfg.Ollama.Timeout) } // Check Sandbox defaults if cfg.Sandbox.Timeout != 30*time.Second { t.Errorf("expected default Sandbox Timeout 30s, got %v", cfg.Sandbox.Timeout) } if cfg.Sandbox.MaxMemory != 512*1024*1024 { t.Errorf("expected default Sandbox MaxMemory 512MB, got %d", cfg.Sandbox.MaxMemory) } if cfg.Sandbox.WorkingDir != "/tmp/orca/sandbox" { t.Errorf("expected default Sandbox WorkingDir '/tmp/orca/sandbox', got %q", cfg.Sandbox.WorkingDir) } // Check Session defaults if cfg.Session.MaxHistory != 100 { t.Errorf("expected default Session MaxHistory 100, got %d", cfg.Session.MaxHistory) } if cfg.Session.StorageDir == "" { t.Error("expected non-empty Session StorageDir") } } func TestDefaultConfigStorageDir(t *testing.T) { cfg := DefaultConfig() home, _ := os.UserHomeDir() expected := home + "/.orca/sessions" if cfg.Session.StorageDir != expected { t.Errorf("expected StorageDir %q, got %q", expected, cfg.Session.StorageDir) } } func TestLoadConfigFromEnv(t *testing.T) { // Set environment variables os.Setenv("ORCA_OLLAMA_BASE_URL", "http://custom:11434") os.Setenv("ORCA_OLLAMA_MODEL", "codellama") os.Setenv("ORCA_OLLAMA_TIMEOUT", "60s") os.Setenv("ORCA_SANDBOX_TIMEOUT", "120s") os.Setenv("ORCA_SANDBOX_MAX_MEMORY", "1073741824") os.Setenv("ORCA_SANDBOX_WORKING_DIR", "/custom/sandbox") os.Setenv("ORCA_SESSION_STORAGE_DIR", "/custom/sessions") os.Setenv("ORCA_SESSION_MAX_HISTORY", "200") defer func() { os.Unsetenv("ORCA_OLLAMA_BASE_URL") os.Unsetenv("ORCA_OLLAMA_MODEL") os.Unsetenv("ORCA_OLLAMA_TIMEOUT") os.Unsetenv("ORCA_SANDBOX_TIMEOUT") os.Unsetenv("ORCA_SANDBOX_MAX_MEMORY") os.Unsetenv("ORCA_SANDBOX_WORKING_DIR") os.Unsetenv("ORCA_SESSION_STORAGE_DIR") os.Unsetenv("ORCA_SESSION_MAX_HISTORY") }() cfg := LoadConfigFromEnv() if cfg.Ollama.BaseURL != "http://custom:11434" { t.Errorf("expected Ollama BaseURL 'http://custom:11434', got %q", cfg.Ollama.BaseURL) } if cfg.Ollama.Model != "codellama" { t.Errorf("expected Ollama Model 'codellama', got %q", cfg.Ollama.Model) } if cfg.Ollama.Timeout != 60*time.Second { t.Errorf("expected Ollama Timeout 60s, got %v", cfg.Ollama.Timeout) } if cfg.Sandbox.Timeout != 120*time.Second { t.Errorf("expected Sandbox Timeout 120s, got %v", cfg.Sandbox.Timeout) } if cfg.Sandbox.MaxMemory != 1073741824 { t.Errorf("expected Sandbox MaxMemory 1073741824, got %d", cfg.Sandbox.MaxMemory) } if cfg.Sandbox.WorkingDir != "/custom/sandbox" { t.Errorf("expected Sandbox WorkingDir '/custom/sandbox', got %q", cfg.Sandbox.WorkingDir) } if cfg.Session.StorageDir != "/custom/sessions" { t.Errorf("expected Session StorageDir '/custom/sessions', got %q", cfg.Session.StorageDir) } if cfg.Session.MaxHistory != 200 { t.Errorf("expected Session MaxHistory 200, got %d", cfg.Session.MaxHistory) } } func TestLoadConfigFromEnvPartial(t *testing.T) { os.Setenv("ORCA_OLLAMA_MODEL", "mistral") defer os.Unsetenv("ORCA_OLLAMA_MODEL") cfg := LoadConfigFromEnv() // Should use env override if cfg.Ollama.Model != "mistral" { t.Errorf("expected Model 'mistral', got %q", cfg.Ollama.Model) } // Should keep defaults for unset values if cfg.Ollama.BaseURL != "http://localhost:11434" { t.Errorf("expected default BaseURL, got %q", cfg.Ollama.BaseURL) } } func TestConfigIsValid(t *testing.T) { cfg := DefaultConfig() if err := cfg.IsValid(); err != nil { t.Errorf("default config should be valid: %v", err) } } func TestConfigInvalidBaseURL(t *testing.T) { cfg := DefaultConfig() cfg.Provider = ProviderOllama cfg.Ollama.BaseURL = "" if err := cfg.IsValid(); err == nil { t.Error("expected error for empty BaseURL") } } func TestConfigInvalidModel(t *testing.T) { cfg := DefaultConfig() cfg.Provider = ProviderOllama cfg.Ollama.Model = "" if err := cfg.IsValid(); err == nil { t.Error("expected error for empty Model") } } func TestConfigInvalidOllamaTimeout(t *testing.T) { cfg := DefaultConfig() cfg.Provider = ProviderOllama cfg.Ollama.Timeout = 0 if err := cfg.IsValid(); err == nil { t.Error("expected error for zero Ollama Timeout") } } func TestConfigInvalidDeepSeekAPIKey(t *testing.T) { cfg := DefaultConfig() cfg.Provider = ProviderDeepSeek cfg.DeepSeek.APIKey = "" if err := cfg.IsValid(); err == nil { t.Error("expected error for empty DeepSeek APIKey") } } func TestConfigInvalidSandboxTimeout(t *testing.T) { cfg := DefaultConfig() cfg.Sandbox.Timeout = -1 if err := cfg.IsValid(); err == nil { t.Error("expected error for negative Sandbox Timeout") } } func TestConfigInvalidMaxMemory(t *testing.T) { cfg := DefaultConfig() cfg.Sandbox.MaxMemory = 0 if err := cfg.IsValid(); err == nil { t.Error("expected error for zero MaxMemory") } } func TestConfigInvalidMaxHistory(t *testing.T) { cfg := DefaultConfig() cfg.Session.MaxHistory = 0 if err := cfg.IsValid(); err == nil { t.Error("expected error for zero MaxHistory") } } func TestConfigError(t *testing.T) { err := errConfig("test error") if err.Error() != "config: test error" { t.Errorf("unexpected error message: %s", err.Error()) } ce, ok := err.(*ConfigError) if !ok { t.Fatal("expected ConfigError type") } if ce.Message != "test error" { t.Errorf("expected Message 'test error', got %q", ce.Message) } } func TestLoadConfigFromEnvInvalidTimeout(t *testing.T) { os.Setenv("ORCA_OLLAMA_TIMEOUT", "not-a-duration") defer os.Unsetenv("ORCA_OLLAMA_TIMEOUT") cfg := LoadConfigFromEnv() // Should keep default when env var is unparseable if cfg.Ollama.Timeout != 120*time.Second { t.Errorf("expected default 120s when env is invalid, got %v", cfg.Ollama.Timeout) } } func TestLoadConfigFromEnvInvalidMaxMemory(t *testing.T) { os.Setenv("ORCA_SANDBOX_MAX_MEMORY", "not-a-number") defer os.Unsetenv("ORCA_SANDBOX_MAX_MEMORY") cfg := LoadConfigFromEnv() // Should keep default when env var is unparseable if cfg.Sandbox.MaxMemory != 512*1024*1024 { t.Errorf("expected default MaxMemory when env is invalid, got %d", cfg.Sandbox.MaxMemory) } } func TestLoadConfigFromEnvInvalidMaxHistory(t *testing.T) { os.Setenv("ORCA_SESSION_MAX_HISTORY", "not-a-number") defer os.Unsetenv("ORCA_SESSION_MAX_HISTORY") cfg := LoadConfigFromEnv() if cfg.Session.MaxHistory != 100 { t.Errorf("expected default MaxHistory when env is invalid, got %d", cfg.Session.MaxHistory) } }