Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove more side effects from application config testing #1684

Merged
merged 3 commits into from
Mar 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions internal/config/application.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,13 +270,12 @@ func loadConfig(v *viper.Viper, configPath string) error {
}
}

// 4. look for .<appname>/config.yaml in xdg locations (starting with xdg home config dir, then moving upwards)

// 4. look for <appname>/config.yaml in xdg locations (starting with xdg home config dir, then moving upwards)
v.SetConfigName("config")
configPath = path.Join(xdg.ConfigHome, "."+internal.ApplicationName)
configPath = path.Join(xdg.ConfigHome, internal.ApplicationName)
v.AddConfigPath(configPath)
for _, dir := range xdg.ConfigDirs {
v.AddConfigPath(path.Join(dir, "."+internal.ApplicationName))
v.AddConfigPath(path.Join(dir, internal.ApplicationName))
}
if err = v.ReadInConfig(); err == nil {
v.Set("config", v.ConfigFileUsed())
Expand Down
74 changes: 41 additions & 33 deletions internal/config/application_test.go
Original file line number Diff line number Diff line change
@@ -1,25 +1,43 @@
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, <XDG_CONFIG_HOME>/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(t *testing.T)
cleanup func()
}{
{
name: "explicit config",
Expand All @@ -29,92 +47,82 @@ func TestApplicationConfig(t *testing.T) {
assertions: func(t *testing.T, app *Application) {
assert.Equal(t, "test-explicit-config", app.File)
},
Cleanup: func(t *testing.T) {},
},
{
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
if err != nil {
t.Fatalf("%s failed to change cwd: %+v", t.Name(), err)
}
require.NoError(t, err)
return ""
},
assertions: func(t *testing.T, app *Application) {
assert.Equal(t, "test-wd-named-config", app.File)
},
Cleanup: func(t *testing.T) {},
},
{
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
if err != nil {
t.Fatalf("%s failed to change cwd: %+v", t.Name(), err)
}
require.NoError(t, err)
return ""
},
assertions: func(t *testing.T, app *Application) {
assert.Equal(t, "test-dir-config", app.File)
},
Cleanup: func(t *testing.T) {},
},
{
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")
err := os.Link("./test-fixtures/config-home-test/config-file/.syft.yaml", "./test-fixtures/config-home-test/.syft.yaml")
if err != nil {
t.Fatalf("%s failed to link home config: %+v", t.Name(), err)
}
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)
},
Cleanup: func(t *testing.T) {
err := os.Remove("./test-fixtures/config-home-test/.syft.yaml") //
if err != nil {
t.Fatalf("%s failed to remove home config link: %+v", t.Name(), err)
}
},
},
{
name: "XDG file config",
setup: func(t *testing.T) string {
wd, err := os.Getwd()
if err != nil {
t.Fatalf("%s: failed to get working directory: %+v", t.Name(), err)
}
require.NoError(t, err)
configDir := path.Join(wd, "./test-fixtures/config-home-test") // set HOME to testdata
t.Setenv("XDG_CONFIG_DIRS", configDir)
// 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(t *testing.T) {},
cleanup: func() {
require.NoError(t, os.Unsetenv("XDG_CONFIG_DIRS"))
kzantow marked this conversation as resolved.
Show resolved Hide resolved
xdg.Reload()
},
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
defer test.Cleanup(t)
wd, err := os.Getwd()
if err != nil {
t.Fatalf("failed to get working directory: %+v", err)
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)
if err != nil {
t.Fatalf("failed to load application config: %+v", err)
}
require.NoError(t, err)
test.assertions(t, application)
})
}
Expand Down