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