terraform/internal/plugin/grpc_provisioner_test.go
Sarah French 2e5b5dee5d
Some checks failed
build / Determine intended Terraform version (push) Has been cancelled
build / Determine Go toolchain version (push) Has been cancelled
Quick Checks / Unit Tests (push) Has been cancelled
Quick Checks / Race Tests (push) Has been cancelled
Quick Checks / End-to-end Tests (push) Has been cancelled
Quick Checks / Code Consistency Checks (push) Has been cancelled
build / Generate release metadata (push) Has been cancelled
build / Build for freebsd_386 (push) Has been cancelled
build / Build for linux_386 (push) Has been cancelled
build / Build for openbsd_386 (push) Has been cancelled
build / Build for windows_386 (push) Has been cancelled
build / Build for darwin_amd64 (push) Has been cancelled
build / Build for freebsd_amd64 (push) Has been cancelled
build / Build for linux_amd64 (push) Has been cancelled
build / Build for openbsd_amd64 (push) Has been cancelled
build / Build for solaris_amd64 (push) Has been cancelled
build / Build for windows_amd64 (push) Has been cancelled
build / Build for freebsd_arm (push) Has been cancelled
build / Build for linux_arm (push) Has been cancelled
build / Build for darwin_arm64 (push) Has been cancelled
build / Build for linux_arm64 (push) Has been cancelled
build / Build for windows_arm64 (push) Has been cancelled
build / Build Docker image for linux_386 (push) Has been cancelled
build / Build Docker image for linux_amd64 (push) Has been cancelled
build / Build Docker image for linux_arm (push) Has been cancelled
build / Build Docker image for linux_arm64 (push) Has been cancelled
build / Build e2etest for linux_386 (push) Has been cancelled
build / Build e2etest for windows_386 (push) Has been cancelled
build / Build e2etest for darwin_amd64 (push) Has been cancelled
build / Build e2etest for linux_amd64 (push) Has been cancelled
build / Build e2etest for windows_amd64 (push) Has been cancelled
build / Build e2etest for linux_arm (push) Has been cancelled
build / Build e2etest for darwin_arm64 (push) Has been cancelled
build / Build e2etest for linux_arm64 (push) Has been cancelled
build / Run e2e test for linux_386 (push) Has been cancelled
build / Run e2e test for windows_386 (push) Has been cancelled
build / Run e2e test for darwin_amd64 (push) Has been cancelled
build / Run e2e test for linux_amd64 (push) Has been cancelled
build / Run e2e test for windows_amd64 (push) Has been cancelled
build / Run e2e test for linux_arm (push) Has been cancelled
build / Run e2e test for linux_arm64 (push) Has been cancelled
build / Run terraform-exec test for linux amd64 (push) Has been cancelled
Upgrade protoc and protoc-gen-go-grpc versions to matching terraform-plugin-go (#37647)
* Update protoc version in downloader script

* go get google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1

This matched terraform-plugin-go

* make protobuf

* Run `make protobuf`

* Update generator to handle generic types from google.golang.org/grpc

Looks like this was added in v1.69.3 in https://github.com/grpc/grpc-go/pull/7057 ?

* Run `make generate`

* Fix "cannot infer Res" compile error - more usage of generics

* More fixing compile errors due to switching to use of a generic

* Make putting `google.golang.org/grpc` import into generated files conditional

* Run `make generate`

* Update more places where generics now need to be used

* Update generator to handle any types from google.golang.org/grpc in same switch case.
2025-10-22 14:46:18 +01:00

150 lines
3.5 KiB
Go

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package plugin
import (
"io"
"testing"
"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"
"go.uber.org/mock/gomock"
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[provisioners.ProvisionResourceResponse](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)
}
}