Add additional test to demonstrate strict/relaxed enum semantics

This commit is contained in:
Vivek Lakshmanan 2020-11-03 23:05:53 -08:00
parent 43e48950df
commit 3c2b7a8945
4 changed files with 150 additions and 9 deletions

View file

@ -898,19 +898,19 @@ func (pkg *pkgContext) genResource(w io.Writer, r *schema.Resource) error {
fmt.Fprintf(w, "\t}\n")
for _, p := range r.InputProperties {
if !p.IsRequired {
continue
}
switch p.Type.(type) {
case *schema.EnumType:
// We use a concrete type for strict enums
fmt.Fprintf(w, "\tif err := args.%s.Validate(); err != nil {\n", Title(p.Name))
fmt.Fprintf(w, "\t\treturn nil, errors.Errorf(\"invalid value for required argument '%s': %%w\", err)\n", Title(p.Name))
fmt.Fprintf(w, "\t\treturn nil, fmt.Errorf(\"invalid value for enum '%s': %%w\", err)\n", Title(p.Name))
fmt.Fprintf(w, "\t}\n")
default:
fmt.Fprintf(w, "\tif args.%s == nil {\n", Title(p.Name))
fmt.Fprintf(w, "\t\treturn nil, errors.New(\"invalid value for required argument '%s'\")\n", Title(p.Name))
if p.IsRequired {
fmt.Fprintf(w, "\tif args.%s == nil {\n", Title(p.Name))
fmt.Fprintf(w, "\t\treturn nil, errors.New(\"invalid value for required argument '%s'\")\n", Title(p.Name))
fmt.Fprintf(w, "\t}\n")
}
}
fmt.Fprintf(w, "\t}\n")
}
for _, p := range r.InputProperties {
@ -1602,7 +1602,7 @@ func GeneratePackage(tool string, pkg *schema.Package) (map[string][]byte, error
pkg.getImports(r, imports)
buffer := &bytes.Buffer{}
pkg.genHeader(buffer, []string{"context", "reflect"}, imports)
pkg.genHeader(buffer, []string{"context", "reflect", "fmt"}, imports)
if err := pkg.genResource(buffer, r); err != nil {
return nil, err

View file

@ -4,6 +4,7 @@
package v1
import (
"fmt"
"reflect"
"github.com/pkg/errors"
@ -26,7 +27,7 @@ func NewRubberTree(ctx *pulumi.Context,
return nil, errors.New("missing one or more required arguments")
}
if err := args.Type.Validate(); err != nil {
return nil, errors.Errorf("invalid value for required argument 'Type': %w", err)
return nil, fmt.Errorf("invalid value for enum 'Type': %w", err)
}
var resource RubberTree
err := ctx.RegisterResource("plant-provider:tree/v1:RubberTree", name, args, &resource, opts...)

View file

@ -0,0 +1,139 @@
package v1
import (
"github.com/pulumi/pulumi/pkg/v2/codegen/internal/test/testdata/simple-enum-schema/go/plant"
"github.com/pulumi/pulumi/sdk/v2/go/common/resource"
"github.com/pulumi/pulumi/sdk/v2/go/pulumi"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"sync"
"testing"
)
type mocks int
func (mocks) NewResource(typeToken, name string, inputs resource.PropertyMap, provider, id string) (string, resource.PropertyMap, error) {
return name + "_id", inputs, nil
}
func (mocks) Call(token string, args resource.PropertyMap, provider string) (resource.PropertyMap, error) {
return args, nil
}
func TestRubberTree(t *testing.T) {
t.Run("Success", func(t *testing.T) {
pulumi.RunErr(func(ctx *pulumi.Context) error {
tree, err := NewRubberTree(ctx, "blah", &RubberTreeArgs{
Container: plant.ContainerArgs{
Color: plant.Red,
Material: pulumi.String("ceramic"),
Size: plant.FourInch,
},
Farm: Plants_R_Us,
Type: Ruby,
})
require.NoError(t, err)
require.NotNil(t, tree)
var wg sync.WaitGroup
wg.Add(1)
pulumi.All(tree.URN(), tree.Container.Material(), tree.Container.Color(), tree.Container.Size(), tree.Type).ApplyT(func(all []interface{}) error {
urn := all[0].(pulumi.URN)
material := all[1].(*string)
color := all[2].(*string)
size := all[3].(*int)
typ := all[4].(string)
assert.Equal(t, *material, "ceramic", "unexpected material on resource: %v", urn)
assert.Equal(t, *color, "red", "unexpected color on resource: %v", urn)
assert.Equal(t, *size, 4, "unexpected size on resource: %v", urn)
assert.Equal(t, typ, "Ruby", "unexpected type on resource: %v", urn)
wg.Done()
return nil
})
wg.Wait()
return nil
}, pulumi.WithMocks("project", "stack", mocks(0)))
})
t.Run("StringsForRelaxedEnum", func(t *testing.T) {
pulumi.RunErr(func(ctx *pulumi.Context) error {
tree, err := NewRubberTree(ctx, "blah", &RubberTreeArgs{
Container: plant.ContainerArgs{
Color: pulumi.String("Magenta"),
Material: pulumi.String("ceramic"),
Size: plant.ContainerSize(22),
},
Farm: Plants_R_Us,
Type: Ruby,
})
require.NoError(t, err)
require.NotNil(t, tree)
var wg sync.WaitGroup
wg.Add(1)
pulumi.All(tree.URN(), tree.Container.Material(), tree.Container.Color(), tree.Container.Size(), tree.Type).ApplyT(func(all []interface{}) error {
urn := all[0].(pulumi.URN)
material := all[1].(*string)
color := all[2].(*string)
size := all[3].(*int)
typ := all[4].(string)
assert.Equal(t, *material, "ceramic", "unexpected material on resource: %v", urn)
assert.Equal(t, *color, "Magenta", "unexpected color on resource: %v", urn)
assert.Equal(t, *size, 22, "unexpected size on resource: %v", urn)
assert.Equal(t, typ, "Ruby", "unexpected type on resource: %v", urn)
wg.Done()
return nil
})
wg.Wait()
return nil
}, pulumi.WithMocks("project", "stack", mocks(1)))
})
t.Run("StringsForStrictEnum", func(t *testing.T) {
pulumi.RunErr(func(ctx *pulumi.Context) error {
tree, err := NewRubberTree(ctx, "blah", &RubberTreeArgs{
Container: plant.ContainerArgs{
Color: pulumi.String("Magenta"),
Material: pulumi.String("ceramic"),
Size: plant.ContainerSize(22),
},
Farm: Plants_R_Us,
Type: "Burgundy",
})
require.NoError(t, err)
require.NotNil(t, tree)
var wg sync.WaitGroup
wg.Add(1)
pulumi.All(tree.URN(), tree.Container.Material(), tree.Container.Color(), tree.Container.Size(), tree.Type).ApplyT(func(all []interface{}) error {
urn := all[0].(pulumi.URN)
material := all[1].(*string)
color := all[2].(*string)
size := all[3].(*int)
typ := all[4].(string)
assert.Equal(t, *material, "ceramic", "unexpected material on resource: %v", urn)
assert.Equal(t, *color, "Magenta", "unexpected color on resource: %v", urn)
assert.Equal(t, *size, 22, "unexpected size on resource: %v", urn)
assert.Equal(t, typ, "Burgundy", "unexpected type on resource: %v", urn)
wg.Done()
return nil
})
wg.Wait()
return nil
}, pulumi.WithMocks("project", "stack", mocks(1)))
})
t.Run("ValidateStrictEnum", func(t *testing.T) {
pulumi.RunErr(func(ctx *pulumi.Context) error {
tree, err := NewRubberTree(ctx, "blah", &RubberTreeArgs{
Container: plant.ContainerArgs{
Color: plant.Red,
Material: pulumi.String("ceramic"),
},
Farm: Plants_R_Us,
Type: "Mauve",
})
require.Error(t, err)
require.Contains(t, err.Error(), "invalid value for enum 'Type'")
require.Nil(t, tree)
return nil
}, pulumi.WithMocks("project", "stack", mocks(2)))
})
}

View file

@ -352,6 +352,7 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 h1:MtvEpTB6LX3vkb4ax0b5D2DHbNAUsen0Gx5wZoq3lV4=
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=