kubeform.dev/terraform-backend-sdk@v0.0.0-20220310143633-45f07fe731c5/terraform/evaluate_valid_test.go (about)

     1  package terraform
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/hashicorp/hcl/v2"
     7  	"github.com/hashicorp/hcl/v2/hclsyntax"
     8  
     9  	"kubeform.dev/terraform-backend-sdk/addrs"
    10  	"kubeform.dev/terraform-backend-sdk/configs/configschema"
    11  	"kubeform.dev/terraform-backend-sdk/lang"
    12  )
    13  
    14  func TestStaticValidateReferences(t *testing.T) {
    15  	tests := []struct {
    16  		Ref     string
    17  		WantErr string
    18  	}{
    19  		{
    20  			"aws_instance.no_count",
    21  			``,
    22  		},
    23  		{
    24  			"aws_instance.count",
    25  			``,
    26  		},
    27  		{
    28  			"aws_instance.count[0]",
    29  			``,
    30  		},
    31  		{
    32  			"aws_instance.nonexist",
    33  			`Reference to undeclared resource: A managed resource "aws_instance" "nonexist" has not been declared in the root module.`,
    34  		},
    35  		{
    36  			"beep.boop",
    37  			`Reference to undeclared resource: A managed resource "beep" "boop" has not been declared in the root module.
    38  
    39  Did you mean the data resource data.beep.boop?`,
    40  		},
    41  		{
    42  			"aws_instance.no_count[0]",
    43  			`Unexpected resource instance key: Because aws_instance.no_count does not have "count" or "for_each" set, references to it must not include an index key. Remove the bracketed index to refer to the single instance of this resource.`,
    44  		},
    45  		{
    46  			"aws_instance.count.foo",
    47  			// In this case we return two errors that are somewhat redundant with
    48  			// one another, but we'll accept that because they both report the
    49  			// problem from different perspectives and so give the user more
    50  			// opportunity to understand what's going on here.
    51  			`2 problems:
    52  
    53  - Missing resource instance key: Because aws_instance.count has "count" set, its attributes must be accessed on specific instances.
    54  
    55  For example, to correlate with indices of a referring resource, use:
    56      aws_instance.count[count.index]
    57  - Unsupported attribute: This object has no argument, nested block, or exported attribute named "foo".`,
    58  		},
    59  		{
    60  			"boop_instance.yep",
    61  			``,
    62  		},
    63  		{
    64  			"boop_whatever.nope",
    65  			`Invalid resource type: A managed resource type "boop_whatever" is not supported by provider "registry.terraform.io/foobar/beep".`,
    66  		},
    67  	}
    68  
    69  	cfg := testModule(t, "static-validate-refs")
    70  	evaluator := &Evaluator{
    71  		Config: cfg,
    72  		Plugins: schemaOnlyProvidersForTesting(map[addrs.Provider]*ProviderSchema{
    73  			addrs.NewDefaultProvider("aws"): {
    74  				ResourceTypes: map[string]*configschema.Block{
    75  					"aws_instance": {},
    76  				},
    77  			},
    78  			addrs.MustParseProviderSourceString("foobar/beep"): {
    79  				ResourceTypes: map[string]*configschema.Block{
    80  					// intentional mismatch between resource type prefix and provider type
    81  					"boop_instance": {},
    82  				},
    83  			},
    84  		}),
    85  	}
    86  
    87  	for _, test := range tests {
    88  		t.Run(test.Ref, func(t *testing.T) {
    89  			traversal, hclDiags := hclsyntax.ParseTraversalAbs([]byte(test.Ref), "", hcl.Pos{Line: 1, Column: 1})
    90  			if hclDiags.HasErrors() {
    91  				t.Fatal(hclDiags.Error())
    92  			}
    93  
    94  			refs, diags := lang.References([]hcl.Traversal{traversal})
    95  			if diags.HasErrors() {
    96  				t.Fatal(diags.Err())
    97  			}
    98  
    99  			data := &evaluationStateData{
   100  				Evaluator: evaluator,
   101  			}
   102  
   103  			diags = data.StaticValidateReferences(refs, nil)
   104  			if diags.HasErrors() {
   105  				if test.WantErr == "" {
   106  					t.Fatalf("Unexpected diagnostics: %s", diags.Err())
   107  				}
   108  
   109  				gotErr := diags.Err().Error()
   110  				if gotErr != test.WantErr {
   111  					t.Fatalf("Wrong diagnostics\ngot:  %s\nwant: %s", gotErr, test.WantErr)
   112  				}
   113  				return
   114  			}
   115  
   116  			if test.WantErr != "" {
   117  				t.Fatalf("Expected diagnostics, but got none\nwant: %s", test.WantErr)
   118  			}
   119  		})
   120  	}
   121  }