fix: isolate config tests from the host dokku installation

The config tests wrote to the real `DOKKU_ROOT` and `DOKKU_LIB_ROOT`, including the global `ENV` file, and relied on a `dokku` user and group existing. That held only because the result of applying ownership was discarded; now that it is reported, the tests failed under `ci-go-coverage`, which runs them in a build image that has no `dokku` user. They now use the temporary directories and current-user ownership the migration tests already use.
This commit is contained in:
Jose Diaz-Gonzalez
2026-09-18 01:05:35 -04:00
parent 0c3ae47299
commit e715944c86
2 changed files with 33 additions and 70 deletions

View File

@@ -6,68 +6,47 @@ import (
"strings"
"testing"
"github.com/dokku/dokku/plugins/common"
. "github.com/onsi/gomega"
)
var (
testAppName = "test-app-1"
dokkuRoot = common.MustGetEnv("DOKKU_ROOT")
dokkuLibRoot = common.MustGetEnv("DOKKU_LIB_ROOT")
testAppRoot = filepath.Join(dokkuRoot, testAppName)
testAppDir = filepath.Join(dokkuLibRoot, "config", testAppName)
globalConfigFile = filepath.Join(dokkuLibRoot, "config", "--global", "ENV")
)
const testAppName = "test-app-1"
func setupTests() (err error) {
if err := os.Setenv("PLUGIN_PATH", "/var/lib/dokku/plugins"); err != nil {
return err
}
// setupTestApp points the dokku environment at temporary directories and seeds
// the app and global config the tests read, returning the app's config
// directory. Nothing is written to a real dokku installation and no dokku user
// needs to exist, which matters now that a failure to apply ownership is
// reported rather than discarded. The directories are removed with the test.
func setupTestApp(t *testing.T) (testAppDir string) {
t.Helper()
if err := os.Setenv("PLUGIN_ENABLED_PATH", "/var/lib/dokku/plugins/enabled"); err != nil {
return err
}
dokkuRoot, libRoot := setupIsolatedEnv(t)
t.Setenv("PLUGIN_ENABLED_PATH", filepath.Join(libRoot, "plugins", "enabled"))
t.Setenv("PLUGIN_CORE_AVAILABLE_PATH", filepath.Join(libRoot, "core-plugins", "available"))
return os.Setenv("PLUGIN_CORE_AVAILABLE_PATH", "/var/lib/dokku/core-plugins/available")
}
Expect(os.MkdirAll(filepath.Join(dokkuRoot, testAppName), 0755)).To(Succeed())
func setupTestApp() (err error) {
Expect(os.MkdirAll(testAppRoot, 0766)).To(Succeed())
Expect(os.MkdirAll(testAppDir, 0766)).To(Succeed())
b := []byte("export testKey=TESTING\n")
if err = os.WriteFile(strings.Join([]string{testAppDir, "/ENV"}, ""), b, 0644); err != nil {
return
}
testAppDir = filepath.Join(libRoot, "config", testAppName)
Expect(os.MkdirAll(testAppDir, 0755)).To(Succeed())
Expect(os.WriteFile(filepath.Join(testAppDir, "ENV"), []byte("export testKey=TESTING\n"), 0600)).To(Succeed())
Expect(os.MkdirAll(filepath.Dir(globalConfigFile), 0766)).To(Succeed())
b = []byte("export testKey=GLOBAL_TESTING\nexport globalKey=GLOBAL_VALUE")
if err = os.WriteFile(globalConfigFile, b, 0644); err != nil {
return
}
return
}
globalConfigFile := filepath.Join(libRoot, "config", "--global", "ENV")
Expect(os.MkdirAll(filepath.Dir(globalConfigFile), 0755)).To(Succeed())
Expect(os.WriteFile(globalConfigFile, []byte("export testKey=GLOBAL_TESTING\nexport globalKey=GLOBAL_VALUE"), 0600)).To(Succeed())
func teardownTestApp() {
os.RemoveAll(testAppRoot)
os.RemoveAll(testAppDir)
return testAppDir
}
func TestConfigGetWithDefault(t *testing.T) {
RegisterTestingT(t)
Expect(setupTests()).To(Succeed())
Expect(setupTestApp()).To(Succeed())
setupTestApp(t)
Expect(GetWithDefault(testAppName, "unknownKey", "UNKNOWN")).To(Equal("UNKNOWN"))
Expect(GetWithDefault(testAppName, "testKey", "testKey")).To(Equal("TESTING"))
Expect(GetWithDefault(testAppName+"-nonexistent", "testKey", "default")).To(Equal("default"))
teardownTestApp()
}
func TestConfigGet(t *testing.T) {
RegisterTestingT(t)
Expect(setupTests()).To(Succeed())
Expect(setupTestApp()).To(Succeed())
defer teardownTestApp()
setupTestApp(t)
expectValue(testAppName, "testKey", "TESTING")
expectValue("", "testKey", "GLOBAL_TESTING")
@@ -78,9 +57,7 @@ func TestConfigGet(t *testing.T) {
func TestConfigSetMany(t *testing.T) {
RegisterTestingT(t)
Expect(setupTests()).To(Succeed())
Expect(setupTestApp()).To(Succeed())
defer teardownTestApp()
setupTestApp(t)
expectValue(testAppName, "testKey", "TESTING")
@@ -102,9 +79,7 @@ func TestConfigSetMany(t *testing.T) {
func TestConfigUnsetAll(t *testing.T) {
RegisterTestingT(t)
Expect(setupTests()).To(Succeed())
Expect(setupTestApp()).To(Succeed())
defer teardownTestApp()
setupTestApp(t)
expectValue(testAppName, "testKey", "TESTING")
expectValue("", "testKey", "GLOBAL_TESTING")
@@ -119,9 +94,7 @@ func TestConfigUnsetAll(t *testing.T) {
func TestConfigUnsetMany(t *testing.T) {
RegisterTestingT(t)
Expect(setupTests()).To(Succeed())
Expect(setupTestApp()).To(Succeed())
defer teardownTestApp()
setupTestApp(t)
expectValue(testAppName, "testKey", "TESTING")
expectValue("", "testKey", "GLOBAL_TESTING")
@@ -140,9 +113,7 @@ func TestConfigUnsetMany(t *testing.T) {
func TestConfigImport(t *testing.T) {
RegisterTestingT(t)
Expect(setupTests()).To(Succeed())
Expect(setupTestApp()).To(Succeed())
defer teardownTestApp()
setupTestApp(t)
tempFile, err := os.CreateTemp("", "test-config-import-*.env")
Expect(err).To(Succeed())
@@ -179,9 +150,7 @@ testKey2=TESTING-updated2
func TestConfigImportJSON(t *testing.T) {
RegisterTestingT(t)
Expect(setupTests()).To(Succeed())
Expect(setupTestApp()).To(Succeed())
defer teardownTestApp()
setupTestApp(t)
tempFile, err := os.CreateTemp("", "test-config-import-*.json")
Expect(err).To(Succeed())
@@ -216,9 +185,7 @@ func TestConfigImportJSON(t *testing.T) {
func TestEnvironmentLoading(t *testing.T) {
RegisterTestingT(t)
Expect(setupTests()).To(Succeed())
Expect(setupTestApp()).To(Succeed())
defer teardownTestApp()
setupTestApp(t)
env, err := LoadMergedAppEnv(testAppName)
Expect(err).To(Succeed())
@@ -241,9 +208,7 @@ func TestEnvironmentLoading(t *testing.T) {
func TestInvalidKeys(t *testing.T) {
RegisterTestingT(t)
Expect(setupTests()).To(Succeed())
Expect(setupTestApp()).To(Succeed())
defer teardownTestApp()
setupTestApp(t)
invalidKeys := []string{"0invalidKey", "invalid:key", "invalid=Key", "!invalidKey"}
for _, key := range invalidKeys {
@@ -259,11 +224,9 @@ func TestInvalidKeys(t *testing.T) {
func TestInvalidEnvOnDisk(t *testing.T) {
RegisterTestingT(t)
Expect(setupTests()).To(Succeed())
Expect(setupTestApp()).To(Succeed())
defer teardownTestApp()
testAppDir := setupTestApp(t)
appConfigFile := strings.Join([]string{testAppDir, "/ENV"}, "")
appConfigFile := filepath.Join(testAppDir, "ENV")
b := []byte("export --invalid-key=TESTING\nexport valid_key=value\n")
if err := os.WriteFile(appConfigFile, b, 0644); err != nil {
return

View File

@@ -11,9 +11,9 @@ import (
// setupIsolatedEnv points the dokku env at temporary directories and tells the
// permission helpers to chown files to the current user (a no-op) so the test
// works without root. The package-level paths in config_test.go are captured at
// init against the real dokku directories, so a test using this helper must not
// use them.
// works without root and without a dokku user existing. Every test in this
// package goes through it, directly or via setupTestApp, so none of them touch
// a real dokku installation.
func setupIsolatedEnv(t *testing.T) (dokkuRoot string, libRoot string) {
t.Helper()