437 lines
10 KiB
Go
437 lines
10 KiB
Go
package template_test
|
|
|
|
import (
|
|
"context"
|
|
"io"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"net/url"
|
|
"os"
|
|
"path/filepath"
|
|
"sort"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/influxdata/influx-cli/v2/api"
|
|
"github.com/influxdata/influx-cli/v2/pkg/template"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestSourcesFromPath(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
type contents struct {
|
|
name string
|
|
encoding template.Encoding
|
|
contents string
|
|
}
|
|
testCases := []struct {
|
|
name string
|
|
setup func(t *testing.T, rootDir string)
|
|
inPath func(rootDir string) string
|
|
inEncoding template.Encoding
|
|
recursive bool
|
|
expected func(rootDir string) []contents
|
|
}{
|
|
{
|
|
name: "JSON file",
|
|
setup: func(t *testing.T, rootDir string) {
|
|
require.NoError(t, os.WriteFile(filepath.Join(rootDir, "foo.json"), []byte("foo"), os.ModePerm))
|
|
},
|
|
inPath: func(rootDir string) string {
|
|
return filepath.Join(rootDir, "foo.json")
|
|
},
|
|
expected: func(string) []contents {
|
|
return []contents{{
|
|
name: "foo.json",
|
|
encoding: template.EncodingJson,
|
|
contents: "foo",
|
|
}}
|
|
},
|
|
},
|
|
{
|
|
name: "YAML file",
|
|
setup: func(t *testing.T, rootDir string) {
|
|
require.NoError(t, os.WriteFile(filepath.Join(rootDir, "foo.yaml"), []byte("foo"), os.ModePerm))
|
|
},
|
|
inPath: func(rootDir string) string {
|
|
return filepath.Join(rootDir, "foo.yaml")
|
|
},
|
|
expected: func(string) []contents {
|
|
return []contents{{
|
|
name: "foo.yaml",
|
|
encoding: template.EncodingYaml,
|
|
contents: "foo",
|
|
}}
|
|
},
|
|
},
|
|
{
|
|
name: "YML file",
|
|
setup: func(t *testing.T, rootDir string) {
|
|
require.NoError(t, os.WriteFile(filepath.Join(rootDir, "foo.yml"), []byte("foo"), os.ModePerm))
|
|
},
|
|
inPath: func(rootDir string) string {
|
|
return filepath.Join(rootDir, "foo.yml")
|
|
},
|
|
expected: func(string) []contents {
|
|
return []contents{{
|
|
name: "foo.yml",
|
|
encoding: template.EncodingYaml,
|
|
contents: "foo",
|
|
}}
|
|
},
|
|
},
|
|
{
|
|
name: "JSONNET file",
|
|
setup: func(t *testing.T, rootDir string) {
|
|
require.NoError(t, os.WriteFile(filepath.Join(rootDir, "foo.jsonnet"), []byte("foo"), os.ModePerm))
|
|
},
|
|
inPath: func(rootDir string) string {
|
|
return filepath.Join(rootDir, "foo.jsonnet")
|
|
},
|
|
expected: func(string) []contents {
|
|
return []contents{{
|
|
name: "foo.jsonnet",
|
|
encoding: template.EncodingJsonnet,
|
|
contents: "foo",
|
|
}}
|
|
},
|
|
},
|
|
{
|
|
name: "explicit inEncoding",
|
|
setup: func(t *testing.T, rootDir string) {
|
|
require.NoError(t, os.WriteFile(filepath.Join(rootDir, "foo"), []byte("foo"), os.ModePerm))
|
|
},
|
|
inEncoding: template.EncodingJson,
|
|
inPath: func(rootDir string) string {
|
|
return filepath.Join(rootDir, "foo")
|
|
},
|
|
expected: func(string) []contents {
|
|
return []contents{{
|
|
name: "foo",
|
|
encoding: template.EncodingJson,
|
|
contents: "foo",
|
|
}}
|
|
},
|
|
},
|
|
{
|
|
name: "directory - non-recursive",
|
|
setup: func(t *testing.T, rootDir string) {
|
|
require.NoError(t, os.Mkdir(filepath.Join(rootDir, "bar"), os.ModePerm))
|
|
require.NoError(t, os.WriteFile(filepath.Join(rootDir, "foo.json"), []byte("foo.json"), os.ModePerm))
|
|
require.NoError(t, os.WriteFile(filepath.Join(rootDir, "foo.yml"), []byte("foo.yml"), os.ModePerm))
|
|
require.NoError(t, os.WriteFile(filepath.Join(rootDir, "bar", "foo.jsonnet"), []byte("foo.jsonnet"), os.ModePerm))
|
|
require.NoError(t, os.WriteFile(filepath.Join(rootDir, "bar", "foo.yaml"), []byte("foo.yaml"), os.ModePerm))
|
|
},
|
|
inPath: func(rootDir string) string {
|
|
return rootDir
|
|
},
|
|
expected: func(rootDir string) []contents {
|
|
return []contents{
|
|
{
|
|
name: filepath.Join(rootDir, "foo.json"),
|
|
contents: "foo.json",
|
|
encoding: template.EncodingJson,
|
|
},
|
|
{
|
|
name: filepath.Join(rootDir, "foo.yml"),
|
|
contents: "foo.yml",
|
|
encoding: template.EncodingYaml,
|
|
},
|
|
}
|
|
},
|
|
},
|
|
{
|
|
name: "directory - recursive",
|
|
setup: func(t *testing.T, rootDir string) {
|
|
require.NoError(t, os.Mkdir(filepath.Join(rootDir, "bar"), os.ModePerm))
|
|
require.NoError(t, os.WriteFile(filepath.Join(rootDir, "foo.json"), []byte("foo.json"), os.ModePerm))
|
|
require.NoError(t, os.WriteFile(filepath.Join(rootDir, "foo.yml"), []byte("foo.yml"), os.ModePerm))
|
|
require.NoError(t, os.WriteFile(filepath.Join(rootDir, "bar", "foo.jsonnet"), []byte("foo.jsonnet"), os.ModePerm))
|
|
require.NoError(t, os.WriteFile(filepath.Join(rootDir, "bar", "foo.yaml"), []byte("foo.yaml"), os.ModePerm))
|
|
},
|
|
inPath: func(rootDir string) string {
|
|
return rootDir
|
|
},
|
|
recursive: true,
|
|
expected: func(rootDir string) []contents {
|
|
return []contents{
|
|
{
|
|
name: filepath.Join(rootDir, "foo.json"),
|
|
contents: "foo.json",
|
|
encoding: template.EncodingJson,
|
|
},
|
|
{
|
|
name: filepath.Join(rootDir, "foo.yml"),
|
|
contents: "foo.yml",
|
|
encoding: template.EncodingYaml,
|
|
},
|
|
{
|
|
name: filepath.Join(rootDir, "bar", "foo.yaml"),
|
|
contents: "foo.yaml",
|
|
encoding: template.EncodingYaml,
|
|
},
|
|
{
|
|
name: filepath.Join(rootDir, "bar", "foo.jsonnet"),
|
|
contents: "foo.jsonnet",
|
|
encoding: template.EncodingJsonnet,
|
|
},
|
|
}
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
tc := tc
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tmp, err := os.MkdirTemp("", "")
|
|
require.NoError(t, err)
|
|
defer os.RemoveAll(tmp)
|
|
tc.setup(t, tmp)
|
|
|
|
sources, err := template.SourcesFromPath(tc.inPath(tmp), tc.recursive, tc.inEncoding)
|
|
require.NoError(t, err)
|
|
expected := tc.expected(tmp)
|
|
require.Len(t, sources, len(expected))
|
|
|
|
sort.Slice(sources, func(i, j int) bool {
|
|
return sources[i].Name < sources[j].Name
|
|
})
|
|
sort.Slice(expected, func(i, j int) bool {
|
|
return expected[i].name < expected[j].name
|
|
})
|
|
|
|
for i := range expected {
|
|
source := sources[i]
|
|
contents := expected[i]
|
|
|
|
require.Equal(t, contents.encoding, source.Encoding)
|
|
sourceIn, err := source.Open(context.Background())
|
|
require.NoError(t, err)
|
|
bytes, err := io.ReadAll(sourceIn)
|
|
sourceIn.Close()
|
|
require.NoError(t, err)
|
|
require.Equal(t, contents.contents, string(bytes))
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSourceFromURL(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
testCases := []struct {
|
|
name string
|
|
filename string
|
|
inEncoding template.Encoding
|
|
expectEncoding template.Encoding
|
|
resStatus int
|
|
resBody string
|
|
expectErr bool
|
|
}{
|
|
{
|
|
name: "JSON file",
|
|
filename: "foo.json",
|
|
expectEncoding: template.EncodingJson,
|
|
resStatus: 200,
|
|
resBody: "Foo bar",
|
|
},
|
|
{
|
|
name: "YAML file",
|
|
filename: "foo.yaml",
|
|
expectEncoding: template.EncodingYaml,
|
|
resStatus: 200,
|
|
resBody: "Foo bar",
|
|
},
|
|
{
|
|
name: "YML file",
|
|
filename: "foo.yml",
|
|
expectEncoding: template.EncodingYaml,
|
|
resStatus: 200,
|
|
resBody: "Foo bar",
|
|
},
|
|
{
|
|
name: "JSONNET file",
|
|
filename: "foo.jsonnet",
|
|
expectEncoding: template.EncodingJsonnet,
|
|
resStatus: 200,
|
|
resBody: "Foo bar",
|
|
},
|
|
{
|
|
name: "explicit encoding",
|
|
filename: "foo",
|
|
inEncoding: template.EncodingJson,
|
|
expectEncoding: template.EncodingJson,
|
|
resStatus: 200,
|
|
resBody: "Foo bar",
|
|
},
|
|
{
|
|
name: "err response",
|
|
filename: "foo.json",
|
|
expectEncoding: template.EncodingJson,
|
|
resStatus: 403,
|
|
resBody: "OH NO",
|
|
expectErr: true,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
tc := tc
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
|
rw.WriteHeader(tc.resStatus)
|
|
rw.Write([]byte(tc.resBody))
|
|
}))
|
|
defer server.Close()
|
|
|
|
u, err := url.Parse(server.URL)
|
|
require.NoError(t, err)
|
|
u.Path = tc.filename
|
|
|
|
source := template.SourceFromURL(u, tc.inEncoding)
|
|
in, err := source.Open(context.Background())
|
|
if tc.expectErr {
|
|
require.Error(t, err)
|
|
require.Contains(t, err.Error(), "bad response")
|
|
require.Contains(t, err.Error(), tc.resBody)
|
|
return
|
|
}
|
|
require.NoError(t, err)
|
|
defer in.Close()
|
|
bytes, err := io.ReadAll(in)
|
|
require.NoError(t, err)
|
|
require.Equal(t, tc.resBody, string(bytes))
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestTemplateSource_Read(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
yamlTemplate := `---
|
|
apiVersion: influxdata.com/v2alpha1
|
|
kind: Bucket
|
|
meta: null
|
|
spec:
|
|
name: test
|
|
retentionRules:
|
|
- type: expire
|
|
---
|
|
apiVersion: influxdata.com/v2alpha1
|
|
kind: Bucket
|
|
meta: null
|
|
spec:
|
|
name: test2
|
|
retentionRules:
|
|
- type: expire
|
|
`
|
|
jsonTemplate := `[
|
|
{
|
|
"apiVersion": "influxdata.com/v2alpha1",
|
|
"kind": "Bucket",
|
|
"spec": {
|
|
"name": "test",
|
|
"retentionRules": [
|
|
{
|
|
"type": "expire"
|
|
}
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"apiVersion": "influxdata.com/v2alpha1",
|
|
"kind": "Bucket",
|
|
"spec": {
|
|
"name": "test2",
|
|
"retentionRules": [
|
|
{
|
|
"type": "expire"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
]
|
|
`
|
|
jsonnetTemplate := `local Bucket(name) = {
|
|
apiVersion: "influxdata.com/v2alpha1",
|
|
kind: "Bucket",
|
|
spec: {
|
|
name: name,
|
|
retentionRules: [{
|
|
type: "expire",
|
|
}],
|
|
},
|
|
};
|
|
[Bucket("test"), Bucket("test2")]
|
|
`
|
|
|
|
parsed := []api.TemplateEntry{
|
|
{
|
|
ApiVersion: "influxdata.com/v2alpha1",
|
|
Kind: "Bucket",
|
|
Spec: map[string]interface{}{
|
|
"name": "test",
|
|
"retentionRules": []interface{}{
|
|
map[string]interface{}{
|
|
"type": "expire",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
ApiVersion: "influxdata.com/v2alpha1",
|
|
Kind: "Bucket",
|
|
Spec: map[string]interface{}{
|
|
"name": "test2",
|
|
"retentionRules": []interface{}{
|
|
map[string]interface{}{
|
|
"type": "expire",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
testCases := []struct {
|
|
name string
|
|
encoding template.Encoding
|
|
data string
|
|
}{
|
|
{
|
|
name: "JSON",
|
|
encoding: template.EncodingJson,
|
|
data: jsonTemplate,
|
|
},
|
|
{
|
|
name: "YAML",
|
|
encoding: template.EncodingYaml,
|
|
data: yamlTemplate,
|
|
},
|
|
{
|
|
name: "JSONNET",
|
|
encoding: template.EncodingJsonnet,
|
|
data: jsonnetTemplate,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
tc := tc
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
source := template.SourceFromReader(strings.NewReader(tc.data), tc.encoding)
|
|
tmpl, err := source.Read(context.Background())
|
|
require.NoError(t, err)
|
|
expected := api.TemplateApplyTemplate{
|
|
Sources: []string{source.Name + ".generated.json"},
|
|
Contents: parsed,
|
|
}
|
|
require.Equal(t, expected, tmpl)
|
|
})
|
|
}
|
|
}
|