Files

132 lines
3.7 KiB
Go

package server
import (
"os"
"strings"
"testing"
"time"
)
func mustDefaultConfig(t *testing.T) *Config {
t.Helper()
cfg, err := DefaultConfig()
if err != nil {
t.Fatalf("DefaultConfig: %v", err)
}
return cfg
}
func TestDefaultConfig(t *testing.T) {
cfg := mustDefaultConfig(t)
if cfg.Listen != DefaultListen {
t.Errorf("expected Listen=%s, got %s", DefaultListen, cfg.Listen)
}
if cfg.DefaultTerminalCols != DefaultTerminalCols {
t.Errorf("expected cols=%d, got %d", DefaultTerminalCols, cfg.DefaultTerminalCols)
}
if cfg.DefaultTerminalRows != DefaultTerminalRows {
t.Errorf("expected rows=%d, got %d", DefaultTerminalRows, cfg.DefaultTerminalRows)
}
if cfg.SQLiteBusyTimeoutMs != DefaultSQLiteBusyTimeoutMs {
t.Errorf("expected busy_timeout=%d, got %d", DefaultSQLiteBusyTimeoutMs, cfg.SQLiteBusyTimeoutMs)
}
}
func TestConfigPaths(t *testing.T) {
cfg := mustDefaultConfig(t)
cfg.StateDir = "/tmp/shellctl-test"
cfg.RuntimeDir = "/tmp/shellctl-test/runtime"
if cfg.JobsDir() != "/tmp/shellctl-test/jobs" {
t.Errorf("unexpected JobsDir: %s", cfg.JobsDir())
}
if cfg.DBPath() != "/tmp/shellctl-test/shellctl.db" {
t.Errorf("unexpected DBPath: %s", cfg.DBPath())
}
if cfg.TmuxSocket() != "/tmp/shellctl-test/runtime/tmux.sock" {
t.Errorf("unexpected TmuxSocket: %s", cfg.TmuxSocket())
}
if cfg.RunnerPath() != "/tmp/shellctl-test/runtime/bin/shellctl-runner" {
t.Errorf("unexpected RunnerPath: %s", cfg.RunnerPath())
}
}
func TestConfigAuthTokenFromEnv(t *testing.T) {
t.Setenv("SHELLCTL_AUTH_TOKEN", "my-secret-token")
cfg := mustDefaultConfig(t)
if cfg.AuthToken != "my-secret-token" {
t.Errorf("expected auth token from env, got %q", cfg.AuthToken)
}
}
func TestConfigNoAuthToken(t *testing.T) {
t.Setenv("SHELLCTL_AUTH_TOKEN", "")
cfg := mustDefaultConfig(t)
if cfg.AuthToken != "" {
t.Errorf("expected empty auth token, got %q", cfg.AuthToken)
}
}
func TestDefaultConfigSnapshotFields(t *testing.T) {
cfg := mustDefaultConfig(t)
if cfg.SnapshotTimeout != 45*time.Second {
t.Errorf("SnapshotTimeout = %v, want 45s", cfg.SnapshotTimeout)
}
}
func TestSnapshotTimeoutDefaultsWhenEnvUnset(t *testing.T) {
t.Setenv(SnapshotTimeoutEnv, "")
_ = os.Unsetenv(SnapshotTimeoutEnv)
cfg := mustDefaultConfig(t)
if cfg.SnapshotTimeout != 45*time.Second {
t.Errorf("SnapshotTimeout = %v, want 45s", cfg.SnapshotTimeout)
}
}
func TestSnapshotTimeoutDefaultsWhenEnvEmpty(t *testing.T) {
t.Setenv(SnapshotTimeoutEnv, "")
cfg := mustDefaultConfig(t)
if cfg.SnapshotTimeout != 45*time.Second {
t.Errorf("SnapshotTimeout = %v, want 45s", cfg.SnapshotTimeout)
}
}
func TestSnapshotTimeoutFromEnv(t *testing.T) {
cases := []struct {
raw string
want time.Duration
}{
{"900s", 900 * time.Second},
{"15m", 15 * time.Minute},
{"15m30s", 15*time.Minute + 30*time.Second},
{" 15m ", 15 * time.Minute},
}
for _, tc := range cases {
t.Run(tc.raw, func(t *testing.T) {
t.Setenv(SnapshotTimeoutEnv, tc.raw)
cfg := mustDefaultConfig(t)
if cfg.SnapshotTimeout != tc.want {
t.Errorf("SnapshotTimeout = %v, want %v", cfg.SnapshotTimeout, tc.want)
}
})
}
}
func TestSnapshotTimeoutRejectsUnusableEnv(t *testing.T) {
for _, raw := range []string{"fifteen minutes", "600", "10 m", "0", "0s", "-1s", "-5m"} {
t.Run(raw, func(t *testing.T) {
t.Setenv(SnapshotTimeoutEnv, raw)
cfg, err := DefaultConfig()
if err == nil {
t.Fatalf("%q must fail startup, not run with a substituted timeout", raw)
}
if !strings.Contains(err.Error(), SnapshotTimeoutEnv) {
t.Errorf("error %q must name %s so the operator knows what to fix", err, SnapshotTimeoutEnv)
}
if cfg != nil {
t.Errorf("%q yielded a usable config; an unusable timeout must yield none", raw)
}
})
}
}