terraform/internal/plugin/grpc_provisioner_test.go

148 lines
3.4 KiB
Go

package plugin
import (
"io"
"testing"
"github.com/golang/mock/gomock"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/hashicorp/terraform/internal/configs/hcl2shim"
"github.com/hashicorp/terraform/internal/provisioners"
proto "github.com/hashicorp/terraform/internal/tfplugin5"
"github.com/zclconf/go-cty/cty"
mockproto "github.com/hashicorp/terraform/internal/plugin/mock_proto"
)
var _ provisioners.Interface = (*GRPCProvisioner)(nil)
var (
equateEmpty = cmpopts.EquateEmpty()
typeComparer = cmp.Comparer(cty.Type.Equals)
valueComparer = cmp.Comparer(cty.Value.RawEquals)
)
func mockProvisionerClient(t *testing.T) *mockproto.MockProvisionerClient {
ctrl := gomock.NewController(t)
client := mockproto.NewMockProvisionerClient(ctrl)
// we always need a GetSchema method
client.EXPECT().GetSchema(
gomock.Any(),
gomock.Any(),
).Return(provisionerProtoSchema(), nil)
return client
}
func provisionerProtoSchema() *proto.GetProvisionerSchema_Response {
return &proto.GetProvisionerSchema_Response{
Provisioner: &proto.Schema{
Block: &proto.Schema_Block{
Attributes: []*proto.Schema_Attribute{
{
Name: "attr",
Type: []byte(`"string"`),
Required: true,
},
},
},
},
}
}
func TestGRPCProvisioner_GetSchema(t *testing.T) {
p := &GRPCProvisioner{
client: mockProvisionerClient(t),
}
resp := p.GetSchema()
checkDiags(t, resp.Diagnostics)
}
func TestGRPCProvisioner_ValidateProvisionerConfig(t *testing.T) {
client := mockProvisionerClient(t)
p := &GRPCProvisioner{
client: client,
}
client.EXPECT().ValidateProvisionerConfig(
gomock.Any(),
gomock.Any(),
).Return(&proto.ValidateProvisionerConfig_Response{}, nil)
cfg := hcl2shim.HCL2ValueFromConfigValue(map[string]interface{}{"attr": "value"})
resp := p.ValidateProvisionerConfig(provisioners.ValidateProvisionerConfigRequest{Config: cfg})
checkDiags(t, resp.Diagnostics)
}
func TestGRPCProvisioner_ProvisionResource(t *testing.T) {
ctrl := gomock.NewController(t)
client := mockproto.NewMockProvisionerClient(ctrl)
// we always need a GetSchema method
client.EXPECT().GetSchema(
gomock.Any(),
gomock.Any(),
).Return(provisionerProtoSchema(), nil)
stream := mockproto.NewMockProvisioner_ProvisionResourceClient(ctrl)
stream.EXPECT().Recv().Return(&proto.ProvisionResource_Response{
Output: "provisioned",
}, io.EOF)
client.EXPECT().ProvisionResource(
gomock.Any(),
gomock.Any(),
).Return(stream, nil)
p := &GRPCProvisioner{
client: client,
}
rec := &provisionRecorder{}
resp := p.ProvisionResource(provisioners.ProvisionResourceRequest{
Config: cty.ObjectVal(map[string]cty.Value{
"attr": cty.StringVal("value"),
}),
Connection: cty.EmptyObjectVal,
UIOutput: rec,
})
if resp.Diagnostics.HasErrors() {
t.Fatal(resp.Diagnostics.Err())
}
if len(rec.output) == 0 || rec.output[0] != "provisioned" {
t.Fatalf("expected %q, got %q", []string{"provisioned"}, rec.output)
}
}
type provisionRecorder struct {
output []string
}
func (r *provisionRecorder) Output(s string) {
r.output = append(r.output, s)
}
func TestGRPCProvisioner_Stop(t *testing.T) {
ctrl := gomock.NewController(t)
client := mockproto.NewMockProvisionerClient(ctrl)
p := &GRPCProvisioner{
client: client,
}
client.EXPECT().Stop(
gomock.Any(),
gomock.Any(),
).Return(&proto.Stop_Response{}, nil)
err := p.Stop()
if err != nil {
t.Fatal(err)
}
}