From cff26ced76ee5ee1ce344434f12166c5825a63f0 Mon Sep 17 00:00:00 2001 From: Ian Wahbe Date: Wed, 18 Dec 2024 18:59:21 +0100 Subject: [PATCH] Fix the concurrent writes in TestDetailedDiffMap (#2775) Calling `pb.NewResource` mutates the associated `.ResourceSchema`. This is safe in sequence (since the mutation is idempotent), but not in parallel. By turning the schemas into schema generators, we avoid concurrent writes. An example of the failure is https://github.com/pulumi/pulumi-terraform-bridge/actions/runs/12396464885/job/34605333073?pr=2774. --- pkg/pf/tests/diff_map_test.go | 113 ++++++++++++++++++---------------- 1 file changed, 60 insertions(+), 53 deletions(-) diff --git a/pkg/pf/tests/diff_map_test.go b/pkg/pf/tests/diff_map_test.go index e69036d66..189abf206 100644 --- a/pkg/pf/tests/diff_map_test.go +++ b/pkg/pf/tests/diff_map_test.go @@ -18,73 +18,83 @@ import ( func TestDetailedDiffMap(t *testing.T) { t.Parallel() - attributeSchema := rschema.Schema{ - Attributes: map[string]rschema.Attribute{ - "key": rschema.MapAttribute{ - Optional: true, - ElementType: types.StringType, + attributeSchema := pb.NewResource(pb.NewResourceArgs{ + ResourceSchema: rschema.Schema{ + Attributes: map[string]rschema.Attribute{ + "key": rschema.MapAttribute{ + Optional: true, + ElementType: types.StringType, + }, }, }, - } - - attributeReplaceSchema := rschema.Schema{ - Attributes: map[string]rschema.Attribute{ - "key": rschema.MapAttribute{ - Optional: true, - ElementType: types.StringType, - PlanModifiers: []planmodifier.Map{ - mapplanmodifier.RequiresReplace(), + }) + + attributeReplaceSchema := pb.NewResource(pb.NewResourceArgs{ + ResourceSchema: rschema.Schema{ + Attributes: map[string]rschema.Attribute{ + "key": rschema.MapAttribute{ + Optional: true, + ElementType: types.StringType, + PlanModifiers: []planmodifier.Map{ + mapplanmodifier.RequiresReplace(), + }, }, }, }, - } - - nestedAttributeSchema := rschema.Schema{ - Attributes: map[string]rschema.Attribute{ - "key": rschema.MapNestedAttribute{ - Optional: true, - NestedObject: rschema.NestedAttributeObject{ - Attributes: map[string]rschema.Attribute{ - "nested": rschema.StringAttribute{Optional: true}, + }) + + nestedAttributeSchema := pb.NewResource(pb.NewResourceArgs{ + ResourceSchema: rschema.Schema{ + Attributes: map[string]rschema.Attribute{ + "key": rschema.MapNestedAttribute{ + Optional: true, + NestedObject: rschema.NestedAttributeObject{ + Attributes: map[string]rschema.Attribute{ + "nested": rschema.StringAttribute{Optional: true}, + }, }, }, }, }, - } - - nestedAttributeReplaceSchema := rschema.Schema{ - Attributes: map[string]rschema.Attribute{ - "key": rschema.MapNestedAttribute{ - Optional: true, - NestedObject: rschema.NestedAttributeObject{ - Attributes: map[string]rschema.Attribute{ - "nested": rschema.StringAttribute{Optional: true}, + }) + + nestedAttributeReplaceSchema := pb.NewResource(pb.NewResourceArgs{ + ResourceSchema: rschema.Schema{ + Attributes: map[string]rschema.Attribute{ + "key": rschema.MapNestedAttribute{ + Optional: true, + NestedObject: rschema.NestedAttributeObject{ + Attributes: map[string]rschema.Attribute{ + "nested": rschema.StringAttribute{Optional: true}, + }, + }, + PlanModifiers: []planmodifier.Map{ + mapplanmodifier.RequiresReplace(), }, - }, - PlanModifiers: []planmodifier.Map{ - mapplanmodifier.RequiresReplace(), }, }, }, - } - - nestedAttributeNestedReplaceSchema := rschema.Schema{ - Attributes: map[string]rschema.Attribute{ - "key": rschema.MapNestedAttribute{ - Optional: true, - NestedObject: rschema.NestedAttributeObject{ - Attributes: map[string]rschema.Attribute{ - "nested": rschema.StringAttribute{ - Optional: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.RequiresReplace(), + }) + + nestedAttributeNestedReplaceSchema := pb.NewResource(pb.NewResourceArgs{ + ResourceSchema: rschema.Schema{ + Attributes: map[string]rschema.Attribute{ + "key": rschema.MapNestedAttribute{ + Optional: true, + NestedObject: rschema.NestedAttributeObject{ + Attributes: map[string]rschema.Attribute{ + "nested": rschema.StringAttribute{ + Optional: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, }, }, }, }, }, }, - } + }) attrMap := func(m *map[string]*string) cty.Value { if m == nil { @@ -126,7 +136,7 @@ func TestDetailedDiffMap(t *testing.T) { schemaValueMakerPairs := []struct { name string - schema rschema.Schema + res pb.Resource valueMaker func(*map[string]*string) cty.Value }{ {"attribute no replace", attributeSchema, attrMap}, @@ -174,12 +184,9 @@ func TestDetailedDiffMap(t *testing.T) { t.Parallel() initialValue := schemaValueMakerPair.valueMaker(scenario.initialValue) changeValue := schemaValueMakerPair.valueMaker(scenario.changeValue) - res := pb.NewResource(pb.NewResourceArgs{ - ResourceSchema: schemaValueMakerPair.schema, - }) diff := crosstests.Diff( - t, res, map[string]cty.Value{"key": initialValue}, map[string]cty.Value{"key": changeValue}, + t, schemaValueMakerPair.res, map[string]cty.Value{"key": initialValue}, map[string]cty.Value{"key": changeValue}, crosstests.DisableAccurateBridgePreview(), )