github.com/rstandt/terraform@v0.12.32-0.20230710220336-b1063613405c/helper/plugin/grpc_provisioner_test.go (about)

     1  package plugin
     2  
     3  import (
     4  	"testing"
     5  	"unicode/utf8"
     6  
     7  	"github.com/golang/mock/gomock"
     8  	"github.com/hashicorp/terraform/helper/schema"
     9  	proto "github.com/hashicorp/terraform/internal/tfplugin5"
    10  	mockproto "github.com/hashicorp/terraform/plugin/mock_proto"
    11  	"github.com/hashicorp/terraform/terraform"
    12  	context "golang.org/x/net/context"
    13  )
    14  
    15  var _ proto.ProvisionerServer = (*GRPCProvisionerServer)(nil)
    16  
    17  type validUTF8Matcher string
    18  
    19  func (m validUTF8Matcher) Matches(x interface{}) bool {
    20  	resp := x.(*proto.ProvisionResource_Response)
    21  	return utf8.Valid([]byte(resp.Output))
    22  }
    23  
    24  func (m validUTF8Matcher) String() string {
    25  	return string(m)
    26  }
    27  
    28  func mockProvisionerServer(t *testing.T, c *gomock.Controller) *mockproto.MockProvisioner_ProvisionResourceServer {
    29  	server := mockproto.NewMockProvisioner_ProvisionResourceServer(c)
    30  
    31  	server.EXPECT().Send(
    32  		validUTF8Matcher("check for valid utf8"),
    33  	).Return(nil)
    34  
    35  	return server
    36  }
    37  
    38  // ensure that a provsioner cannot return invalid utf8 which isn't allowed in
    39  // the grpc protocol.
    40  func TestProvisionerInvalidUTF8(t *testing.T) {
    41  	p := &schema.Provisioner{
    42  		ConnSchema: map[string]*schema.Schema{
    43  			"foo": {
    44  				Type:     schema.TypeString,
    45  				Optional: true,
    46  			},
    47  		},
    48  
    49  		Schema: map[string]*schema.Schema{
    50  			"foo": {
    51  				Type:     schema.TypeInt,
    52  				Optional: true,
    53  			},
    54  		},
    55  
    56  		ApplyFunc: func(ctx context.Context) error {
    57  			out := ctx.Value(schema.ProvOutputKey).(terraform.UIOutput)
    58  			out.Output("invalid \xc3\x28\n")
    59  			return nil
    60  		},
    61  	}
    62  
    63  	ctrl := gomock.NewController(t)
    64  	defer ctrl.Finish()
    65  
    66  	srv := mockProvisionerServer(t, ctrl)
    67  	cfg := &proto.DynamicValue{
    68  		Msgpack: []byte("\x81\xa3foo\x01"),
    69  	}
    70  	conn := &proto.DynamicValue{
    71  		Msgpack: []byte("\x81\xa3foo\xa4host"),
    72  	}
    73  	provisionerServer := NewGRPCProvisionerServerShim(p)
    74  	req := &proto.ProvisionResource_Request{
    75  		Config:     cfg,
    76  		Connection: conn,
    77  	}
    78  
    79  	if err := provisionerServer.ProvisionResource(req, srv); err != nil {
    80  		t.Fatal(err)
    81  	}
    82  }