2018-08-08 22:57:31 +02:00
|
|
|
package plugin
|
|
|
|
|
|
|
|
import (
|
|
|
|
"io"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/golang/mock/gomock"
|
2018-08-15 18:03:39 +02:00
|
|
|
"github.com/google/go-cmp/cmp"
|
|
|
|
"github.com/google/go-cmp/cmp/cmpopts"
|
2021-05-17 21:17:09 +02:00
|
|
|
"github.com/hashicorp/terraform/internal/configs/hcl2shim"
|
2021-05-17 19:51:48 +02:00
|
|
|
"github.com/hashicorp/terraform/internal/provisioners"
|
2018-11-19 18:39:16 +01:00
|
|
|
proto "github.com/hashicorp/terraform/internal/tfplugin5"
|
2018-08-08 22:57:31 +02:00
|
|
|
"github.com/zclconf/go-cty/cty"
|
|
|
|
|
2021-05-17 21:35:22 +02:00
|
|
|
mockproto "github.com/hashicorp/terraform/internal/plugin/mock_proto"
|
2018-08-08 22:57:31 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
var _ provisioners.Interface = (*GRPCProvisioner)(nil)
|
|
|
|
|
2018-08-15 18:03:39 +02:00
|
|
|
var (
|
|
|
|
equateEmpty = cmpopts.EquateEmpty()
|
|
|
|
typeComparer = cmp.Comparer(cty.Type.Equals)
|
|
|
|
valueComparer = cmp.Comparer(cty.Value.RawEquals)
|
|
|
|
)
|
|
|
|
|
2018-08-08 22:57:31 +02:00
|
|
|
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) {
|
2021-10-29 03:16:26 +02:00
|
|
|
ctrl := gomock.NewController(t)
|
|
|
|
client := mockproto.NewMockProvisionerClient(ctrl)
|
2018-08-08 22:57:31 +02:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|