github.com/pulumi/terraform@v1.4.0/pkg/plugin6/grpc_provider_test.go (about)

     1  package plugin6
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"testing"
     7  
     8  	"github.com/golang/mock/gomock"
     9  	"github.com/google/go-cmp/cmp"
    10  	"github.com/google/go-cmp/cmp/cmpopts"
    11  	"github.com/pulumi/terraform/pkg/configs/hcl2shim"
    12  	"github.com/pulumi/terraform/pkg/providers"
    13  	"github.com/pulumi/terraform/pkg/tfdiags"
    14  	"github.com/zclconf/go-cty/cty"
    15  
    16  	mockproto "github.com/pulumi/terraform/pkg/plugin6/mock_proto"
    17  	proto "github.com/pulumi/terraform/pkg/tfplugin6"
    18  )
    19  
    20  var _ providers.Interface = (*GRPCProvider)(nil)
    21  
    22  var (
    23  	equateEmpty   = cmpopts.EquateEmpty()
    24  	typeComparer  = cmp.Comparer(cty.Type.Equals)
    25  	valueComparer = cmp.Comparer(cty.Value.RawEquals)
    26  )
    27  
    28  func mockProviderClient(t *testing.T) *mockproto.MockProviderClient {
    29  	ctrl := gomock.NewController(t)
    30  	client := mockproto.NewMockProviderClient(ctrl)
    31  
    32  	// we always need a GetSchema method
    33  	client.EXPECT().GetProviderSchema(
    34  		gomock.Any(),
    35  		gomock.Any(),
    36  		gomock.Any(),
    37  	).Return(providerProtoSchema(), nil)
    38  
    39  	return client
    40  }
    41  
    42  func checkDiags(t *testing.T, d tfdiags.Diagnostics) {
    43  	t.Helper()
    44  	if d.HasErrors() {
    45  		t.Fatal(d.Err())
    46  	}
    47  }
    48  
    49  // checkDiagsHasError ensures error diagnostics are present or fails the test.
    50  func checkDiagsHasError(t *testing.T, d tfdiags.Diagnostics) {
    51  	t.Helper()
    52  
    53  	if !d.HasErrors() {
    54  		t.Fatal("expected error diagnostics")
    55  	}
    56  }
    57  
    58  func providerProtoSchema() *proto.GetProviderSchema_Response {
    59  	return &proto.GetProviderSchema_Response{
    60  		Provider: &proto.Schema{
    61  			Block: &proto.Schema_Block{
    62  				Attributes: []*proto.Schema_Attribute{
    63  					{
    64  						Name:     "attr",
    65  						Type:     []byte(`"string"`),
    66  						Required: true,
    67  					},
    68  				},
    69  			},
    70  		},
    71  		ResourceSchemas: map[string]*proto.Schema{
    72  			"resource": {
    73  				Version: 1,
    74  				Block: &proto.Schema_Block{
    75  					Attributes: []*proto.Schema_Attribute{
    76  						{
    77  							Name:     "attr",
    78  							Type:     []byte(`"string"`),
    79  							Required: true,
    80  						},
    81  					},
    82  				},
    83  			},
    84  		},
    85  		DataSourceSchemas: map[string]*proto.Schema{
    86  			"data": {
    87  				Version: 1,
    88  				Block: &proto.Schema_Block{
    89  					Attributes: []*proto.Schema_Attribute{
    90  						{
    91  							Name:     "attr",
    92  							Type:     []byte(`"string"`),
    93  							Required: true,
    94  						},
    95  					},
    96  				},
    97  			},
    98  		},
    99  	}
   100  }
   101  
   102  func TestGRPCProvider_GetSchema(t *testing.T) {
   103  	p := &GRPCProvider{
   104  		client: mockProviderClient(t),
   105  	}
   106  
   107  	resp := p.GetProviderSchema()
   108  	checkDiags(t, resp.Diagnostics)
   109  }
   110  
   111  // Ensure that gRPC errors are returned early.
   112  // Reference: https://github.com/pulumi/terraform/issues/31047
   113  func TestGRPCProvider_GetSchema_GRPCError(t *testing.T) {
   114  	ctrl := gomock.NewController(t)
   115  	client := mockproto.NewMockProviderClient(ctrl)
   116  
   117  	client.EXPECT().GetProviderSchema(
   118  		gomock.Any(),
   119  		gomock.Any(),
   120  		gomock.Any(),
   121  	).Return(&proto.GetProviderSchema_Response{}, fmt.Errorf("test error"))
   122  
   123  	p := &GRPCProvider{
   124  		client: client,
   125  	}
   126  
   127  	resp := p.GetProviderSchema()
   128  
   129  	checkDiagsHasError(t, resp.Diagnostics)
   130  }
   131  
   132  // Ensure that provider error diagnostics are returned early.
   133  // Reference: https://github.com/pulumi/terraform/issues/31047
   134  func TestGRPCProvider_GetSchema_ResponseErrorDiagnostic(t *testing.T) {
   135  	ctrl := gomock.NewController(t)
   136  	client := mockproto.NewMockProviderClient(ctrl)
   137  
   138  	client.EXPECT().GetProviderSchema(
   139  		gomock.Any(),
   140  		gomock.Any(),
   141  		gomock.Any(),
   142  	).Return(&proto.GetProviderSchema_Response{
   143  		Diagnostics: []*proto.Diagnostic{
   144  			{
   145  				Severity: proto.Diagnostic_ERROR,
   146  				Summary:  "error summary",
   147  				Detail:   "error detail",
   148  			},
   149  		},
   150  		// Trigger potential panics
   151  		Provider: &proto.Schema{},
   152  	}, nil)
   153  
   154  	p := &GRPCProvider{
   155  		client: client,
   156  	}
   157  
   158  	resp := p.GetProviderSchema()
   159  
   160  	checkDiagsHasError(t, resp.Diagnostics)
   161  }
   162  
   163  func TestGRPCProvider_PrepareProviderConfig(t *testing.T) {
   164  	client := mockProviderClient(t)
   165  	p := &GRPCProvider{
   166  		client: client,
   167  	}
   168  
   169  	client.EXPECT().ValidateProviderConfig(
   170  		gomock.Any(),
   171  		gomock.Any(),
   172  	).Return(&proto.ValidateProviderConfig_Response{}, nil)
   173  
   174  	cfg := hcl2shim.HCL2ValueFromConfigValue(map[string]interface{}{"attr": "value"})
   175  	resp := p.ValidateProviderConfig(providers.ValidateProviderConfigRequest{Config: cfg})
   176  	checkDiags(t, resp.Diagnostics)
   177  }
   178  
   179  func TestGRPCProvider_ValidateResourceConfig(t *testing.T) {
   180  	client := mockProviderClient(t)
   181  	p := &GRPCProvider{
   182  		client: client,
   183  	}
   184  
   185  	client.EXPECT().ValidateResourceConfig(
   186  		gomock.Any(),
   187  		gomock.Any(),
   188  	).Return(&proto.ValidateResourceConfig_Response{}, nil)
   189  
   190  	cfg := hcl2shim.HCL2ValueFromConfigValue(map[string]interface{}{"attr": "value"})
   191  	resp := p.ValidateResourceConfig(providers.ValidateResourceConfigRequest{
   192  		TypeName: "resource",
   193  		Config:   cfg,
   194  	})
   195  	checkDiags(t, resp.Diagnostics)
   196  }
   197  
   198  func TestGRPCProvider_ValidateDataResourceConfig(t *testing.T) {
   199  	client := mockProviderClient(t)
   200  	p := &GRPCProvider{
   201  		client: client,
   202  	}
   203  
   204  	client.EXPECT().ValidateDataResourceConfig(
   205  		gomock.Any(),
   206  		gomock.Any(),
   207  	).Return(&proto.ValidateDataResourceConfig_Response{}, nil)
   208  
   209  	cfg := hcl2shim.HCL2ValueFromConfigValue(map[string]interface{}{"attr": "value"})
   210  	resp := p.ValidateDataResourceConfig(providers.ValidateDataResourceConfigRequest{
   211  		TypeName: "data",
   212  		Config:   cfg,
   213  	})
   214  	checkDiags(t, resp.Diagnostics)
   215  }
   216  
   217  func TestGRPCProvider_UpgradeResourceState(t *testing.T) {
   218  	client := mockProviderClient(t)
   219  	p := &GRPCProvider{
   220  		client: client,
   221  	}
   222  
   223  	client.EXPECT().UpgradeResourceState(
   224  		gomock.Any(),
   225  		gomock.Any(),
   226  	).Return(&proto.UpgradeResourceState_Response{
   227  		UpgradedState: &proto.DynamicValue{
   228  			Msgpack: []byte("\x81\xa4attr\xa3bar"),
   229  		},
   230  	}, nil)
   231  
   232  	resp := p.UpgradeResourceState(providers.UpgradeResourceStateRequest{
   233  		TypeName:     "resource",
   234  		Version:      0,
   235  		RawStateJSON: []byte(`{"old_attr":"bar"}`),
   236  	})
   237  	checkDiags(t, resp.Diagnostics)
   238  
   239  	expected := cty.ObjectVal(map[string]cty.Value{
   240  		"attr": cty.StringVal("bar"),
   241  	})
   242  
   243  	if !cmp.Equal(expected, resp.UpgradedState, typeComparer, valueComparer, equateEmpty) {
   244  		t.Fatal(cmp.Diff(expected, resp.UpgradedState, typeComparer, valueComparer, equateEmpty))
   245  	}
   246  }
   247  
   248  func TestGRPCProvider_UpgradeResourceStateJSON(t *testing.T) {
   249  	client := mockProviderClient(t)
   250  	p := &GRPCProvider{
   251  		client: client,
   252  	}
   253  
   254  	client.EXPECT().UpgradeResourceState(
   255  		gomock.Any(),
   256  		gomock.Any(),
   257  	).Return(&proto.UpgradeResourceState_Response{
   258  		UpgradedState: &proto.DynamicValue{
   259  			Json: []byte(`{"attr":"bar"}`),
   260  		},
   261  	}, nil)
   262  
   263  	resp := p.UpgradeResourceState(providers.UpgradeResourceStateRequest{
   264  		TypeName:     "resource",
   265  		Version:      0,
   266  		RawStateJSON: []byte(`{"old_attr":"bar"}`),
   267  	})
   268  	checkDiags(t, resp.Diagnostics)
   269  
   270  	expected := cty.ObjectVal(map[string]cty.Value{
   271  		"attr": cty.StringVal("bar"),
   272  	})
   273  
   274  	if !cmp.Equal(expected, resp.UpgradedState, typeComparer, valueComparer, equateEmpty) {
   275  		t.Fatal(cmp.Diff(expected, resp.UpgradedState, typeComparer, valueComparer, equateEmpty))
   276  	}
   277  }
   278  
   279  func TestGRPCProvider_Configure(t *testing.T) {
   280  	client := mockProviderClient(t)
   281  	p := &GRPCProvider{
   282  		client: client,
   283  	}
   284  
   285  	client.EXPECT().ConfigureProvider(
   286  		gomock.Any(),
   287  		gomock.Any(),
   288  	).Return(&proto.ConfigureProvider_Response{}, nil)
   289  
   290  	resp := p.ConfigureProvider(providers.ConfigureProviderRequest{
   291  		Config: cty.ObjectVal(map[string]cty.Value{
   292  			"attr": cty.StringVal("foo"),
   293  		}),
   294  	})
   295  	checkDiags(t, resp.Diagnostics)
   296  }
   297  
   298  func TestGRPCProvider_Stop(t *testing.T) {
   299  	ctrl := gomock.NewController(t)
   300  	client := mockproto.NewMockProviderClient(ctrl)
   301  	p := &GRPCProvider{
   302  		client: client,
   303  	}
   304  
   305  	client.EXPECT().StopProvider(
   306  		gomock.Any(),
   307  		gomock.Any(),
   308  	).Return(&proto.StopProvider_Response{}, nil)
   309  
   310  	err := p.Stop()
   311  	if err != nil {
   312  		t.Fatal(err)
   313  	}
   314  }
   315  
   316  func TestGRPCProvider_ReadResource(t *testing.T) {
   317  	client := mockProviderClient(t)
   318  	p := &GRPCProvider{
   319  		client: client,
   320  	}
   321  
   322  	client.EXPECT().ReadResource(
   323  		gomock.Any(),
   324  		gomock.Any(),
   325  	).Return(&proto.ReadResource_Response{
   326  		NewState: &proto.DynamicValue{
   327  			Msgpack: []byte("\x81\xa4attr\xa3bar"),
   328  		},
   329  	}, nil)
   330  
   331  	resp := p.ReadResource(providers.ReadResourceRequest{
   332  		TypeName: "resource",
   333  		PriorState: cty.ObjectVal(map[string]cty.Value{
   334  			"attr": cty.StringVal("foo"),
   335  		}),
   336  	})
   337  
   338  	checkDiags(t, resp.Diagnostics)
   339  
   340  	expected := cty.ObjectVal(map[string]cty.Value{
   341  		"attr": cty.StringVal("bar"),
   342  	})
   343  
   344  	if !cmp.Equal(expected, resp.NewState, typeComparer, valueComparer, equateEmpty) {
   345  		t.Fatal(cmp.Diff(expected, resp.NewState, typeComparer, valueComparer, equateEmpty))
   346  	}
   347  }
   348  
   349  func TestGRPCProvider_ReadResourceJSON(t *testing.T) {
   350  	client := mockProviderClient(t)
   351  	p := &GRPCProvider{
   352  		client: client,
   353  	}
   354  
   355  	client.EXPECT().ReadResource(
   356  		gomock.Any(),
   357  		gomock.Any(),
   358  	).Return(&proto.ReadResource_Response{
   359  		NewState: &proto.DynamicValue{
   360  			Json: []byte(`{"attr":"bar"}`),
   361  		},
   362  	}, nil)
   363  
   364  	resp := p.ReadResource(providers.ReadResourceRequest{
   365  		TypeName: "resource",
   366  		PriorState: cty.ObjectVal(map[string]cty.Value{
   367  			"attr": cty.StringVal("foo"),
   368  		}),
   369  	})
   370  
   371  	checkDiags(t, resp.Diagnostics)
   372  
   373  	expected := cty.ObjectVal(map[string]cty.Value{
   374  		"attr": cty.StringVal("bar"),
   375  	})
   376  
   377  	if !cmp.Equal(expected, resp.NewState, typeComparer, valueComparer, equateEmpty) {
   378  		t.Fatal(cmp.Diff(expected, resp.NewState, typeComparer, valueComparer, equateEmpty))
   379  	}
   380  }
   381  
   382  func TestGRPCProvider_ReadEmptyJSON(t *testing.T) {
   383  	client := mockProviderClient(t)
   384  	p := &GRPCProvider{
   385  		client: client,
   386  	}
   387  
   388  	client.EXPECT().ReadResource(
   389  		gomock.Any(),
   390  		gomock.Any(),
   391  	).Return(&proto.ReadResource_Response{
   392  		NewState: &proto.DynamicValue{
   393  			Json: []byte(``),
   394  		},
   395  	}, nil)
   396  
   397  	obj := cty.ObjectVal(map[string]cty.Value{
   398  		"attr": cty.StringVal("foo"),
   399  	})
   400  	resp := p.ReadResource(providers.ReadResourceRequest{
   401  		TypeName:   "resource",
   402  		PriorState: obj,
   403  	})
   404  
   405  	checkDiags(t, resp.Diagnostics)
   406  
   407  	expected := cty.NullVal(obj.Type())
   408  
   409  	if !cmp.Equal(expected, resp.NewState, typeComparer, valueComparer, equateEmpty) {
   410  		t.Fatal(cmp.Diff(expected, resp.NewState, typeComparer, valueComparer, equateEmpty))
   411  	}
   412  }
   413  
   414  func TestGRPCProvider_PlanResourceChange(t *testing.T) {
   415  	client := mockProviderClient(t)
   416  	p := &GRPCProvider{
   417  		client: client,
   418  	}
   419  
   420  	expectedPrivate := []byte(`{"meta": "data"}`)
   421  
   422  	client.EXPECT().PlanResourceChange(
   423  		gomock.Any(),
   424  		gomock.Any(),
   425  	).Return(&proto.PlanResourceChange_Response{
   426  		PlannedState: &proto.DynamicValue{
   427  			Msgpack: []byte("\x81\xa4attr\xa3bar"),
   428  		},
   429  		RequiresReplace: []*proto.AttributePath{
   430  			{
   431  				Steps: []*proto.AttributePath_Step{
   432  					{
   433  						Selector: &proto.AttributePath_Step_AttributeName{
   434  							AttributeName: "attr",
   435  						},
   436  					},
   437  				},
   438  			},
   439  		},
   440  		PlannedPrivate: expectedPrivate,
   441  	}, nil)
   442  
   443  	resp := p.PlanResourceChange(providers.PlanResourceChangeRequest{
   444  		TypeName: "resource",
   445  		PriorState: cty.ObjectVal(map[string]cty.Value{
   446  			"attr": cty.StringVal("foo"),
   447  		}),
   448  		ProposedNewState: cty.ObjectVal(map[string]cty.Value{
   449  			"attr": cty.StringVal("bar"),
   450  		}),
   451  		Config: cty.ObjectVal(map[string]cty.Value{
   452  			"attr": cty.StringVal("bar"),
   453  		}),
   454  	})
   455  
   456  	checkDiags(t, resp.Diagnostics)
   457  
   458  	expectedState := cty.ObjectVal(map[string]cty.Value{
   459  		"attr": cty.StringVal("bar"),
   460  	})
   461  
   462  	if !cmp.Equal(expectedState, resp.PlannedState, typeComparer, valueComparer, equateEmpty) {
   463  		t.Fatal(cmp.Diff(expectedState, resp.PlannedState, typeComparer, valueComparer, equateEmpty))
   464  	}
   465  
   466  	expectedReplace := `[]cty.Path{cty.Path{cty.GetAttrStep{Name:"attr"}}}`
   467  	replace := fmt.Sprintf("%#v", resp.RequiresReplace)
   468  	if expectedReplace != replace {
   469  		t.Fatalf("expected %q, got %q", expectedReplace, replace)
   470  	}
   471  
   472  	if !bytes.Equal(expectedPrivate, resp.PlannedPrivate) {
   473  		t.Fatalf("expected %q, got %q", expectedPrivate, resp.PlannedPrivate)
   474  	}
   475  }
   476  
   477  func TestGRPCProvider_PlanResourceChangeJSON(t *testing.T) {
   478  	client := mockProviderClient(t)
   479  	p := &GRPCProvider{
   480  		client: client,
   481  	}
   482  
   483  	expectedPrivate := []byte(`{"meta": "data"}`)
   484  
   485  	client.EXPECT().PlanResourceChange(
   486  		gomock.Any(),
   487  		gomock.Any(),
   488  	).Return(&proto.PlanResourceChange_Response{
   489  		PlannedState: &proto.DynamicValue{
   490  			Json: []byte(`{"attr":"bar"}`),
   491  		},
   492  		RequiresReplace: []*proto.AttributePath{
   493  			{
   494  				Steps: []*proto.AttributePath_Step{
   495  					{
   496  						Selector: &proto.AttributePath_Step_AttributeName{
   497  							AttributeName: "attr",
   498  						},
   499  					},
   500  				},
   501  			},
   502  		},
   503  		PlannedPrivate: expectedPrivate,
   504  	}, nil)
   505  
   506  	resp := p.PlanResourceChange(providers.PlanResourceChangeRequest{
   507  		TypeName: "resource",
   508  		PriorState: cty.ObjectVal(map[string]cty.Value{
   509  			"attr": cty.StringVal("foo"),
   510  		}),
   511  		ProposedNewState: cty.ObjectVal(map[string]cty.Value{
   512  			"attr": cty.StringVal("bar"),
   513  		}),
   514  		Config: cty.ObjectVal(map[string]cty.Value{
   515  			"attr": cty.StringVal("bar"),
   516  		}),
   517  	})
   518  
   519  	checkDiags(t, resp.Diagnostics)
   520  
   521  	expectedState := cty.ObjectVal(map[string]cty.Value{
   522  		"attr": cty.StringVal("bar"),
   523  	})
   524  
   525  	if !cmp.Equal(expectedState, resp.PlannedState, typeComparer, valueComparer, equateEmpty) {
   526  		t.Fatal(cmp.Diff(expectedState, resp.PlannedState, typeComparer, valueComparer, equateEmpty))
   527  	}
   528  
   529  	expectedReplace := `[]cty.Path{cty.Path{cty.GetAttrStep{Name:"attr"}}}`
   530  	replace := fmt.Sprintf("%#v", resp.RequiresReplace)
   531  	if expectedReplace != replace {
   532  		t.Fatalf("expected %q, got %q", expectedReplace, replace)
   533  	}
   534  
   535  	if !bytes.Equal(expectedPrivate, resp.PlannedPrivate) {
   536  		t.Fatalf("expected %q, got %q", expectedPrivate, resp.PlannedPrivate)
   537  	}
   538  }
   539  
   540  func TestGRPCProvider_ApplyResourceChange(t *testing.T) {
   541  	client := mockProviderClient(t)
   542  	p := &GRPCProvider{
   543  		client: client,
   544  	}
   545  
   546  	expectedPrivate := []byte(`{"meta": "data"}`)
   547  
   548  	client.EXPECT().ApplyResourceChange(
   549  		gomock.Any(),
   550  		gomock.Any(),
   551  	).Return(&proto.ApplyResourceChange_Response{
   552  		NewState: &proto.DynamicValue{
   553  			Msgpack: []byte("\x81\xa4attr\xa3bar"),
   554  		},
   555  		Private: expectedPrivate,
   556  	}, nil)
   557  
   558  	resp := p.ApplyResourceChange(providers.ApplyResourceChangeRequest{
   559  		TypeName: "resource",
   560  		PriorState: cty.ObjectVal(map[string]cty.Value{
   561  			"attr": cty.StringVal("foo"),
   562  		}),
   563  		PlannedState: cty.ObjectVal(map[string]cty.Value{
   564  			"attr": cty.StringVal("bar"),
   565  		}),
   566  		Config: cty.ObjectVal(map[string]cty.Value{
   567  			"attr": cty.StringVal("bar"),
   568  		}),
   569  		PlannedPrivate: expectedPrivate,
   570  	})
   571  
   572  	checkDiags(t, resp.Diagnostics)
   573  
   574  	expectedState := cty.ObjectVal(map[string]cty.Value{
   575  		"attr": cty.StringVal("bar"),
   576  	})
   577  
   578  	if !cmp.Equal(expectedState, resp.NewState, typeComparer, valueComparer, equateEmpty) {
   579  		t.Fatal(cmp.Diff(expectedState, resp.NewState, typeComparer, valueComparer, equateEmpty))
   580  	}
   581  
   582  	if !bytes.Equal(expectedPrivate, resp.Private) {
   583  		t.Fatalf("expected %q, got %q", expectedPrivate, resp.Private)
   584  	}
   585  }
   586  func TestGRPCProvider_ApplyResourceChangeJSON(t *testing.T) {
   587  	client := mockProviderClient(t)
   588  	p := &GRPCProvider{
   589  		client: client,
   590  	}
   591  
   592  	expectedPrivate := []byte(`{"meta": "data"}`)
   593  
   594  	client.EXPECT().ApplyResourceChange(
   595  		gomock.Any(),
   596  		gomock.Any(),
   597  	).Return(&proto.ApplyResourceChange_Response{
   598  		NewState: &proto.DynamicValue{
   599  			Json: []byte(`{"attr":"bar"}`),
   600  		},
   601  		Private: expectedPrivate,
   602  	}, nil)
   603  
   604  	resp := p.ApplyResourceChange(providers.ApplyResourceChangeRequest{
   605  		TypeName: "resource",
   606  		PriorState: cty.ObjectVal(map[string]cty.Value{
   607  			"attr": cty.StringVal("foo"),
   608  		}),
   609  		PlannedState: cty.ObjectVal(map[string]cty.Value{
   610  			"attr": cty.StringVal("bar"),
   611  		}),
   612  		Config: cty.ObjectVal(map[string]cty.Value{
   613  			"attr": cty.StringVal("bar"),
   614  		}),
   615  		PlannedPrivate: expectedPrivate,
   616  	})
   617  
   618  	checkDiags(t, resp.Diagnostics)
   619  
   620  	expectedState := cty.ObjectVal(map[string]cty.Value{
   621  		"attr": cty.StringVal("bar"),
   622  	})
   623  
   624  	if !cmp.Equal(expectedState, resp.NewState, typeComparer, valueComparer, equateEmpty) {
   625  		t.Fatal(cmp.Diff(expectedState, resp.NewState, typeComparer, valueComparer, equateEmpty))
   626  	}
   627  
   628  	if !bytes.Equal(expectedPrivate, resp.Private) {
   629  		t.Fatalf("expected %q, got %q", expectedPrivate, resp.Private)
   630  	}
   631  }
   632  
   633  func TestGRPCProvider_ImportResourceState(t *testing.T) {
   634  	client := mockProviderClient(t)
   635  	p := &GRPCProvider{
   636  		client: client,
   637  	}
   638  
   639  	expectedPrivate := []byte(`{"meta": "data"}`)
   640  
   641  	client.EXPECT().ImportResourceState(
   642  		gomock.Any(),
   643  		gomock.Any(),
   644  	).Return(&proto.ImportResourceState_Response{
   645  		ImportedResources: []*proto.ImportResourceState_ImportedResource{
   646  			{
   647  				TypeName: "resource",
   648  				State: &proto.DynamicValue{
   649  					Msgpack: []byte("\x81\xa4attr\xa3bar"),
   650  				},
   651  				Private: expectedPrivate,
   652  			},
   653  		},
   654  	}, nil)
   655  
   656  	resp := p.ImportResourceState(providers.ImportResourceStateRequest{
   657  		TypeName: "resource",
   658  		ID:       "foo",
   659  	})
   660  
   661  	checkDiags(t, resp.Diagnostics)
   662  
   663  	expectedResource := providers.ImportedResource{
   664  		TypeName: "resource",
   665  		State: cty.ObjectVal(map[string]cty.Value{
   666  			"attr": cty.StringVal("bar"),
   667  		}),
   668  		Private: expectedPrivate,
   669  	}
   670  
   671  	imported := resp.ImportedResources[0]
   672  	if !cmp.Equal(expectedResource, imported, typeComparer, valueComparer, equateEmpty) {
   673  		t.Fatal(cmp.Diff(expectedResource, imported, typeComparer, valueComparer, equateEmpty))
   674  	}
   675  }
   676  func TestGRPCProvider_ImportResourceStateJSON(t *testing.T) {
   677  	client := mockProviderClient(t)
   678  	p := &GRPCProvider{
   679  		client: client,
   680  	}
   681  
   682  	expectedPrivate := []byte(`{"meta": "data"}`)
   683  
   684  	client.EXPECT().ImportResourceState(
   685  		gomock.Any(),
   686  		gomock.Any(),
   687  	).Return(&proto.ImportResourceState_Response{
   688  		ImportedResources: []*proto.ImportResourceState_ImportedResource{
   689  			{
   690  				TypeName: "resource",
   691  				State: &proto.DynamicValue{
   692  					Json: []byte(`{"attr":"bar"}`),
   693  				},
   694  				Private: expectedPrivate,
   695  			},
   696  		},
   697  	}, nil)
   698  
   699  	resp := p.ImportResourceState(providers.ImportResourceStateRequest{
   700  		TypeName: "resource",
   701  		ID:       "foo",
   702  	})
   703  
   704  	checkDiags(t, resp.Diagnostics)
   705  
   706  	expectedResource := providers.ImportedResource{
   707  		TypeName: "resource",
   708  		State: cty.ObjectVal(map[string]cty.Value{
   709  			"attr": cty.StringVal("bar"),
   710  		}),
   711  		Private: expectedPrivate,
   712  	}
   713  
   714  	imported := resp.ImportedResources[0]
   715  	if !cmp.Equal(expectedResource, imported, typeComparer, valueComparer, equateEmpty) {
   716  		t.Fatal(cmp.Diff(expectedResource, imported, typeComparer, valueComparer, equateEmpty))
   717  	}
   718  }
   719  
   720  func TestGRPCProvider_ReadDataSource(t *testing.T) {
   721  	client := mockProviderClient(t)
   722  	p := &GRPCProvider{
   723  		client: client,
   724  	}
   725  
   726  	client.EXPECT().ReadDataSource(
   727  		gomock.Any(),
   728  		gomock.Any(),
   729  	).Return(&proto.ReadDataSource_Response{
   730  		State: &proto.DynamicValue{
   731  			Msgpack: []byte("\x81\xa4attr\xa3bar"),
   732  		},
   733  	}, nil)
   734  
   735  	resp := p.ReadDataSource(providers.ReadDataSourceRequest{
   736  		TypeName: "data",
   737  		Config: cty.ObjectVal(map[string]cty.Value{
   738  			"attr": cty.StringVal("foo"),
   739  		}),
   740  	})
   741  
   742  	checkDiags(t, resp.Diagnostics)
   743  
   744  	expected := cty.ObjectVal(map[string]cty.Value{
   745  		"attr": cty.StringVal("bar"),
   746  	})
   747  
   748  	if !cmp.Equal(expected, resp.State, typeComparer, valueComparer, equateEmpty) {
   749  		t.Fatal(cmp.Diff(expected, resp.State, typeComparer, valueComparer, equateEmpty))
   750  	}
   751  }
   752  
   753  func TestGRPCProvider_ReadDataSourceJSON(t *testing.T) {
   754  	client := mockProviderClient(t)
   755  	p := &GRPCProvider{
   756  		client: client,
   757  	}
   758  
   759  	client.EXPECT().ReadDataSource(
   760  		gomock.Any(),
   761  		gomock.Any(),
   762  	).Return(&proto.ReadDataSource_Response{
   763  		State: &proto.DynamicValue{
   764  			Json: []byte(`{"attr":"bar"}`),
   765  		},
   766  	}, nil)
   767  
   768  	resp := p.ReadDataSource(providers.ReadDataSourceRequest{
   769  		TypeName: "data",
   770  		Config: cty.ObjectVal(map[string]cty.Value{
   771  			"attr": cty.StringVal("foo"),
   772  		}),
   773  	})
   774  
   775  	checkDiags(t, resp.Diagnostics)
   776  
   777  	expected := cty.ObjectVal(map[string]cty.Value{
   778  		"attr": cty.StringVal("bar"),
   779  	})
   780  
   781  	if !cmp.Equal(expected, resp.State, typeComparer, valueComparer, equateEmpty) {
   782  		t.Fatal(cmp.Diff(expected, resp.State, typeComparer, valueComparer, equateEmpty))
   783  	}
   784  }