Extend agent template tests to also validate that updated templates get re-rendered. (#9097)

This commit is contained in:
ncabatoff 2020-05-29 13:36:59 -04:00 committed by GitHub
parent 12d704d97f
commit 4481521c0e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 79 additions and 38 deletions

View File

@ -6,6 +6,7 @@ import (
"io/ioutil"
"net/http"
"os"
"path/filepath"
"reflect"
"strings"
"sync"
@ -770,19 +771,22 @@ func TestAgent_Template_Basic(t *testing.T) {
for tcname, tc := range testCases {
t.Run(tcname, func(t *testing.T) {
// make some template files
var templatePaths []string
for i := 0; i < tc.templateCount; i++ {
path := makeTempFile(t, fmt.Sprintf("render_%d", i), templateContents(i))
templatePaths = append(templatePaths, path)
}
// create temp dir for this test run
tmpDir, err := ioutil.TempDir(tmpDirRoot, tcname)
if err != nil {
t.Fatal(err)
}
// make some template files
var templatePaths []string
for i := 0; i < tc.templateCount; i++ {
fileName := filepath.Join(tmpDir, fmt.Sprintf("render_%d.tmpl", i))
if err := ioutil.WriteFile(fileName, []byte(templateContents(i)), 0600); err != nil {
t.Fatal(err)
}
templatePaths = append(templatePaths, fileName)
}
// build up the template config to be added to the Agent config.hcl file
var templateConfigStrings []string
for i, t := range templatePaths {
@ -854,50 +858,85 @@ auto_auth {
// end and no longer be running. If we are not using exit_after_auth, then
// we need to shut down the command
if !tc.exitAfterAuth {
defer func() {
cmd.ShutdownCh <- struct{}{}
wg.Wait()
}()
}
verify := func(suffix string) {
t.Helper()
// We need to poll for a bit to give Agent time to render the
// templates. Without this this, the test will attempt to read
// the temp dir before Agent has had time to render and will
// likely fail the test
tick := time.Tick(1 * time.Second)
timeout := time.After(30 * time.Second)
timeout := time.After(10 * time.Second)
var err error
for {
select {
case <-timeout:
t.Error("timed out waiting for templates to render")
t.Fatalf("timed out waiting for templates to render, last error: %v", err)
case <-tick:
}
// Check for files rendered in the directory and break
// early for shutdown if we do have all the files
// rendered
if testListFiles(t, tmpDir) == len(templatePaths) {
break
//----------------------------------------------------
// Perform the tests
//----------------------------------------------------
if numFiles := testListFiles(t, tmpDir, ".json"); numFiles != len(templatePaths) {
err = fmt.Errorf("expected (%d) templates, got (%d)", len(templatePaths), numFiles)
continue
}
for i := range templatePaths {
fileName := filepath.Join(tmpDir, fmt.Sprintf("render_%d.json", i))
var c []byte
c, err = ioutil.ReadFile(fileName)
if err != nil {
continue
}
if string(c) != templateRendered(i)+suffix {
err = fmt.Errorf("expected='%s', got='%s'", templateRendered(i)+suffix, string(c))
continue
}
}
return
}
cmd.ShutdownCh <- struct{}{}
}
wg.Wait()
//----------------------------------------------------
// Perform the tests
//----------------------------------------------------
verify("")
if numFiles := testListFiles(t, tmpDir); numFiles != len(templatePaths) {
t.Fatalf("expected (%d) templates, got (%d)", len(templatePaths), numFiles)
for i := 0; i < tc.templateCount; i++ {
fileName := filepath.Join(tmpDir, fmt.Sprintf("render_%d.tmpl", i))
if err := ioutil.WriteFile(fileName, []byte(templateContents(i)+"{}"), 0600); err != nil {
t.Fatal(err)
}
}
verify("{}")
})
}
}
func testListFiles(t *testing.T, dir string) int {
func testListFiles(t *testing.T, dir, extension string) int {
t.Helper()
files, err := ioutil.ReadDir(dir)
if err != nil {
t.Fatal(err)
}
var count int
for _, f := range files {
if filepath.Ext(f.Name()) == extension {
count++
}
}
return len(files)
return count
}
// TestAgent_Template_ExitCounter tests that Vault Agent correctly renders all
@ -1117,24 +1156,22 @@ exit_after_auth = true
// a slice of template options
var templates = []string{
`{{ with secret "secret/otherapp"}}
{
{{ if .Data.data.username}}"username":"{{ .Data.data.username}}",{{ end }}
{{ if .Data.data.password }}"password":"{{ .Data.data.password }}",{{ end }}
{{ .Data.data.cert }}
`{{- with secret "secret/otherapp"}}{"secret": "other",
{{- if .Data.data.username}}"username":"{{ .Data.data.username}}",{{- end }}
{{- if .Data.data.password }}"password":"{{ .Data.data.password }}"{{- end }}}
{{- end }}`,
`{{- with secret "secret/myapp"}}{"secret": "myapp",
{{- if .Data.data.username}}"username":"{{ .Data.data.username}}",{{- end }}
{{- if .Data.data.password }}"password":"{{ .Data.data.password }}"{{- end }}}
{{- end }}`,
`{{- with secret "secret/myapp"}}{"secret": "myapp",
{{- if .Data.data.password }}"password":"{{ .Data.data.password }}"{{- end }}}
{{- end }}`,
}
{{ end }}`,
`{{ with secret "secret/myapp"}}
{
{{ if .Data.data.username}}"username":"{{ .Data.data.username}}",{{ end }}
{{ if .Data.data.password }}"password":"{{ .Data.data.password }}",{{ end }}
}
{{ end }}`,
`{{ with secret "secret/myapp"}}
{
{{ if .Data.data.password }}"password":"{{ .Data.data.password }}",{{ end }}
}
{{ end }}`,
var rendered = []string{
`{"secret": "other","username":"barstuff","password":"zap"}`,
`{"secret": "myapp","username":"bar","password":"zap"}`,
`{"secret": "myapp","password":"zap"}`,
}
// templateContents returns a template from the above templates slice. Each
@ -1145,6 +1182,10 @@ func templateContents(seed int) string {
index := seed % len(templates)
return templates[index]
}
func templateRendered(seed int) string {
index := seed % len(templates)
return rendered[index]
}
var templateConfigString = `
template {