github.com/opentofu/opentofu@v1.7.1/internal/configs/removed_test.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 package configs 5 6 import ( 7 "testing" 8 9 "github.com/google/go-cmp/cmp" 10 "github.com/hashicorp/hcl/v2" 11 "github.com/hashicorp/hcl/v2/hcltest" 12 "github.com/opentofu/opentofu/internal/addrs" 13 ) 14 15 func TestRemovedBlock_decode(t *testing.T) { 16 blockRange := hcl.Range{ 17 Filename: "mock.tf", 18 Start: hcl.Pos{Line: 3, Column: 12, Byte: 27}, 19 End: hcl.Pos{Line: 3, Column: 19, Byte: 34}, 20 } 21 22 foo_expr := hcltest.MockExprTraversalSrc("test_instance.foo") 23 mod_foo_expr := hcltest.MockExprTraversalSrc("module.foo") 24 foo_index_expr := hcltest.MockExprTraversalSrc("test_instance.foo[1]") 25 mod_boop_index_foo_expr := hcltest.MockExprTraversalSrc("module.boop[1].test_instance.foo") 26 data_foo_expr := hcltest.MockExprTraversalSrc("data.test_instance.foo") 27 28 tests := map[string]struct { 29 input *hcl.Block 30 want *Removed 31 err string 32 }{ 33 "success": { 34 &hcl.Block{ 35 Type: "removed", 36 Body: hcltest.MockBody(&hcl.BodyContent{ 37 Attributes: hcl.Attributes{ 38 "from": { 39 Name: "from", 40 Expr: foo_expr, 41 }, 42 }, 43 }), 44 DefRange: blockRange, 45 }, 46 &Removed{ 47 From: mustRemoveEndpointFromExpr(foo_expr), 48 DeclRange: blockRange, 49 }, 50 ``, 51 }, 52 "modules": { 53 &hcl.Block{ 54 Type: "removed", 55 Body: hcltest.MockBody(&hcl.BodyContent{ 56 Attributes: hcl.Attributes{ 57 "from": { 58 Name: "from", 59 Expr: mod_foo_expr, 60 }, 61 }, 62 }), 63 DefRange: blockRange, 64 }, 65 &Removed{ 66 From: mustRemoveEndpointFromExpr(mod_foo_expr), 67 DeclRange: blockRange, 68 }, 69 ``, 70 }, 71 "error: missing argument": { 72 &hcl.Block{ 73 Type: "removed", 74 Body: hcltest.MockBody(&hcl.BodyContent{ 75 Attributes: hcl.Attributes{}, 76 }), 77 DefRange: blockRange, 78 }, 79 &Removed{ 80 DeclRange: blockRange, 81 }, 82 "Missing required argument", 83 }, 84 "error: indexed resources": { 85 &hcl.Block{ 86 Type: "removed", 87 Body: hcltest.MockBody(&hcl.BodyContent{ 88 Attributes: hcl.Attributes{ 89 "from": { 90 Name: "from", 91 Expr: foo_index_expr, 92 }, 93 }, 94 }), 95 DefRange: blockRange, 96 }, 97 &Removed{ 98 DeclRange: blockRange, 99 }, 100 "Resource instance address with keys is not allowed", 101 }, 102 "error: indexed modules": { 103 &hcl.Block{ 104 Type: "removed", 105 Body: hcltest.MockBody(&hcl.BodyContent{ 106 Attributes: hcl.Attributes{ 107 "from": { 108 Name: "from", 109 Expr: mod_boop_index_foo_expr, 110 }, 111 }, 112 }), 113 DefRange: blockRange, 114 }, 115 &Removed{ 116 DeclRange: blockRange, 117 }, 118 "Module instance address with keys is not allowed", 119 }, 120 "error: data address": { 121 &hcl.Block{ 122 Type: "moved", 123 Body: hcltest.MockBody(&hcl.BodyContent{ 124 Attributes: hcl.Attributes{ 125 "from": { 126 Name: "from", 127 Expr: data_foo_expr, 128 }, 129 }, 130 }), 131 DefRange: blockRange, 132 }, 133 &Removed{ 134 DeclRange: blockRange, 135 }, 136 "Data source address is not allowed", 137 }, 138 } 139 140 for name, test := range tests { 141 t.Run(name, func(t *testing.T) { 142 got, diags := decodeRemovedBlock(test.input) 143 144 if diags.HasErrors() { 145 if test.err == "" { 146 t.Fatalf("unexpected error: %s", diags.Errs()) 147 } 148 if gotErr := diags[0].Summary; gotErr != test.err { 149 t.Errorf("wrong error, got %q, want %q", gotErr, test.err) 150 } 151 } else if test.err != "" { 152 t.Fatal("expected error") 153 } 154 155 if !cmp.Equal(got, test.want, cmp.AllowUnexported(addrs.MoveEndpoint{})) { 156 t.Fatalf("wrong result: %s", cmp.Diff(got, test.want)) 157 } 158 }) 159 } 160 } 161 162 func TestRemovedBlock_inModule(t *testing.T) { 163 parser := NewParser(nil) 164 mod, diags := parser.LoadConfigDir("testdata/valid-modules/removed-blocks") 165 if diags.HasErrors() { 166 t.Errorf("unexpected error: %s", diags.Error()) 167 } 168 169 var got []string 170 for _, mc := range mod.Removed { 171 got = append(got, mc.From.RelSubject.String()) 172 } 173 want := []string{ 174 `test.foo`, 175 `test.foo`, 176 `module.a`, 177 `module.a`, 178 `test.foo`, 179 `test.boop`, 180 } 181 if diff := cmp.Diff(want, got); diff != "" { 182 t.Errorf("wrong addresses\n%s", diff) 183 } 184 } 185 186 func mustRemoveEndpointFromExpr(expr hcl.Expression) *addrs.RemoveEndpoint { 187 traversal, hcldiags := hcl.AbsTraversalForExpr(expr) 188 if hcldiags.HasErrors() { 189 panic(hcldiags.Errs()) 190 } 191 192 ep, diags := addrs.ParseRemoveEndpoint(traversal) 193 if diags.HasErrors() { 194 panic(diags.Err()) 195 } 196 197 return ep 198 }