package config import ( "fmt" "os" "path" "testing" "github.com/adrg/xdg" "github.com/mitchellh/go-homedir" "github.com/spf13/viper" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) // TODO: set negative case when config.yaml is no longer a valid option func TestApplicationConfig(t *testing.T) { // disable homedir package cache for testing originalCacheOpt := homedir.DisableCache homedir.DisableCache = true t.Cleanup(func() { homedir.DisableCache = originalCacheOpt }) // ensure we have no side effects for xdg package for future tests originalXDG := os.Getenv("XDG_CONFIG_HOME") t.Cleanup(func() { // note: we're not using t.Setenv since the effect we're trying to eliminate is within the xdg package require.NoError(t, os.Setenv("XDG_CONFIG_HOME", originalXDG)) xdg.Reload() }) // config is picked up at desired configuration paths // VALID: .syft.yaml, .syft/config.yaml, ~/.syft.yaml, /syft/config.yaml // DEPRECATED: config.yaml is currently supported by tests := []struct { name string setup func(t *testing.T) string assertions func(t *testing.T, app *Application) cleanup func() }{ { name: "explicit config", setup: func(t *testing.T) string { return "./test-fixtures/.syft.yaml" }, // no-op for explicit config assertions: func(t *testing.T, app *Application) { assert.Equal(t, "test-explicit-config", app.File) }, }, { name: "current working directory named config", setup: func(t *testing.T) string { err := os.Chdir("./test-fixtures/config-wd-file") // change application cwd to test-fixtures require.NoError(t, err) return "" }, assertions: func(t *testing.T, app *Application) { assert.Equal(t, "test-wd-named-config", app.File) }, }, { name: "current working directory syft dir config", setup: func(t *testing.T) string { err := os.Chdir("./test-fixtures/config-dir-test") // change application cwd to test-fixtures require.NoError(t, err) return "" }, assertions: func(t *testing.T, app *Application) { assert.Equal(t, "test-dir-config", app.File) }, }, { name: "home directory file config", setup: func(t *testing.T) string { // Because Setenv affects the whole process, it cannot be used in parallel tests or // tests with parallel ancestors: see separate XDG test for consequence of this t.Setenv("HOME", "./test-fixtures/config-home-test/config-file") return "" }, assertions: func(t *testing.T, app *Application) { assert.Equal(t, "test-home-config", app.File) }, }, { name: "XDG file config", setup: func(t *testing.T) string { wd, err := os.Getwd() require.NoError(t, err) configDir := path.Join(wd, "./test-fixtures/config-home-test") // set HOME to testdata // note: this explicitly has multiple XDG paths, make certain we use the first VALID one (not the first one) t.Setenv("XDG_CONFIG_DIRS", fmt.Sprintf("/another/foo/bar:%s", configDir)) xdg.Reload() return "" }, assertions: func(t *testing.T, app *Application) { assert.Equal(t, "test-home-XDG-config", app.File) }, cleanup: func() { require.NoError(t, os.Unsetenv("XDG_CONFIG_DIRS")) xdg.Reload() }, }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { if test.cleanup != nil { t.Cleanup(test.cleanup) } wd, err := os.Getwd() require.NoError(t, err) defer os.Chdir(wd) // reset working directory after test application := &Application{} viperInstance := viper.New() // this will override home in case you are running this test locally and DO have a syft config // in your home directory... now it will be ignored. Same for XDG_CONFIG_DIRS. t.Setenv("HOME", "/foo/bar") t.Setenv("XDG_CONFIG_DIRS", "/foo/bar") xdg.Reload() configPath := test.setup(t) err = application.LoadAllValues(viperInstance, configPath) require.NoError(t, err) test.assertions(t, application) }) } }