package config_test import ( "net/url" "os" "runtime" "strings" "testing" "git.netflux.io/rob/clipper/config" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) type env map[string]string // clearenv clears prefixed keys from the environment. Currently it does not // clear AWS_* environment variables. func clearenv() { for _, kv := range os.Environ() { split := strings.SplitN(kv, "=", 2) k := split[0] if !strings.HasPrefix(k, config.Prefix) { continue } os.Unsetenv(k) } } // setupenv sets up a valid environment, including AWS_* configuration // variables. func setupenv() { e := env{ "CLIPPER_ENV": "development", "CLIPPER_DATABASE_URL": "postgresql://localhost:5432/db", "CLIPPER_FILE_STORE_HTTP_ROOT": "/data", "CLIPPER_S3_BUCKET": "bucket", "AWS_ACCESS_KEY_ID": "key", "AWS_SECRET_ACCESS_KEY": "secret", "AWS_REGION": "eu-west-1", } for k, v := range e { os.Setenv(k, v) } } func mustParseURL(t *testing.T, u string) *url.URL { pu, err := url.Parse(u) require.NoError(t, err) return pu } func TestNewFromEnv(t *testing.T) { t.Run("ENV", func(t *testing.T) { defer clearenv() setupenv() os.Setenv("CLIPPER_ENV", "foo") c, err := config.NewFromEnv() assert.EqualError(t, err, "invalid CLIPPER_ENV value: foo") os.Setenv("CLIPPER_ENV", "") c, err = config.NewFromEnv() require.NoError(t, err) assert.Equal(t, config.EnvDevelopment, c.Environment) os.Setenv("CLIPPER_ENV", "development") c, err = config.NewFromEnv() require.NoError(t, err) assert.Equal(t, config.EnvDevelopment, c.Environment) os.Setenv("CLIPPER_ENV", "production") c, err = config.NewFromEnv() require.NoError(t, err) assert.Equal(t, config.EnvProduction, c.Environment) }) t.Run("BIND_ADDR", func(t *testing.T) { defer clearenv() setupenv() os.Setenv("CLIPPER_BIND_ADDR", "") c, err := config.NewFromEnv() require.NoError(t, err) assert.Equal(t, config.DefaultBindAddr, c.BindAddr) os.Setenv("CLIPPER_BIND_ADDR", "example.com:1234") c, err = config.NewFromEnv() require.NoError(t, err) assert.Equal(t, "example.com:1234", c.BindAddr) }) t.Run("TLS_CERT_FILE and TLS_KEY_FILE", func(t *testing.T) { defer clearenv() setupenv() c, err := config.NewFromEnv() require.NoError(t, err) assert.Equal(t, "", c.TLSCertFile) assert.Equal(t, "", c.TLSKeyFile) const expErr = "both CLIPPER_TLS_CERT_FILE and CLIPPER_TLS_KEY_FILE must be set" os.Setenv("CLIPPER_TLS_CERT_FILE", "foo") os.Setenv("CLIPPER_TLS_KEY_FILE", "") c, err = config.NewFromEnv() assert.EqualError(t, err, expErr) os.Setenv("CLIPPER_TLS_CERT_FILE", "") os.Setenv("CLIPPER_TLS_KEY_FILE", "bar") c, err = config.NewFromEnv() assert.EqualError(t, err, expErr) os.Setenv("CLIPPER_TLS_CERT_FILE", "foo") os.Setenv("CLIPPER_TLS_KEY_FILE", "bar") c, err = config.NewFromEnv() require.NoError(t, err) assert.Equal(t, "foo", c.TLSCertFile) assert.Equal(t, "bar", c.TLSKeyFile) }) t.Run("DATABASE_URL", func(t *testing.T) { defer clearenv() setupenv() os.Unsetenv("CLIPPER_DATABASE_URL") _, err := config.NewFromEnv() assert.EqualError(t, err, "CLIPPER_DATABASE_URL not set") os.Setenv("CLIPPER_DATABASE_URL", "foo") c, err := config.NewFromEnv() require.NoError(t, err) assert.Equal(t, "foo", c.DatabaseURL) }) t.Run("FILE_STORE", func(t *testing.T) { defer clearenv() setupenv() os.Unsetenv("CLIPPER_FILE_STORE") c, err := config.NewFromEnv() require.NoError(t, err) assert.Equal(t, config.FileSystemStore, c.FileStore) os.Setenv("CLIPPER_FILE_STORE", "foo") c, err = config.NewFromEnv() assert.EqualError(t, err, "invalid CLIPPER_FILE_STORE value: foo") os.Setenv("CLIPPER_FILE_STORE", "filesystem") c, err = config.NewFromEnv() require.NoError(t, err) assert.Equal(t, config.FileSystemStore, c.FileStore) os.Setenv("CLIPPER_FILE_STORE", "s3") c, err = config.NewFromEnv() require.NoError(t, err) assert.Equal(t, config.S3Store, c.FileStore) }) t.Run("FILE_STORE_HTTP_ROOT", func(t *testing.T) { defer clearenv() setupenv() os.Unsetenv("CLIPPER_FILE_STORE_HTTP_ROOT") _, err := config.NewFromEnv() require.EqualError(t, err, "FILE_STORE_HTTP_ROOT not set") os.Setenv("CLIPPER_FILE_STORE_HTTP_ROOT", "/foo") c, err := config.NewFromEnv() require.NoError(t, err) assert.Equal(t, "/foo", c.FileStoreHTTPRoot) }) t.Run("FILE_STORE_HTTP_BASE_URL", func(t *testing.T) { defer clearenv() setupenv() os.Setenv("CLIPPER_FILE_STORE_HTTP_BASE_URL", "%%") _, err := config.NewFromEnv() require.EqualError(t, err, "invalid CLIPPER_FILE_STORE_HTTP_BASE_URL: %%/") os.Unsetenv("CLIPPER_FILE_STORE_HTTP_BASE_URL") c, err := config.NewFromEnv() require.NoError(t, err) assert.Equal(t, mustParseURL(t, "/"), c.FileStoreHTTPBaseURL) os.Setenv("CLIPPER_FILE_STORE_HTTP_BASE_URL", "/foo") c, err = config.NewFromEnv() require.NoError(t, err) assert.Equal(t, mustParseURL(t, "/foo/"), c.FileStoreHTTPBaseURL) os.Setenv("CLIPPER_FILE_STORE_HTTP_BASE_URL", "/foo/") c, err = config.NewFromEnv() require.NoError(t, err) assert.Equal(t, mustParseURL(t, "/foo/"), c.FileStoreHTTPBaseURL) os.Setenv("CLIPPER_FILE_STORE_HTTP_BASE_URL", "https://www.example.com/foo") c, err = config.NewFromEnv() require.NoError(t, err) assert.Equal(t, mustParseURL(t, "https://www.example.com/foo/"), c.FileStoreHTTPBaseURL) }) t.Run("ASSETS_HTTP_ROOT", func(t *testing.T) { defer clearenv() setupenv() os.Unsetenv("CLIPPER_ASSETS_HTTP_ROOT") c, err := config.NewFromEnv() require.NoError(t, err) assert.Equal(t, "", c.AssetsHTTPRoot) os.Setenv("CLIPPER_ASSETS_HTTP_ROOT", "/bar") c, err = config.NewFromEnv() require.NoError(t, err) assert.Equal(t, "/bar", c.AssetsHTTPRoot) }) t.Run("FFMPEG_WORKER_POOL_SIZE", func(t *testing.T) { defer clearenv() setupenv() os.Setenv("CLIPPER_FFMPEG_WORKER_POOL_SIZE", "nope") c, err := config.NewFromEnv() assert.EqualError(t, err, "invalid CLIPPER_FFMPEG_WORKER_POOL_SIZE value: nope") os.Unsetenv("CLIPPER_FFMPEG_WORKER_POOL_SIZE") c, err = config.NewFromEnv() require.NoError(t, err) assert.Equal(t, runtime.NumCPU(), c.FFmpegWorkerPoolSize) os.Setenv("CLIPPER_FFMPEG_WORKER_POOL_SIZE", "10") c, err = config.NewFromEnv() require.NoError(t, err) assert.Equal(t, 10, c.FFmpegWorkerPoolSize) }) t.Run("AWS configuration", func(t *testing.T) { defer clearenv() setupenv() os.Setenv("CLIPPER_FILE_STORE", "s3") os.Unsetenv("AWS_ACCESS_KEY_ID") _, err := config.NewFromEnv() assert.EqualError(t, err, "AWS_ACCESS_KEY_ID not set") os.Setenv("AWS_ACCESS_KEY_ID", "key") os.Unsetenv("AWS_SECRET_ACCESS_KEY") _, err = config.NewFromEnv() assert.EqualError(t, err, "AWS_SECRET_ACCESS_KEY not set") os.Setenv("AWS_ACCESS_KEY_ID", "key") os.Setenv("AWS_SECRET_ACCESS_KEY", "secret") os.Unsetenv("AWS_REGION") _, err = config.NewFromEnv() assert.EqualError(t, err, "AWS_REGION not set") os.Setenv("AWS_ACCESS_KEY_ID", "key") os.Setenv("AWS_SECRET_ACCESS_KEY", "secret") os.Setenv("AWS_REGION", "eu-west-1") os.Unsetenv("CLIPPER_S3_BUCKET") _, err = config.NewFromEnv() assert.EqualError(t, err, "S3_BUCKET not set") os.Setenv("AWS_ACCESS_KEY_ID", "key") os.Setenv("AWS_SECRET_ACCESS_KEY", "secret") os.Setenv("AWS_REGION", "eu-west-1") os.Setenv("CLIPPER_S3_BUCKET", "bucket") c, err := config.NewFromEnv() require.NoError(t, err) assert.Equal(t, "key", c.AWSAccessKeyID) assert.Equal(t, "secret", c.AWSSecretAccessKey) assert.Equal(t, "eu-west-1", c.AWSRegion) assert.Equal(t, "bucket", c.S3Bucket) }) }