Skip to content

Commit 82f47ca

Browse files
authored
Merge pull request #31184 from hashicorp/bflad-GetProviderSchema-early-diag-return
Return early on GetProviderSchema RPC responses with error diagnostics
2 parents 472df96 + 0b404f4 commit 82f47ca

File tree

4 files changed

+130
-0
lines changed

4 files changed

+130
-0
lines changed

internal/plugin/grpc_provider.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,10 @@ func (p *GRPCProvider) GetProviderSchema() (resp providers.GetProviderSchemaResp
137137

138138
resp.Diagnostics = resp.Diagnostics.Append(convert.ProtoToDiagnostics(protoResp.Diagnostics))
139139

140+
if resp.Diagnostics.HasErrors() {
141+
return resp
142+
}
143+
140144
if protoResp.Provider == nil {
141145
resp.Diagnostics = resp.Diagnostics.Append(errors.New("missing provider schema"))
142146
return resp

internal/plugin/grpc_provider_test.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,15 @@ func checkDiags(t *testing.T, d tfdiags.Diagnostics) {
3939
}
4040
}
4141

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+
4251
func providerProtoSchema() *proto.GetProviderSchema_Response {
4352
return &proto.GetProviderSchema_Response{
4453
Provider: &proto.Schema{
@@ -92,6 +101,58 @@ func TestGRPCProvider_GetSchema(t *testing.T) {
92101
checkDiags(t, resp.Diagnostics)
93102
}
94103

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+
95156
func TestGRPCProvider_PrepareProviderConfig(t *testing.T) {
96157
client := mockProviderClient(t)
97158
p := &GRPCProvider{

internal/plugin6/grpc_provider.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,10 @@ func (p *GRPCProvider) GetProviderSchema() (resp providers.GetProviderSchemaResp
144144

145145
resp.Diagnostics = resp.Diagnostics.Append(convert.ProtoToDiagnostics(protoResp.Diagnostics))
146146

147+
if resp.Diagnostics.HasErrors() {
148+
return resp
149+
}
150+
147151
if protoResp.Provider == nil {
148152
resp.Diagnostics = resp.Diagnostics.Append(errors.New("missing provider schema"))
149153
return resp

internal/plugin6/grpc_provider_test.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,15 @@ func checkDiags(t *testing.T, d tfdiags.Diagnostics) {
4646
}
4747
}
4848

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+
4958
func providerProtoSchema() *proto.GetProviderSchema_Response {
5059
return &proto.GetProviderSchema_Response{
5160
Provider: &proto.Schema{
@@ -99,6 +108,58 @@ func TestGRPCProvider_GetSchema(t *testing.T) {
99108
checkDiags(t, resp.Diagnostics)
100109
}
101110

111+
// Ensure that gRPC errors are returned early.
112+
// Reference: https://github.com/hashicorp/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/hashicorp/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+
102163
func TestGRPCProvider_PrepareProviderConfig(t *testing.T) {
103164
client := mockProviderClient(t)
104165
p := &GRPCProvider{

0 commit comments

Comments
 (0)