From 1dcca465df609ed3ef15505ed2d0973377d6c713 Mon Sep 17 00:00:00 2001 From: VenelinMartinov Date: Thu, 23 May 2024 13:16:41 +0300 Subject: [PATCH] Rapid test parent name propagation (#2017) This adds parent name propagation to the rapid generated properties, so that nested properties have distinct name from their parents - they will always refer to the full lineage. --- pkg/tests/cross-tests/rapid_test.go | 4 +-- pkg/tests/cross-tests/rapid_tv_gen.go | 39 ++++++++++++++------------- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/pkg/tests/cross-tests/rapid_test.go b/pkg/tests/cross-tests/rapid_test.go index 1aa4259ca..85782bd36 100644 --- a/pkg/tests/cross-tests/rapid_test.go +++ b/pkg/tests/cross-tests/rapid_test.go @@ -39,7 +39,7 @@ func TestDiffConvergence(outerT *testing.T) { rapid.Check(outerT, func(t *rapid.T) { outerT.Logf("Iterating..") - tv := tvg.GenBlockWithDepth(3).Draw(t, "tv") + tv := tvg.GenBlockWithDepth(3, "").Draw(t, "tv") t.Logf("Schema:\n%v\n", (&prettySchemaWrapper{schema.Schema{Elem: &schema.Resource{ Schema: tv.schemaMap, @@ -75,7 +75,7 @@ func TestCreateInputsConvergence(outerT *testing.T) { rapid.Check(outerT, func(t *rapid.T) { outerT.Logf("Iterating..") depth := rapid.IntRange(1, 3).Draw(t, "schemaDepth") - tv := typedValGenerator.GenBlockWithDepth(depth).Draw(t, "tv") + tv := typedValGenerator.GenBlockWithDepth(depth, "").Draw(t, "tv") t.Logf("Schema:\n%v\n", (&prettySchemaWrapper{schema.Schema{Elem: &schema.Resource{ Schema: tv.schemaMap, diff --git a/pkg/tests/cross-tests/rapid_tv_gen.go b/pkg/tests/cross-tests/rapid_tv_gen.go index 741ff6383..083efac7e 100644 --- a/pkg/tests/cross-tests/rapid_tv_gen.go +++ b/pkg/tests/cross-tests/rapid_tv_gen.go @@ -55,10 +55,10 @@ type tvGen struct { generateConfigModeAttr bool } -func (tvg *tvGen) GenBlock() *rapid.Generator[tv] { +func (tvg *tvGen) GenBlock(parentName string) *rapid.Generator[tv] { return rapid.Custom[tv](func(t *rapid.T) tv { depth := rapid.IntRange(0, 3).Draw(t, "depth") - tv := tvg.GenBlockOrAttrWithDepth(depth).Draw(t, "tv") + tv := tvg.GenBlockOrAttrWithDepth(depth, parentName).Draw(t, "tv") return tv }) } @@ -71,15 +71,15 @@ func (tvg *tvGen) GenAttr() *rapid.Generator[tv] { }) } -func (tvg *tvGen) GenBlockOrAttrWithDepth(depth int) *rapid.Generator[tv] { +func (tvg *tvGen) GenBlockOrAttrWithDepth(depth int, parentName string) *rapid.Generator[tv] { opts := []*rapid.Generator[tv]{ tvg.GenAttrWithDepth(depth), } if depth > 1 { opts = append(opts, - tvg.GenSingleNestedBlock(depth-1), - tvg.GenListNestedBlock(depth-1), - tvg.GenSetNestedBlock(depth-1), + tvg.GenSingleNestedBlock(depth-1, parentName), + tvg.GenListNestedBlock(depth-1, parentName), + tvg.GenSetNestedBlock(depth-1, parentName), ) } return rapid.OneOf(opts...) @@ -178,15 +178,15 @@ func (tvg *tvGen) GenSetAttr(depth int) *rapid.Generator[tv] { } // TF blocks can be resource or datasource inputs, or nested blocks. -func (tvg *tvGen) GenBlockWithDepth(depth int) *rapid.Generator[tb] { +func (tvg *tvGen) GenBlockWithDepth(depth int, parentName string) *rapid.Generator[tb] { return rapid.Custom[tb](func(t *rapid.T) tb { fieldSchemas := map[string]*schema.Schema{} fieldTypes := map[string]tftypes.Type{} fieldGenerators := map[string]*rapid.Generator[tftypes.Value]{} nFields := rapid.IntRange(0, 3).Draw(t, "nFields") for i := 0; i < nFields; i++ { - fieldName := fmt.Sprintf("d%df%d", depth, i) - fieldTV := tvg.GenBlockOrAttrWithDepth(depth-1).Draw(t, fieldName) + fieldName := fmt.Sprintf("%sd%df%d", parentName, depth, i) + fieldTV := tvg.GenBlockOrAttrWithDepth(depth, fieldName).Draw(t, fieldName) fieldSchemas[fieldName] = &fieldTV.schema fieldGenerators[fieldName] = fieldTV.valueGen fieldTypes[fieldName] = fieldTV.typ @@ -218,22 +218,21 @@ func (tvg *tvGen) GenBlockWithDepth(depth int) *rapid.Generator[tb] { // are typically encoded as MaxItems=1 lists with a *Resource Elem. // // See https://developer.hashicorp.com/terraform/plugin/framework/handling-data/blocks/single-nested -func (tvg *tvGen) GenSingleNestedBlock(depth int) *rapid.Generator[tv] { - return rapid.Custom[tv](func(t *rapid.T) tv { - st := tvg.GenSchemaTransform().Draw(t, "schemaTransform") - bl := tvg.GenBlockWithDepth(depth).Draw(t, "block") +func (tvg *tvGen) GenSingleNestedBlock(depth int, parentName string) *rapid.Generator[tv] { + ge := rapid.Custom[tv](func(t *rapid.T) tv { + bl := tvg.GenBlockWithDepth(depth, parentName).Draw(t, "block") listWrapType := tftypes.List{ElementType: bl.typ} listWrap := func(v tftypes.Value) tftypes.Value { return tftypes.NewValue(listWrapType, []tftypes.Value{v}) } return tv{ - schema: st(schema.Schema{ + schema: schema.Schema{ Type: schema.TypeList, MaxItems: 1, Elem: &schema.Resource{ Schema: bl.schemaMap, }, - }), + }, typ: listWrapType, // A few open questions here, can these values ever be unknown (likely yes) and how is that // represented in TF? Also, can these values be null or this is just represented as an empty @@ -245,11 +244,13 @@ func (tvg *tvGen) GenSingleNestedBlock(depth int) *rapid.Generator[tv] { valueGen: rapid.Map(bl.valueGen, listWrap), } }) + + return tvg.WithSchemaTransform(ge) } -func (tvg *tvGen) GenListNestedBlock(depth int) *rapid.Generator[tv] { +func (tvg *tvGen) GenListNestedBlock(depth int, parentName string) *rapid.Generator[tv] { ge := rapid.Custom[tv](func(t *rapid.T) tv { - bl := tvg.GenBlockWithDepth(depth).Draw(t, "block") + bl := tvg.GenBlockWithDepth(depth, parentName).Draw(t, "block") listWrapType := tftypes.List{ElementType: bl.typ} listWrap := func(vs []tftypes.Value) tftypes.Value { return tftypes.NewValue(listWrapType, vs) @@ -280,9 +281,9 @@ func (tvg *tvGen) GenListNestedBlock(depth int) *rapid.Generator[tv] { return ge } -func (tvg *tvGen) GenSetNestedBlock(depth int) *rapid.Generator[tv] { +func (tvg *tvGen) GenSetNestedBlock(depth int, parentName string) *rapid.Generator[tv] { ge := rapid.Custom[tv](func(t *rapid.T) tv { - bl := tvg.GenBlockWithDepth(depth).Draw(t, "block") + bl := tvg.GenBlockWithDepth(depth, parentName).Draw(t, "block") setWrapType := tftypes.Set{ElementType: bl.typ} setWrap := func(vs []tftypes.Value) tftypes.Value { return tftypes.NewValue(setWrapType, vs)