62 lines
2.0 KiB
Go
62 lines
2.0 KiB
Go
package config
|
|
|
|
import (
|
|
"bytes"
|
|
"io"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestConfigFilePreservesDefaultsWithoutSharingMutableData(t *testing.T) {
|
|
type cfg struct {
|
|
Writer io.Writer `json:"-"`
|
|
Secret string `json:"-"`
|
|
Values map[string]int64 `json:"values"`
|
|
Timers map[string]time.Duration `json:"timers"`
|
|
ID int64 `json:"id"`
|
|
}
|
|
var writer bytes.Buffer
|
|
base := cfg{Writer: &writer, Secret: "borrowedSecret", Values: map[string]int64{"old": 7}, ID: 9007199254740993}
|
|
file := filepath.Join(t.TempDir(), "config.json")
|
|
if err := os.WriteFile(file, []byte(`{"values":{"new":2},"timers":{"retry":"2s"}}`), 0600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
next, err := DecodeFile(file, base)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if next.Writer != &writer || next.Secret != base.Secret || next.ID != base.ID || next.Timers["retry"] != 2*time.Second || len(base.Values) != 1 {
|
|
t.Fatal("defaults lost or mutated")
|
|
}
|
|
next.Values["old"] = 9
|
|
if base.Values["old"] != 7 {
|
|
t.Fatal("defaults shared map")
|
|
}
|
|
if err = os.WriteFile(file, []byte(`{"values":{"secretValue":"credential-super-secret"}}`), 0600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err = DecodeFile(file, base); err == nil || strings.Contains(err.Error(), "credential-super-secret") {
|
|
t.Fatal("decode error leaked contents", err)
|
|
}
|
|
}
|
|
func TestEnvCollectionPrecisionAndDurationMaps(t *testing.T) {
|
|
type cfg struct {
|
|
IDs []int64 `json:"ids"`
|
|
Timers map[string]time.Duration `json:"timers"`
|
|
}
|
|
lookup := func(key string) (string, bool) {
|
|
v, ok := map[string]string{"IDS": "[9007199254740993]", "TIMERS": `{"backoff":"250ms"}`}[key]
|
|
return v, ok
|
|
}
|
|
c, err := OverlayEnv(cfg{}, EnvOptions{Lookup: lookup})
|
|
if err != nil || c.IDs[0] != 9007199254740993 || c.Timers["backoff"] != 250*time.Millisecond {
|
|
t.Fatal(c, err)
|
|
}
|
|
if _, err = OverlayEnv(cfg{}, EnvOptions{Lookup: func(key string) (string, bool) { return `{"x":"1s","x":"2s"}`, key == "TIMERS" }}); err == nil {
|
|
t.Fatal("duplicate map key accepted")
|
|
}
|
|
}
|