Files
galaxy-game/rtmanager/internal/config/config_test.go
T
2026-04-28 20:39:18 +02:00

143 lines
5.0 KiB
Go

package config
import (
"strings"
"testing"
"time"
"github.com/stretchr/testify/require"
)
func validEnv(t *testing.T) {
t.Helper()
t.Setenv("RTMANAGER_POSTGRES_PRIMARY_DSN", "postgres://rtm:secret@localhost:5432/galaxy?search_path=rtmanager&sslmode=disable")
t.Setenv("RTMANAGER_REDIS_MASTER_ADDR", "localhost:6379")
t.Setenv("RTMANAGER_REDIS_PASSWORD", "secret")
t.Setenv("RTMANAGER_GAME_STATE_ROOT", "/var/lib/galaxy/games")
t.Setenv("RTMANAGER_LOBBY_INTERNAL_BASE_URL", "http://lobby:8095")
}
func TestLoadFromEnvAcceptsDefaults(t *testing.T) {
validEnv(t)
cfg, err := LoadFromEnv()
require.NoError(t, err)
require.Equal(t, ":8096", cfg.InternalHTTP.Addr)
require.Equal(t, "unix:///var/run/docker.sock", cfg.Docker.Host)
require.Equal(t, "galaxy-net", cfg.Docker.Network)
require.Equal(t, "json-file", cfg.Docker.LogDriver)
require.Equal(t, ImagePullPolicyIfMissing, cfg.Docker.PullPolicy)
require.Equal(t, "runtime:start_jobs", cfg.Streams.StartJobs)
require.Equal(t, "runtime:stop_jobs", cfg.Streams.StopJobs)
require.Equal(t, "runtime:job_results", cfg.Streams.JobResults)
require.Equal(t, "runtime:health_events", cfg.Streams.HealthEvents)
require.Equal(t, "notification:intents", cfg.Streams.NotificationIntents)
require.Equal(t, 30*time.Second, cfg.Container.StopTimeout)
require.Equal(t, 30*24*time.Hour, cfg.Container.Retention)
require.Equal(t, "/var/lib/galaxy-game", cfg.Container.EngineStateMountPath)
require.Equal(t, "GAME_STATE_PATH", cfg.Container.EngineStateEnvName)
require.EqualValues(t, 0o750, cfg.Container.GameStateDirMode)
require.Equal(t, 60*time.Second, cfg.Coordination.GameLeaseTTL)
require.Equal(t, "http://lobby:8095", cfg.Lobby.BaseURL)
require.Equal(t, 2*time.Second, cfg.Lobby.Timeout)
require.Equal(t, "galaxy-rtmanager", cfg.Telemetry.ServiceName)
}
func TestLoadFromEnvHonoursOverrides(t *testing.T) {
validEnv(t)
t.Setenv("RTMANAGER_INTERNAL_HTTP_ADDR", ":9000")
t.Setenv("RTMANAGER_DOCKER_NETWORK", "custom-net")
t.Setenv("RTMANAGER_IMAGE_PULL_POLICY", "always")
t.Setenv("RTMANAGER_REDIS_START_JOBS_STREAM", "custom:start_jobs")
t.Setenv("RTMANAGER_GAME_LEASE_TTL_SECONDS", "120")
t.Setenv("RTMANAGER_CONTAINER_STOP_TIMEOUT_SECONDS", "45")
t.Setenv("RTMANAGER_CONTAINER_RETENTION_DAYS", "7")
t.Setenv("RTMANAGER_GAME_STATE_DIR_MODE", "0700")
cfg, err := LoadFromEnv()
require.NoError(t, err)
require.Equal(t, ":9000", cfg.InternalHTTP.Addr)
require.Equal(t, "custom-net", cfg.Docker.Network)
require.Equal(t, ImagePullPolicyAlways, cfg.Docker.PullPolicy)
require.Equal(t, "custom:start_jobs", cfg.Streams.StartJobs)
require.Equal(t, 120*time.Second, cfg.Coordination.GameLeaseTTL)
require.Equal(t, 45*time.Second, cfg.Container.StopTimeout)
require.Equal(t, 7*24*time.Hour, cfg.Container.Retention)
require.EqualValues(t, 0o700, cfg.Container.GameStateDirMode)
}
func TestLoadFromEnvRejectsUnknownPullPolicy(t *testing.T) {
validEnv(t)
t.Setenv("RTMANAGER_IMAGE_PULL_POLICY", "weekly")
_, err := LoadFromEnv()
require.Error(t, err)
require.Contains(t, err.Error(), "image pull policy")
}
func TestLoadFromEnvRequiresGameStateRoot(t *testing.T) {
t.Setenv("RTMANAGER_POSTGRES_PRIMARY_DSN", "postgres://rtm:secret@localhost:5432/galaxy")
t.Setenv("RTMANAGER_REDIS_MASTER_ADDR", "localhost:6379")
t.Setenv("RTMANAGER_REDIS_PASSWORD", "secret")
t.Setenv("RTMANAGER_LOBBY_INTERNAL_BASE_URL", "http://lobby:8095")
_, err := LoadFromEnv()
require.Error(t, err)
require.Contains(t, err.Error(), "RTMANAGER_GAME_STATE_ROOT")
}
func TestLoadFromEnvRequiresLobbyBaseURL(t *testing.T) {
t.Setenv("RTMANAGER_POSTGRES_PRIMARY_DSN", "postgres://rtm:secret@localhost:5432/galaxy")
t.Setenv("RTMANAGER_REDIS_MASTER_ADDR", "localhost:6379")
t.Setenv("RTMANAGER_REDIS_PASSWORD", "secret")
t.Setenv("RTMANAGER_GAME_STATE_ROOT", "/var/lib/galaxy/games")
_, err := LoadFromEnv()
require.Error(t, err)
require.Contains(t, err.Error(), "RTMANAGER_LOBBY_INTERNAL_BASE_URL")
}
func TestLoadFromEnvRejectsRelativeStateRoot(t *testing.T) {
validEnv(t)
t.Setenv("RTMANAGER_GAME_STATE_ROOT", "relative/path")
_, err := LoadFromEnv()
require.Error(t, err)
require.Contains(t, err.Error(), "absolute path")
}
func TestLoadFromEnvRejectsBadLogLevel(t *testing.T) {
validEnv(t)
t.Setenv("RTMANAGER_LOG_LEVEL", "verbose")
_, err := LoadFromEnv()
require.Error(t, err)
require.Contains(t, err.Error(), "RTMANAGER_LOG_LEVEL")
}
func TestImagePullPolicyValidate(t *testing.T) {
require.NoError(t, ImagePullPolicyIfMissing.Validate())
require.NoError(t, ImagePullPolicyAlways.Validate())
require.NoError(t, ImagePullPolicyNever.Validate())
require.Error(t, ImagePullPolicy("monthly").Validate())
}
func TestInternalHTTPValidateRejectsBadAddr(t *testing.T) {
cfg := DefaultConfig().InternalHTTP
cfg.Addr = "not-an-addr"
err := cfg.Validate()
require.Error(t, err)
require.Contains(t, err.Error(), "host:port")
}
func TestStreamsValidateRequiresAllNames(t *testing.T) {
cfg := DefaultConfig().Streams
cfg.StartJobs = " "
err := cfg.Validate()
require.Error(t, err)
require.True(t, strings.Contains(err.Error(), "start jobs"))
}