Detach callback values before publishing configuration
This commit is contained in:
52
callback_ownership_test.go
Normal file
52
callback_ownership_test.go
Normal file
@@ -0,0 +1,52 @@
|
||||
package configkit
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestCallbackAssignmentsAreDetachedAcrossLoads(t *testing.T) {
|
||||
type object struct{ Value string }
|
||||
type cfg struct {
|
||||
Map map[string][]*object
|
||||
Pointer *object
|
||||
Secret Secret
|
||||
}
|
||||
for _, validatorAssignment := range []bool{false, true} {
|
||||
name := "resolver"
|
||||
if validatorAssignment {
|
||||
name = "validator"
|
||||
}
|
||||
t.Run(name, func(t *testing.T) {
|
||||
external := &object{Value: "original"}
|
||||
shared := map[string][]*object{"key": {external}}
|
||||
definition := Definition[cfg]{Resolve: func(c *cfg, r *Resolution) error {
|
||||
Normalize(r, Keys("map"), &c.Map, shared, "populate")
|
||||
c.Pointer = external
|
||||
r.Record(Keys("pointer"), ChangeNormalization, "populate")
|
||||
c.Secret = SecretEnv("CONFIGKIT_CALLBACK_SECRET")
|
||||
r.Record(Keys("secret"), ChangeNormalization, "reference")
|
||||
return nil
|
||||
}}
|
||||
if validatorAssignment {
|
||||
definition.Validate = func(c *cfg, v *Validation) { c.Map = shared; c.Pointer = external }
|
||||
}
|
||||
calls := 0
|
||||
lookup := func(string) (string, bool) { calls++; return "credential", true }
|
||||
first, err := loadWithSecretLookup(NoSource(), lookup, Options[cfg]{Definition: definition})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
second, err := loadWithSecretLookup(NoSource(), lookup, Options[cfg]{Definition: definition})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
first.Config.Map["key"][0].Value = "changed"
|
||||
first.Config.Pointer.Value = "changed pointer"
|
||||
external.Value = "external change"
|
||||
if second.Config.Map["key"][0].Value != "original" || second.Config.Pointer.Value != "original" {
|
||||
t.Fatal("published configuration shares callback state")
|
||||
}
|
||||
if second.Config.Secret.Value() != "credential" || !second.Config.Secret.IsResolved() || calls != 2 {
|
||||
t.Fatal("publication changed secret state or repeated environment lookup")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user