Skip to content

Commit bfec06a

Browse files
committed
Prevent EnsureProviderValid from mutating
This function has caused repeated test failures with concurrent map mutations, the most recent of which is https://github.com/pulumi/pulumi-terraform-bridge/actions/runs/12772071950/job/35600764628?pr=2832. This commit converts the function to return a copy instead of mutating.
1 parent 5ed2021 commit bfec06a

File tree

3 files changed

+41
-9
lines changed

3 files changed

+41
-9
lines changed

pkg/internal/tests/pulcheck/pulcheck.go

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,39 @@ func resourceNeedsUpdate(res *schema.Resource) bool {
5252
return false
5353
}
5454

55+
func copyMap[K comparable, V any](m map[K]V, cp func(V) V) map[K]V {
56+
dst := make(map[K]V, len(m))
57+
for k, v := range m {
58+
dst[k] = cp(v)
59+
}
60+
return dst
61+
}
62+
63+
// WithValidProvider returns a copy of tfp, with all required fields filled with default
64+
// values.
65+
//
5566
// This is an experimental API.
56-
func EnsureProviderValid(t T, tfp *schema.Provider) {
67+
func WithValidProvider(t T, tfp *schema.Provider) *schema.Provider {
68+
if tfp == nil {
69+
return nil
70+
}
71+
72+
// Copy tfp as deep as we will mutate.
73+
{
74+
dst := *tfp // memcopy
75+
dst.ResourcesMap = copyMap(tfp.ResourcesMap, func(v *schema.Resource) *schema.Resource {
76+
cp := *v // memcopy
77+
cp.Schema = copyMap(cp.Schema, func(s *schema.Schema) *schema.Schema {
78+
cp := *s
79+
return &cp
80+
})
81+
return &cp
82+
})
83+
tfp = &dst
84+
}
85+
86+
// Now ensure that tfp is valid
87+
5788
for _, r := range tfp.ResourcesMap {
5889
if r.Schema["id"] == nil {
5990
r.Schema["id"] = &schema.Schema{
@@ -108,6 +139,8 @@ func EnsureProviderValid(t T, tfp *schema.Provider) {
108139
}
109140
}
110141
require.NoError(t, tfp.InternalValidate())
142+
143+
return tfp
111144
}
112145

113146
func ProviderServerFromInfo(
@@ -206,7 +239,7 @@ func BridgedProvider(t T, providerName string, tfp *schema.Provider, opts ...Bri
206239
opt(&options)
207240
}
208241

209-
EnsureProviderValid(t, tfp)
242+
tfp = WithValidProvider(t, tfp)
210243

211244
// If the PULUMI_ACCURATE_BRIDGE_PREVIEWS environment variable is set, use it to enable
212245
// accurate bridge previews.
@@ -230,10 +263,8 @@ func BridgedProvider(t T, providerName string, tfp *schema.Provider, opts ...Bri
230263
EnableAccurateBridgePreview: accurateBridgePreviews,
231264
Config: options.configInfo,
232265
}
233-
makeToken := func(module, name string) (string, error) {
234-
return tokens.MakeStandard(providerName)(module, name)
235-
}
236-
provider.MustComputeTokens(tokens.SingleModule(providerName, "index", makeToken))
266+
provider.MustComputeTokens(tokens.SingleModule(providerName,
267+
"index", tokens.MakeStandard(providerName)))
237268

238269
return provider
239270
}

pkg/tests/import_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,9 @@ func TestFullyComputedNestedAttribute(t *testing.T) {
6262
return []*schema.ResourceData{rd}, nil
6363
}
6464
}
65-
tfp := &schema.Provider{ResourcesMap: resMap}
66-
bridgedProvider := pulcheck.BridgedProvider(t, "prov", tfp)
65+
bridgedProvider := pulcheck.BridgedProvider(t, "prov", &schema.Provider{
66+
ResourcesMap: resMap,
67+
})
6768

6869
program := `
6970
name: test

pkg/tests/tfcheck/tfcheck.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ func NewTfDriver(t pulcheck.T, dir, providerName string, prov any) *TFDriver {
7676
}
7777

7878
func newTfDriverSDK(t pulcheck.T, dir, providerName string, prov *schema.Provider) *TFDriver {
79-
pulcheck.EnsureProviderValid(t, prov)
79+
prov = pulcheck.WithValidProvider(t, prov)
8080
v6server, err := tf5to6server.UpgradeServer(context.Background(),
8181
func() tfprotov5.ProviderServer { return prov.GRPCProvider() })
8282
require.NoError(t, err)

0 commit comments

Comments
 (0)