diff --git a/internal/config/config_load.go b/internal/config/config_load.go index cb63775a..2e62ad4a 100644 --- a/internal/config/config_load.go +++ b/internal/config/config_load.go @@ -379,6 +379,9 @@ func (c *Config) applyEnvOverrides() { if c.Tools.Browser.RemoteURL != "" { c.Tools.Browser.Enabled = true } + + // Cron job execution + envStr("GOCLAW_CRON_JOB_TIMEOUT", &c.Cron.JobTimeout) } // Save writes the config to a JSON file. diff --git a/internal/config/config_load_test.go b/internal/config/config_load_test.go index 912c04bc..49e9db49 100644 --- a/internal/config/config_load_test.go +++ b/internal/config/config_load_test.go @@ -5,6 +5,7 @@ import ( "os" "path/filepath" "testing" + "time" ) // --- Default --- @@ -429,3 +430,55 @@ func TestLoad_OwnerIDsEmpty(t *testing.T) { } } } + +// --- Cron job timeout env override --- + +func TestLoad_CronJobTimeout_EnvVar(t *testing.T) { + t.Setenv("GOCLAW_CRON_JOB_TIMEOUT", "1h") + + cfg, err := Load("/nonexistent/path") + if err != nil { + t.Fatalf("load error: %v", err) + } + if got := cfg.Cron.JobTimeoutDuration(); got != time.Hour { + t.Fatalf("cron timeout: got %v, want 1h", got) + } +} + +func TestLoad_CronJobTimeout_Invalid_FallsBackToDefault(t *testing.T) { + t.Setenv("GOCLAW_CRON_JOB_TIMEOUT", "not-a-duration") + + cfg, err := Load("/nonexistent/path") + if err != nil { + t.Fatalf("load error: %v", err) + } + if got := cfg.Cron.JobTimeoutDuration(); got != DefaultJobTimeout { + t.Fatalf("invalid duration should fall back to default %v, got %v", DefaultJobTimeout, got) + } +} + +func TestLoad_CronJobTimeout_Unset_UsesDefault(t *testing.T) { + cfg, err := Load("/nonexistent/path") + if err != nil { + t.Fatalf("load error: %v", err) + } + if got := cfg.Cron.JobTimeoutDuration(); got != DefaultJobTimeout { + t.Fatalf("unset env should use default %v, got %v", DefaultJobTimeout, got) + } +} + +func TestLoad_CronJobTimeout_EnvOverridesFile(t *testing.T) { + dir := t.TempDir() + cfgPath := filepath.Join(dir, "config.json5") + os.WriteFile(cfgPath, []byte(`{"cron":{"job_timeout":"5m"}}`), 0644) + + t.Setenv("GOCLAW_CRON_JOB_TIMEOUT", "30m") + + cfg, err := Load(cfgPath) + if err != nil { + t.Fatalf("load error: %v", err) + } + if got := cfg.Cron.JobTimeoutDuration(); got != 30*time.Minute { + t.Fatalf("env should override file: got %v, want 30m", got) + } +}