github.com/terramate-io/tf@v0.0.0-20230830114523-fce866b4dfcd/command/views/hook_count_test.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 package views 5 6 import ( 7 "reflect" 8 "testing" 9 10 "github.com/zclconf/go-cty/cty" 11 12 "github.com/terramate-io/tf/addrs" 13 "github.com/terramate-io/tf/plans" 14 "github.com/terramate-io/tf/states" 15 "github.com/terramate-io/tf/terraform" 16 17 legacy "github.com/terramate-io/tf/legacy/terraform" 18 ) 19 20 func TestCountHook_impl(t *testing.T) { 21 var _ terraform.Hook = new(countHook) 22 } 23 24 func TestCountHookPostDiff_DestroyDeposed(t *testing.T) { 25 h := new(countHook) 26 27 resources := map[string]*legacy.InstanceDiff{ 28 "lorem": &legacy.InstanceDiff{DestroyDeposed: true}, 29 } 30 31 for k := range resources { 32 addr := addrs.Resource{ 33 Mode: addrs.ManagedResourceMode, 34 Type: "test_instance", 35 Name: k, 36 }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance) 37 38 h.PostDiff(addr, states.DeposedKey("deadbeef"), plans.Delete, cty.DynamicVal, cty.DynamicVal) 39 } 40 41 expected := new(countHook) 42 expected.ToAdd = 0 43 expected.ToChange = 0 44 expected.ToRemoveAndAdd = 0 45 expected.ToRemove = 1 46 47 if !reflect.DeepEqual(expected, h) { 48 t.Fatalf("Expected %#v, got %#v instead.", expected, h) 49 } 50 } 51 52 func TestCountHookPostDiff_DestroyOnly(t *testing.T) { 53 h := new(countHook) 54 55 resources := map[string]*legacy.InstanceDiff{ 56 "foo": &legacy.InstanceDiff{Destroy: true}, 57 "bar": &legacy.InstanceDiff{Destroy: true}, 58 "lorem": &legacy.InstanceDiff{Destroy: true}, 59 "ipsum": &legacy.InstanceDiff{Destroy: true}, 60 } 61 62 for k := range resources { 63 addr := addrs.Resource{ 64 Mode: addrs.ManagedResourceMode, 65 Type: "test_instance", 66 Name: k, 67 }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance) 68 69 h.PostDiff(addr, states.CurrentGen, plans.Delete, cty.DynamicVal, cty.DynamicVal) 70 } 71 72 expected := new(countHook) 73 expected.ToAdd = 0 74 expected.ToChange = 0 75 expected.ToRemoveAndAdd = 0 76 expected.ToRemove = 4 77 78 if !reflect.DeepEqual(expected, h) { 79 t.Fatalf("Expected %#v, got %#v instead.", expected, h) 80 } 81 } 82 83 func TestCountHookPostDiff_AddOnly(t *testing.T) { 84 h := new(countHook) 85 86 resources := map[string]*legacy.InstanceDiff{ 87 "foo": &legacy.InstanceDiff{ 88 Attributes: map[string]*legacy.ResourceAttrDiff{ 89 "foo": &legacy.ResourceAttrDiff{RequiresNew: true}, 90 }, 91 }, 92 "bar": &legacy.InstanceDiff{ 93 Attributes: map[string]*legacy.ResourceAttrDiff{ 94 "foo": &legacy.ResourceAttrDiff{RequiresNew: true}, 95 }, 96 }, 97 "lorem": &legacy.InstanceDiff{ 98 Attributes: map[string]*legacy.ResourceAttrDiff{ 99 "foo": &legacy.ResourceAttrDiff{RequiresNew: true}, 100 }, 101 }, 102 } 103 104 for k := range resources { 105 addr := addrs.Resource{ 106 Mode: addrs.ManagedResourceMode, 107 Type: "test_instance", 108 Name: k, 109 }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance) 110 111 h.PostDiff(addr, states.CurrentGen, plans.Create, cty.DynamicVal, cty.DynamicVal) 112 } 113 114 expected := new(countHook) 115 expected.ToAdd = 3 116 expected.ToChange = 0 117 expected.ToRemoveAndAdd = 0 118 expected.ToRemove = 0 119 120 if !reflect.DeepEqual(expected, h) { 121 t.Fatalf("Expected %#v, got %#v instead.", expected, h) 122 } 123 } 124 125 func TestCountHookPostDiff_ChangeOnly(t *testing.T) { 126 h := new(countHook) 127 128 resources := map[string]*legacy.InstanceDiff{ 129 "foo": &legacy.InstanceDiff{ 130 Destroy: false, 131 Attributes: map[string]*legacy.ResourceAttrDiff{ 132 "foo": &legacy.ResourceAttrDiff{}, 133 }, 134 }, 135 "bar": &legacy.InstanceDiff{ 136 Destroy: false, 137 Attributes: map[string]*legacy.ResourceAttrDiff{ 138 "foo": &legacy.ResourceAttrDiff{}, 139 }, 140 }, 141 "lorem": &legacy.InstanceDiff{ 142 Destroy: false, 143 Attributes: map[string]*legacy.ResourceAttrDiff{ 144 "foo": &legacy.ResourceAttrDiff{}, 145 }, 146 }, 147 } 148 149 for k := range resources { 150 addr := addrs.Resource{ 151 Mode: addrs.ManagedResourceMode, 152 Type: "test_instance", 153 Name: k, 154 }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance) 155 156 h.PostDiff(addr, states.CurrentGen, plans.Update, cty.DynamicVal, cty.DynamicVal) 157 } 158 159 expected := new(countHook) 160 expected.ToAdd = 0 161 expected.ToChange = 3 162 expected.ToRemoveAndAdd = 0 163 expected.ToRemove = 0 164 165 if !reflect.DeepEqual(expected, h) { 166 t.Fatalf("Expected %#v, got %#v instead.", expected, h) 167 } 168 } 169 170 func TestCountHookPostDiff_Mixed(t *testing.T) { 171 h := new(countHook) 172 173 resources := map[string]plans.Action{ 174 "foo": plans.Delete, 175 "bar": plans.NoOp, 176 "lorem": plans.Update, 177 "ipsum": plans.Delete, 178 } 179 180 for k, a := range resources { 181 addr := addrs.Resource{ 182 Mode: addrs.ManagedResourceMode, 183 Type: "test_instance", 184 Name: k, 185 }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance) 186 187 h.PostDiff(addr, states.CurrentGen, a, cty.DynamicVal, cty.DynamicVal) 188 } 189 190 expected := new(countHook) 191 expected.ToAdd = 0 192 expected.ToChange = 1 193 expected.ToRemoveAndAdd = 0 194 expected.ToRemove = 2 195 196 if !reflect.DeepEqual(expected, h) { 197 t.Fatalf("Expected %#v, got %#v instead.", 198 expected, h) 199 } 200 } 201 202 func TestCountHookPostDiff_NoChange(t *testing.T) { 203 h := new(countHook) 204 205 resources := map[string]*legacy.InstanceDiff{ 206 "foo": &legacy.InstanceDiff{}, 207 "bar": &legacy.InstanceDiff{}, 208 "lorem": &legacy.InstanceDiff{}, 209 "ipsum": &legacy.InstanceDiff{}, 210 } 211 212 for k := range resources { 213 addr := addrs.Resource{ 214 Mode: addrs.ManagedResourceMode, 215 Type: "test_instance", 216 Name: k, 217 }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance) 218 219 h.PostDiff(addr, states.CurrentGen, plans.NoOp, cty.DynamicVal, cty.DynamicVal) 220 } 221 222 expected := new(countHook) 223 expected.ToAdd = 0 224 expected.ToChange = 0 225 expected.ToRemoveAndAdd = 0 226 expected.ToRemove = 0 227 228 if !reflect.DeepEqual(expected, h) { 229 t.Fatalf("Expected %#v, got %#v instead.", 230 expected, h) 231 } 232 } 233 234 func TestCountHookPostDiff_DataSource(t *testing.T) { 235 h := new(countHook) 236 237 resources := map[string]plans.Action{ 238 "foo": plans.Delete, 239 "bar": plans.NoOp, 240 "lorem": plans.Update, 241 "ipsum": plans.Delete, 242 } 243 244 for k, a := range resources { 245 addr := addrs.Resource{ 246 Mode: addrs.DataResourceMode, 247 Type: "test_instance", 248 Name: k, 249 }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance) 250 251 h.PostDiff(addr, states.CurrentGen, a, cty.DynamicVal, cty.DynamicVal) 252 } 253 254 expected := new(countHook) 255 expected.ToAdd = 0 256 expected.ToChange = 0 257 expected.ToRemoveAndAdd = 0 258 expected.ToRemove = 0 259 260 if !reflect.DeepEqual(expected, h) { 261 t.Fatalf("Expected %#v, got %#v instead.", 262 expected, h) 263 } 264 } 265 266 func TestCountHookApply_ChangeOnly(t *testing.T) { 267 h := new(countHook) 268 269 resources := map[string]*legacy.InstanceDiff{ 270 "foo": &legacy.InstanceDiff{ 271 Destroy: false, 272 Attributes: map[string]*legacy.ResourceAttrDiff{ 273 "foo": &legacy.ResourceAttrDiff{}, 274 }, 275 }, 276 "bar": &legacy.InstanceDiff{ 277 Destroy: false, 278 Attributes: map[string]*legacy.ResourceAttrDiff{ 279 "foo": &legacy.ResourceAttrDiff{}, 280 }, 281 }, 282 "lorem": &legacy.InstanceDiff{ 283 Destroy: false, 284 Attributes: map[string]*legacy.ResourceAttrDiff{ 285 "foo": &legacy.ResourceAttrDiff{}, 286 }, 287 }, 288 } 289 290 for k := range resources { 291 addr := addrs.Resource{ 292 Mode: addrs.ManagedResourceMode, 293 Type: "test_instance", 294 Name: k, 295 }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance) 296 297 h.PreApply(addr, states.CurrentGen, plans.Update, cty.DynamicVal, cty.DynamicVal) 298 h.PostApply(addr, states.CurrentGen, cty.DynamicVal, nil) 299 } 300 301 expected := &countHook{pending: make(map[string]plans.Action)} 302 expected.Added = 0 303 expected.Changed = 3 304 expected.Removed = 0 305 306 if !reflect.DeepEqual(expected, h) { 307 t.Fatalf("Expected:\n%#v\nGot:\n%#v\n", expected, h) 308 } 309 } 310 311 func TestCountHookApply_DestroyOnly(t *testing.T) { 312 h := new(countHook) 313 314 resources := map[string]*legacy.InstanceDiff{ 315 "foo": &legacy.InstanceDiff{Destroy: true}, 316 "bar": &legacy.InstanceDiff{Destroy: true}, 317 "lorem": &legacy.InstanceDiff{Destroy: true}, 318 "ipsum": &legacy.InstanceDiff{Destroy: true}, 319 } 320 321 for k := range resources { 322 addr := addrs.Resource{ 323 Mode: addrs.ManagedResourceMode, 324 Type: "test_instance", 325 Name: k, 326 }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance) 327 328 h.PreApply(addr, states.CurrentGen, plans.Delete, cty.DynamicVal, cty.DynamicVal) 329 h.PostApply(addr, states.CurrentGen, cty.DynamicVal, nil) 330 } 331 332 expected := &countHook{pending: make(map[string]plans.Action)} 333 expected.Added = 0 334 expected.Changed = 0 335 expected.Removed = 4 336 337 if !reflect.DeepEqual(expected, h) { 338 t.Fatalf("Expected:\n%#v\nGot:\n%#v\n", expected, h) 339 } 340 }