diff --git a/acceptance/acceptance_test.go b/acceptance/acceptance_test.go index 475401711f..5801d3c8c2 100644 --- a/acceptance/acceptance_test.go +++ b/acceptance/acceptance_test.go @@ -331,7 +331,7 @@ func testAccept(t *testing.T, inprocessMode bool, singleTest string) int { t.Parallel() } - expanded := internal.ExpandEnvMatrix(config.EnvMatrix) + expanded := internal.ExpandEnvMatrix(config.EnvMatrix, config.EnvMatrixExclude) if testdiff.OverwriteMode && len(expanded) > 1 { // All variants of the test are producing the same output, @@ -351,9 +351,6 @@ func testAccept(t *testing.T, inprocessMode bool, singleTest string) int { runTest(t, dir, 0, coverDir, repls.Clone(), config, expanded[0], envFilters) } else { for ind, envset := range expanded { - if forbiddenEnvSet(envset) { - continue - } envname := strings.Join(envset, "/") t.Run(envname, func(t *testing.T) { if !inprocessMode { @@ -371,23 +368,6 @@ func testAccept(t *testing.T, inprocessMode bool, singleTest string) int { return selectedDirs - skippedDirs } -func forbiddenEnvSet(envset []string) bool { - hasTerraform := false - hasReadplan := false - - for _, pair := range envset { - if pair == "DATABRICKS_BUNDLE_ENGINE=terraform" { - hasTerraform = true - } - if pair == "READPLAN=1" { - hasReadplan = true - } - } - - // Do not run terraform tests with --plan option: - return hasTerraform && hasReadplan -} - func getEnvFilters(t *testing.T) []string { envFilterValue := os.Getenv(EnvFilterVar) if envFilterValue == "" { diff --git a/acceptance/internal/config.go b/acceptance/internal/config.go index 2129fa5573..327bf34105 100644 --- a/acceptance/internal/config.go +++ b/acceptance/internal/config.go @@ -100,6 +100,13 @@ type TestConfig struct { // similar to github actions matrix strategy. EnvMatrix map[string][]string + // Environment variables matrix exclusion list. + // Exclude certain configuration from the grid generated by EnvMatrix. + // They key is arbitrary string and the value is a list of KEY=value pairs to exclude. + // For example: + // EnvMatrixExclude.noplantf = ["READPLAN=1", "DATABRICKS_BUNDLE_ENGINE=terraform"] + EnvMatrixExclude map[string][]string + // List of keys for which to do string replacement value -> [KEY]. If not set, defaults to true. EnvRepl map[string]bool @@ -269,7 +276,8 @@ func (t mapTransformer) Transformer(typ reflect.Type) func(dst, src reflect.Valu // output: [["KEY=A", "OTHER=VALUE"], ["KEY=B", "OTHER=VALUE"]] // // If any entries is an empty list, that variable is dropped from the matrix before processing. -func ExpandEnvMatrix(matrix map[string][]string) [][]string { +// The exclude parameter specifies combinations to exclude from the result. +func ExpandEnvMatrix(matrix, exclude map[string][]string) [][]string { result := [][]string{{}} if len(matrix) == 0 { @@ -314,5 +322,51 @@ func ExpandEnvMatrix(matrix map[string][]string) [][]string { result = newResult } + // Filter out excluded combinations + if len(exclude) > 0 { + result = filterExcludedEnvSets(result, exclude) + } + return result } + +// filterExcludedEnvSets removes environment sets that match exclusion rules. +// An environment set is excluded if it contains all KEY=value pairs from any exclusion rule. +func filterExcludedEnvSets(envSets [][]string, exclude map[string][]string) [][]string { + var filtered [][]string + + for _, envSet := range envSets { + excluded := false + + // Check each exclusion rule + for _, excludeRule := range exclude { + if matchesExclusionRule(envSet, excludeRule) { + excluded = true + break + } + } + + if !excluded { + filtered = append(filtered, envSet) + } + } + + return filtered +} + +// matchesExclusionRule returns true if envSet contains all KEY=value pairs from excludeRule. +func matchesExclusionRule(envSet, excludeRule []string) bool { + for _, excludePair := range excludeRule { + found := false + for _, envPair := range envSet { + if envPair == excludePair { + found = true + break + } + } + if !found { + return false + } + } + return true +} diff --git a/acceptance/internal/config_test.go b/acceptance/internal/config_test.go index 12305e2a33..ea06335c5d 100644 --- a/acceptance/internal/config_test.go +++ b/acceptance/internal/config_test.go @@ -10,6 +10,7 @@ func TestExpandEnvMatrix(t *testing.T) { tests := []struct { name string matrix map[string][]string + exclude map[string][]string expected [][]string }{ { @@ -90,11 +91,80 @@ func TestExpandEnvMatrix(t *testing.T) { {"KEY=B", "OTHER=VALUE"}, }, }, + { + name: "exclude single combination", + matrix: map[string][]string{ + "KEY1": {"A", "B"}, + "KEY2": {"C", "D"}, + }, + exclude: map[string][]string{ + "rule1": {"KEY1=A", "KEY2=C"}, + }, + expected: [][]string{ + {"KEY1=A", "KEY2=D"}, + {"KEY1=B", "KEY2=C"}, + {"KEY1=B", "KEY2=D"}, + }, + }, + { + name: "exclude multiple combinations", + matrix: map[string][]string{ + "KEY1": {"A", "B"}, + "KEY2": {"C", "D"}, + }, + exclude: map[string][]string{ + "rule1": {"KEY1=A", "KEY2=C"}, + "rule2": {"KEY1=B", "KEY2=D"}, + }, + expected: [][]string{ + {"KEY1=A", "KEY2=D"}, + {"KEY1=B", "KEY2=C"}, + }, + }, + { + name: "exclude with terraform and readplan example", + matrix: map[string][]string{ + "DATABRICKS_BUNDLE_ENGINE": {"terraform", "direct"}, + "READPLAN": {"0", "1"}, + }, + exclude: map[string][]string{ + "noplantf": {"READPLAN=1", "DATABRICKS_BUNDLE_ENGINE=terraform"}, + }, + expected: [][]string{ + {"DATABRICKS_BUNDLE_ENGINE=terraform", "READPLAN=0"}, + {"DATABRICKS_BUNDLE_ENGINE=direct", "READPLAN=0"}, + {"DATABRICKS_BUNDLE_ENGINE=direct", "READPLAN=1"}, + }, + }, + { + name: "exclude rule with subset of keys matches", + matrix: map[string][]string{ + "KEY1": {"A"}, + "KEY2": {"B"}, + "KEY3": {"C"}, + }, + exclude: map[string][]string{ + "rule1": {"KEY1=A", "KEY2=B"}, + }, + expected: nil, + }, + { + name: "exclude rule with more keys than envset does not match", + matrix: map[string][]string{ + "KEY1": {"A"}, + }, + exclude: map[string][]string{ + "rule1": {"KEY1=A", "KEY2=B"}, + }, + expected: [][]string{ + {"KEY1=A"}, + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - result := ExpandEnvMatrix(tt.matrix) + result := ExpandEnvMatrix(tt.matrix, tt.exclude) assert.Equal(t, tt.expected, result) }) } diff --git a/acceptance/test.toml b/acceptance/test.toml index d2f3e3864a..f4cf64ea92 100644 --- a/acceptance/test.toml +++ b/acceptance/test.toml @@ -16,6 +16,7 @@ Env.PYTHONUNBUFFERED = "1" Env.PYTHONUTF8 = "1" EnvMatrix.DATABRICKS_BUNDLE_ENGINE = ["terraform", "direct"] +EnvMatrixExclude.noplantf = ["DATABRICKS_BUNDLE_ENGINE=terraform", "READPLAN=1"] EnvRepl.DATABRICKS_BUNDLE_ENGINE = false # >>> datetime.datetime.fromtimestamp(18000000000)