Complete facade inspection and secrets bootstrap

This commit is contained in:
2026-09-12 16:19:22 +00:00
parent da307c9f49
commit 550f92d7c6
7 changed files with 358 additions and 6 deletions

View File

@@ -1,10 +1,14 @@
package configkit_test
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
"os"
"reflect"
"strings"
"testing"
configkit "gitea.maximumdirect.net/eric/ConfigKit/internal/facade"
@@ -29,6 +33,10 @@ func TestFacadeValuesRemainRootOwned(t *testing.T) {
reflect.TypeFor[configkit.FilesystemContext](), reflect.TypeFor[configkit.Override](),
reflect.TypeFor[configkit.Definition[struct{}]](), reflect.TypeFor[configkit.Options[struct{}]](),
reflect.TypeFor[configkit.Result[struct{}]](),
reflect.TypeFor[configkit.ValueSnapshot](), reflect.TypeFor[configkit.ValueChange](),
reflect.TypeFor[configkit.SecretReferenceInfo](), reflect.TypeFor[configkit.Explanation](),
reflect.TypeFor[configkit.SecretFileResult](), reflect.TypeFor[configkit.SecretsReport](),
reflect.TypeFor[configkit.SecretsError](),
} {
if candidate.PkgPath() != packagePath {
t.Fatalf("type %s belongs to %q", candidate, candidate.PkgPath())
@@ -48,6 +56,118 @@ func TestFacadeValuesRemainRootOwned(t *testing.T) {
}
}
func TestFacadeInspectionUsesFrozenState(t *testing.T) {
t.Setenv("FACADE_INSPECTION_SECRET", "credential")
type configuration struct {
Value string `yaml:"value"`
Secret configkit.Secret `yaml:"secret"`
}
result, err := configkit.Load[configuration](configkit.Bytes("inspection.yml", []byte("value: original\nsecret: FACADE_INSPECTION_SECRET\n")))
if err != nil {
t.Fatal(err)
}
if !result.Config.Secret.IsResolved() || result.Config.Secret.Value() != "credential" {
t.Fatalf("secret = %#v", result.Config.Secret)
}
explanation, ok := result.Explain(configkit.Keys("value"))
if !ok || explanation.Effective.YAML != "original\n" {
t.Fatalf("explanation = %#v, %v", explanation, ok)
}
explanation.Effective.YAML = "mutated\n"
result.Config.Value = "mutated"
var effective bytes.Buffer
if err := result.WriteEffective(&effective); err != nil || !strings.Contains(effective.String(), "value: original\n") || strings.Contains(effective.String(), "credential") {
t.Fatalf("effective = %q, %v", effective.String(), err)
}
again, ok := result.Explain(configkit.Keys("value"))
if !ok || again.Effective.YAML != "original\n" {
t.Fatalf("inspection changed = %#v, %v", again, ok)
}
secret, ok := result.Explain(configkit.Keys("secret"))
if !ok || secret.SecretReference == nil || secret.SecretReference.Name != "FACADE_INSPECTION_SECRET" {
t.Fatalf("secret explanation = %#v, %v", secret, ok)
}
var explanationOutput bytes.Buffer
if err := result.WriteExplanation(&explanationOutput, configkit.Keys("value")); err != nil || !strings.Contains(explanationOutput.String(), `path: "/value"`) {
t.Fatalf("explanation output = %q, %v", explanationOutput.String(), err)
}
unknown := bytes.NewBufferString("unchanged")
if err := result.WriteExplanation(unknown, configkit.Keys("unknown")); err == nil || unknown.String() != "unchanged" {
t.Fatalf("unknown explanation = %q, %v", unknown.String(), err)
}
var nilResult *configkit.Result[configuration]
if _, ok := nilResult.Explain(configkit.Keys("value")); ok {
t.Fatal("nil result explained a path")
}
if err := nilResult.WriteEffective(io.Discard); err == nil {
t.Fatal("nil result rendered effective configuration")
}
}
func TestFacadeSecretsBootstrapUsesFacadeRecords(t *testing.T) {
const (
loadedName = "FACADE_BOOTSTRAP_LOADED"
existingName = "FACADE_BOOTSTRAP_EXISTING"
)
restore := func(name string) {
value, present := os.LookupEnv(name)
t.Cleanup(func() {
if present {
_ = os.Setenv(name, value)
} else {
_ = os.Unsetenv(name)
}
})
}
restore(loadedName)
restore(existingName)
if err := os.Unsetenv(loadedName); err != nil {
t.Fatal(err)
}
if err := os.Setenv(existingName, ""); err != nil {
t.Fatal(err)
}
directory := t.TempDir()
if err := os.WriteFile(directory+"/"+loadedName, []byte("bootstrap\n"), 0o600); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(directory+"/"+existingName, []byte("ignored\n"), 0o600); err != nil {
t.Fatal(err)
}
report, err := configkit.LoadSecretsDir(directory)
if err != nil {
t.Fatal(err)
}
entries := report.Entries()
if len(entries) != 2 || os.Getenv(loadedName) != "bootstrap" {
t.Fatalf("entries/environment = %#v / %q", entries, os.Getenv(loadedName))
}
status := map[string]configkit.SecretFileResult{}
for _, entry := range entries {
status[entry.Name] = entry
}
if status[loadedName].Status != configkit.SecretFileLoaded || status[existingName].Status != configkit.SecretFileSkippedExisting || !status[existingName].ExistingEmpty {
t.Fatalf("statuses = %#v", status)
}
entries[0].Name = "mutated"
if report.Entries()[0].Name == "mutated" {
t.Fatal("report entries share mutable state")
}
var rendered bytes.Buffer
if _, err := report.WriteTo(&rendered); err != nil || strings.Contains(rendered.String(), "bootstrap") || strings.Contains(rendered.String(), "ignored") {
t.Fatalf("report rendering = %q, %v", rendered.String(), err)
}
failedReport, err := configkit.LoadSecretsDir("")
var secretsError *configkit.SecretsError
if failedReport == nil || !errors.As(err, &secretsError) || len(secretsError.Diagnostics()) != 1 || secretsError.Diagnostics()[0].Code != configkit.CodeSecretsInvalidPath {
t.Fatalf("bootstrap failure = %#v / %#v", failedReport, err)
}
}
func TestFacadeLoadBridgesLifecycleCallbacks(t *testing.T) {
t.Setenv("FACADE_SECRET_NAME", "credential")