github.com/kevinklinger/open_terraform@v1.3.6/noninternal/plugin/grpc_provider_test.go (about)

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