Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,6 @@ config.yaml

# Build artifacts
latest.txt

# Claude
/.claude/*.local.*
7 changes: 3 additions & 4 deletions internal/tiger/cmd/auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import (
"testing"
"time"

"github.com/spf13/viper"
"github.com/timescale/tiger-cli/internal/tiger/config"
)

Expand Down Expand Up @@ -44,8 +43,9 @@ func setupAuthTest(t *testing.T) string {
os.Setenv("TIGER_CONFIG_DIR", tmpDir)

// Reset global config and viper to ensure test isolation
config.ResetGlobalConfig()
viper.Reset()
if _, err := config.UseTestConfig(tmpDir, map[string]any{}); err != nil {
t.Fatalf("Failed to use test config: %v", err)
}

// Also ensure config file doesn't exist
configFile := config.GetConfigFile(tmpDir)
Expand All @@ -56,7 +56,6 @@ func setupAuthTest(t *testing.T) string {
config.RemoveAPIKeyFromKeyring()
// Reset global config and viper first
config.ResetGlobalConfig()
viper.Reset()
validateAPIKeyForLogin = originalValidator // Restore original validator
// Remove config file explicitly
configFile := config.GetConfigFile(tmpDir)
Expand Down
83 changes: 71 additions & 12 deletions internal/tiger/cmd/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"strings"
"testing"

"github.com/spf13/viper"
"gopkg.in/yaml.v3"

"github.com/timescale/tiger-cli/internal/tiger/config"
Expand All @@ -17,12 +16,6 @@ import (
func setupConfigTest(t *testing.T) (string, func()) {
t.Helper()

// Reset viper state to ensure clean test environment
viper.Reset()

// Reset global config in the config package
config.ResetGlobalConfig()

// Create temporary directory for test config
tmpDir, err := os.MkdirTemp("", "tiger-config-test-*")
if err != nil {
Expand All @@ -32,11 +25,12 @@ func setupConfigTest(t *testing.T) (string, func()) {
// Set environment variable to use test directory
os.Setenv("TIGER_CONFIG_DIR", tmpDir)

config.UseTestConfig(tmpDir, map[string]any{})

// Clean up function
cleanup := func() {
os.RemoveAll(tmpDir)
os.Unsetenv("TIGER_CONFIG_DIR")
viper.Reset()

// Reset global config in the config package
// This is important for test isolation
Expand Down Expand Up @@ -563,18 +557,20 @@ func TestConfigReset(t *testing.T) {
t.Errorf("Expected output to contain reset message, got '%s'", strings.TrimSpace(output))
}

// Verify all values were reset to defaults
cfg, err = config.Load()
if err != nil {
t.Fatalf("Failed to load config: %v", err)
}

// ProjectID should be preserved
if cfg.ProjectID != "custom-project" {
t.Errorf("Expected ProjectID %s, got %s", "custom-project", cfg.ProjectID)
}

// Verify all other values were reset to defaults
if cfg.APIURL != config.DefaultAPIURL {
t.Errorf("Expected default APIURL %s, got %s", config.DefaultAPIURL, cfg.APIURL)
}
if cfg.ProjectID != "" {
t.Errorf("Expected empty ProjectID, got %s", cfg.ProjectID)
}
if cfg.ServiceID != "" {
t.Errorf("Expected empty ServiceID, got %s", cfg.ServiceID)
}
Expand Down Expand Up @@ -671,3 +667,66 @@ func TestConfigCommands_Integration(t *testing.T) {
t.Errorf("Expected output reset to default %s, got %s", config.DefaultOutput, cfg.Output)
}
}

func TestConfigSet_OutputDoesPersist(t *testing.T) {
tmpDir, _ := setupConfigTest(t)

// Start with default config (no output setting in file)
configFile := config.GetConfigFile(tmpDir)

// Execute config set to explicitly set output to json
_, err := executeConfigCommand("config", "set", "output", "json")
if err != nil {
t.Fatalf("Failed to set output to json: %v", err)
}

// Read the config file directly
configBytes, err := os.ReadFile(configFile)
if err != nil {
t.Fatalf("Failed to read config file: %v", err)
}

// Parse the YAML to check
var configMap map[string]interface{}
if err := yaml.Unmarshal(configBytes, &configMap); err != nil {
t.Fatalf("Failed to parse config YAML: %v", err)
}

if outputVal, exists := configMap["output"]; !exists || outputVal != "json" {
t.Errorf("Expected output in config file to be 'json', got: %v (exists: %v)", outputVal, exists)
}

// Also verify by loading config
cfg, err := config.Load()
if err != nil {
t.Fatalf("Failed to load config: %v", err)
}

if cfg.Output != "json" {
t.Errorf("Expected loaded config output to be 'json', got: %s", cfg.Output)
}

// Now test that setting it to a different value updates the file
_, err = executeConfigCommand("config", "set", "output", "yaml")
if err != nil {
t.Fatalf("Failed to set output to yaml: %v", err)
}

// Read the config file again
configBytes, err = os.ReadFile(configFile)
if err != nil {
t.Fatalf("Failed to read config file after second set: %v", err)
}

configContent := string(configBytes)

// Verify that output was updated in the config file
if !strings.Contains(configContent, "output: yaml") {
t.Errorf("Config file should contain 'output: yaml' after update. Config content:\n%s", configContent)
}

// Should NOT contain the old value
if strings.Contains(configContent, "output: json") {
t.Errorf("Config file should NOT contain old 'output: json' value. Config content:\n%s", configContent)
}
}
92 changes: 37 additions & 55 deletions internal/tiger/cmd/db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,10 @@ func setupDBTest(t *testing.T) string {

// Reset global config and viper to ensure test isolation
config.ResetGlobalConfig()
viper.Reset()

t.Cleanup(func() {
// Reset global config and viper first
config.ResetGlobalConfig()
viper.Reset()
// Clean up environment variable BEFORE cleaning up file system
os.Unsetenv("TIGER_CONFIG_DIR")
// Then clean up file system
Expand All @@ -64,12 +62,10 @@ func TestDBConnectionString_NoServiceID(t *testing.T) {
tmpDir := setupDBTest(t)

// Set up config with project ID but no default service ID
cfg := &config.Config{
APIURL: "https://api.tigerdata.com/public/v1",
ProjectID: "test-project-123",
ConfigDir: tmpDir,
}
err := cfg.Save()
_, err := config.UseTestConfig(tmpDir, map[string]any{
"api_url": "https://api.tigerdata.com/public/v1",
"project_id": "test-project-123",
})
if err != nil {
t.Fatalf("Failed to save test config: %v", err)
}
Expand All @@ -96,13 +92,11 @@ func TestDBConnectionString_NoAuth(t *testing.T) {
tmpDir := setupDBTest(t)

// Set up config with project ID and service ID
cfg := &config.Config{
APIURL: "https://api.tigerdata.com/public/v1",
ProjectID: "test-project-123",
ServiceID: "svc-12345",
ConfigDir: tmpDir,
}
err := cfg.Save()
_, err := config.UseTestConfig(tmpDir, map[string]any{
"api_url": "https://api.tigerdata.com/public/v1",
"project_id": "test-project-123",
"service_id": "svc-12345",
})
if err != nil {
t.Fatalf("Failed to save test config: %v", err)
}
Expand Down Expand Up @@ -172,12 +166,10 @@ func TestDBConnect_NoServiceID(t *testing.T) {
tmpDir := setupDBTest(t)

// Set up config with project ID but no default service ID
cfg := &config.Config{
APIURL: "https://api.tigerdata.com/public/v1",
ProjectID: "test-project-123",
ConfigDir: tmpDir,
}
err := cfg.Save()
_, err := config.UseTestConfig(tmpDir, map[string]any{
"api_url": "https://api.tigerdata.com/public/v1",
"project_id": "test-project-123",
})
if err != nil {
t.Fatalf("Failed to save test config: %v", err)
}
Expand All @@ -204,13 +196,11 @@ func TestDBConnect_NoAuth(t *testing.T) {
tmpDir := setupDBTest(t)

// Set up config with project ID and service ID
cfg := &config.Config{
APIURL: "https://api.tigerdata.com/public/v1",
ProjectID: "test-project-123",
ServiceID: "svc-12345",
ConfigDir: tmpDir,
}
err := cfg.Save()
_, err := config.UseTestConfig(tmpDir, map[string]any{
"api_url": "https://api.tigerdata.com/public/v1",
"project_id": "test-project-123",
"service_id": "svc-12345",
})
if err != nil {
t.Fatalf("Failed to save test config: %v", err)
}
Expand All @@ -237,13 +227,11 @@ func TestDBConnect_PsqlNotFound(t *testing.T) {
tmpDir := setupDBTest(t)

// Set up config
cfg := &config.Config{
APIURL: "http://localhost:9999",
ProjectID: "test-project-123",
ServiceID: "svc-12345",
ConfigDir: tmpDir,
}
err := cfg.Save()
_, err := config.UseTestConfig(tmpDir, map[string]any{
"api_url": "http://localhost:9999",
"project_id": "test-project-123",
"service_id": "svc-12345",
})
if err != nil {
t.Fatalf("Failed to save test config: %v", err)
}
Expand Down Expand Up @@ -596,12 +584,10 @@ func TestDBTestConnection_NoServiceID(t *testing.T) {
tmpDir := setupDBTest(t)

// Set up config with project ID but no default service ID
cfg := &config.Config{
APIURL: "https://api.tigerdata.com/public/v1",
ProjectID: "test-project-123",
ConfigDir: tmpDir,
}
err := cfg.Save()
_, err := config.UseTestConfig(tmpDir, map[string]any{
"api_url": "https://api.tigerdata.com/public/v1",
"project_id": "test-project-123",
})
if err != nil {
t.Fatalf("Failed to save test config: %v", err)
}
Expand All @@ -628,13 +614,11 @@ func TestDBTestConnection_NoAuth(t *testing.T) {
tmpDir := setupDBTest(t)

// Set up config with project ID and service ID
cfg := &config.Config{
APIURL: "https://api.tigerdata.com/public/v1",
ProjectID: "test-project-123",
ServiceID: "svc-12345",
ConfigDir: tmpDir,
}
err := cfg.Save()
_, err := config.UseTestConfig(tmpDir, map[string]any{
"api_url": "https://api.tigerdata.com/public/v1",
"project_id": "test-project-123",
"service_id": "svc-12345",
})
if err != nil {
t.Fatalf("Failed to save test config: %v", err)
}
Expand Down Expand Up @@ -980,13 +964,11 @@ func TestDBTestConnection_TimeoutParsing(t *testing.T) {
tmpDir := setupDBTest(t)

// Set up config
cfg := &config.Config{
APIURL: "http://localhost:9999", // Non-existent server
ProjectID: "test-project-123",
ServiceID: "svc-12345",
ConfigDir: tmpDir,
}
err := cfg.Save()
_, err := config.UseTestConfig(tmpDir, map[string]any{
"api_url": "http://localhost:9999", // Non-existent server
"project_id": "test-project-123",
"service_id": "svc-12345",
})
if err != nil {
t.Fatalf("Failed to save test config: %v", err)
}
Expand Down
3 changes: 0 additions & 3 deletions internal/tiger/cmd/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ func setupIntegrationTest(t *testing.T) string {

// Reset global config and viper to ensure test isolation
config.ResetGlobalConfig()
viper.Reset()

// Re-establish viper environment configuration after reset
viper.SetEnvPrefix("TIGER")
Expand All @@ -50,7 +49,6 @@ func setupIntegrationTest(t *testing.T) string {
t.Cleanup(func() {
// Reset global config and viper first
config.ResetGlobalConfig()
viper.Reset()
// Clean up environment variable BEFORE cleaning up file system
os.Unsetenv("TIGER_CONFIG_DIR")
// Then clean up file system
Expand All @@ -65,7 +63,6 @@ func executeIntegrationCommand(args ...string) (string, error) {
// Reset both global config and viper before each command execution
// This ensures fresh config loading with proper flag precedence
config.ResetGlobalConfig()
viper.Reset()

// Re-establish viper environment configuration after reset
viper.SetEnvPrefix("TIGER")
Expand Down
6 changes: 3 additions & 3 deletions internal/tiger/cmd/root_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (

func TestMain(m *testing.M) {
// Clean up any global state before tests
viper.Reset()
config.ResetGlobalConfig()
code := m.Run()
os.Exit(code)
}
Expand All @@ -27,7 +27,7 @@ func setupTestCommand(t *testing.T) (string, func()) {
// Clean up function
cleanup := func() {
os.RemoveAll(tmpDir)
viper.Reset()
config.ResetGlobalConfig()
}

t.Cleanup(cleanup)
Expand Down Expand Up @@ -121,7 +121,7 @@ func TestFlagBindingWithViper(t *testing.T) {
}

// Reset for next test
viper.Reset()
config.ResetGlobalConfig()

// Test 2: Flag should override environment variable
testCmd2 := buildRootCmd()
Expand Down
3 changes: 1 addition & 2 deletions internal/tiger/cmd/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -908,8 +908,7 @@ func setDefaultService(serviceID string, output io.Writer) error {
return fmt.Errorf("failed to load config: %w", err)
}

cfg.ServiceID = serviceID
if err := cfg.Save(); err != nil {
if err := cfg.Set("service_id", serviceID); err != nil {
return fmt.Errorf("failed to save config: %w", err)
}

Expand Down
Loading