From e1eadf705d9d6ee5a6425c06c88ce41c32739ad4 Mon Sep 17 00:00:00 2001 From: Virgil Date: Sun, 5 Apr 2026 03:36:21 +0000 Subject: [PATCH] fix(proxy): separate config loading from validation Co-Authored-By: Virgil --- config_load_test.go | 63 +++++++++++++++++++++++++++++++++++++++++++++ core_impl.go | 2 +- 2 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 config_load_test.go diff --git a/config_load_test.go b/config_load_test.go new file mode 100644 index 0000000..14bc4aa --- /dev/null +++ b/config_load_test.go @@ -0,0 +1,63 @@ +package proxy + +import ( + "os" + "path/filepath" + "testing" +) + +func TestConfig_LoadConfig_Good(t *testing.T) { + dir := t.TempDir() + path := filepath.Join(dir, "config.json") + data := []byte(`{"mode":"nicehash","workers":"rig-id","bind":[{"host":"0.0.0.0","port":3333}],"pools":[{"url":"pool.example:3333","enabled":true}]}`) + if err := os.WriteFile(path, data, 0o600); err != nil { + t.Fatalf("expected config file write to succeed: %v", err) + } + + cfg, result := LoadConfig(path) + if !result.OK { + t.Fatalf("expected load to succeed, got error: %v", result.Error) + } + if cfg == nil { + t.Fatal("expected config to be returned") + } + if got := cfg.Mode; got != "nicehash" { + t.Fatalf("expected mode to round-trip, got %q", got) + } + if got := cfg.configPath; got != path { + t.Fatalf("expected config path to be recorded, got %q", got) + } +} + +func TestConfig_LoadConfig_Bad(t *testing.T) { + cfg, result := LoadConfig(filepath.Join(t.TempDir(), "missing.json")) + if result.OK { + t.Fatalf("expected missing config file to fail, got cfg=%+v", cfg) + } + if cfg != nil { + t.Fatalf("expected no config on read failure, got %+v", cfg) + } +} + +func TestConfig_LoadConfig_Ugly(t *testing.T) { + dir := t.TempDir() + path := filepath.Join(dir, "config.json") + data := []byte(`{"mode":"invalid","workers":"rig-id","bind":[],"pools":[]}`) + if err := os.WriteFile(path, data, 0o600); err != nil { + t.Fatalf("expected config file write to succeed: %v", err) + } + + cfg, result := LoadConfig(path) + if !result.OK { + t.Fatalf("expected syntactically valid JSON to load, got error: %v", result.Error) + } + if cfg == nil { + t.Fatal("expected config to be returned") + } + if got := cfg.Mode; got != "invalid" { + t.Fatalf("expected invalid mode value to be preserved, got %q", got) + } + if validation := cfg.Validate(); validation.OK { + t.Fatal("expected semantic validation to fail separately from loading") + } +} diff --git a/core_impl.go b/core_impl.go index 60d2067..9a3214c 100644 --- a/core_impl.go +++ b/core_impl.go @@ -72,7 +72,7 @@ func LoadConfig(path string) (*Config, Result) { return nil, newErrorResult(NewScopedError("proxy.config", "parse config failed", err)) } config.configPath = path - return config, config.Validate() + return config, newSuccessResult() } // cfg := &proxy.Config{