Skip to content

Commit

Permalink
acc: Implement config merge (#2294)
Browse files Browse the repository at this point in the history
## Changes
Instead of using leaf-most config, all configs from root at
acceptance/test.toml to all intermediate ones to leaf config are merged
into one. Maps are merged, slices are appended, other values are
overridden.

I had to disable caching, because it is tricky when merging is involved
- deep copy is needed. There is performance
impact but currently it is tiny, about 1%.

Also, remove empty root config.

## Tests

Manually checked that inheritance of LocalOnly setting worked for these
tests:

Before - integration tests showed:

```
PASS acceptance.TestAccept/bundle/templates/wrong-url (0.70s)
PASS acceptance.TestAccept/bundle/templates/wrong-path (0.44s)
```

After:

```
SKIP acceptance.TestAccept/bundle/templates/wrong-url (0.00s)
SKIP acceptance.TestAccept/bundle/templates/wrong-path (0.00s)
      acceptance_test.go:216: Disabled via LocalOnly setting in bundle/templates/test.toml, bundle/templates/wrong-path/test.toml (CLOUD_ENV=***)
```
  • Loading branch information
denik authored Feb 7, 2025
1 parent f71583f commit 2e52c31
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 35 deletions.
5 changes: 5 additions & 0 deletions NOTICE
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,8 @@ License - https://github.com/hexops/gotextdiff/blob/main/LICENSE
https://github.com/BurntSushi/toml
Copyright (c) 2013 TOML authors
https://github.com/BurntSushi/toml/blob/master/COPYING

dario.cat/mergo
Copyright (c) 2013 Dario Castañé. All rights reserved.
Copyright (c) 2012 The Go Authors. All rights reserved.
https://github.com/darccio/mergo/blob/master/LICENSE
56 changes: 25 additions & 31 deletions acceptance/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,18 @@ package acceptance_test
import (
"os"
"path/filepath"
"sync"
"slices"
"strings"
"testing"

"dario.cat/mergo"
"github.com/BurntSushi/toml"
"github.com/databricks/cli/libs/testdiff"
"github.com/stretchr/testify/require"
)

const configFilename = "test.toml"

var (
configCache map[string]TestConfig
configMutex sync.Mutex
)

type TestConfig struct {
// Place to describe what's wrong with this test. Does not affect how the test is run.
Badness string
Expand Down Expand Up @@ -65,58 +62,55 @@ type ServerStub struct {
}
}

// FindConfig finds the closest config file.
func FindConfig(t *testing.T, dir string) (string, bool) {
shared := false
// FindConfigs finds all the config relevant for this test,
// ordered from the most outermost (at acceptance/) to current test directory (identified by dir).
// Argument dir must be a relative path from the root of acceptance tests (<project_root>/acceptance/).
func FindConfigs(t *testing.T, dir string) []string {
configs := []string{}
for {
path := filepath.Join(dir, configFilename)
_, err := os.Stat(path)

if err == nil {
return path, shared
configs = append(configs, path)
}

shared = true

if dir == "" || dir == "." {
break
}

if os.IsNotExist(err) {
dir = filepath.Dir(dir)
dir = filepath.Dir(dir)

if err == nil || os.IsNotExist(err) {
continue
}

t.Fatalf("Error while reading %s: %s", path, err)
}

t.Fatal("Config not found: " + configFilename)
return "", shared
slices.Reverse(configs)
return configs
}

// LoadConfig loads the config file. Non-leaf configs are cached.
func LoadConfig(t *testing.T, dir string) (TestConfig, string) {
path, leafConfig := FindConfig(t, dir)
configs := FindConfigs(t, dir)

if leafConfig {
return DoLoadConfig(t, path), path
if len(configs) == 0 {
return TestConfig{}, "(no config)"
}

configMutex.Lock()
defer configMutex.Unlock()
result := DoLoadConfig(t, configs[0])

if configCache == nil {
configCache = make(map[string]TestConfig)
}

result, ok := configCache[path]
if ok {
return result, path
for _, cfgName := range configs[1:] {
cfg := DoLoadConfig(t, cfgName)
err := mergo.Merge(&result, cfg, mergo.WithOverride, mergo.WithAppendSlice)
if err != nil {
t.Fatalf("Error during config merge: %s: %s", cfgName, err)
}
}

result = DoLoadConfig(t, path)
configCache[path] = result
return result, path
return result, strings.Join(configs, ", ")
}

func DoLoadConfig(t *testing.T, path string) TestConfig {
Expand Down
2 changes: 0 additions & 2 deletions acceptance/test.toml

This file was deleted.

1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.23
toolchain go1.23.4

require (
dario.cat/mergo v1.0.1 // BSD 3-Clause
github.com/BurntSushi/toml v1.4.0 // MIT
github.com/Masterminds/semver/v3 v3.3.1 // MIT
github.com/briandowns/spinner v1.23.1 // Apache 2.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 2e52c31

Please sign in to comment.