diff options
| author | Fuwn <[email protected]> | 2026-02-28 05:39:38 -0800 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2026-02-28 05:39:38 -0800 |
| commit | 2525861018ccd4db2f683a8778e5784a9e2942f5 (patch) | |
| tree | 6232a03b8ff0633adf920bafdcb946b2c1b62928 /internal/config | |
| parent | chore(compose): add thin mode override (diff) | |
| download | plutia-test-2525861018ccd4db2f683a8778e5784a9e2942f5.tar.xz plutia-test-2525861018ccd4db2f683a8778e5784a9e2942f5.zip | |
feat(config): allow optional config file with default fallback
Diffstat (limited to 'internal/config')
| -rw-r--r-- | internal/config/config.go | 12 | ||||
| -rw-r--r-- | internal/config/config_load_test.go | 82 |
2 files changed, 89 insertions, 5 deletions
diff --git a/internal/config/config.go b/internal/config/config.go index 69173fd..47f5842 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -89,11 +89,13 @@ func Load(path string) (Config, error) { b, err := os.ReadFile(path) if err != nil { - return Config{}, fmt.Errorf("read config: %w", err) - } - - if err := yaml.Unmarshal(b, &cfg); err != nil { - return Config{}, fmt.Errorf("parse config: %w", err) + if !errors.Is(err, os.ErrNotExist) { + return Config{}, fmt.Errorf("read config: %w", err) + } + } else { + if err := yaml.Unmarshal(b, &cfg); err != nil { + return Config{}, fmt.Errorf("parse config: %w", err) + } } } diff --git a/internal/config/config_load_test.go b/internal/config/config_load_test.go new file mode 100644 index 0000000..516dd93 --- /dev/null +++ b/internal/config/config_load_test.go @@ -0,0 +1,82 @@ +package config + +import ( + "os" + "path/filepath" + "testing" + "time" +) + +func TestLoadMissingConfigFileFallsBackToDefaults(t *testing.T) { + cfg, err := Load(filepath.Join(t.TempDir(), "missing.yaml")) + if err != nil { + t.Fatalf("load missing config: %v", err) + } + + def := Default() + if cfg.Mode != def.Mode { + t.Fatalf("mode mismatch: got %q want %q", cfg.Mode, def.Mode) + } + if cfg.VerifyPolicy != def.VerifyPolicy { + t.Fatalf("verify policy mismatch: got %q want %q", cfg.VerifyPolicy, def.VerifyPolicy) + } + if cfg.CheckpointInterval != def.CheckpointInterval { + t.Fatalf("checkpoint interval mismatch: got %d want %d", cfg.CheckpointInterval, def.CheckpointInterval) + } + if cfg.VerifyWorkers != def.VerifyWorkers { + t.Fatalf("verify workers mismatch: got %d want %d", cfg.VerifyWorkers, def.VerifyWorkers) + } +} + +func TestLoadPartialConfigRetainsDefaultValues(t *testing.T) { + configPath := filepath.Join(t.TempDir(), "partial.yaml") + content := []byte("mode: thin\nverify: full\n") + + if err := os.WriteFile(configPath, content, 0o644); err != nil { + t.Fatalf("write partial config: %v", err) + } + + cfg, err := Load(configPath) + if err != nil { + t.Fatalf("load partial config: %v", err) + } + + if cfg.Mode != ModeThin { + t.Fatalf("mode mismatch: got %q want %q", cfg.Mode, ModeThin) + } + if cfg.VerifyPolicy != VerifyFull { + t.Fatalf("verify policy mismatch: got %q want %q", cfg.VerifyPolicy, VerifyFull) + } + + def := Default() + if cfg.PLCSource != def.PLCSource { + t.Fatalf("plc_source mismatch: got %q want %q", cfg.PLCSource, def.PLCSource) + } + if cfg.RequestTimeout != 10*time.Second { + t.Fatalf("request_timeout mismatch: got %s want 10s", cfg.RequestTimeout) + } + if cfg.CommitBatchSize != def.CommitBatchSize { + t.Fatalf("commit_batch_size mismatch: got %d want %d", cfg.CommitBatchSize, def.CommitBatchSize) + } +} + +func TestLoadMissingConfigFileAppliesEnvOverrides(t *testing.T) { + t.Setenv("PLUTIA_MODE", ModeThin) + t.Setenv("PLUTIA_VERIFY", VerifyFull) + t.Setenv("PLUTIA_REQUEST_TIMEOUT", "15s") + + cfg, err := Load(filepath.Join(t.TempDir(), "missing.yaml")) + if err != nil { + t.Fatalf("load missing config with env overrides: %v", err) + } + + if cfg.Mode != ModeThin { + t.Fatalf("mode mismatch: got %q want %q", cfg.Mode, ModeThin) + } + if cfg.VerifyPolicy != VerifyFull { + t.Fatalf("verify policy mismatch: got %q want %q", cfg.VerifyPolicy, VerifyFull) + } + if cfg.RequestTimeout != 15*time.Second { + t.Fatalf("request_timeout mismatch: got %s want 15s", cfg.RequestTimeout) + } +} |