Apply ConfigKit operational configuration defaults
This commit is contained in:
184
internal/core/config/operational_document_test.go
Normal file
184
internal/core/config/operational_document_test.go
Normal file
@@ -0,0 +1,184 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
configkit "gitea.maximumdirect.net/eric/ConfigKit"
|
||||
)
|
||||
|
||||
func TestDocumentLoadAppliesOperationalDefaultsAndNormalization(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
loaded, err := loadDocumentSource(configkit.Bytes("document.yml", []byte(`version: 5
|
||||
concurrency:
|
||||
total_llm: 4
|
||||
promptkit:
|
||||
profile_dir: " ./profiles "
|
||||
local_backend:
|
||||
endpoint: " https://localhost:8080/v1 "
|
||||
output:
|
||||
directory: " ./output "
|
||||
cache:
|
||||
chunk_plans:
|
||||
mode: " refresh "
|
||||
directory: " "
|
||||
checkpoints:
|
||||
directory: " "
|
||||
debug:
|
||||
directory: " ./debug "
|
||||
`)), LoadOptions{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if loaded.Config.Concurrency.TotalLLM == nil || *loaded.Config.Concurrency.TotalLLM != 4 || loaded.Config.Concurrency.StageWorkers["extract"] != 4 {
|
||||
t.Fatalf("concurrency = %#v", loaded.Config.Concurrency)
|
||||
}
|
||||
if loaded.Config.PromptKit.ProfileDir == nil || *loaded.Config.PromptKit.ProfileDir != "./profiles" ||
|
||||
loaded.Config.PromptKit.LocalBackend == nil || loaded.Config.PromptKit.LocalBackend.Endpoint == nil || *loaded.Config.PromptKit.LocalBackend.Endpoint != "https://localhost:8080/v1" ||
|
||||
loaded.Config.PromptKit.LocalBackend.ConcurrencyLimit == nil || *loaded.Config.PromptKit.LocalBackend.ConcurrencyLimit != 0 {
|
||||
t.Fatalf("promptkit = %#v", loaded.Config.PromptKit)
|
||||
}
|
||||
if loaded.Config.Output.Directory == nil || *loaded.Config.Output.Directory != "./output" ||
|
||||
loaded.Config.Cache.ChunkPlans.Mode == nil || *loaded.Config.Cache.ChunkPlans.Mode != "refresh" ||
|
||||
loaded.Config.Cache.ChunkPlans.Directory == nil || *loaded.Config.Cache.ChunkPlans.Directory != "" ||
|
||||
loaded.Config.Cache.Checkpoints.Directory == nil || *loaded.Config.Cache.Checkpoints.Directory != "" ||
|
||||
loaded.Config.Debug.Directory == nil || *loaded.Config.Debug.Directory != "./debug" {
|
||||
t.Fatalf("state = %#v, %#v, %#v", loaded.Config.Output, loaded.Config.Cache, loaded.Config.Debug)
|
||||
}
|
||||
if diagnostics := loaded.Diagnostics(); len(diagnostics) != 0 {
|
||||
t.Fatalf("diagnostics = %#v", diagnostics)
|
||||
}
|
||||
extractHistory := loaded.Metadata().History(configkit.Keys("concurrency", "stage_workers", "extract"))
|
||||
if len(extractHistory) == 0 || extractHistory[len(extractHistory)-1].Origin.Operation != configkit.ChangeDerivedDefault {
|
||||
t.Fatalf("extract history = %#v", extractHistory)
|
||||
}
|
||||
outputHistory := loaded.Metadata().History(configkit.Keys("output", "directory"))
|
||||
if len(outputHistory) == 0 || outputHistory[len(outputHistory)-1].Origin.Operation != configkit.ChangeNormalization {
|
||||
t.Fatalf("output history = %#v", outputHistory)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDocumentLoadDerivesWorkersAfterProfileAndCLIOverrides(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
directory := t.TempDir()
|
||||
main := filepath.Join(directory, "config.yml")
|
||||
profiles := filepath.Join(directory, "profiles")
|
||||
if err := os.Mkdir(profiles, 0o755); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := os.WriteFile(main, []byte("version: 5\nconcurrency:\n total_llm: 4\n"), 0o600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := os.WriteFile(filepath.Join(profiles, "development.yml"), []byte("concurrency:\n total_llm: 3\n"), 0o600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
profiled, err := loadDocument(main, LoadOptions{Profile: "development"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if profiled.Config.Concurrency.TotalLLM == nil || *profiled.Config.Concurrency.TotalLLM != 3 || profiled.Config.Concurrency.StageWorkers["extract"] != 3 {
|
||||
t.Fatalf("profiled concurrency = %#v", profiled.Config.Concurrency)
|
||||
}
|
||||
|
||||
overridden, err := loadDocument(main, LoadOptions{Overrides: []configkit.Override{{
|
||||
Path: configkit.Keys("concurrency", "total_llm"), Value: 2, Flag: "--total-llm",
|
||||
}}})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if overridden.Config.Concurrency.TotalLLM == nil || *overridden.Config.Concurrency.TotalLLM != 2 || overridden.Config.Concurrency.StageWorkers["extract"] != 2 {
|
||||
t.Fatalf("overridden concurrency = %#v", overridden.Config.Concurrency)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDocumentLoadRetainsExplicitWorkerAndRejectsInvalidOperationalValues(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
loaded, err := loadDocumentSource(configkit.Bytes("explicit.yml", []byte(`version: 5
|
||||
concurrency:
|
||||
total_llm: 4
|
||||
stage_workers:
|
||||
extract: 0
|
||||
`)), LoadOptions{})
|
||||
if loaded != nil {
|
||||
t.Fatalf("loaded = %#v, want validation failure", loaded.Config)
|
||||
}
|
||||
assertDocumentDiagnostic(t, err, configkit.CodeValidateError, "/concurrency/stage_workers/extract")
|
||||
|
||||
_, err = loadDocumentSource(configkit.Bytes("invalid.yml", []byte(`version: 5
|
||||
concurrency:
|
||||
total_llm: 0
|
||||
output:
|
||||
directory: ""
|
||||
promptkit:
|
||||
local_backend:
|
||||
endpoint: "ftp://localhost"
|
||||
concurrency_limit: -1
|
||||
`)), LoadOptions{})
|
||||
var loadError *configkit.LoadError
|
||||
if !errors.As(err, &loadError) {
|
||||
t.Fatalf("error = %v, want ConfigKit load error", err)
|
||||
}
|
||||
seen := make(map[string]bool)
|
||||
for _, diagnostic := range loadError.Diagnostics() {
|
||||
if diagnostic.Code != configkit.CodeValidateError || diagnostic.Primary == nil {
|
||||
t.Fatalf("diagnostic = %#v", diagnostic)
|
||||
}
|
||||
seen[diagnostic.Path.String()] = true
|
||||
}
|
||||
for _, path := range []string{"/concurrency/total_llm", "/output/directory", "/promptkit/local_backend/endpoint", "/promptkit/local_backend/concurrency_limit"} {
|
||||
if !seen[path] {
|
||||
t.Fatalf("diagnostics missing %s: %#v", path, loadError.Diagnostics())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDocumentLoadDistinguishesRequiredAndOptionalPathValues(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
loaded, err := loadDocumentSource(configkit.Bytes("cache.yml", []byte(`version: 5
|
||||
cache:
|
||||
chunk_plans:
|
||||
directory: " "
|
||||
checkpoints:
|
||||
directory: " "
|
||||
`)), LoadOptions{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if loaded.Config.Cache.ChunkPlans.Directory == nil || *loaded.Config.Cache.ChunkPlans.Directory != "" ||
|
||||
loaded.Config.Cache.Checkpoints.Directory == nil || *loaded.Config.Cache.Checkpoints.Directory != "" {
|
||||
t.Fatalf("cache directories = %#v", loaded.Config.Cache)
|
||||
}
|
||||
|
||||
_, err = loadDocumentSource(configkit.Bytes("output.yml", []byte("version: 5\noutput:\n directory: ' '\n")), LoadOptions{})
|
||||
assertDocumentDiagnostic(t, err, configkit.CodeValidateError, "/output/directory")
|
||||
|
||||
_, err = loadDocumentSource(configkit.Bytes("promptkit.yml", []byte("version: 5\npromptkit:\n profile_file: null\n local_backend: {}\n")), LoadOptions{})
|
||||
assertDocumentDiagnostic(t, err, configkit.CodeResolveError, "/promptkit/profile_file")
|
||||
|
||||
_, err = loadDocumentSource(configkit.Bytes("empty-source.yml", []byte("version: 5\npromptkit:\n profile_dir: ' '\n")), LoadOptions{})
|
||||
assertDocumentDiagnostic(t, err, configkit.CodeValidateError, "/promptkit/profile_dir")
|
||||
|
||||
_, err = loadDocumentSource(configkit.Bytes("missing-endpoint.yml", []byte("version: 5\npromptkit:\n local_backend: {}\n")), LoadOptions{})
|
||||
assertDocumentDiagnostic(t, err, configkit.CodeValidateError, "/promptkit/local_backend/endpoint")
|
||||
}
|
||||
|
||||
func assertDocumentDiagnostic(t *testing.T, err error, code configkit.Code, path string) {
|
||||
t.Helper()
|
||||
var loadError *configkit.LoadError
|
||||
if !errors.As(err, &loadError) {
|
||||
t.Fatalf("error = %v, want ConfigKit load error", err)
|
||||
}
|
||||
for _, diagnostic := range loadError.Diagnostics() {
|
||||
if diagnostic.Code == code && diagnostic.Path.String() == path {
|
||||
return
|
||||
}
|
||||
}
|
||||
t.Fatalf("diagnostics = %#v, want %s at %s", loadError.Diagnostics(), code, path)
|
||||
}
|
||||
Reference in New Issue
Block a user