Skip to content

Commit f1783b9

Browse files
authored
internal: Implement fwserver ImportResourceState testing and update proto6server testing (#361)
Reference: #215
1 parent 7b5f42d commit f1783b9

6 files changed

+380
-281
lines changed

internal/fwserver/server_importresourcestate_test.go

+213-11
Original file line numberDiff line numberDiff line change
@@ -5,32 +5,234 @@ import (
55
"testing"
66

77
"github.com/google/go-cmp/cmp"
8+
"github.com/hashicorp/terraform-plugin-framework/diag"
89
"github.com/hashicorp/terraform-plugin-framework/internal/fwserver"
9-
"github.com/hashicorp/terraform-plugin-framework/internal/testing/emptyprovider"
10+
"github.com/hashicorp/terraform-plugin-framework/internal/testing/testprovider"
11+
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
12+
"github.com/hashicorp/terraform-plugin-framework/types"
13+
"github.com/hashicorp/terraform-plugin-go/tftypes"
1014
)
1115

12-
// TODO: Migrate tfsdk.Provider bits of proto6server.testProviderServer to
13-
// new internal/testing/provider.Provider that allows customization of all
14-
// method implementations via struct fields. Then, create additional test
15-
// cases in this unit test.
16-
//
17-
// For now this testing is covered by proto6server.ImportResourceState.
18-
//
19-
// Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/215
2016
func TestServerImportResourceState(t *testing.T) {
2117
t.Parallel()
2218

19+
testType := tftypes.Object{
20+
AttributeTypes: map[string]tftypes.Type{
21+
"id": tftypes.String,
22+
"optional": tftypes.String,
23+
"required": tftypes.String,
24+
},
25+
}
26+
27+
testEmptyStateValue := tftypes.NewValue(testType, map[string]tftypes.Value{
28+
"id": tftypes.NewValue(tftypes.String, nil),
29+
"optional": tftypes.NewValue(tftypes.String, nil),
30+
"required": tftypes.NewValue(tftypes.String, nil),
31+
})
32+
33+
testStateValue := tftypes.NewValue(testType, map[string]tftypes.Value{
34+
"id": tftypes.NewValue(tftypes.String, "test-id"),
35+
"optional": tftypes.NewValue(tftypes.String, nil),
36+
"required": tftypes.NewValue(tftypes.String, nil),
37+
})
38+
39+
testSchema := tfsdk.Schema{
40+
Attributes: map[string]tfsdk.Attribute{
41+
"id": {
42+
Computed: true,
43+
Type: types.StringType,
44+
},
45+
"optional": {
46+
Optional: true,
47+
Type: types.StringType,
48+
},
49+
"required": {
50+
Required: true,
51+
Type: types.StringType,
52+
},
53+
},
54+
}
55+
56+
testEmptyState := &tfsdk.State{
57+
Raw: testEmptyStateValue,
58+
Schema: testSchema,
59+
}
60+
61+
testState := &tfsdk.State{
62+
Raw: testStateValue,
63+
Schema: testSchema,
64+
}
65+
2366
testCases := map[string]struct {
2467
server *fwserver.Server
2568
request *fwserver.ImportResourceStateRequest
2669
expectedResponse *fwserver.ImportResourceStateResponse
2770
}{
28-
"empty-provider": {
71+
"nil": {
2972
server: &fwserver.Server{
30-
Provider: &emptyprovider.Provider{},
73+
Provider: &testprovider.Provider{},
3174
},
3275
expectedResponse: &fwserver.ImportResourceStateResponse{},
3376
},
77+
"request-id": {
78+
server: &fwserver.Server{
79+
Provider: &testprovider.Provider{},
80+
},
81+
request: &fwserver.ImportResourceStateRequest{
82+
EmptyState: *testEmptyState,
83+
ID: "test-id",
84+
ResourceType: &testprovider.ResourceType{
85+
GetSchemaMethod: func(_ context.Context) (tfsdk.Schema, diag.Diagnostics) {
86+
return testSchema, nil
87+
},
88+
NewResourceMethod: func(_ context.Context, _ tfsdk.Provider) (tfsdk.Resource, diag.Diagnostics) {
89+
return &testprovider.ResourceWithImportState{
90+
Resource: &testprovider.Resource{},
91+
ImportStateMethod: func(ctx context.Context, req tfsdk.ImportResourceStateRequest, resp *tfsdk.ImportResourceStateResponse) {
92+
if req.ID != "test-id" {
93+
resp.Diagnostics.AddError("unexpected req.ID value: %s", req.ID)
94+
}
95+
96+
tfsdk.ResourceImportStatePassthroughID(ctx, tftypes.NewAttributePath().WithAttributeName("id"), req, resp)
97+
},
98+
}, nil
99+
},
100+
},
101+
TypeName: "test_resource",
102+
},
103+
expectedResponse: &fwserver.ImportResourceStateResponse{
104+
ImportedResources: []fwserver.ImportedResource{
105+
{
106+
State: *testState,
107+
TypeName: "test_resource",
108+
},
109+
},
110+
},
111+
},
112+
"request-resourcetype-importstate-not-implemented": {
113+
server: &fwserver.Server{
114+
Provider: &testprovider.Provider{},
115+
},
116+
request: &fwserver.ImportResourceStateRequest{
117+
EmptyState: *testEmptyState,
118+
ID: "test-id",
119+
ResourceType: &testprovider.ResourceType{
120+
GetSchemaMethod: func(_ context.Context) (tfsdk.Schema, diag.Diagnostics) {
121+
return testSchema, nil
122+
},
123+
NewResourceMethod: func(_ context.Context, _ tfsdk.Provider) (tfsdk.Resource, diag.Diagnostics) {
124+
return &testprovider.Resource{}, nil
125+
},
126+
},
127+
TypeName: "test_resource",
128+
},
129+
expectedResponse: &fwserver.ImportResourceStateResponse{
130+
Diagnostics: diag.Diagnostics{
131+
diag.NewErrorDiagnostic(
132+
"Resource Import Not Implemented",
133+
"This resource does not support import. Please contact the provider developer for additional information.",
134+
),
135+
},
136+
},
137+
},
138+
"response-diagnostics": {
139+
server: &fwserver.Server{
140+
Provider: &testprovider.Provider{},
141+
},
142+
request: &fwserver.ImportResourceStateRequest{
143+
EmptyState: *testEmptyState,
144+
ID: "test-id",
145+
ResourceType: &testprovider.ResourceType{
146+
GetSchemaMethod: func(_ context.Context) (tfsdk.Schema, diag.Diagnostics) {
147+
return testSchema, nil
148+
},
149+
NewResourceMethod: func(_ context.Context, _ tfsdk.Provider) (tfsdk.Resource, diag.Diagnostics) {
150+
return &testprovider.ResourceWithImportState{
151+
Resource: &testprovider.Resource{},
152+
ImportStateMethod: func(ctx context.Context, req tfsdk.ImportResourceStateRequest, resp *tfsdk.ImportResourceStateResponse) {
153+
resp.Diagnostics.AddWarning("warning summary", "warning detail")
154+
resp.Diagnostics.AddError("error summary", "error detail")
155+
},
156+
}, nil
157+
},
158+
},
159+
},
160+
expectedResponse: &fwserver.ImportResourceStateResponse{
161+
Diagnostics: diag.Diagnostics{
162+
diag.NewWarningDiagnostic(
163+
"warning summary",
164+
"warning detail",
165+
),
166+
diag.NewErrorDiagnostic(
167+
"error summary",
168+
"error detail",
169+
),
170+
},
171+
},
172+
},
173+
"response-importedresources": {
174+
server: &fwserver.Server{
175+
Provider: &testprovider.Provider{},
176+
},
177+
request: &fwserver.ImportResourceStateRequest{
178+
EmptyState: *testEmptyState,
179+
ID: "test-id",
180+
ResourceType: &testprovider.ResourceType{
181+
GetSchemaMethod: func(_ context.Context) (tfsdk.Schema, diag.Diagnostics) {
182+
return testSchema, nil
183+
},
184+
NewResourceMethod: func(_ context.Context, _ tfsdk.Provider) (tfsdk.Resource, diag.Diagnostics) {
185+
return &testprovider.ResourceWithImportState{
186+
Resource: &testprovider.Resource{},
187+
ImportStateMethod: func(ctx context.Context, req tfsdk.ImportResourceStateRequest, resp *tfsdk.ImportResourceStateResponse) {
188+
tfsdk.ResourceImportStatePassthroughID(ctx, tftypes.NewAttributePath().WithAttributeName("id"), req, resp)
189+
},
190+
}, nil
191+
},
192+
},
193+
TypeName: "test_resource",
194+
},
195+
expectedResponse: &fwserver.ImportResourceStateResponse{
196+
ImportedResources: []fwserver.ImportedResource{
197+
{
198+
State: *testState,
199+
TypeName: "test_resource",
200+
},
201+
},
202+
},
203+
},
204+
"response-importedresources-empty-state": {
205+
server: &fwserver.Server{
206+
Provider: &testprovider.Provider{},
207+
},
208+
request: &fwserver.ImportResourceStateRequest{
209+
EmptyState: *testEmptyState,
210+
ID: "test-id",
211+
ResourceType: &testprovider.ResourceType{
212+
GetSchemaMethod: func(_ context.Context) (tfsdk.Schema, diag.Diagnostics) {
213+
return testSchema, nil
214+
},
215+
NewResourceMethod: func(_ context.Context, _ tfsdk.Provider) (tfsdk.Resource, diag.Diagnostics) {
216+
return &testprovider.ResourceWithImportState{
217+
Resource: &testprovider.Resource{},
218+
ImportStateMethod: func(ctx context.Context, req tfsdk.ImportResourceStateRequest, resp *tfsdk.ImportResourceStateResponse) {
219+
// Intentionally empty
220+
},
221+
}, nil
222+
},
223+
},
224+
TypeName: "test_resource",
225+
},
226+
expectedResponse: &fwserver.ImportResourceStateResponse{
227+
Diagnostics: diag.Diagnostics{
228+
diag.NewErrorDiagnostic(
229+
"Missing Resource Import State",
230+
"An unexpected error was encountered when importing the resource. This is always a problem with the provider. Please give the following information to the provider developer:\n\n"+
231+
"Resource ImportState method returned no State in response. If import is intentionally not supported, remove the Resource type ImportState method or return an error.",
232+
),
233+
},
234+
},
235+
},
34236
}
35237

36238
for name, testCase := range testCases {

internal/proto6server/serve_provider_test.go

+4-6
Original file line numberDiff line numberDiff line change
@@ -297,12 +297,10 @@ func (t *testServeProvider) GetSchema(_ context.Context) (tfsdk.Schema, diag.Dia
297297

298298
func (t *testServeProvider) GetResources(_ context.Context) (map[string]tfsdk.ResourceType, diag.Diagnostics) {
299299
return map[string]tfsdk.ResourceType{
300-
"test_one": testServeResourceTypeOne{},
301-
"test_two": testServeResourceTypeTwo{},
302-
"test_three": testServeResourceTypeThree{},
303-
"test_attribute_plan_modifiers": testServeResourceTypeAttributePlanModifiers{},
304-
"test_import_state": testServeResourceTypeImportState{},
305-
"test_import_state_not_implemented": testServeResourceTypeImportStateNotImplemented{},
300+
"test_one": testServeResourceTypeOne{},
301+
"test_two": testServeResourceTypeTwo{},
302+
"test_three": testServeResourceTypeThree{},
303+
"test_attribute_plan_modifiers": testServeResourceTypeAttributePlanModifiers{},
306304
}, nil
307305
}
308306

internal/proto6server/serve_resource_import_state_not_implemented_test.go

-54
This file was deleted.

internal/proto6server/serve_resource_import_state_test.go

-81
This file was deleted.

0 commit comments

Comments
 (0)