Persist rewrote overrides.yaml with only this process's runtime values, so saving one key (for example websockets:generate-vapid-keys --update) dropped every key persisted earlier. It now starts from the saved file and lets runtime values win.
159 lines
4.8 KiB
Go
159 lines
4.8 KiB
Go
package compass
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
"testing/fstest"
|
|
)
|
|
|
|
func TestSetWinsOverPersistedOverrides(t *testing.T) {
|
|
dir := writeConfigTree(t, map[string]string{
|
|
"app.yaml": "name: base\n",
|
|
"env/development/overrides.yaml": "app:\n name: persisted\n",
|
|
})
|
|
cfg, err := Open(Options{Dir: dir, Env: "development", Environ: []string{}})
|
|
if err != nil {
|
|
t.Fatalf("Open: %v", err)
|
|
}
|
|
if got := cfg.String("app.name"); got != "persisted" {
|
|
t.Fatalf("loaded persisted name = %q, want persisted", got)
|
|
}
|
|
if err := cfg.Set("app.name", "runtime"); err != nil {
|
|
t.Fatalf("Set: %v", err)
|
|
}
|
|
if got := cfg.String("app.name"); got != "runtime" {
|
|
t.Fatalf("Set should win, got %q", got)
|
|
}
|
|
}
|
|
|
|
func TestPersistWritesEnvOverridesAtomicallyWithRestrictivePerms(t *testing.T) {
|
|
dir := writeConfigTree(t, map[string]string{
|
|
"app.yaml": "name: base\n",
|
|
})
|
|
cfg, err := Open(Options{Dir: dir, Env: "development", Environ: []string{}})
|
|
if err != nil {
|
|
t.Fatalf("Open: %v", err)
|
|
}
|
|
if err := cfg.Set("app.name", "saved"); err != nil {
|
|
t.Fatalf("Set: %v", err)
|
|
}
|
|
if err := cfg.Persist(); err != nil {
|
|
t.Fatalf("Persist: %v", err)
|
|
}
|
|
path := filepath.Join(dir, "env", "development", "overrides.yaml")
|
|
info, err := os.Stat(path)
|
|
if err != nil {
|
|
t.Fatalf("stat overrides: %v", err)
|
|
}
|
|
if info.Mode().Perm() != 0o600 {
|
|
t.Fatalf("overrides perm = %o, want 0600", info.Mode().Perm())
|
|
}
|
|
body, err := os.ReadFile(path)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !strings.Contains(string(body), "saved") {
|
|
t.Fatalf("overrides.yaml = %q, want to contain saved", body)
|
|
}
|
|
tmp := filepath.Join(dir, "env", "development", "overrides.yaml.tmp")
|
|
if _, err := os.Stat(tmp); !os.IsNotExist(err) {
|
|
t.Fatalf("temporary persist file should not remain: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestReloadClearsSetAndRereadsFiles(t *testing.T) {
|
|
dir := writeConfigTree(t, map[string]string{
|
|
"app.yaml": "name: base\n",
|
|
})
|
|
cfg, err := Open(Options{Dir: dir, Env: "development", Environ: []string{}})
|
|
if err != nil {
|
|
t.Fatalf("Open: %v", err)
|
|
}
|
|
fsys := fstest.MapFS{
|
|
"config/config.yaml": {Data: []byte("posts_per_page: 10\n")},
|
|
}
|
|
if err := cfg.MergePlugin("golem15.hello", fsys); err != nil {
|
|
t.Fatalf("MergePlugin: %v", err)
|
|
}
|
|
if err := cfg.Set("app.name", "runtime"); err != nil {
|
|
t.Fatalf("Set: %v", err)
|
|
}
|
|
if err := cfg.Persist(); err != nil {
|
|
t.Fatalf("Persist: %v", err)
|
|
}
|
|
if err := cfg.Set("app.name", "runtime2"); err != nil {
|
|
t.Fatalf("Set runtime2: %v", err)
|
|
}
|
|
if err := cfg.Set("golem15.hello.posts_per_page", 99); err != nil {
|
|
t.Fatalf("Set posts: %v", err)
|
|
}
|
|
if err := os.WriteFile(filepath.Join(dir, "app.yaml"), []byte("name: disk\n"), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := cfg.Reload(); err != nil {
|
|
t.Fatalf("Reload: %v", err)
|
|
}
|
|
if got := cfg.String("app.name"); got != "runtime" {
|
|
t.Fatalf("after Reload, name = %q, want persisted runtime (Set cleared)", got)
|
|
}
|
|
if got := cfg.Int("golem15.hello.posts_per_page"); got != 10 {
|
|
t.Fatalf("after Reload, posts_per_page = %d, want plugin default 10", got)
|
|
}
|
|
}
|
|
|
|
func TestPersistRejectsInvalidEnvName(t *testing.T) {
|
|
dir := writeConfigTree(t, map[string]string{
|
|
"app.yaml": "name: base\n",
|
|
})
|
|
_, err := Open(Options{Dir: dir, Env: "../etc", Environ: []string{}})
|
|
if err == nil {
|
|
t.Fatal("expected invalid environment name to fail")
|
|
}
|
|
if strings.Contains(strings.ToLower(err.Error()), "etc") {
|
|
t.Fatalf("error should not echo unsanitized env path: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestPersistKeepsEarlierOverrides(t *testing.T) {
|
|
dir := writeConfigTree(t, map[string]string{
|
|
"app.yaml": "name: base\n",
|
|
"env/development/overrides.yaml": "app:\n name: persisted\n",
|
|
})
|
|
cfg, err := Open(Options{Dir: dir, Env: "development", Environ: []string{}})
|
|
if err != nil {
|
|
t.Fatalf("Open: %v", err)
|
|
}
|
|
if err := cfg.Set("push.public_key", "saved-key"); err != nil {
|
|
t.Fatalf("Set: %v", err)
|
|
}
|
|
if err := cfg.Persist(); err != nil {
|
|
t.Fatalf("Persist: %v", err)
|
|
}
|
|
again, err := Open(Options{Dir: dir, Env: "development", Environ: []string{}})
|
|
if err != nil {
|
|
t.Fatalf("reopen: %v", err)
|
|
}
|
|
if got := again.String("push.public_key"); got != "saved-key" {
|
|
t.Fatalf("push.public_key = %q, want saved-key", got)
|
|
}
|
|
if got := again.String("app.name"); got != "persisted" {
|
|
t.Fatalf("app.name = %q, want the earlier persisted value", got)
|
|
}
|
|
// A runtime value replaces the persisted value of the same key.
|
|
if err := again.Set("app.name", "runtime"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := again.Persist(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
third, err := Open(Options{Dir: dir, Env: "development", Environ: []string{}})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if third.String("app.name") != "runtime" || third.String("push.public_key") != "saved-key" {
|
|
t.Fatalf("after second Persist: app.name=%q push.public_key=%q", third.String("app.name"), third.String("push.public_key"))
|
|
}
|
|
}
|