check / check (push) Successful in 57s
The image's HEALTHCHECK requests /.well-known/healthcheck through nginx on the port from PORT, so it fails unless both processes answer. The backend reads PORT and DEBUG with strconv instead of viper, which turned a bad PORT into 0 and a bad DEBUG into false. Those, and a BIND_ADDRESS that is not an IP address, now stop the start with an error naming the variable; the TRUSTED_PROXIES error names it too. README.md gains "Running under upaas". Its first-run steps create the host directory owned by uid 1000, so the image changes no ownership. Model: opus-5-5
122 lines
3.3 KiB
Go
122 lines
3.3 KiB
Go
package config_test
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
|
|
"sneak.berlin/go/netwatch/internal/config"
|
|
"sneak.berlin/go/netwatch/internal/globals"
|
|
"sneak.berlin/go/netwatch/internal/logger"
|
|
|
|
"go.uber.org/fx"
|
|
)
|
|
|
|
// requireConfigError builds the config as main does and fails the
|
|
// test unless that fails with an error naming setting. It uses
|
|
// fx.New, because fxtest.New fails the test itself on an error.
|
|
func requireConfigError(t *testing.T, setting string) {
|
|
t.Helper()
|
|
|
|
app := fx.New(
|
|
fx.NopLogger,
|
|
fx.Provide(globals.New, logger.New, config.New),
|
|
fx.Invoke(func(*config.Config) {}),
|
|
)
|
|
|
|
err := app.Err()
|
|
if err == nil || !strings.Contains(err.Error(), setting) {
|
|
t.Fatalf("config error = %v, want one naming %s", err, setting)
|
|
}
|
|
}
|
|
|
|
// TestSettingsLoadAsGiven: valid values pass the checks and are used
|
|
// as given. bin/entrypoint.sh starts the server with these
|
|
// BIND_ADDRESS and PORT values.
|
|
func TestSettingsLoadAsGiven(t *testing.T) {
|
|
t.Setenv("BIND_ADDRESS", "127.0.0.1")
|
|
t.Setenv("PORT", "8081")
|
|
t.Setenv("DEBUG", "true")
|
|
|
|
var cfg *config.Config
|
|
|
|
app := fx.New(
|
|
fx.NopLogger,
|
|
fx.Provide(globals.New, logger.New, config.New),
|
|
fx.Populate(&cfg),
|
|
)
|
|
|
|
err := app.Err()
|
|
if err != nil {
|
|
t.Fatalf("config error = %v", err)
|
|
}
|
|
|
|
if cfg.BindAddress != "127.0.0.1" || cfg.Port != 8081 || !cfg.Debug {
|
|
t.Fatalf("BindAddress, Port, Debug = %q, %d, %t; "+
|
|
"want \"127.0.0.1\", 8081, true",
|
|
cfg.BindAddress, cfg.Port, cfg.Debug)
|
|
}
|
|
}
|
|
|
|
// TestPortMustBeAPortNumber: viper reads a value that is not a number
|
|
// as 0, on which the server would listen on a random port.
|
|
func TestPortMustBeAPortNumber(t *testing.T) {
|
|
for _, value := range []string{"abc", "0", "65536", "8080.5"} {
|
|
t.Run(value, func(t *testing.T) {
|
|
t.Setenv("PORT", value)
|
|
|
|
requireConfigError(t, "PORT")
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestDebugMustBeTrueOrFalse: viper reads any other value, such as
|
|
// "yes", as false.
|
|
func TestDebugMustBeTrueOrFalse(t *testing.T) {
|
|
t.Setenv("DEBUG", "yes")
|
|
|
|
requireConfigError(t, "DEBUG")
|
|
}
|
|
|
|
// TestBindAddressMustBeAnIPAddress: a host name would be looked up
|
|
// only once the server starts listening, and a mistyped one would stop
|
|
// it then with an error that does not name the setting.
|
|
func TestBindAddressMustBeAnIPAddress(t *testing.T) {
|
|
t.Setenv("BIND_ADDRESS", "localhost")
|
|
|
|
requireConfigError(t, "BIND_ADDRESS")
|
|
}
|
|
|
|
// TestReportsPerMinuteMustBePositive: unchecked, zero would panic
|
|
// when the routes are built, and a negative rate would lift the
|
|
// limit.
|
|
func TestReportsPerMinuteMustBePositive(t *testing.T) {
|
|
t.Setenv("REPORTS_PER_MINUTE", "0")
|
|
|
|
requireConfigError(t, "REPORTS_PER_MINUTE")
|
|
}
|
|
|
|
// TestDataDirMaxBytesMustBeANumber: viper reads a value that is not
|
|
// a number, such as "1GB", as 0, which would refuse every report.
|
|
func TestDataDirMaxBytesMustBeANumber(t *testing.T) {
|
|
t.Setenv("DATA_DIR_MAX_BYTES", "1GB")
|
|
|
|
requireConfigError(t, "DATA_DIR_MAX_BYTES")
|
|
}
|
|
|
|
// TestCORSAllowedOriginsMustBeOrigins: "*" would let every origin in,
|
|
// and an entry that is not a plain origin would match no page.
|
|
func TestCORSAllowedOriginsMustBeOrigins(t *testing.T) {
|
|
for _, entry := range []string{
|
|
"*",
|
|
"https://*.netwatch.example",
|
|
"netwatch.example",
|
|
"https://netwatch.example/",
|
|
} {
|
|
t.Run(entry, func(t *testing.T) {
|
|
t.Setenv("CORS_ALLOWED_ORIGINS", entry)
|
|
|
|
requireConfigError(t, "CORS_ALLOWED_ORIGINS")
|
|
})
|
|
}
|
|
}
|