Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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