github.com/opentofu/opentofu@v1.7.1/internal/tofu/validate_selfref_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 tofu
     7  
     8  import (
     9  	"fmt"
    10  	"testing"
    11  
    12  	"github.com/opentofu/opentofu/internal/configs/configschema"
    13  	"github.com/opentofu/opentofu/internal/providers"
    14  
    15  	"github.com/hashicorp/hcl/v2"
    16  	"github.com/hashicorp/hcl/v2/hcltest"
    17  	"github.com/opentofu/opentofu/internal/addrs"
    18  	"github.com/zclconf/go-cty/cty"
    19  )
    20  
    21  func TestValidateSelfRef(t *testing.T) {
    22  	rAddr := addrs.Resource{
    23  		Mode: addrs.ManagedResourceMode,
    24  		Type: "aws_instance",
    25  		Name: "foo",
    26  	}
    27  
    28  	tests := []struct {
    29  		Name string
    30  		Addr addrs.Referenceable
    31  		Expr hcl.Expression
    32  		Err  bool
    33  	}{
    34  		{
    35  			"no references at all",
    36  			rAddr,
    37  			hcltest.MockExprLiteral(cty.StringVal("bar")),
    38  			false,
    39  		},
    40  
    41  		{
    42  			"non self reference",
    43  			rAddr,
    44  			hcltest.MockExprTraversalSrc("aws_instance.bar.id"),
    45  			false,
    46  		},
    47  
    48  		{
    49  			"self reference",
    50  			rAddr,
    51  			hcltest.MockExprTraversalSrc("aws_instance.foo.id"),
    52  			true,
    53  		},
    54  
    55  		{
    56  			"self reference other index",
    57  			rAddr,
    58  			hcltest.MockExprTraversalSrc("aws_instance.foo[4].id"),
    59  			false,
    60  		},
    61  
    62  		{
    63  			"self reference same index",
    64  			rAddr.Instance(addrs.IntKey(4)),
    65  			hcltest.MockExprTraversalSrc("aws_instance.foo[4].id"),
    66  			true,
    67  		},
    68  
    69  		{
    70  			"self reference whole",
    71  			rAddr.Instance(addrs.IntKey(4)),
    72  			hcltest.MockExprTraversalSrc("aws_instance.foo"),
    73  			true,
    74  		},
    75  	}
    76  
    77  	for i, test := range tests {
    78  		t.Run(fmt.Sprintf("%d-%s", i, test.Name), func(t *testing.T) {
    79  			body := hcltest.MockBody(&hcl.BodyContent{
    80  				Attributes: hcl.Attributes{
    81  					"foo": {
    82  						Name: "foo",
    83  						Expr: test.Expr,
    84  					},
    85  				},
    86  			})
    87  
    88  			ps := providers.ProviderSchema{
    89  				ResourceTypes: map[string]providers.Schema{
    90  					"aws_instance": {
    91  						Block: &configschema.Block{
    92  							Attributes: map[string]*configschema.Attribute{
    93  								"foo": {
    94  									Type:     cty.String,
    95  									Required: true,
    96  								},
    97  							},
    98  						},
    99  					},
   100  				},
   101  			}
   102  
   103  			diags := validateSelfRef(test.Addr, body, ps)
   104  			if diags.HasErrors() != test.Err {
   105  				if test.Err {
   106  					t.Errorf("unexpected success; want error")
   107  				} else {
   108  					t.Errorf("unexpected error\n\n%s", diags.Err())
   109  				}
   110  			}
   111  		})
   112  	}
   113  }