Stop startup on a list or map setting in neoirc.yaml (closes #268)
check / check (push) Failing after 6s
check / check (push) Failing after 6s
Every setting is now read through one helper that uses cast.ToStringE, the conversion viper.GetString wraps, keeping its error instead of returning the empty string. TRUSTED_PROXIES uses the same helper. A config file that does not parse makes New return an error naming the file instead of panicking. Model: opus-5-5
This commit is contained in:
1 parent
f42c6214a0
commit
dc19d0d7d1
4 files changed
+175
-91
No files matched your search
@@ -287,49 +287,93 @@ func TestTrustedProxies(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTrustedProxiesNotAStringInYAMLStopsStartup(t *testing.T) {
|
||||
// YAML reads the first value as a list and the second as a map.
|
||||
values := []string{"[10.0.0.1]", "{proxy: 10.0.0.1}"}
|
||||
// unsetEnv removes the environment variable key for the rest of the
|
||||
// test, so that config.New reads key from the config file.
|
||||
func unsetEnv(t *testing.T, key string) {
|
||||
t.Helper()
|
||||
|
||||
for _, value := range values {
|
||||
t.Run(value, func(t *testing.T) {
|
||||
// t.Setenv puts back whatever value was there after the
|
||||
// test, including when Unsetenv removes it.
|
||||
t.Setenv("TRUSTED_PROXIES", "")
|
||||
// t.Setenv puts back whatever value was there after the test,
|
||||
// including when Unsetenv removes it.
|
||||
t.Setenv(key, "")
|
||||
|
||||
err := os.Unsetenv("TRUSTED_PROXIES")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// loadConfig names the app neoirc-test, so config.New reads
|
||||
// $HOME/.config/neoirc-test/neoirc-test.yaml.
|
||||
home := t.TempDir()
|
||||
t.Setenv("HOME", home)
|
||||
|
||||
dir := filepath.Join(home, ".config", "neoirc-test")
|
||||
|
||||
err = os.MkdirAll(dir, 0o700)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = os.WriteFile(
|
||||
filepath.Join(dir, "neoirc-test.yaml"),
|
||||
[]byte("TRUSTED_PROXIES: "+value+"\n"), 0o600,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Viper keeps the values it read from this file after the
|
||||
// file is gone. Reset clears them for later tests.
|
||||
t.Cleanup(viper.Reset)
|
||||
|
||||
_, err = loadConfig(t)
|
||||
if err == nil || !strings.Contains(err.Error(), "TRUSTED_PROXIES") {
|
||||
t.Errorf("error = %v, want one naming TRUSTED_PROXIES", err)
|
||||
}
|
||||
})
|
||||
err := os.Unsetenv(key)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// writeConfigFile writes content to the config file config.New reads
|
||||
// when HOME is home, and returns the file's path.
|
||||
func writeConfigFile(t *testing.T, home, content string) string {
|
||||
t.Helper()
|
||||
|
||||
// loadConfig names the app neoirc-test, so config.New reads
|
||||
// $HOME/.config/neoirc-test/neoirc-test.yaml.
|
||||
dir := filepath.Join(home, ".config", "neoirc-test")
|
||||
|
||||
err := os.MkdirAll(dir, 0o700)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
path := filepath.Join(dir, "neoirc-test.yaml")
|
||||
|
||||
err = os.WriteFile(path, []byte(content), 0o600)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Viper keeps the file and the values it read from it after the
|
||||
// file is gone. Reset clears them for later tests.
|
||||
t.Cleanup(viper.Reset)
|
||||
|
||||
return path
|
||||
}
|
||||
|
||||
func TestListOrMapInConfigFileStopsStartup(t *testing.T) {
|
||||
// YAML reads the first value as a list and the second as a map.
|
||||
values := []string{`[":6667"]`, `{addr: ":6667"}`}
|
||||
keys := []string{"IRC_LISTEN_ADDR", "MOTD", "TRUSTED_PROXIES"}
|
||||
|
||||
for _, key := range keys {
|
||||
for _, value := range values {
|
||||
t.Run(key+"="+value, func(t *testing.T) {
|
||||
home := t.TempDir()
|
||||
t.Setenv("HOME", home)
|
||||
unsetEnv(t, key)
|
||||
writeConfigFile(t, home, key+": "+value+"\n")
|
||||
|
||||
_, err := loadConfig(t)
|
||||
if err == nil || !strings.Contains(err.Error(), key) {
|
||||
t.Errorf("error = %v, want one naming %s", err, key)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSingleValuesInConfigFileAreUsed(t *testing.T) {
|
||||
home := t.TempDir()
|
||||
t.Setenv("HOME", home)
|
||||
unsetEnv(t, "PORT")
|
||||
unsetEnv(t, "DEBUG")
|
||||
unsetEnv(t, "MOTD")
|
||||
writeConfigFile(t, home, "PORT: 9000\nDEBUG: true\nMOTD: hello\n")
|
||||
|
||||
cfg := newConfig(t)
|
||||
if cfg.Port != 9000 || !cfg.Debug || cfg.MOTD != "hello" {
|
||||
t.Errorf("Port, Debug, MOTD = %d, %t, %q, want 9000, true, %q",
|
||||
cfg.Port, cfg.Debug, cfg.MOTD, "hello")
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigFileThatDoesNotParseStopsStartup(t *testing.T) {
|
||||
home := t.TempDir()
|
||||
t.Setenv("HOME", home)
|
||||
path := writeConfigFile(t, home, "MOTD: [unclosed\n")
|
||||
|
||||
_, err := loadConfig(t)
|
||||
if err == nil || !strings.Contains(err.Error(), path) {
|
||||
t.Errorf("error = %v, want one naming %s", err, path)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user