From 427c900d8b3db343585dad619e2ae0d951a22e9e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 4 Feb 2026 21:45:32 +0000 Subject: [PATCH 1/3] Initial plan From e816a84b168b030827e1aa45c6ccc84c735a0ab3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 4 Feb 2026 21:48:21 +0000 Subject: [PATCH 2/3] test(config): add comprehensive test coverage for daemon config loader - Test default values and path resolution - Test env var parsing and precedence - Test flag overrides env vars - Test validation errors (invalid poll intervals, empty addr, missing web-dir) - Test web-assets mode validation and normalization - Test env var fallbacks (RATELORD_CONFIG_PATH, RATELORD_PORT) - Test helper functions (resolvePath, normalizeWebAssetsMode) Addresses PR feedback requesting test coverage for config.go Co-authored-by: rmax <26015+rmax@users.noreply.github.com> --- cmd/ratelord-d/config_test.go | 472 ++++++++++++++++++++++++++++++++++ 1 file changed, 472 insertions(+) create mode 100644 cmd/ratelord-d/config_test.go diff --git a/cmd/ratelord-d/config_test.go b/cmd/ratelord-d/config_test.go new file mode 100644 index 0000000..0a66b8f --- /dev/null +++ b/cmd/ratelord-d/config_test.go @@ -0,0 +1,472 @@ +package main + +import ( + "os" + "path/filepath" + "strings" + "testing" + "time" +) + +func TestLoadConfig_Defaults(t *testing.T) { + // Setup: Create temp dir and cd into it + tmpDir := t.TempDir() + oldWd, _ := os.Getwd() + defer os.Chdir(oldWd) + os.Chdir(tmpDir) + + config, err := LoadConfig([]string{}) + if err != nil { + t.Fatalf("LoadConfig failed: %v", err) + } + + // Verify defaults + if config.Addr != defaultAddr { + t.Errorf("expected default addr %s, got %s", defaultAddr, config.Addr) + } + if config.PollInterval != defaultPollInterval { + t.Errorf("expected default poll interval %v, got %v", defaultPollInterval, config.PollInterval) + } + if config.WebAssetsMode != defaultWebAssetsMode { + t.Errorf("expected default web assets mode %s, got %s", defaultWebAssetsMode, config.WebAssetsMode) + } + if !strings.HasSuffix(config.DBPath, "ratelord.db") { + t.Errorf("expected DBPath to end with ratelord.db, got %s", config.DBPath) + } + if !strings.HasSuffix(config.PolicyPath, "policy.json") { + t.Errorf("expected PolicyPath to end with policy.json, got %s", config.PolicyPath) + } +} + +func TestLoadConfig_EnvVars(t *testing.T) { + tmpDir := t.TempDir() + oldWd, _ := os.Getwd() + defer os.Chdir(oldWd) + os.Chdir(tmpDir) + + // Set env vars + os.Setenv("RATELORD_DB_PATH", "/custom/db.db") + os.Setenv("RATELORD_POLICY_PATH", "/custom/policy.json") + os.Setenv("RATELORD_ADDR", "0.0.0.0:9000") + os.Setenv("RATELORD_POLL_INTERVAL", "30s") + os.Setenv("RATELORD_WEB_ASSETS_MODE", "off") + defer func() { + os.Unsetenv("RATELORD_DB_PATH") + os.Unsetenv("RATELORD_POLICY_PATH") + os.Unsetenv("RATELORD_ADDR") + os.Unsetenv("RATELORD_POLL_INTERVAL") + os.Unsetenv("RATELORD_WEB_ASSETS_MODE") + }() + + config, err := LoadConfig([]string{}) + if err != nil { + t.Fatalf("LoadConfig failed: %v", err) + } + + if config.DBPath != "/custom/db.db" { + t.Errorf("expected DBPath from env /custom/db.db, got %s", config.DBPath) + } + if config.PolicyPath != "/custom/policy.json" { + t.Errorf("expected PolicyPath from env /custom/policy.json, got %s", config.PolicyPath) + } + if config.Addr != "0.0.0.0:9000" { + t.Errorf("expected Addr from env 0.0.0.0:9000, got %s", config.Addr) + } + if config.PollInterval != 30*time.Second { + t.Errorf("expected PollInterval from env 30s, got %v", config.PollInterval) + } + if config.WebAssetsMode != "off" { + t.Errorf("expected WebAssetsMode from env off, got %s", config.WebAssetsMode) + } +} + +func TestLoadConfig_FlagOverridesEnv(t *testing.T) { + tmpDir := t.TempDir() + oldWd, _ := os.Getwd() + defer os.Chdir(oldWd) + os.Chdir(tmpDir) + + // Set env vars + os.Setenv("RATELORD_ADDR", "env-addr:8080") + os.Setenv("RATELORD_POLL_INTERVAL", "15s") + defer func() { + os.Unsetenv("RATELORD_ADDR") + os.Unsetenv("RATELORD_POLL_INTERVAL") + }() + + // Flags should override env + config, err := LoadConfig([]string{ + "-addr", "flag-addr:9090", + "-poll-interval", "25s", + }) + if err != nil { + t.Fatalf("LoadConfig failed: %v", err) + } + + if config.Addr != "flag-addr:9090" { + t.Errorf("expected flag to override env for addr, got %s", config.Addr) + } + if config.PollInterval != 25*time.Second { + t.Errorf("expected flag to override env for poll-interval, got %v", config.PollInterval) + } +} + +func TestLoadConfig_InvalidPollInterval_Env(t *testing.T) { + tmpDir := t.TempDir() + oldWd, _ := os.Getwd() + defer os.Chdir(oldWd) + os.Chdir(tmpDir) + + os.Setenv("RATELORD_POLL_INTERVAL", "invalid") + defer os.Unsetenv("RATELORD_POLL_INTERVAL") + + _, err := LoadConfig([]string{}) + if err == nil { + t.Fatal("expected error for invalid RATELORD_POLL_INTERVAL, got nil") + } + if !strings.Contains(err.Error(), "invalid RATELORD_POLL_INTERVAL") { + t.Errorf("expected error message to contain 'invalid RATELORD_POLL_INTERVAL', got: %v", err) + } +} + +func TestLoadConfig_InvalidPollInterval_Flag(t *testing.T) { + tmpDir := t.TempDir() + oldWd, _ := os.Getwd() + defer os.Chdir(oldWd) + os.Chdir(tmpDir) + + _, err := LoadConfig([]string{"-poll-interval", "not-a-duration"}) + if err == nil { + t.Fatal("expected error for invalid poll-interval flag, got nil") + } + if !strings.Contains(err.Error(), "invalid poll interval") { + t.Errorf("expected error message to contain 'invalid poll interval', got: %v", err) + } +} + +func TestLoadConfig_EmptyAddr(t *testing.T) { + tmpDir := t.TempDir() + oldWd, _ := os.Getwd() + defer os.Chdir(oldWd) + os.Chdir(tmpDir) + + _, err := LoadConfig([]string{"-addr", ""}) + if err == nil { + t.Fatal("expected error for empty addr, got nil") + } + if !strings.Contains(err.Error(), "addr cannot be empty") { + t.Errorf("expected error about empty addr, got: %v", err) + } +} + +func TestLoadConfig_EmptyAddr_Whitespace(t *testing.T) { + tmpDir := t.TempDir() + oldWd, _ := os.Getwd() + defer os.Chdir(oldWd) + os.Chdir(tmpDir) + + _, err := LoadConfig([]string{"-addr", " "}) + if err == nil { + t.Fatal("expected error for whitespace-only addr, got nil") + } + if !strings.Contains(err.Error(), "addr cannot be empty") { + t.Errorf("expected error about empty addr, got: %v", err) + } +} + +func TestLoadConfig_WebAssets_FS_MissingWebDir(t *testing.T) { + tmpDir := t.TempDir() + oldWd, _ := os.Getwd() + defer os.Chdir(oldWd) + os.Chdir(tmpDir) + + _, err := LoadConfig([]string{"-web-assets", "fs"}) + if err == nil { + t.Fatal("expected error when web-assets=fs but web-dir is missing, got nil") + } + if !strings.Contains(err.Error(), "web-assets=fs requires web-dir") { + t.Errorf("expected error about missing web-dir, got: %v", err) + } +} + +func TestLoadConfig_WebAssets_FS_WithWebDir(t *testing.T) { + tmpDir := t.TempDir() + oldWd, _ := os.Getwd() + defer os.Chdir(oldWd) + os.Chdir(tmpDir) + + webDir := filepath.Join(tmpDir, "web") + config, err := LoadConfig([]string{"-web-assets", "fs", "-web-dir", webDir}) + if err != nil { + t.Fatalf("LoadConfig failed: %v", err) + } + + if config.WebAssetsMode != "fs" { + t.Errorf("expected WebAssetsMode fs, got %s", config.WebAssetsMode) + } + if config.WebDir != webDir { + t.Errorf("expected WebDir %s, got %s", webDir, config.WebDir) + } +} + +func TestLoadConfig_InvalidWebAssetsMode(t *testing.T) { + tmpDir := t.TempDir() + oldWd, _ := os.Getwd() + defer os.Chdir(oldWd) + os.Chdir(tmpDir) + + _, err := LoadConfig([]string{"-web-assets", "invalid-mode"}) + if err == nil { + t.Fatal("expected error for invalid web-assets mode, got nil") + } + if !strings.Contains(err.Error(), "unsupported web-assets mode") { + t.Errorf("expected error about unsupported web-assets mode, got: %v", err) + } +} + +func TestLoadConfig_PathResolution_Relative(t *testing.T) { + tmpDir := t.TempDir() + oldWd, _ := os.Getwd() + defer os.Chdir(oldWd) + os.Chdir(tmpDir) + + config, err := LoadConfig([]string{ + "-db", "data/ratelord.db", + "-policy", "config/policy.json", + }) + if err != nil { + t.Fatalf("LoadConfig failed: %v", err) + } + + expectedDB := filepath.Join(tmpDir, "data/ratelord.db") + expectedPolicy := filepath.Join(tmpDir, "config/policy.json") + + if config.DBPath != expectedDB { + t.Errorf("expected DBPath %s, got %s", expectedDB, config.DBPath) + } + if config.PolicyPath != expectedPolicy { + t.Errorf("expected PolicyPath %s, got %s", expectedPolicy, config.PolicyPath) + } +} + +func TestLoadConfig_PathResolution_Absolute(t *testing.T) { + tmpDir := t.TempDir() + oldWd, _ := os.Getwd() + defer os.Chdir(oldWd) + os.Chdir(tmpDir) + + absDBPath := "/absolute/path/to/db.db" + absPolicyPath := "/absolute/path/to/policy.json" + + config, err := LoadConfig([]string{ + "-db", absDBPath, + "-policy", absPolicyPath, + }) + if err != nil { + t.Fatalf("LoadConfig failed: %v", err) + } + + if config.DBPath != absDBPath { + t.Errorf("expected DBPath %s, got %s", absDBPath, config.DBPath) + } + if config.PolicyPath != absPolicyPath { + t.Errorf("expected PolicyPath %s, got %s", absPolicyPath, config.PolicyPath) + } +} + +func TestLoadConfig_EnvPortOnly(t *testing.T) { + tmpDir := t.TempDir() + oldWd, _ := os.Getwd() + defer os.Chdir(oldWd) + os.Chdir(tmpDir) + + os.Setenv("RATELORD_PORT", "3000") + defer os.Unsetenv("RATELORD_PORT") + + config, err := LoadConfig([]string{}) + if err != nil { + t.Fatalf("LoadConfig failed: %v", err) + } + + expected := "127.0.0.1:3000" + if config.Addr != expected { + t.Errorf("expected addr %s from RATELORD_PORT, got %s", expected, config.Addr) + } +} + +func TestLoadConfig_EnvAddrOverridesPort(t *testing.T) { + tmpDir := t.TempDir() + oldWd, _ := os.Getwd() + defer os.Chdir(oldWd) + os.Chdir(tmpDir) + + os.Setenv("RATELORD_ADDR", "0.0.0.0:8080") + os.Setenv("RATELORD_PORT", "3000") + defer func() { + os.Unsetenv("RATELORD_ADDR") + os.Unsetenv("RATELORD_PORT") + }() + + config, err := LoadConfig([]string{}) + if err != nil { + t.Fatalf("LoadConfig failed: %v", err) + } + + // RATELORD_ADDR should take precedence over RATELORD_PORT + if config.Addr != "0.0.0.0:8080" { + t.Errorf("expected RATELORD_ADDR to override RATELORD_PORT, got %s", config.Addr) + } +} + +func TestLoadConfig_PolicyPathFallback(t *testing.T) { + tmpDir := t.TempDir() + oldWd, _ := os.Getwd() + defer os.Chdir(oldWd) + os.Chdir(tmpDir) + + // Test that RATELORD_CONFIG_PATH is used as fallback for RATELORD_POLICY_PATH + os.Setenv("RATELORD_CONFIG_PATH", "/fallback/config.json") + defer os.Unsetenv("RATELORD_CONFIG_PATH") + + config, err := LoadConfig([]string{}) + if err != nil { + t.Fatalf("LoadConfig failed: %v", err) + } + + if config.PolicyPath != "/fallback/config.json" { + t.Errorf("expected PolicyPath from RATELORD_CONFIG_PATH fallback, got %s", config.PolicyPath) + } +} + +func TestLoadConfig_PolicyPathPrimaryOverFallback(t *testing.T) { + tmpDir := t.TempDir() + oldWd, _ := os.Getwd() + defer os.Chdir(oldWd) + os.Chdir(tmpDir) + + // Test that RATELORD_POLICY_PATH takes precedence over RATELORD_CONFIG_PATH + os.Setenv("RATELORD_POLICY_PATH", "/primary/policy.json") + os.Setenv("RATELORD_CONFIG_PATH", "/fallback/config.json") + defer func() { + os.Unsetenv("RATELORD_POLICY_PATH") + os.Unsetenv("RATELORD_CONFIG_PATH") + }() + + config, err := LoadConfig([]string{}) + if err != nil { + t.Fatalf("LoadConfig failed: %v", err) + } + + if config.PolicyPath != "/primary/policy.json" { + t.Errorf("expected PolicyPath from RATELORD_POLICY_PATH, got %s", config.PolicyPath) + } +} + +func TestNormalizeWebAssetsMode(t *testing.T) { + tests := []struct { + input string + expected string + }{ + {"", "embedded"}, + {"embedded", "embedded"}, + {"EMBEDDED", "embedded"}, + {" embedded ", "embedded"}, + {"fs", "fs"}, + {"FS", "fs"}, + {"dir", "fs"}, + {"directory", "fs"}, + {"off", "off"}, + {"OFF", "off"}, + {"disabled", "off"}, + {"none", "off"}, + {"unknown", "unknown"}, + } + + for _, tt := range tests { + t.Run(tt.input, func(t *testing.T) { + result := normalizeWebAssetsMode(tt.input) + if result != tt.expected { + t.Errorf("normalizeWebAssetsMode(%q) = %q, want %q", tt.input, result, tt.expected) + } + }) + } +} + +func TestResolvePath(t *testing.T) { + cwd := "/test/cwd" + + tests := []struct { + name string + input string + expected string + }{ + {"empty", "", ""}, + {"whitespace", " ", ""}, + {"absolute", "/absolute/path", "/absolute/path"}, + {"relative", "relative/path", "/test/cwd/relative/path"}, + {"with_whitespace", " relative/path ", "/test/cwd/relative/path"}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := resolvePath(tt.input, cwd) + if result != tt.expected { + t.Errorf("resolvePath(%q, %q) = %q, want %q", tt.input, cwd, result, tt.expected) + } + }) + } +} + +func TestLoadConfig_WebDirResolution(t *testing.T) { + tmpDir := t.TempDir() + oldWd, _ := os.Getwd() + defer os.Chdir(oldWd) + os.Chdir(tmpDir) + + // Test that web-dir gets resolved when web-assets=fs + config, err := LoadConfig([]string{ + "-web-assets", "fs", + "-web-dir", "relative/web", + }) + if err != nil { + t.Fatalf("LoadConfig failed: %v", err) + } + + expectedWebDir := filepath.Join(tmpDir, "relative/web") + if config.WebDir != expectedWebDir { + t.Errorf("expected WebDir to be resolved to %s, got %s", expectedWebDir, config.WebDir) + } +} + +func TestLoadConfig_WebAssets_Embedded(t *testing.T) { + tmpDir := t.TempDir() + oldWd, _ := os.Getwd() + defer os.Chdir(oldWd) + os.Chdir(tmpDir) + + config, err := LoadConfig([]string{"-web-assets", "embedded"}) + if err != nil { + t.Fatalf("LoadConfig failed: %v", err) + } + + if config.WebAssetsMode != "embedded" { + t.Errorf("expected WebAssetsMode embedded, got %s", config.WebAssetsMode) + } + // WebDir can be empty for embedded mode +} + +func TestLoadConfig_WebAssets_Off(t *testing.T) { + tmpDir := t.TempDir() + oldWd, _ := os.Getwd() + defer os.Chdir(oldWd) + os.Chdir(tmpDir) + + config, err := LoadConfig([]string{"-web-assets", "off"}) + if err != nil { + t.Fatalf("LoadConfig failed: %v", err) + } + + if config.WebAssetsMode != "off" { + t.Errorf("expected WebAssetsMode off, got %s", config.WebAssetsMode) + } +} From c935d940386dd55320b3bec44ec74bc55fbbe0f7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 4 Feb 2026 21:50:32 +0000 Subject: [PATCH 3/3] fix(test): improve error handling in config tests - Add proper error checking for os.Getwd() and os.Chdir() - Fix variable declaration issues in error test cases - All tests still pass Co-authored-by: rmax <26015+rmax@users.noreply.github.com> --- cmd/ratelord-d/config_test.go | 183 ++++++++++++++++++++++++++-------- 1 file changed, 139 insertions(+), 44 deletions(-) diff --git a/cmd/ratelord-d/config_test.go b/cmd/ratelord-d/config_test.go index 0a66b8f..447146d 100644 --- a/cmd/ratelord-d/config_test.go +++ b/cmd/ratelord-d/config_test.go @@ -11,9 +11,14 @@ import ( func TestLoadConfig_Defaults(t *testing.T) { // Setup: Create temp dir and cd into it tmpDir := t.TempDir() - oldWd, _ := os.Getwd() + oldWd, err := os.Getwd() + if err != nil { + t.Fatalf("failed to get working directory: %v", err) + } defer os.Chdir(oldWd) - os.Chdir(tmpDir) + if err := os.Chdir(tmpDir); err != nil { + t.Fatalf("failed to change directory: %v", err) + } config, err := LoadConfig([]string{}) if err != nil { @@ -40,9 +45,14 @@ func TestLoadConfig_Defaults(t *testing.T) { func TestLoadConfig_EnvVars(t *testing.T) { tmpDir := t.TempDir() - oldWd, _ := os.Getwd() + oldWd, err := os.Getwd() + if err != nil { + t.Fatalf("failed to get working directory: %v", err) + } defer os.Chdir(oldWd) - os.Chdir(tmpDir) + if err := os.Chdir(tmpDir); err != nil { + t.Fatalf("failed to change directory: %v", err) + } // Set env vars os.Setenv("RATELORD_DB_PATH", "/custom/db.db") @@ -82,9 +92,14 @@ func TestLoadConfig_EnvVars(t *testing.T) { func TestLoadConfig_FlagOverridesEnv(t *testing.T) { tmpDir := t.TempDir() - oldWd, _ := os.Getwd() + oldWd, err := os.Getwd() + if err != nil { + t.Fatalf("failed to get working directory: %v", err) + } defer os.Chdir(oldWd) - os.Chdir(tmpDir) + if err := os.Chdir(tmpDir); err != nil { + t.Fatalf("failed to change directory: %v", err) + } // Set env vars os.Setenv("RATELORD_ADDR", "env-addr:8080") @@ -113,14 +128,19 @@ func TestLoadConfig_FlagOverridesEnv(t *testing.T) { func TestLoadConfig_InvalidPollInterval_Env(t *testing.T) { tmpDir := t.TempDir() - oldWd, _ := os.Getwd() + oldWd, err := os.Getwd() + if err != nil { + t.Fatalf("failed to get working directory: %v", err) + } defer os.Chdir(oldWd) - os.Chdir(tmpDir) + if err := os.Chdir(tmpDir); err != nil { + t.Fatalf("failed to change directory: %v", err) + } os.Setenv("RATELORD_POLL_INTERVAL", "invalid") defer os.Unsetenv("RATELORD_POLL_INTERVAL") - _, err := LoadConfig([]string{}) + _, err = LoadConfig([]string{}) if err == nil { t.Fatal("expected error for invalid RATELORD_POLL_INTERVAL, got nil") } @@ -131,11 +151,16 @@ func TestLoadConfig_InvalidPollInterval_Env(t *testing.T) { func TestLoadConfig_InvalidPollInterval_Flag(t *testing.T) { tmpDir := t.TempDir() - oldWd, _ := os.Getwd() + oldWd, err := os.Getwd() + if err != nil { + t.Fatalf("failed to get working directory: %v", err) + } defer os.Chdir(oldWd) - os.Chdir(tmpDir) + if err := os.Chdir(tmpDir); err != nil { + t.Fatalf("failed to change directory: %v", err) + } - _, err := LoadConfig([]string{"-poll-interval", "not-a-duration"}) + _, err = LoadConfig([]string{"-poll-interval", "not-a-duration"}) if err == nil { t.Fatal("expected error for invalid poll-interval flag, got nil") } @@ -146,11 +171,16 @@ func TestLoadConfig_InvalidPollInterval_Flag(t *testing.T) { func TestLoadConfig_EmptyAddr(t *testing.T) { tmpDir := t.TempDir() - oldWd, _ := os.Getwd() + oldWd, err := os.Getwd() + if err != nil { + t.Fatalf("failed to get working directory: %v", err) + } defer os.Chdir(oldWd) - os.Chdir(tmpDir) + if err := os.Chdir(tmpDir); err != nil { + t.Fatalf("failed to change directory: %v", err) + } - _, err := LoadConfig([]string{"-addr", ""}) + _, err = LoadConfig([]string{"-addr", ""}) if err == nil { t.Fatal("expected error for empty addr, got nil") } @@ -161,11 +191,16 @@ func TestLoadConfig_EmptyAddr(t *testing.T) { func TestLoadConfig_EmptyAddr_Whitespace(t *testing.T) { tmpDir := t.TempDir() - oldWd, _ := os.Getwd() + oldWd, err := os.Getwd() + if err != nil { + t.Fatalf("failed to get working directory: %v", err) + } defer os.Chdir(oldWd) - os.Chdir(tmpDir) + if err := os.Chdir(tmpDir); err != nil { + t.Fatalf("failed to change directory: %v", err) + } - _, err := LoadConfig([]string{"-addr", " "}) + _, err = LoadConfig([]string{"-addr", " "}) if err == nil { t.Fatal("expected error for whitespace-only addr, got nil") } @@ -176,11 +211,16 @@ func TestLoadConfig_EmptyAddr_Whitespace(t *testing.T) { func TestLoadConfig_WebAssets_FS_MissingWebDir(t *testing.T) { tmpDir := t.TempDir() - oldWd, _ := os.Getwd() + oldWd, err := os.Getwd() + if err != nil { + t.Fatalf("failed to get working directory: %v", err) + } defer os.Chdir(oldWd) - os.Chdir(tmpDir) + if err := os.Chdir(tmpDir); err != nil { + t.Fatalf("failed to change directory: %v", err) + } - _, err := LoadConfig([]string{"-web-assets", "fs"}) + _, err = LoadConfig([]string{"-web-assets", "fs"}) if err == nil { t.Fatal("expected error when web-assets=fs but web-dir is missing, got nil") } @@ -191,9 +231,14 @@ func TestLoadConfig_WebAssets_FS_MissingWebDir(t *testing.T) { func TestLoadConfig_WebAssets_FS_WithWebDir(t *testing.T) { tmpDir := t.TempDir() - oldWd, _ := os.Getwd() + oldWd, err := os.Getwd() + if err != nil { + t.Fatalf("failed to get working directory: %v", err) + } defer os.Chdir(oldWd) - os.Chdir(tmpDir) + if err := os.Chdir(tmpDir); err != nil { + t.Fatalf("failed to change directory: %v", err) + } webDir := filepath.Join(tmpDir, "web") config, err := LoadConfig([]string{"-web-assets", "fs", "-web-dir", webDir}) @@ -211,11 +256,16 @@ func TestLoadConfig_WebAssets_FS_WithWebDir(t *testing.T) { func TestLoadConfig_InvalidWebAssetsMode(t *testing.T) { tmpDir := t.TempDir() - oldWd, _ := os.Getwd() + oldWd, err := os.Getwd() + if err != nil { + t.Fatalf("failed to get working directory: %v", err) + } defer os.Chdir(oldWd) - os.Chdir(tmpDir) + if err := os.Chdir(tmpDir); err != nil { + t.Fatalf("failed to change directory: %v", err) + } - _, err := LoadConfig([]string{"-web-assets", "invalid-mode"}) + _, err = LoadConfig([]string{"-web-assets", "invalid-mode"}) if err == nil { t.Fatal("expected error for invalid web-assets mode, got nil") } @@ -226,9 +276,14 @@ func TestLoadConfig_InvalidWebAssetsMode(t *testing.T) { func TestLoadConfig_PathResolution_Relative(t *testing.T) { tmpDir := t.TempDir() - oldWd, _ := os.Getwd() + oldWd, err := os.Getwd() + if err != nil { + t.Fatalf("failed to get working directory: %v", err) + } defer os.Chdir(oldWd) - os.Chdir(tmpDir) + if err := os.Chdir(tmpDir); err != nil { + t.Fatalf("failed to change directory: %v", err) + } config, err := LoadConfig([]string{ "-db", "data/ratelord.db", @@ -251,9 +306,14 @@ func TestLoadConfig_PathResolution_Relative(t *testing.T) { func TestLoadConfig_PathResolution_Absolute(t *testing.T) { tmpDir := t.TempDir() - oldWd, _ := os.Getwd() + oldWd, err := os.Getwd() + if err != nil { + t.Fatalf("failed to get working directory: %v", err) + } defer os.Chdir(oldWd) - os.Chdir(tmpDir) + if err := os.Chdir(tmpDir); err != nil { + t.Fatalf("failed to change directory: %v", err) + } absDBPath := "/absolute/path/to/db.db" absPolicyPath := "/absolute/path/to/policy.json" @@ -276,9 +336,14 @@ func TestLoadConfig_PathResolution_Absolute(t *testing.T) { func TestLoadConfig_EnvPortOnly(t *testing.T) { tmpDir := t.TempDir() - oldWd, _ := os.Getwd() + oldWd, err := os.Getwd() + if err != nil { + t.Fatalf("failed to get working directory: %v", err) + } defer os.Chdir(oldWd) - os.Chdir(tmpDir) + if err := os.Chdir(tmpDir); err != nil { + t.Fatalf("failed to change directory: %v", err) + } os.Setenv("RATELORD_PORT", "3000") defer os.Unsetenv("RATELORD_PORT") @@ -296,9 +361,14 @@ func TestLoadConfig_EnvPortOnly(t *testing.T) { func TestLoadConfig_EnvAddrOverridesPort(t *testing.T) { tmpDir := t.TempDir() - oldWd, _ := os.Getwd() + oldWd, err := os.Getwd() + if err != nil { + t.Fatalf("failed to get working directory: %v", err) + } defer os.Chdir(oldWd) - os.Chdir(tmpDir) + if err := os.Chdir(tmpDir); err != nil { + t.Fatalf("failed to change directory: %v", err) + } os.Setenv("RATELORD_ADDR", "0.0.0.0:8080") os.Setenv("RATELORD_PORT", "3000") @@ -320,9 +390,14 @@ func TestLoadConfig_EnvAddrOverridesPort(t *testing.T) { func TestLoadConfig_PolicyPathFallback(t *testing.T) { tmpDir := t.TempDir() - oldWd, _ := os.Getwd() + oldWd, err := os.Getwd() + if err != nil { + t.Fatalf("failed to get working directory: %v", err) + } defer os.Chdir(oldWd) - os.Chdir(tmpDir) + if err := os.Chdir(tmpDir); err != nil { + t.Fatalf("failed to change directory: %v", err) + } // Test that RATELORD_CONFIG_PATH is used as fallback for RATELORD_POLICY_PATH os.Setenv("RATELORD_CONFIG_PATH", "/fallback/config.json") @@ -340,9 +415,14 @@ func TestLoadConfig_PolicyPathFallback(t *testing.T) { func TestLoadConfig_PolicyPathPrimaryOverFallback(t *testing.T) { tmpDir := t.TempDir() - oldWd, _ := os.Getwd() + oldWd, err := os.Getwd() + if err != nil { + t.Fatalf("failed to get working directory: %v", err) + } defer os.Chdir(oldWd) - os.Chdir(tmpDir) + if err := os.Chdir(tmpDir); err != nil { + t.Fatalf("failed to change directory: %v", err) + } // Test that RATELORD_POLICY_PATH takes precedence over RATELORD_CONFIG_PATH os.Setenv("RATELORD_POLICY_PATH", "/primary/policy.json") @@ -419,9 +499,14 @@ func TestResolvePath(t *testing.T) { func TestLoadConfig_WebDirResolution(t *testing.T) { tmpDir := t.TempDir() - oldWd, _ := os.Getwd() + oldWd, err := os.Getwd() + if err != nil { + t.Fatalf("failed to get working directory: %v", err) + } defer os.Chdir(oldWd) - os.Chdir(tmpDir) + if err := os.Chdir(tmpDir); err != nil { + t.Fatalf("failed to change directory: %v", err) + } // Test that web-dir gets resolved when web-assets=fs config, err := LoadConfig([]string{ @@ -440,9 +525,14 @@ func TestLoadConfig_WebDirResolution(t *testing.T) { func TestLoadConfig_WebAssets_Embedded(t *testing.T) { tmpDir := t.TempDir() - oldWd, _ := os.Getwd() + oldWd, err := os.Getwd() + if err != nil { + t.Fatalf("failed to get working directory: %v", err) + } defer os.Chdir(oldWd) - os.Chdir(tmpDir) + if err := os.Chdir(tmpDir); err != nil { + t.Fatalf("failed to change directory: %v", err) + } config, err := LoadConfig([]string{"-web-assets", "embedded"}) if err != nil { @@ -457,9 +547,14 @@ func TestLoadConfig_WebAssets_Embedded(t *testing.T) { func TestLoadConfig_WebAssets_Off(t *testing.T) { tmpDir := t.TempDir() - oldWd, _ := os.Getwd() + oldWd, err := os.Getwd() + if err != nil { + t.Fatalf("failed to get working directory: %v", err) + } defer os.Chdir(oldWd) - os.Chdir(tmpDir) + if err := os.Chdir(tmpDir); err != nil { + t.Fatalf("failed to change directory: %v", err) + } config, err := LoadConfig([]string{"-web-assets", "off"}) if err != nil {