1 Commits
Author SHA1 Message Date
sneak e2aaf6dc35 Stop startup when a setting does not parse (closes #219)
check / check (push) Waiting to run
config.New read the number and true/false settings with viper's
GetInt, GetFloat64 and GetBool. These return zero or false for a value
that does not parse, so a typo silently changed how the server ran.

config.New now parses these settings with strconv and checks the
duration settings with time.ParseDuration. Each number and duration
must also be finite and above zero. PORT and NEOIRC_HASHCASH_BITS may
be zero: port 0 lets the system pick a port, and 0 bits turns proof of
work off. A bad value makes config.New return an error naming the
setting and its value, and startup stops. Unset settings keep their
defaults.

Model: opus-5-5
2026-10-27 23:09:39 +00:00
2 changed files with 13 additions and 11 deletions
+3 -3
View File
@@ -191,9 +191,9 @@ func parseInt(key string, minimum int, value *int) error {
return nil
}
// parseFloat sets *value to the setting key read as a decimal number. It
// returns an error when the value does not parse or is not a finite
// number above zero.
// parseFloat sets *value to the setting key read as a floating-point
// number. It returns an error when the value does not parse or is not a
// finite number above zero.
func parseFloat(key string, value *float64) error {
raw := viper.GetString(key)
+10 -8
View File
@@ -78,26 +78,28 @@ func TestUnsetSettingsKeepDefaults(t *testing.T) {
}
func TestValidSettingsAreUsed(t *testing.T) {
t.Setenv("PORT", "9000")
t.Setenv("MAX_MESSAGE_SIZE", "1024")
// Each whole number is the lowest value its setting allows, and 1ns
// is the shortest duration allowed.
t.Setenv("PORT", "0")
t.Setenv("MAX_MESSAGE_SIZE", "1")
t.Setenv("NEOIRC_HASHCASH_BITS", "0")
t.Setenv("LOGIN_RATE_BURST", "10")
t.Setenv("LOGIN_RATE_BURST", "1")
t.Setenv("LOGIN_RATE_LIMIT", "0.5")
t.Setenv("DEBUG", "true")
t.Setenv("MAINTENANCE_MODE", "true")
t.Setenv("MESSAGE_MAX_AGE", "24h")
t.Setenv("MESSAGE_MAX_AGE", "1ns")
t.Setenv("QUEUE_MAX_AGE", "1h30m")
t.Setenv("SESSION_IDLE_TIMEOUT", "45m")
want := settings{
Port: 9000,
MaxMessageSize: 1024,
Port: 0,
MaxMessageSize: 1,
HashcashBits: 0,
LoginRateBurst: 10,
LoginRateBurst: 1,
LoginRateLimit: 0.5,
Debug: true,
MaintenanceMode: true,
MessageMaxAge: "24h",
MessageMaxAge: "1ns",
QueueMaxAge: "1h30m",
SessionIdleTimeout: "45m",
}