Commit 163c3a6e authored by Geoff Simmons's avatar Geoff Simmons

Refactor the interface in template.go.

InitTemplates() takes a map of template paths to file paths, and
returns a map of parsed template to file paths.

Add WriteTemplate(), which takes a parsed template and a file path,
and generates VCL at the path from a spec and the template. Meant
for iteration on the map returned by InitTemplates().
parent ace00d98
......@@ -29,9 +29,9 @@
package vcl
import (
"bytes"
"fmt"
"path"
"os"
"path/filepath"
"regexp"
"text/template"
)
......@@ -41,25 +41,22 @@ var fMap = template.FuncMap{
"vclMangle": func(s string) string { return mangle(s) },
}
const (
tmplSrc = "backends.tmpl"
)
var (
tmpl *template.Template
vclIllegal = regexp.MustCompile("[^[:word:]-]+")
)
var vclIllegal = regexp.MustCompile("[^[:word:]-]+")
// InitTemplates initializes templates for VCL generation.
func InitTemplates(tmplDir string) error {
var err error
tmplPath := path.Join(tmplDir, tmplSrc)
func InitTemplates(
tmplMap map[string]string) (map[*template.Template]string, error) {
tmpl, err = template.New(tmplSrc).Funcs(fMap).ParseFiles(tmplPath)
if err != nil {
return err
tmpls2files := make(map[*template.Template]string, len(tmplMap))
for tmplPath, filePath := range tmplMap {
if tmpl, err := template.New(filepath.Base(tmplPath)).
Funcs(fMap).ParseFiles(tmplPath); err != nil {
return nil, err
} else {
tmpls2files[tmpl] = filePath
}
}
return nil
return tmpls2files, nil
}
func replIllegal(ill []byte) []byte {
......@@ -71,21 +68,24 @@ func replIllegal(ill []byte) []byte {
return repl
}
// GetSrc returns the VCL generated to implement a Spec.
func (spec Spec) GetSrc() (string, error) {
var buf bytes.Buffer
if err := tmpl.Execute(&buf, spec); err != nil {
return "", err
// WriteTemplate generates a VCL file at path to implement spec, using
// the template.
func (spec Spec) WriteTemplate(tmpl *template.Template, path string) error {
file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0644)
if err != nil {
return err
}
if err = tmpl.Execute(file, spec); err != nil {
file.Close()
return err
}
return buf.String(), nil
return file.Close()
}
func mangle(s string) string {
if s == "" {
return s
}
prefixed := "vk8s_" + s
bytes := []byte(prefixed)
mangled := vclIllegal.ReplaceAllFunc(bytes, replIllegal)
mangled := vclIllegal.ReplaceAllFunc([]byte(s), replIllegal)
return string(mangled)
}
......@@ -34,28 +34,50 @@ import (
"io/ioutil"
"os"
"path/filepath"
"runtime"
"strings"
"testing"
"text/template"
"time"
)
func cmpGold(got []byte, goldfile string) (bool, error) {
goldpath := filepath.Join("testdata", goldfile)
gold, err := ioutil.ReadFile(goldpath)
var (
testdir string
tmpdir string
)
func cmpGold(t *testing.T, gotPath string, goldfile string) bool {
goldPath := filepath.Join(testdir, "testdata", goldfile)
gold, err := ioutil.ReadFile(goldPath)
if err != nil {
return false, err
t.Fatalf("Cannot read %s: %s", goldPath, err)
return false
}
return bytes.Equal(got, gold), nil
got, err := ioutil.ReadFile(gotPath)
if err != nil {
t.Fatalf("Cannot read %s: %s", gotPath, err)
return false
}
return bytes.Equal(got, gold)
}
func TestMain(m *testing.M) {
tmplDir := ""
tmplEnv, exists := os.LookupEnv("TEMPLATE_DIR")
if !exists {
tmplDir = tmplEnv
var err error
_, filename, _, ok := runtime.Caller(0)
if !ok {
fmt.Println("Cannot get test directory")
os.Exit(-1)
}
if err := InitTemplates(tmplDir); err != nil {
fmt.Printf("Cannot parse templates: %v\n", err)
testdir = filepath.Dir(filename)
tmpdir, err = ioutil.TempDir("", "k8s-vcl-reloader")
if err != nil {
fmt.Println("Cannot create tmp directory:", err)
os.Exit(-1)
}
tmpdir = filepath.Join(tmpdir, "vcl_test")
if err = os.Mkdir(tmpdir, 0755); err != nil {
fmt.Printf("Cannot make tmp directory %s: %s", tmpdir, err)
os.Exit(-1)
}
code := m.Run()
......@@ -142,26 +164,33 @@ var testSpec = Spec{
}
func TestTemplate(t *testing.T) {
var buf bytes.Buffer
var tmpl *template.Template
gold := "backends.golden"
if err := tmpl.Execute(&buf, testSpec); err != nil {
t.Fatal("Execute():", err)
}
ok, err := cmpGold(buf.Bytes(), gold)
tmplMap := make(map[string]string)
vclPath := filepath.Join(tmpdir, "backends.vcl")
tmplMap[filepath.Join(testdir, "testdata", "backends.tmpl")] = vclPath
tmpl2file, err := InitTemplates(tmplMap);
if err != nil {
t.Fatalf("Reading %s: %v", gold, err)
t.Fatal("InitTemplates():", err)
}
if !ok {
t.Errorf("Generated VCL does not match gold file: %s", gold)
if testing.Verbose() {
t.Logf("Generated: %s", buf.String())
}
for t := range tmpl2file {
tmpl = t
}
if err = testSpec.WriteTemplate(tmpl, vclPath); err != nil {
t.Fatal("WriteTemplate():", err)
}
if !cmpGold(t, vclPath, gold) {
t.Errorf("Generated VCL at %s does not match gold file %s",
vclPath, filepath.Join("testdata", gold))
}
}
func TestFQVersion(t *testing.T) {
fqVersion := testSpec.FQVersion()
if !strings.HasPrefix(fqVersion, testSpec.Version + "-") {
if !strings.HasPrefix(fqVersion, testSpec.Version+"-") {
t.Fatal("FQVersion(): does not begin with spec.Version + "+
"\"-\":", fqVersion)
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment