package config import ( "os" "path/filepath" "testing" "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) const validKey = "sha256:0000000000000000000000000000000000000000000000000000000000000000" func setValid(t *testing.T) { t.Setenv("MASTER_URL", "wss://10.0.0.5:8090/agent") t.Setenv("MASTER_KEY", validKey) t.Setenv("AGENT_TOKEN", "pua_abc") t.Setenv("SELF_ID", "") t.Setenv("LOG_LEVEL", "") t.Setenv("UPDATE_TIMEOUT", "") t.Setenv("DOCKER_CONFIG", "") } func TestLoad_Valid(t *testing.T) { setValid(t) cfg, err := Load() require.NoError(t, err) host, _ := os.Hostname() assert.Equal(t, &Config{ MasterURL: "wss://10.0.0.5:8090/agent", MasterKey: validKey, Token: "pua_abc", SelfID: host, LogLevel: "info", UpdateTimeout: 5 * time.Minute, }, cfg) } func TestLoad_Invalid(t *testing.T) { cases := []struct { name, key, value, wantErr string }{ {"missing url", "MASTER_URL", "", "MASTER_URL is required"}, {"plain ws", "MASTER_URL", "ws://10.0.0.5:8090/agent", "MASTER_URL must start with wss://"}, {"missing key", "MASTER_KEY", "", "MASTER_KEY is required"}, {"malformed key", "MASTER_KEY", "abc", "MASTER_KEY must look like sha256:<64 hex>"}, {"missing token", "AGENT_TOKEN", "", "AGENT_TOKEN is required"}, } for _, c := range cases { t.Run(c.name, func(t *testing.T) { setValid(t) t.Setenv(c.key, c.value) _, err := Load() assert.ErrorContains(t, err, c.wantErr) }) } } func TestLoad_JobSettings(t *testing.T) { withConfig := func(t *testing.T, body string) string { dir := t.TempDir() require.NoError(t, os.WriteFile(filepath.Join(dir, "config.json"), []byte(body), 0o600)) return dir } cases := []struct { name string timeout string dockerCfg func(t *testing.T) string wantTime time.Duration wantErr string }{ {name: "defaults", wantTime: 5 * time.Minute}, {name: "custom timeout", timeout: "90s", wantTime: 90 * time.Second}, {name: "zero timeout", timeout: "0", wantErr: "UPDATE_TIMEOUT"}, {name: "garbage timeout", timeout: "abc", wantErr: "UPDATE_TIMEOUT"}, {name: "docker config without file", dockerCfg: func(t *testing.T) string { return t.TempDir() }, wantErr: "DOCKER_CONFIG"}, {name: "docker config not json", dockerCfg: func(t *testing.T) string { return withConfig(t, "nope") }, wantErr: "not valid JSON"}, {name: "docker config ok", dockerCfg: func(t *testing.T) string { return withConfig(t, `{"auths":{}}`) }, wantTime: 5 * time.Minute}, } for _, c := range cases { t.Run(c.name, func(t *testing.T) { setValid(t) t.Setenv("UPDATE_TIMEOUT", c.timeout) dir := "" if c.dockerCfg != nil { dir = c.dockerCfg(t) t.Setenv("DOCKER_CONFIG", dir) } cfg, err := Load() if c.wantErr != "" { assert.ErrorContains(t, err, c.wantErr) return } require.NoError(t, err) assert.Equal(t, c.wantTime, cfg.UpdateTimeout) assert.Equal(t, dir, cfg.DockerConfig) }) } }