package config import ( "os" "path" "strings" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.uber.org/zap" ) func initJson(t *testing.T, content string) string { tmpPath := t.TempDir() confPath := path.Join(tmpPath, "config.json") err := os.WriteFile(confPath, []byte(content), 0o644) require.NoError(t, err) return confPath } func setEnv(t *testing.T, envVars map[string]string) { for key, val := range envVars { t.Setenv(key, val) } } // remove all polyculeconnect environment variables from the environment and put them back after the test func clearEnv(t *testing.T) { for _, envvar := range os.Environ() { if strings.HasPrefix(envvar, "POLYCULECONNECT") { splitVar := strings.SplitN(envvar, "=", 2) require.True(t, len(splitVar) >= 2, "invalid format for envvar %q", envvar) require.NoError(t, os.Unsetenv(splitVar[0]), "failed to unset var %q", splitVar[0]) t.Cleanup(func() { os.Setenv(splitVar[0], splitVar[1]) }) } } } func TestDefault(t *testing.T) { clearEnv(t) t.Run("no file", func(t *testing.T) { conf, err := New("/this/path/does/not/exist") require.NoError(t, err) assert.Equal(t, defaultConfig(), *conf) }) t.Run("empty config", func(t *testing.T) { confPath := initJson(t, `{}`) conf, err := New(confPath) require.NoError(t, err) assert.Equal(t, defaultConfig(), *conf) }) } // Since we still use a JSON conf for the OIDC config, we still need to check this for now // But as soon as the config file is not necessary, this will probably disappear func TestInvalidJSON(t *testing.T) { clearEnv(t) confPath := initJson(t, "toto") errMsg := "failed to parse config file: invalid character 'o' in literal true (expecting 'r')" _, err := New(confPath) assert.ErrorContains(t, err, errMsg) } func TestJSONConfig(t *testing.T) { clearEnv(t) confPath := initJson(t, `{ "log": {"level":"info"}, "server": { "mode": "net", "host": "0.0.0.0", "port": 1337 } }`) conf, err := New(confPath) require.NoError(t, err) assert.Equal(t, ModeNet, conf.ServerMode) assert.Equal(t, "0.0.0.0", conf.Host) assert.Equal(t, 1337, conf.Port) } func TestJSONConfigOverriden(t *testing.T) { clearEnv(t) confPath := initJson(t, `{ "log": {"level":"info"}, "server": { "mode": "net", "host": "0.0.0.0", "port": 1337 } }`) envVars := map[string]string{ string("POLYCULECONNECT_SERVER_MODE"): string(ModeUnix), string("POLYCULECONNECT_SERVER_SOCK"): "/run/polyculeconnect.sock", } setEnv(t, envVars) conf, err := New(confPath) require.NoError(t, err) assert.Equal(t, ModeUnix, conf.ServerMode) assert.Equal(t, "0.0.0.0", conf.Host) assert.Equal(t, 1337, conf.Port) assert.Equal(t, "/run/polyculeconnect.sock", conf.SockPath) } func TestHostNetMode(t *testing.T) { clearEnv(t) envVars := map[string]string{ string("POLYCULECONNECT_SERVER_MODE"): string(ModeNet), string("POLYCULECONNECT_SERVER_HOST"): "127.0.0.1", string("POLYCULECONNECT_SERVER_PORT"): "8888", } setEnv(t, envVars) conf, err := New("") require.NoError(t, err) assert.Equal(t, ModeNet, conf.ServerMode) assert.Equal(t, "127.0.0.1", conf.Host) assert.Equal(t, 8888, conf.Port) } func TestHostSocketMode(t *testing.T) { clearEnv(t) envVars := map[string]string{ string("POLYCULECONNECT_SERVER_MODE"): string(ModeUnix), string("POLYCULECONNECT_SERVER_SOCK"): "/run/polyculeconnect.sock", } setEnv(t, envVars) conf, err := New("") require.NoError(t, err) assert.Equal(t, ModeUnix, conf.ServerMode) assert.Equal(t, "/run/polyculeconnect.sock", conf.SockPath) } func TestLogLevel(t *testing.T) { clearEnv(t) envVars := map[string]string{ string("POLYCULECONNECT_LOG_LEVEL"): "error", } setEnv(t, envVars) conf, err := New("") require.NoError(t, err) assert.Equal(t, zap.NewAtomicLevelAt(zap.ErrorLevel), conf.LogLevel) } func TestSqliteConfig(t *testing.T) { clearEnv(t) envVars := map[string]string{ string("POLYCULECONNECT_STORAGE_TYPE"): "sqlite", string("POLYCULECONNECT_STORAGE_PATH"): "/data/polyculeconnect.db", } setEnv(t, envVars) conf, err := New("") require.NoError(t, err) assert.Equal(t, string(SQLite), conf.StorageType) assert.Equal(t, "/data/polyculeconnect.db", conf.StorageConfig.File) } func TestSqliteConfigJSON(t *testing.T) { clearEnv(t) confPath := initJson(t, `{ "log": {"level":"info"}, "storage": { "type": "sqlite", "path": "/data/polyculeconnect.db" } }`) conf, err := New(confPath) require.NoError(t, err) assert.Equal(t, string(SQLite), conf.StorageType) assert.Equal(t, "/data/polyculeconnect.db", conf.StorageConfig.File) } func TestSqliteConfigJSONOverriden(t *testing.T) { clearEnv(t) confPath := initJson(t, `{ "log": {"level":"info"}, "storage": { "type": "sqlite", "path": "/data/polyculeconnect.db" } }`) envVars := map[string]string{ string("POLYCULECONNECT_STORAGE_PATH"): "/tmp/polyculeconnect.db", } setEnv(t, envVars) conf, err := New(confPath) require.NoError(t, err) assert.Equal(t, string(SQLite), conf.StorageType) assert.Equal(t, "/tmp/polyculeconnect.db", conf.StorageConfig.File) }