In 405d5d63b1 we changed for an ordered
list to a map, however the test is order dependent go maps are
randomized.
Change the test to use a slice with an internal type (instead of pulling
back in k8s.io/kubernetes).
Without this change this test will fail occasionally and has no
guarentee for success because of the random order of maps.
282 lines
5.7 KiB
Go
282 lines
5.7 KiB
Go
package expansion
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
func TestMapReference(t *testing.T) {
|
|
// We use a struct here instead of a map because we need mappings to happen in order.
|
|
// Go maps are randomized.
|
|
type envVar struct {
|
|
Name string
|
|
Value string
|
|
}
|
|
|
|
envs := []envVar{
|
|
{"FOO", "bar"},
|
|
{"ZOO", "$(FOO)-1"},
|
|
{"BLU", "$(ZOO)-2"},
|
|
}
|
|
|
|
declaredEnv := map[string]string{
|
|
"FOO": "bar",
|
|
"ZOO": "$(FOO)-1",
|
|
"BLU": "$(ZOO)-2",
|
|
}
|
|
|
|
serviceEnv := map[string]string{}
|
|
|
|
mapping := MappingFuncFor(declaredEnv, serviceEnv)
|
|
|
|
for _, env := range envs {
|
|
declaredEnv[env.Name] = Expand(env.Value, mapping)
|
|
}
|
|
|
|
expectedEnv := map[string]string{
|
|
"FOO": "bar",
|
|
"ZOO": "bar-1",
|
|
"BLU": "bar-1-2",
|
|
}
|
|
|
|
for k, v := range expectedEnv {
|
|
if e, a := v, declaredEnv[k]; e != a {
|
|
t.Errorf("Expected %v, got %v", e, a)
|
|
} else {
|
|
delete(declaredEnv, k)
|
|
}
|
|
}
|
|
|
|
if len(declaredEnv) != 0 {
|
|
t.Errorf("Unexpected keys in declared env: %v", declaredEnv)
|
|
}
|
|
}
|
|
|
|
func TestMapping(t *testing.T) {
|
|
context := map[string]string{
|
|
"VAR_A": "A",
|
|
"VAR_B": "B",
|
|
"VAR_C": "C",
|
|
"VAR_REF": "$(VAR_A)",
|
|
"VAR_EMPTY": "",
|
|
}
|
|
mapping := MappingFuncFor(context)
|
|
|
|
doExpansionTest(t, mapping)
|
|
}
|
|
|
|
func TestMappingDual(t *testing.T) {
|
|
context := map[string]string{
|
|
"VAR_A": "A",
|
|
"VAR_EMPTY": "",
|
|
}
|
|
context2 := map[string]string{
|
|
"VAR_B": "B",
|
|
"VAR_C": "C",
|
|
"VAR_REF": "$(VAR_A)",
|
|
}
|
|
mapping := MappingFuncFor(context, context2)
|
|
|
|
doExpansionTest(t, mapping)
|
|
}
|
|
|
|
func doExpansionTest(t *testing.T, mapping func(string) string) {
|
|
cases := []struct {
|
|
name string
|
|
input string
|
|
expected string
|
|
}{
|
|
{
|
|
name: "whole string",
|
|
input: "$(VAR_A)",
|
|
expected: "A",
|
|
},
|
|
{
|
|
name: "repeat",
|
|
input: "$(VAR_A)-$(VAR_A)",
|
|
expected: "A-A",
|
|
},
|
|
{
|
|
name: "beginning",
|
|
input: "$(VAR_A)-1",
|
|
expected: "A-1",
|
|
},
|
|
{
|
|
name: "middle",
|
|
input: "___$(VAR_B)___",
|
|
expected: "___B___",
|
|
},
|
|
{
|
|
name: "end",
|
|
input: "___$(VAR_C)",
|
|
expected: "___C",
|
|
},
|
|
{
|
|
name: "compound",
|
|
input: "$(VAR_A)_$(VAR_B)_$(VAR_C)",
|
|
expected: "A_B_C",
|
|
},
|
|
{
|
|
name: "escape & expand",
|
|
input: "$$(VAR_B)_$(VAR_A)",
|
|
expected: "$(VAR_B)_A",
|
|
},
|
|
{
|
|
name: "compound escape",
|
|
input: "$$(VAR_A)_$$(VAR_B)",
|
|
expected: "$(VAR_A)_$(VAR_B)",
|
|
},
|
|
{
|
|
name: "mixed in escapes",
|
|
input: "f000-$$VAR_A",
|
|
expected: "f000-$VAR_A",
|
|
},
|
|
{
|
|
name: "backslash escape ignored",
|
|
input: "foo\\$(VAR_C)bar",
|
|
expected: "foo\\Cbar",
|
|
},
|
|
{
|
|
name: "backslash escape ignored",
|
|
input: "foo\\\\$(VAR_C)bar",
|
|
expected: "foo\\\\Cbar",
|
|
},
|
|
{
|
|
name: "lots of backslashes",
|
|
input: "foo\\\\\\\\$(VAR_A)bar",
|
|
expected: "foo\\\\\\\\Abar",
|
|
},
|
|
{
|
|
name: "nested var references",
|
|
input: "$(VAR_A$(VAR_B))",
|
|
expected: "$(VAR_A$(VAR_B))",
|
|
},
|
|
{
|
|
name: "nested var references second type",
|
|
input: "$(VAR_A$(VAR_B)",
|
|
expected: "$(VAR_A$(VAR_B)",
|
|
},
|
|
{
|
|
name: "value is a reference",
|
|
input: "$(VAR_REF)",
|
|
expected: "$(VAR_A)",
|
|
},
|
|
{
|
|
name: "value is a reference x 2",
|
|
input: "%%$(VAR_REF)--$(VAR_REF)%%",
|
|
expected: "%%$(VAR_A)--$(VAR_A)%%",
|
|
},
|
|
{
|
|
name: "empty var",
|
|
input: "foo$(VAR_EMPTY)bar",
|
|
expected: "foobar",
|
|
},
|
|
{
|
|
name: "unterminated expression",
|
|
input: "foo$(VAR_Awhoops!",
|
|
expected: "foo$(VAR_Awhoops!",
|
|
},
|
|
{
|
|
name: "expression without operator",
|
|
input: "f00__(VAR_A)__",
|
|
expected: "f00__(VAR_A)__",
|
|
},
|
|
{
|
|
name: "shell special vars pass through",
|
|
input: "$?_boo_$!",
|
|
expected: "$?_boo_$!",
|
|
},
|
|
{
|
|
name: "bare operators are ignored",
|
|
input: "$VAR_A",
|
|
expected: "$VAR_A",
|
|
},
|
|
{
|
|
name: "undefined vars are passed through",
|
|
input: "$(VAR_DNE)",
|
|
expected: "$(VAR_DNE)",
|
|
},
|
|
{
|
|
name: "multiple (even) operators, var undefined",
|
|
input: "$$$$$$(BIG_MONEY)",
|
|
expected: "$$$(BIG_MONEY)",
|
|
},
|
|
{
|
|
name: "multiple (even) operators, var defined",
|
|
input: "$$$$$$(VAR_A)",
|
|
expected: "$$$(VAR_A)",
|
|
},
|
|
{
|
|
name: "multiple (odd) operators, var undefined",
|
|
input: "$$$$$$$(GOOD_ODDS)",
|
|
expected: "$$$$(GOOD_ODDS)",
|
|
},
|
|
{
|
|
name: "multiple (odd) operators, var defined",
|
|
input: "$$$$$$$(VAR_A)",
|
|
expected: "$$$A",
|
|
},
|
|
{
|
|
name: "missing open expression",
|
|
input: "$VAR_A)",
|
|
expected: "$VAR_A)",
|
|
},
|
|
{
|
|
name: "shell syntax ignored",
|
|
input: "${VAR_A}",
|
|
expected: "${VAR_A}",
|
|
},
|
|
{
|
|
name: "trailing incomplete expression not consumed",
|
|
input: "$(VAR_B)_______$(A",
|
|
expected: "B_______$(A",
|
|
},
|
|
{
|
|
name: "trailing incomplete expression, no content, is not consumed",
|
|
input: "$(VAR_C)_______$(",
|
|
expected: "C_______$(",
|
|
},
|
|
{
|
|
name: "operator at end of input string is preserved",
|
|
input: "$(VAR_A)foobarzab$",
|
|
expected: "Afoobarzab$",
|
|
},
|
|
{
|
|
name: "shell escaped incomplete expr",
|
|
input: "foo-\\$(VAR_A",
|
|
expected: "foo-\\$(VAR_A",
|
|
},
|
|
{
|
|
name: "lots of $( in middle",
|
|
input: "--$($($($($--",
|
|
expected: "--$($($($($--",
|
|
},
|
|
{
|
|
name: "lots of $( in beginning",
|
|
input: "$($($($($--foo$(",
|
|
expected: "$($($($($--foo$(",
|
|
},
|
|
{
|
|
name: "lots of $( at end",
|
|
input: "foo0--$($($($(",
|
|
expected: "foo0--$($($($(",
|
|
},
|
|
{
|
|
name: "escaped operators in variable names are not escaped",
|
|
input: "$(foo$$var)",
|
|
expected: "$(foo$$var)",
|
|
},
|
|
{
|
|
name: "newline not expanded",
|
|
input: "\n",
|
|
expected: "\n",
|
|
},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
expanded := Expand(tc.input, mapping)
|
|
if e, a := tc.expected, expanded; e != a {
|
|
t.Errorf("%v: expected %q, got %q", tc.name, e, a)
|
|
}
|
|
}
|
|
}
|