orca.ai/internal/config/config_test.go
大森 286d3dae3c feat: add DeepSeek LLM provider support
- Add DeepSeekClient implementing LLM interface
- Support chat and streaming APIs
- Add Provider config option (ollama/deepseek)
- Default to DeepSeek with model deepseek-v4-flash
- Update CLI to display provider info
- Add DeepSeek environment variables (DEEPSEEK_API_KEY, etc.)
2026-05-08 22:04:18 +08:00

234 lines
6.8 KiB
Go

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)
}
}