125 lines
4.1 KiB
Go
125 lines
4.1 KiB
Go
package config
|
|
|
|
import (
|
|
"encoding/json"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
"gitea.maximumdirect.net/eric/notarius/internal/framework/pipeline"
|
|
)
|
|
|
|
func TestVersion3DefaultsAndValidation(t *testing.T) {
|
|
cfg := Default()
|
|
if cfg.Output.Directory != "./notarius-output" || cfg.Debug.Directory != "./notarius-debug" || cfg.Cache.ChunkPlans.Mode != pipeline.ChunkCacheAuto {
|
|
t.Fatalf("unexpected defaults: %#v", cfg)
|
|
}
|
|
if err := cfg.Validate(); err != nil {
|
|
t.Fatalf("Validate() error = %v", err)
|
|
}
|
|
}
|
|
|
|
func TestVersion3FileSchemaIsStrictAndRejectsVersion2BeforeDecode(t *testing.T) {
|
|
_, err := ParseFileConfigYAML([]byte("version: 2\nworkspace:\n directory: /tmp/old\n"))
|
|
if err == nil || !strings.Contains(err.Error(), "version 2-to-3 migration") {
|
|
t.Fatalf("version 2 error = %v", err)
|
|
}
|
|
_, err = ParseFileConfigYAML([]byte("version: 3\nworkspace:\n directory: /tmp/old\n"))
|
|
if err == nil || !strings.Contains(err.Error(), "field workspace not found") {
|
|
t.Fatalf("unknown field error = %v", err)
|
|
}
|
|
_, err = ParseFileConfigYAML([]byte("version: 4\n"))
|
|
if err == nil || !strings.Contains(err.Error(), "unsupported config version 4") {
|
|
t.Fatalf("version 4 error = %v", err)
|
|
}
|
|
}
|
|
|
|
func TestStatePrecedenceAndInvalidSources(t *testing.T) {
|
|
file, err := ParseFileConfigYAML([]byte(`version: 3
|
|
output:
|
|
directory: ./file-output
|
|
cache:
|
|
chunk_plans:
|
|
directory: ./plans
|
|
mode: refresh
|
|
checkpoints:
|
|
directory: ./checkpoints
|
|
debug:
|
|
directory: ./debug
|
|
`))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
cfg := Default()
|
|
if err := cfg.ApplyFileConfig(file); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
lookup := func(name string) (string, bool) {
|
|
values := map[string]string{
|
|
"NOTARIUS_OUTPUT_DIR": "/env/output", "NOTARIUS_CACHE_CHUNK_PLANS_MODE": "auto",
|
|
"NOTARIUS_CACHE_CHUNK_PLANS_DIR": "/env/plans", "NOTARIUS_CACHE_CHECKPOINTS_DIR": "/env/checkpoints", "NOTARIUS_DEBUG_DIR": "/env/debug",
|
|
}
|
|
v, ok := values[name]
|
|
return v, ok
|
|
}
|
|
if err := cfg.ApplyEnvOverridesWithLookup(lookup); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if cfg.Output.Directory != "/env/output" || cfg.Cache.ChunkPlans.Directory != "/env/plans" || cfg.Cache.Checkpoints.Directory != "/env/checkpoints" || cfg.Debug.Directory != "/env/debug" || cfg.Cache.ChunkPlans.Mode != pipeline.ChunkCacheAuto {
|
|
t.Fatalf("unexpected environment precedence: %#v", cfg)
|
|
}
|
|
|
|
bad := Default()
|
|
err = bad.ApplyEnvOverridesWithLookup(func(name string) (string, bool) {
|
|
if name == "NOTARIUS_DEBUG_DIR" {
|
|
return " ", true
|
|
}
|
|
return "", false
|
|
})
|
|
if err == nil || !strings.Contains(err.Error(), "NOTARIUS_DEBUG_DIR") {
|
|
t.Fatalf("empty debug environment error = %v", err)
|
|
}
|
|
invalidFile, err := ParseFileConfigYAML([]byte("version: 3\noutput:\n directory: ' '\n"))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
bad = Default()
|
|
if err := bad.ApplyFileConfig(invalidFile); err == nil || !strings.Contains(err.Error(), "output.directory") {
|
|
t.Fatalf("invalid file error = %v", err)
|
|
}
|
|
}
|
|
|
|
func TestRedactedSummaryContainsOnlyVersion3StateFields(t *testing.T) {
|
|
cfg := Default()
|
|
cfg.Pipelines["example"] = pipeline.PipelineProfile{Input: pipeline.ModuleBinding{Module: "input", Options: map[string]any{"api_key": "secret-value", "safe": "value"}}}
|
|
payload, err := json.Marshal(cfg.RedactedSummaryPayload())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
text := string(payload)
|
|
for _, forbidden := range []string{"workspace", "diagnostics"} {
|
|
if strings.Contains(text, forbidden) {
|
|
t.Fatalf("payload contains %q: %s", forbidden, text)
|
|
}
|
|
}
|
|
if strings.Contains(text, "secret-value") || !strings.Contains(text, "[REDACTED]") {
|
|
t.Fatalf("payload did not redact sensitive option: %s", text)
|
|
}
|
|
}
|
|
|
|
func TestCacheFamilyDefaultsAreIndependent(t *testing.T) {
|
|
base := filepath.Join(t.TempDir(), "cache")
|
|
resolver := func() (string, error) { return base, nil }
|
|
plans, err := DefaultChunkPlanRoot(resolver)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
checkpoints, err := DefaultCheckpointRoot(resolver)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if plans == checkpoints || plans != filepath.Join(base, "notarius", "chunk-plans") || checkpoints != filepath.Join(base, "notarius", "checkpoints") {
|
|
t.Fatalf("roots = %q, %q", plans, checkpoints)
|
|
}
|
|
}
|