Skip to content

Commit eb36de4

Browse files
committed
Initial actions plumbing
1 parent 01f7e04 commit eb36de4

File tree

12 files changed

+580
-18
lines changed

12 files changed

+580
-18
lines changed

go.mod

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -287,12 +287,12 @@ require (
287287
github.com/hashicorp/go-version v1.7.0
288288
github.com/hashicorp/hcl/v2 v2.23.0
289289
github.com/hashicorp/terraform-json v0.25.0
290-
github.com/hashicorp/terraform-plugin-framework v1.15.0
290+
github.com/hashicorp/terraform-plugin-framework v1.16.0-alpha.1.0.20250728185851-cca5c5aac673
291291
github.com/hashicorp/terraform-plugin-framework-jsontypes v0.2.0
292292
github.com/hashicorp/terraform-plugin-framework-timeouts v0.5.0
293293
github.com/hashicorp/terraform-plugin-framework-timetypes v0.5.0
294294
github.com/hashicorp/terraform-plugin-framework-validators v0.18.0
295-
github.com/hashicorp/terraform-plugin-go v0.28.0
295+
github.com/hashicorp/terraform-plugin-go v0.29.0-alpha.1.0.20250717133739-e33a5336fb19
296296
github.com/hashicorp/terraform-plugin-log v0.9.0
297297
github.com/hashicorp/terraform-plugin-mux v0.20.0
298298
github.com/hashicorp/terraform-plugin-sdk/v2 v2.37.0
@@ -347,7 +347,7 @@ require (
347347
github.com/hashicorp/hc-install v0.9.2 // indirect
348348
github.com/hashicorp/logutils v1.0.0 // indirect
349349
github.com/hashicorp/terraform-exec v0.23.0 // indirect
350-
github.com/hashicorp/terraform-registry-address v0.2.5 // indirect
350+
github.com/hashicorp/terraform-registry-address v0.3.0 // indirect
351351
github.com/hashicorp/terraform-svchost v0.1.1 // indirect
352352
github.com/hashicorp/yamux v0.1.1 // indirect
353353
github.com/huandu/xstrings v1.3.3 // indirect
@@ -377,7 +377,7 @@ require (
377377
golang.org/x/sys v0.34.0 // indirect
378378
google.golang.org/appengine v1.6.8 // indirect
379379
google.golang.org/genproto/googleapis/rpc v0.0.0-20250505200425-f936aa4a68b2 // indirect
380-
google.golang.org/grpc v1.72.1 // indirect
380+
google.golang.org/grpc v1.73.0 // indirect
381381
google.golang.org/protobuf v1.36.6 // indirect
382382
)
383383

go.sum

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -660,8 +660,8 @@ github.com/hashicorp/terraform-exec v0.23.0 h1:MUiBM1s0CNlRFsCLJuM5wXZrzA3MnPYEs
660660
github.com/hashicorp/terraform-exec v0.23.0/go.mod h1:mA+qnx1R8eePycfwKkCRk3Wy65mwInvlpAeOwmA7vlY=
661661
github.com/hashicorp/terraform-json v0.25.0 h1:rmNqc/CIfcWawGiwXmRuiXJKEiJu1ntGoxseG1hLhoQ=
662662
github.com/hashicorp/terraform-json v0.25.0/go.mod h1:sMKS8fiRDX4rVlR6EJUMudg1WcanxCMoWwTLkgZP/vc=
663-
github.com/hashicorp/terraform-plugin-framework v1.15.0 h1:LQ2rsOfmDLxcn5EeIwdXFtr03FVsNktbbBci8cOKdb4=
664-
github.com/hashicorp/terraform-plugin-framework v1.15.0/go.mod h1:hxrNI/GY32KPISpWqlCoTLM9JZsGH3CyYlir09bD/fI=
663+
github.com/hashicorp/terraform-plugin-framework v1.16.0-alpha.1.0.20250728185851-cca5c5aac673 h1:NNxkKysLXtHA0BkAMXUV+l/AZla1xyt2+PMiE6KpjM0=
664+
github.com/hashicorp/terraform-plugin-framework v1.16.0-alpha.1.0.20250728185851-cca5c5aac673/go.mod h1:UrhvOHRFMGyYLn35rO3DtvcawLLt65BSQOcLLClRrcQ=
665665
github.com/hashicorp/terraform-plugin-framework-jsontypes v0.2.0 h1:SJXL5FfJJm17554Kpt9jFXngdM6fXbnUnZ6iT2IeiYA=
666666
github.com/hashicorp/terraform-plugin-framework-jsontypes v0.2.0/go.mod h1:p0phD0IYhsu9bR4+6OetVvvH59I6LwjXGnTVEr8ox6E=
667667
github.com/hashicorp/terraform-plugin-framework-timeouts v0.5.0 h1:I/N0g/eLZ1ZkLZXUQ0oRSXa8YG/EF0CEuQP1wXdrzKw=
@@ -670,16 +670,16 @@ github.com/hashicorp/terraform-plugin-framework-timetypes v0.5.0 h1:v3DapR8gsp3E
670670
github.com/hashicorp/terraform-plugin-framework-timetypes v0.5.0/go.mod h1:c3PnGE9pHBDfdEVG9t1S1C9ia5LW+gkFR0CygXlM8ak=
671671
github.com/hashicorp/terraform-plugin-framework-validators v0.18.0 h1:OQnlOt98ua//rCw+QhBbSqfW3QbwtVrcdWeQN5gI3Hw=
672672
github.com/hashicorp/terraform-plugin-framework-validators v0.18.0/go.mod h1:lZvZvagw5hsJwuY7mAY6KUz45/U6fiDR0CzQAwWD0CA=
673-
github.com/hashicorp/terraform-plugin-go v0.28.0 h1:zJmu2UDwhVN0J+J20RE5huiF3XXlTYVIleaevHZgKPA=
674-
github.com/hashicorp/terraform-plugin-go v0.28.0/go.mod h1:FDa2Bb3uumkTGSkTFpWSOwWJDwA7bf3vdP3ltLDTH6o=
673+
github.com/hashicorp/terraform-plugin-go v0.29.0-alpha.1.0.20250717133739-e33a5336fb19 h1:P/ZVGEGXt9xSiLz+CrP/JzV2V8rtlE7994AX4jzcGB8=
674+
github.com/hashicorp/terraform-plugin-go v0.29.0-alpha.1.0.20250717133739-e33a5336fb19/go.mod h1:hL//wLEfYo0YVt0TC/VLzia/ADQQto3HEm4/jX2gkdY=
675675
github.com/hashicorp/terraform-plugin-mux v0.20.0 h1:3QpBnI9uCuL0Yy2Rq/kR9cOdmOFNhw88A2GoZtk5aXM=
676676
github.com/hashicorp/terraform-plugin-mux v0.20.0/go.mod h1:wSIZwJjSYk86NOTX3fKUlThMT4EAV1XpBHz9SAvjQr4=
677677
github.com/hashicorp/terraform-plugin-sdk/v2 v2.37.0 h1:NFPMacTrY/IdcIcnUB+7hsore1ZaRWU9cnB6jFoBnIM=
678678
github.com/hashicorp/terraform-plugin-sdk/v2 v2.37.0/go.mod h1:QYmYnLfsosrxjCnGY1p9c7Zj6n9thnEE+7RObeYs3fA=
679679
github.com/hashicorp/terraform-plugin-testing v1.13.2 h1:mSotG4Odl020vRjIenA3rggwo6Kg6XCKIwtRhYgp+/M=
680680
github.com/hashicorp/terraform-plugin-testing v1.13.2/go.mod h1:WHQ9FDdiLoneey2/QHpGM/6SAYf4A7AZazVg7230pLE=
681-
github.com/hashicorp/terraform-registry-address v0.2.5 h1:2GTftHqmUhVOeuu9CW3kwDkRe4pcBDq0uuK5VJngU1M=
682-
github.com/hashicorp/terraform-registry-address v0.2.5/go.mod h1:PpzXWINwB5kuVS5CA7m1+eO2f1jKb5ZDIxrOPfpnGkg=
681+
github.com/hashicorp/terraform-registry-address v0.3.0 h1:HMpK3nqaGFPS9VmgRXrJL/dzHNdheGVKk5k7VlFxzCo=
682+
github.com/hashicorp/terraform-registry-address v0.3.0/go.mod h1:jRGCMiLaY9zii3GLC7hqpSnwhfnCN5yzvY0hh4iCGbM=
683683
github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ=
684684
github.com/hashicorp/terraform-svchost v0.1.1/go.mod h1:mNsjQfZyf/Jhz35v6/0LWcv26+X7JPS+buii2c9/ctc=
685685
github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE=
@@ -790,10 +790,10 @@ go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg=
790790
go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E=
791791
go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE=
792792
go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs=
793-
go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
794-
go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
795-
go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk=
796-
go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w=
793+
go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY=
794+
go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg=
795+
go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o=
796+
go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w=
797797
go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w=
798798
go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA=
799799
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
@@ -854,8 +854,8 @@ google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAs
854854
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
855855
google.golang.org/genproto/googleapis/rpc v0.0.0-20250505200425-f936aa4a68b2 h1:IqsN8hx+lWLqlN+Sc3DoMy/watjofWiU8sRFgQ8fhKM=
856856
google.golang.org/genproto/googleapis/rpc v0.0.0-20250505200425-f936aa4a68b2/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
857-
google.golang.org/grpc v1.72.1 h1:HR03wO6eyZ7lknl75XlxABNVLLFc2PAb6mHlYh756mA=
858-
google.golang.org/grpc v1.72.1/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM=
857+
google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok=
858+
google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc=
859859
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
860860
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
861861
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=

internal/conns/conns.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,13 @@ type ServicePackage interface {
2020
ServicePackageName() string
2121
}
2222

23+
// ServicePackageWithActions is an interface that extends ServicePackage with actions.
24+
// Actions are imperative operations that can be invoked to perform Day-2 operations.
25+
type ServicePackageWithActions interface {
26+
ServicePackage
27+
Actions(context.Context) []*types.ServicePackageAction
28+
}
29+
2330
// ServicePackageWithEphemeralResources is an interface that extends ServicePackage with ephemeral resources.
2431
// Ephemeral resources are resources that are not part of the Terraform state, but are used to create other resources.
2532
type ServicePackageWithEphemeralResources interface {

internal/framework/action_test.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright (c) HashiCorp, Inc.
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
package framework
5+
6+
import (
7+
"testing"
8+
9+
"github.com/hashicorp/terraform-provider-aws/internal/conns"
10+
)
11+
12+
// Test that ActionWithConfigure can be instantiated and has the expected methods
13+
func TestActionWithConfigureCompilation(t *testing.T) {
14+
// This test ensures our new types compile correctly
15+
var action ActionWithConfigure
16+
17+
// Test that it has the Meta method from withMeta
18+
if action.Meta() != nil {
19+
t.Error("Expected nil meta before configuration")
20+
}
21+
22+
// Test that it embeds withMeta correctly
23+
action.meta = &conns.AWSClient{}
24+
if action.Meta() == nil {
25+
t.Error("Expected non-nil meta after setting")
26+
}
27+
}
28+
29+
// Test that ActionWithModel can be instantiated
30+
func TestActionWithModelCompilation(t *testing.T) {
31+
// Test model
32+
type testModel struct {
33+
Name string `tfsdk:"name"`
34+
}
35+
36+
// This test ensures our new generic type compiles correctly
37+
var action ActionWithModel[testModel]
38+
39+
// Test that it has the Meta method from ActionWithConfigure
40+
if action.Meta() != nil {
41+
t.Error("Expected nil meta before configuration")
42+
}
43+
44+
// Test that it embeds ActionWithConfigure correctly
45+
action.meta = &conns.AWSClient{}
46+
if action.Meta() == nil {
47+
t.Error("Expected non-nil meta after setting")
48+
}
49+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright (c) HashiCorp, Inc.
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
package framework
5+
6+
import (
7+
"context"
8+
9+
"github.com/hashicorp/terraform-plugin-framework/action"
10+
"github.com/hashicorp/terraform-provider-aws/internal/conns"
11+
)
12+
13+
type ActionWithConfigure struct {
14+
withMeta
15+
}
16+
17+
// Metadata should return the full name of the action, such as
18+
// aws_lambda_invoke.
19+
func (*ActionWithConfigure) Metadata(_ context.Context, request action.MetadataRequest, response *action.MetadataResponse) {
20+
// This method is implemented in the wrappers.
21+
panic("not implemented") // lintignore:R009
22+
}
23+
24+
// Configure enables provider-level data or clients to be set in the
25+
// provider-defined Action type.
26+
func (a *ActionWithConfigure) Configure(_ context.Context, request action.ConfigureRequest, _ *action.ConfigureResponse) {
27+
if v, ok := request.ProviderData.(*conns.AWSClient); ok {
28+
a.meta = v
29+
}
30+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright (c) HashiCorp, Inc.
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
package framework
5+
6+
import (
7+
"context"
8+
9+
"github.com/hashicorp/terraform-plugin-framework/action/schema"
10+
"github.com/hashicorp/terraform-plugin-framework/diag"
11+
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
12+
"github.com/hashicorp/terraform-plugin-go/tftypes"
13+
)
14+
15+
// ActionWithModel is a structure to be embedded within an Action that has a corresponding model.
16+
type ActionWithModel[T any] struct {
17+
withModel[T]
18+
ActionWithConfigure
19+
}
20+
21+
// ValidateModel validates the action's model against a schema.
22+
func (a *ActionWithModel[T]) ValidateModel(ctx context.Context, schema *schema.UnlinkedSchema) diag.Diagnostics {
23+
var diags diag.Diagnostics
24+
state := tfsdk.State{
25+
Raw: tftypes.NewValue(schema.Type().TerraformType(ctx), nil),
26+
Schema: schema,
27+
}
28+
29+
diags.Append(a.validateModel(ctx, &state)...)
30+
31+
return diags
32+
}
33+
34+
type ActionValidateModel interface {
35+
ValidateModel(ctx context.Context, schema *schema.UnlinkedSchema) diag.Diagnostics
36+
}
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
// Copyright (c) HashiCorp, Inc.
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
package framework
5+
6+
import (
7+
"context"
8+
"testing"
9+
10+
"github.com/hashicorp/terraform-plugin-framework/action"
11+
"github.com/hashicorp/terraform-plugin-framework/action/schema"
12+
"github.com/hashicorp/terraform-plugin-framework/diag"
13+
"github.com/hashicorp/terraform-plugin-framework/types"
14+
"github.com/hashicorp/terraform-provider-aws/internal/conns"
15+
"github.com/hashicorp/terraform-provider-aws/internal/framework"
16+
)
17+
18+
// testAction implements action.Action for testing
19+
type testAction struct{}
20+
21+
func (t *testAction) Metadata(ctx context.Context, req action.MetadataRequest, resp *action.MetadataResponse) {
22+
resp.TypeName = "aws_test_action"
23+
}
24+
25+
func (t *testAction) Schema(ctx context.Context, req action.SchemaRequest, resp *action.SchemaResponse) {
26+
resp.Schema = schema.UnlinkedSchema{
27+
Description: "Test action for framework integration",
28+
Attributes: map[string]schema.Attribute{
29+
"test_param": schema.StringAttribute{
30+
Required: true,
31+
Description: "Test parameter",
32+
},
33+
},
34+
}
35+
}
36+
37+
func (t *testAction) Invoke(ctx context.Context, req action.InvokeRequest, resp *action.InvokeResponse) {
38+
// Test implementation - just validate we can access the config
39+
var config testActionModel
40+
resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
41+
if resp.Diagnostics.HasError() {
42+
return
43+
}
44+
45+
// Send progress update
46+
resp.SendProgress(action.InvokeProgressEvent{
47+
Message: "Test action executed successfully",
48+
})
49+
}
50+
51+
// testActionModel represents the configuration model for the test action
52+
type testActionModel struct {
53+
TestParam types.String `tfsdk:"test_param"`
54+
}
55+
56+
// Implement ActionValidateModel interface
57+
func (t *testAction) ValidateModel(ctx context.Context, schema *schema.UnlinkedSchema) diag.Diagnostics {
58+
var diags diag.Diagnostics
59+
// Basic validation - ensure required attributes exist
60+
if _, ok := schema.Attributes["test_param"]; !ok {
61+
diags.AddError("Missing required attribute", "test_param attribute is required")
62+
}
63+
return diags
64+
}
65+
66+
// Ensure testAction implements required interfaces
67+
var (
68+
_ action.Action = (*testAction)(nil)
69+
_ framework.ActionValidateModel = (*testAction)(nil)
70+
)
71+
72+
func TestWrappedAction_Basic(t *testing.T) {
73+
ctx := context.Background()
74+
75+
// Create test action
76+
inner := &testAction{}
77+
78+
// Create wrapped action with minimal options
79+
opts := wrappedActionOptions{
80+
bootstrapContext: func(ctx context.Context, getAttribute getAttributeFunc, c *conns.AWSClient) (context.Context, diag.Diagnostics) {
81+
return ctx, nil
82+
},
83+
interceptors: interceptorInvocations{},
84+
typeName: "aws_test_action",
85+
}
86+
87+
wrapped := newWrappedAction(inner, opts)
88+
89+
// Test Metadata
90+
metaReq := action.MetadataRequest{
91+
ProviderTypeName: "aws",
92+
}
93+
var metaResp action.MetadataResponse
94+
wrapped.Metadata(ctx, metaReq, &metaResp)
95+
96+
if metaResp.TypeName != "aws_test_action" {
97+
t.Errorf("Expected TypeName 'aws_test_action', got '%s'", metaResp.TypeName)
98+
}
99+
100+
// Test Schema
101+
schemaReq := action.SchemaRequest{}
102+
var schemaResp action.SchemaResponse
103+
wrapped.Schema(ctx, schemaReq, &schemaResp)
104+
105+
if schemaResp.Diagnostics.HasError() {
106+
t.Errorf("Schema method returned errors: %v", schemaResp.Diagnostics)
107+
}
108+
109+
if unlinkedSchema, ok := schemaResp.Schema.(schema.UnlinkedSchema); ok {
110+
if _, exists := unlinkedSchema.Attributes["test_param"]; !exists {
111+
t.Error("Expected 'test_param' attribute in schema")
112+
}
113+
} else {
114+
t.Error("Expected UnlinkedSchema type")
115+
}
116+
}
117+
118+
func TestActionInterceptors_RegionInjection(t *testing.T) {
119+
ctx := context.Background()
120+
121+
// Create test action
122+
inner := &testAction{}
123+
124+
// Create wrapped action with region interceptor
125+
opts := wrappedActionOptions{
126+
bootstrapContext: func(ctx context.Context, getAttribute getAttributeFunc, c *conns.AWSClient) (context.Context, diag.Diagnostics) {
127+
return ctx, nil
128+
},
129+
interceptors: interceptorInvocations{
130+
actionInjectRegionAttribute(),
131+
},
132+
typeName: "aws_test_action",
133+
}
134+
135+
wrapped := newWrappedAction(inner, opts)
136+
137+
// Test Schema with region injection
138+
schemaReq := action.SchemaRequest{}
139+
var schemaResp action.SchemaResponse
140+
wrapped.Schema(ctx, schemaReq, &schemaResp)
141+
142+
if schemaResp.Diagnostics.HasError() {
143+
t.Errorf("Schema method returned errors: %v", schemaResp.Diagnostics)
144+
}
145+
146+
if unlinkedSchema, ok := schemaResp.Schema.(schema.UnlinkedSchema); ok {
147+
if _, exists := unlinkedSchema.Attributes["region"]; !exists {
148+
t.Error("Expected 'region' attribute to be injected into schema")
149+
}
150+
if _, exists := unlinkedSchema.Attributes["test_param"]; !exists {
151+
t.Error("Expected original 'test_param' attribute to remain in schema")
152+
}
153+
} else {
154+
t.Error("Expected UnlinkedSchema type")
155+
}
156+
}

0 commit comments

Comments
 (0)