packer-cn/packer-plugin-sdk/template/config/decode_test.go

207 lines
4.0 KiB
Go

package config
import (
"reflect"
"strings"
"testing"
"time"
"github.com/hashicorp/packer/packer-plugin-sdk/template/interpolate"
)
func TestDecode(t *testing.T) {
type Target struct {
Name string
Address string
Time time.Duration
Trilean Trilean
}
cases := map[string]struct {
Input []interface{}
Output *Target
Opts *DecodeOpts
}{
"basic": {
[]interface{}{
map[string]interface{}{
"name": "bar",
"time": "5s",
"trilean": "true",
},
},
&Target{
Name: "bar",
Time: 5 * time.Second,
Trilean: TriTrue,
},
nil,
},
"empty-string-trilean": {
[]interface{}{
map[string]interface{}{
"trilean": "",
},
},
&Target{
Trilean: TriUnset,
},
nil,
},
"variables": {
[]interface{}{
map[string]interface{}{
"name": "{{user `name`}}",
},
map[string]interface{}{
"packer_user_variables": map[string]string{
"name": "bar",
},
},
},
&Target{
Name: "bar",
},
nil,
},
"filter": {
[]interface{}{
map[string]interface{}{
"name": "{{user `name`}}",
"address": "{{user `name`}}",
},
map[string]interface{}{
"packer_user_variables": map[string]string{
"name": "bar",
},
},
},
&Target{
Name: "bar",
Address: "{{user `name`}}",
},
&DecodeOpts{
Interpolate: true,
InterpolateFilter: &interpolate.RenderFilter{
Include: []string{"name"},
},
},
},
"build name": {
[]interface{}{
map[string]interface{}{
"name": "{{build_name}}",
},
map[string]interface{}{
"packer_build_name": "foo",
},
},
&Target{
Name: "foo",
},
nil,
},
"build type": {
[]interface{}{
map[string]interface{}{
"name": "{{build_type}}",
},
map[string]interface{}{
"packer_builder_type": "foo",
},
},
&Target{
Name: "foo",
},
nil,
},
}
for k, tc := range cases {
var result Target
err := Decode(&result, tc.Opts, tc.Input...)
if err != nil {
t.Fatalf("err: %s\n\n%s", k, err)
}
if !reflect.DeepEqual(&result, tc.Output) {
t.Fatalf("bad:\n\n%#v\n\n%#v", &result, tc.Output)
}
}
}
func TestDecode_fixerRecommendations(t *testing.T) {
type TestConfig struct {
Name string
}
cases := []struct {
Reason string
Input []interface{}
Opts *DecodeOpts
Expected string
}{
{
Reason: "If no plugin type is provided, don't try to match fixer options",
Input: []interface{}{
map[string]interface{}{
"name": "bar",
"iso_md5": "13123412341234",
},
},
Opts: &DecodeOpts{},
Expected: `unknown configuration key: '"iso_md5"'`,
},
{
Reason: "iso_md5 should always recommend packer fix regardless of plugin type",
Input: []interface{}{
map[string]interface{}{
"name": "bar",
"iso_md5": "13123412341234",
},
},
Opts: &DecodeOpts{PluginType: "someplugin"},
Expected: `Deprecated configuration key: 'iso_md5'`,
},
{
Reason: "filename option should generate a fixer recommendation for the manifest postprocessor",
Input: []interface{}{
map[string]interface{}{
"name": "bar",
"filename": "fakefilename",
},
},
Opts: &DecodeOpts{PluginType: "packer.post-processor.manifest"},
Expected: `Deprecated configuration key: 'filename'`,
},
{
Reason: "filename option should generate an unknown key error for other plugins",
Input: []interface{}{
map[string]interface{}{
"name": "bar",
"filename": "fakefilename",
},
},
Opts: &DecodeOpts{PluginType: "randomplugin"},
Expected: `unknown configuration key: '"filename"'`,
},
}
for _, tc := range cases {
var result TestConfig
err := Decode(&result, tc.Opts, tc.Input...)
if err == nil {
t.Fatalf("Should have had an error: %s", tc.Reason)
}
if !strings.Contains(err.Error(), tc.Expected) {
t.Fatalf("Expected: %s\nActual: %s\n; Reason: %s", tc.Expected, err.Error(), tc.Reason)
}
}
}