github.com/opentofu/opentofu@v1.7.1/internal/lang/blocktoattr/fixup_bench_test.go (about)

     1  // Copyright (c) The OpenTofu Authors
     2  // SPDX-License-Identifier: MPL-2.0
     3  // Copyright (c) 2023 HashiCorp, Inc.
     4  // SPDX-License-Identifier: MPL-2.0
     5  
     6  package blocktoattr
     7  
     8  import (
     9  	"testing"
    10  
    11  	"github.com/hashicorp/hcl/v2"
    12  	"github.com/hashicorp/hcl/v2/hcldec"
    13  	"github.com/hashicorp/hcl/v2/hclsyntax"
    14  	"github.com/opentofu/opentofu/internal/configs/configschema"
    15  	"github.com/zclconf/go-cty/cty"
    16  )
    17  
    18  func ambiguousNestedBlock(nesting int) *configschema.NestedBlock {
    19  	ret := &configschema.NestedBlock{
    20  		Nesting: configschema.NestingList,
    21  		Block: configschema.Block{
    22  			Attributes: map[string]*configschema.Attribute{
    23  				"a": {Type: cty.String, Required: true},
    24  				"b": {Type: cty.String, Optional: true},
    25  			},
    26  		},
    27  	}
    28  	if nesting > 0 {
    29  		ret.BlockTypes = map[string]*configschema.NestedBlock{
    30  			"nested0": ambiguousNestedBlock(nesting - 1),
    31  			"nested1": ambiguousNestedBlock(nesting - 1),
    32  			"nested2": ambiguousNestedBlock(nesting - 1),
    33  			"nested3": ambiguousNestedBlock(nesting - 1),
    34  			"nested4": ambiguousNestedBlock(nesting - 1),
    35  			"nested5": ambiguousNestedBlock(nesting - 1),
    36  			"nested6": ambiguousNestedBlock(nesting - 1),
    37  			"nested7": ambiguousNestedBlock(nesting - 1),
    38  			"nested8": ambiguousNestedBlock(nesting - 1),
    39  			"nested9": ambiguousNestedBlock(nesting - 1),
    40  		}
    41  	}
    42  	return ret
    43  }
    44  
    45  func schemaWithAmbiguousNestedBlock(nesting int) *configschema.Block {
    46  	return &configschema.Block{
    47  		BlockTypes: map[string]*configschema.NestedBlock{
    48  			"maybe_block": ambiguousNestedBlock(nesting),
    49  		},
    50  	}
    51  }
    52  
    53  const configForFixupBlockAttrsBenchmark = `
    54  maybe_block {
    55    a = "hello"
    56    b = "world"
    57    nested0 {
    58      a = "the"
    59      nested1 {
    60  	  a = "deeper"
    61        nested2 {
    62          a = "we"
    63          nested3 {
    64            a = "go"
    65            b = "inside"
    66          }
    67        }
    68      }
    69    }
    70  }
    71  `
    72  
    73  func configBodyForFixupBlockAttrsBenchmark() hcl.Body {
    74  	f, diags := hclsyntax.ParseConfig([]byte(configForFixupBlockAttrsBenchmark), "", hcl.Pos{Line: 1, Column: 1})
    75  	if diags.HasErrors() {
    76  		panic("test configuration is invalid")
    77  	}
    78  	return f.Body
    79  }
    80  
    81  func BenchmarkFixUpBlockAttrs(b *testing.B) {
    82  	for i := 0; i < b.N; i++ {
    83  		b.StopTimer()
    84  		body := configBodyForFixupBlockAttrsBenchmark()
    85  		schema := schemaWithAmbiguousNestedBlock(5)
    86  		b.StartTimer()
    87  
    88  		spec := schema.DecoderSpec()
    89  		fixedBody := FixUpBlockAttrs(body, schema)
    90  		val, diags := hcldec.Decode(fixedBody, spec, nil)
    91  		if diags.HasErrors() {
    92  			b.Fatal("diagnostics during decoding", diags)
    93  		}
    94  		if !val.Type().IsObjectType() {
    95  			b.Fatal("result is not an object")
    96  		}
    97  		blockVal := val.GetAttr("maybe_block")
    98  		if !blockVal.Type().IsListType() || blockVal.LengthInt() != 1 {
    99  			b.Fatal("result has wrong value for 'maybe_block'")
   100  		}
   101  	}
   102  }