414 lines
13 KiB
Go
414 lines
13 KiB
Go
package vars_test
|
|
|
|
import (
|
|
"errors"
|
|
|
|
. "github.com/onsi/ginkgo/v2"
|
|
. "github.com/onsi/gomega"
|
|
|
|
. "github.com/concourse/concourse/vars"
|
|
)
|
|
|
|
var _ = Describe("Template", func() {
|
|
It("can interpolate values into a struct with byte slice", func() {
|
|
template := NewTemplate([]byte("((key))"))
|
|
vars := StaticVariables{"key": "foo"}
|
|
|
|
result, err := template.Evaluate(vars, EvaluateOpts{})
|
|
Expect(err).NotTo(HaveOccurred())
|
|
Expect(result).To(Equal([]byte("foo\n")))
|
|
})
|
|
|
|
It("can interpolate values with leading slash into a struct with byte slice", func() {
|
|
template := NewTemplate([]byte("((/key/foo))"))
|
|
vars := StaticVariables{"/key/foo": "foo"}
|
|
|
|
result, err := template.Evaluate(vars, EvaluateOpts{})
|
|
Expect(err).NotTo(HaveOccurred())
|
|
Expect(result).To(Equal([]byte("foo\n")))
|
|
})
|
|
|
|
It("can interpolate multiple values into a byte slice", func() {
|
|
template := NewTemplate([]byte("((key)): ((value))"))
|
|
vars := StaticVariables{
|
|
"key": "foo",
|
|
"value": "bar",
|
|
}
|
|
|
|
result, err := template.Evaluate(vars, EvaluateOpts{})
|
|
Expect(err).NotTo(HaveOccurred())
|
|
Expect(result).To(Equal([]byte("foo: bar\n")))
|
|
})
|
|
|
|
It("can interpolate boolean values into a byte slice", func() {
|
|
template := NewTemplate([]byte("otherstuff: ((boule))"))
|
|
vars := StaticVariables{"boule": true}
|
|
|
|
result, err := template.Evaluate(vars, EvaluateOpts{})
|
|
Expect(err).NotTo(HaveOccurred())
|
|
Expect(result).To(Equal([]byte("otherstuff: true\n")))
|
|
})
|
|
|
|
It("can interpolate a different data types into a byte slice", func() {
|
|
hashValue := map[string]interface{}{"key2": []string{"value1", "value2"}}
|
|
template := NewTemplate([]byte("name1: ((name1))\nname2: ((name2))\nname3: ((name3))\nname4: ((name4))\nname5: ((name5))\nname6: ((name6))\n1234: value\n"))
|
|
vars := StaticVariables{
|
|
"name1": 1,
|
|
"name2": "nil",
|
|
"name3": true,
|
|
"name4": "",
|
|
"name5": nil,
|
|
"name6": map[string]interface{}{"key": hashValue},
|
|
}
|
|
|
|
result, err := template.Evaluate(vars, EvaluateOpts{})
|
|
Expect(err).NotTo(HaveOccurred())
|
|
Expect(result).To(Equal([]byte(`1234: value
|
|
name1: 1
|
|
name2: nil
|
|
name3: true
|
|
name4: ""
|
|
name5: null
|
|
name6:
|
|
key:
|
|
key2:
|
|
- value1
|
|
- value2
|
|
`)))
|
|
})
|
|
|
|
It("return errors if there are missing variable keys and ExpectAllKeys is true", func() {
|
|
template := NewTemplate([]byte(`
|
|
((key4))_array:
|
|
- ((key_in_array))
|
|
((key)): ((key2))
|
|
((key3)): 2
|
|
dup-key: ((key3))
|
|
`))
|
|
vars := StaticVariables{"key3": "foo"}
|
|
|
|
_, err := template.Evaluate(vars, EvaluateOpts{ExpectAllKeys: true})
|
|
Expect(err).To(HaveOccurred())
|
|
Expect(err.Error()).To(Equal("undefined vars: key, key2, key4, key_in_array"))
|
|
})
|
|
|
|
It("return errors if there are multiple variables with same path and ExpectAllKeys is true", func() {
|
|
template := NewTemplate([]byte("((var1:key1)): ((var2:key1))"))
|
|
vars := NamedVariables{
|
|
"var1": StaticVariables{
|
|
"key3": "fuzz",
|
|
},
|
|
"var2": StaticVariables{
|
|
"key4": "blah",
|
|
},
|
|
}
|
|
|
|
_, err := template.Evaluate(vars, EvaluateOpts{ExpectAllKeys: true})
|
|
Expect(err).To(HaveOccurred())
|
|
Expect(err.Error()).To(Equal("undefined vars: var1:key1, var2:key1"))
|
|
})
|
|
|
|
It("does not return error if there are missing variable keys and ExpectAllKeys is false", func() {
|
|
template := NewTemplate([]byte("((key)): ((key2))\n((key3)): 2"))
|
|
vars := StaticVariables{"key3": "foo"}
|
|
|
|
result, err := template.Evaluate(vars, EvaluateOpts{})
|
|
Expect(err).ToNot(HaveOccurred())
|
|
Expect(result).To(Equal([]byte("((key)): ((key2))\nfoo: 2\n")))
|
|
})
|
|
|
|
It("return errors if there are unused variable keys and ExpectAllVarsUsed is true", func() {
|
|
template := NewTemplate([]byte("((key2))"))
|
|
vars := StaticVariables{"key1": "1", "key2": "2", "key3": "3"}
|
|
|
|
_, err := template.Evaluate(vars, EvaluateOpts{ExpectAllVarsUsed: true})
|
|
Expect(err).To(HaveOccurred())
|
|
Expect(err.Error()).To(Equal("unused vars: key1, key3"))
|
|
})
|
|
|
|
It("return errors if there are unused named variable keys and ExpectAllVarsUsed is true", func() {
|
|
template := NewTemplate([]byte("((key2))"))
|
|
vars := NamedVariables{
|
|
"var1": StaticVariables{
|
|
"key1": "fuzz",
|
|
},
|
|
"var2": StaticVariables{
|
|
"key1": "blah",
|
|
},
|
|
}
|
|
|
|
_, err := template.Evaluate(vars, EvaluateOpts{ExpectAllVarsUsed: true})
|
|
Expect(err).To(HaveOccurred())
|
|
Expect(err.Error()).To(Equal("unused vars: var1:key1, var2:key1"))
|
|
})
|
|
|
|
It("does not return error if there are unused variable keys and ExpectAllVarsUsed is false", func() {
|
|
template := NewTemplate([]byte("((key)): ((key2))"))
|
|
vars := StaticVariables{"key3": "foo"}
|
|
|
|
result, err := template.Evaluate(vars, EvaluateOpts{})
|
|
Expect(err).ToNot(HaveOccurred())
|
|
Expect(result).To(Equal([]byte("((key)): ((key2))\n")))
|
|
})
|
|
|
|
It("return errors if there are not found and unused variables and ExpectAllKeys and ExpectAllVarsUsed are true", func() {
|
|
template := NewTemplate([]byte("((key2))"))
|
|
vars := StaticVariables{"key1": "1", "key3": "3"}
|
|
|
|
_, err := template.Evaluate(vars, EvaluateOpts{ExpectAllKeys: true, ExpectAllVarsUsed: true})
|
|
Expect(err).To(HaveOccurred())
|
|
Expect(err.Error()).To(ContainSubstring("undefined vars: key2"))
|
|
Expect(err.Error()).To(ContainSubstring("unused vars: key1, key3"))
|
|
})
|
|
|
|
Context("When template is a number", func() {
|
|
It("returns it", func() {
|
|
template := NewTemplate([]byte(`1234`))
|
|
vars := StaticVariables{"key": "not key"}
|
|
|
|
result, err := template.Evaluate(vars, EvaluateOpts{})
|
|
Expect(err).NotTo(HaveOccurred())
|
|
Expect(result).To(Equal([]byte("1234\n")))
|
|
})
|
|
})
|
|
|
|
Context("When variable has nil as value for key", func() {
|
|
It("uses null", func() {
|
|
template := NewTemplate([]byte("((key)): value"))
|
|
vars := StaticVariables{"key": nil}
|
|
|
|
result, err := template.Evaluate(vars, EvaluateOpts{})
|
|
Expect(err).NotTo(HaveOccurred())
|
|
Expect(result).To(Equal([]byte("null: value\n")))
|
|
})
|
|
})
|
|
|
|
It("can interpolate unicode values into a byte slice", func() {
|
|
template := NewTemplate([]byte("((Ω))"))
|
|
vars := StaticVariables{"Ω": "☃"}
|
|
|
|
result, err := template.Evaluate(vars, EvaluateOpts{})
|
|
Expect(err).NotTo(HaveOccurred())
|
|
Expect(result).To(Equal([]byte("☃\n")))
|
|
})
|
|
|
|
It("can interpolate keys with dashes and underscores into a byte slice", func() {
|
|
template := NewTemplate([]byte("((with-a-dash)): ((with_an_underscore))"))
|
|
vars := StaticVariables{
|
|
"with-a-dash": "dash",
|
|
"with_an_underscore": "underscore",
|
|
}
|
|
|
|
result, err := template.Evaluate(vars, EvaluateOpts{})
|
|
Expect(err).NotTo(HaveOccurred())
|
|
Expect(result).To(Equal([]byte("dash: underscore\n")))
|
|
})
|
|
|
|
It("can interpolate quoted keys with dot and colon into a byte slice", func() {
|
|
template := NewTemplate([]byte("bar: ((foo:\"with.dot:colon\".buzz))"))
|
|
vars := NamedVariables{
|
|
"foo": StaticVariables{
|
|
"with.dot:colon": map[string]interface{}{
|
|
"buzz": "fuzz",
|
|
},
|
|
},
|
|
}
|
|
|
|
result, err := template.Evaluate(vars, EvaluateOpts{})
|
|
Expect(err).NotTo(HaveOccurred())
|
|
Expect(string(result)).To(Equal("bar: fuzz\n"))
|
|
})
|
|
|
|
It("can interpolate quoted keys with colon and no var source", func() {
|
|
template := NewTemplate([]byte("bar: ((\"with:colon\"))"))
|
|
vars := StaticVariables{
|
|
"with:colon": "foo",
|
|
}
|
|
|
|
result, err := template.Evaluate(vars, EvaluateOpts{})
|
|
Expect(err).NotTo(HaveOccurred())
|
|
Expect(string(result)).To(Equal("bar: foo\n"))
|
|
})
|
|
|
|
It("can interpolate quoted keys with dot in subkey into a byte slice", func() {
|
|
template := NewTemplate([]byte("bar: ((secret-name.\"secret.field\"))"))
|
|
vars := StaticVariables{
|
|
"secret-name": map[string]interface{}{
|
|
"secret.field": "topsekrit",
|
|
},
|
|
}
|
|
|
|
result, err := template.Evaluate(vars, EvaluateOpts{})
|
|
Expect(err).NotTo(HaveOccurred())
|
|
Expect(string(result)).To(Equal(string([]byte("bar: topsekrit\n"))))
|
|
})
|
|
|
|
It("can interpolate a secret key in the middle of a string", func() {
|
|
template := NewTemplate([]byte("url: https://((ip))"))
|
|
vars := StaticVariables{
|
|
"ip": "10.0.0.0",
|
|
}
|
|
|
|
result, err := template.Evaluate(vars, EvaluateOpts{})
|
|
Expect(err).NotTo(HaveOccurred())
|
|
Expect(result).To(Equal([]byte("url: https://10.0.0.0\n")))
|
|
})
|
|
|
|
It("can interpolate multiple secret keys in the middle of a string", func() {
|
|
template := NewTemplate([]byte("uri: nats://nats:((password))@((ip)):4222"))
|
|
vars := StaticVariables{
|
|
"password": "secret",
|
|
"ip": "10.0.0.0",
|
|
}
|
|
|
|
result, err := template.Evaluate(vars, EvaluateOpts{})
|
|
Expect(err).NotTo(HaveOccurred())
|
|
Expect(result).To(Equal([]byte("uri: nats://nats:secret@10.0.0.0:4222\n")))
|
|
})
|
|
|
|
It("allows @ in a var name", func() {
|
|
template := NewTemplate([]byte("((\"foo/bar/me.com-test@me.com/password\"))"))
|
|
vars := StaticVariables{
|
|
"foo/bar/me.com-test@me.com/password": "secret",
|
|
}
|
|
|
|
result, err := template.Evaluate(vars, EvaluateOpts{})
|
|
Expect(err).NotTo(HaveOccurred())
|
|
Expect(result).To(Equal([]byte("secret\n")))
|
|
})
|
|
|
|
It("can interpolate multiple keys of type string and int in the middle of a string", func() {
|
|
template := NewTemplate([]byte("address: ((ip)):((port))"))
|
|
vars := StaticVariables{
|
|
"port": 4222,
|
|
"ip": "10.0.0.0",
|
|
}
|
|
|
|
result, err := template.Evaluate(vars, EvaluateOpts{})
|
|
Expect(err).NotTo(HaveOccurred())
|
|
Expect(result).To(Equal([]byte("address: 10.0.0.0:4222\n")))
|
|
})
|
|
|
|
It("raises error when interpolating an unsupported type in the middle of a string", func() {
|
|
template := NewTemplate([]byte("address: ((definition)):((eulers_number))"))
|
|
vars := StaticVariables{
|
|
"eulers_number": 2.717,
|
|
"definition": "natural_log",
|
|
}
|
|
|
|
_, err := template.Evaluate(vars, EvaluateOpts{})
|
|
Expect(err).To(HaveOccurred())
|
|
Expect(err.Error()).To(ContainSubstring("float64"))
|
|
Expect(err.Error()).To(ContainSubstring("eulers_number"))
|
|
})
|
|
|
|
It("can interpolate a single key multiple times in the middle of a string", func() {
|
|
template := NewTemplate([]byte("acct_and_password: ((user)):((user))"))
|
|
vars := StaticVariables{
|
|
"user": "nats",
|
|
}
|
|
|
|
result, err := template.Evaluate(vars, EvaluateOpts{})
|
|
Expect(err).NotTo(HaveOccurred())
|
|
Expect(result).To(Equal([]byte("acct_and_password: nats:nats\n")))
|
|
})
|
|
|
|
It("can interpolate values into the middle of a key", func() {
|
|
template := NewTemplate([]byte("((iaas))_cpi: props"))
|
|
vars := StaticVariables{
|
|
"iaas": "aws",
|
|
}
|
|
|
|
result, err := template.Evaluate(vars, EvaluateOpts{})
|
|
Expect(err).NotTo(HaveOccurred())
|
|
Expect(result).To(Equal([]byte("aws_cpi: props\n")))
|
|
})
|
|
|
|
It("can interpolate the same value multiple times into a byte slice", func() {
|
|
template := NewTemplate([]byte("((key)): ((key))"))
|
|
vars := StaticVariables{"key": "foo"}
|
|
|
|
result, err := template.Evaluate(vars, EvaluateOpts{})
|
|
Expect(err).NotTo(HaveOccurred())
|
|
Expect(result).To(Equal([]byte("foo: foo\n")))
|
|
})
|
|
|
|
It("can interpolate values with strange newlines", func() {
|
|
template := NewTemplate([]byte("((key))"))
|
|
vars := StaticVariables{"key": "this\nhas\nmany\nlines"}
|
|
|
|
result, err := template.Evaluate(vars, EvaluateOpts{})
|
|
Expect(err).NotTo(HaveOccurred())
|
|
Expect(result).To(Equal([]byte("|-\n this\n has\n many\n lines\n")))
|
|
})
|
|
|
|
It("ignores if operation is not specified", func() {
|
|
template := NewTemplate([]byte("((key))"))
|
|
vars := StaticVariables{"key": "val"}
|
|
|
|
result, err := template.Evaluate(vars, EvaluateOpts{})
|
|
Expect(err).NotTo(HaveOccurred())
|
|
Expect(result).To(Equal([]byte("val\n")))
|
|
})
|
|
|
|
It("ignores an invalid input", func() {
|
|
template := NewTemplate([]byte("(()"))
|
|
vars := StaticVariables{}
|
|
|
|
result, err := template.Evaluate(vars, EvaluateOpts{})
|
|
Expect(err).NotTo(HaveOccurred())
|
|
Expect(result).To(Equal([]byte("(()\n")))
|
|
})
|
|
|
|
It("allow var_source name in variable keys", func() {
|
|
template := NewTemplate([]byte("abc: ((dummy:key))"))
|
|
vars := NamedVariables{
|
|
"dummy": StaticVariables{"key": "val"},
|
|
}
|
|
|
|
result, err := template.Evaluate(vars, EvaluateOpts{})
|
|
Expect(err).NotTo(HaveOccurred())
|
|
Expect(result).To(Equal([]byte("abc: val\n")))
|
|
})
|
|
|
|
It("allows to access sub key of an interpolated value via dot syntax", func() {
|
|
template := NewTemplate([]byte("((key.subkey))"))
|
|
vars := StaticVariables{
|
|
"key": map[interface{}]interface{}{"subkey": "e"},
|
|
}
|
|
|
|
result, err := template.Evaluate(vars, EvaluateOpts{})
|
|
Expect(err).NotTo(HaveOccurred())
|
|
Expect(result).To(Equal([]byte("e\n")))
|
|
})
|
|
|
|
It("returns an error if variable is not found and is being used with a sub key", func() {
|
|
template := NewTemplate([]byte("((key.subkey_not_found))"))
|
|
vars := StaticVariables{}
|
|
|
|
_, err := template.Evaluate(vars, EvaluateOpts{ExpectAllKeys: true})
|
|
Expect(err).To(HaveOccurred())
|
|
Expect(err.Error()).To(ContainSubstring("undefined vars: key"))
|
|
})
|
|
|
|
It("returns an error if accessing sub key of an interpolated value fails", func() {
|
|
template := NewTemplate([]byte("((key.subkey_not_found))"))
|
|
vars := StaticVariables{
|
|
"key": map[interface{}]interface{}{"subkey": "e"},
|
|
}
|
|
|
|
_, err := template.Evaluate(vars, EvaluateOpts{ExpectAllKeys: true})
|
|
Expect(err).To(HaveOccurred())
|
|
Expect(err.Error()).To(ContainSubstring("missing field 'subkey_not_found' in var: key.subkey_not_found"))
|
|
})
|
|
|
|
It("returns error if finding variable fails", func() {
|
|
template := NewTemplate([]byte("((key))"))
|
|
vars := &FakeVariables{GetErr: errors.New("fake-err")}
|
|
|
|
_, err := template.Evaluate(vars, EvaluateOpts{})
|
|
Expect(err).To(HaveOccurred())
|
|
Expect(err.Error()).To(ContainSubstring("fake-err"))
|
|
})
|
|
})
|