github.com/opentofu/opentofu@v1.7.1/internal/instances/set_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 instances 7 8 import ( 9 "testing" 10 11 "github.com/opentofu/opentofu/internal/addrs" 12 "github.com/zclconf/go-cty/cty" 13 ) 14 15 func TestSet(t *testing.T) { 16 exp := NewExpander() 17 18 // The following constructs the following imaginary module/resource tree: 19 // - root module 20 // - test_thing.single: no repetition 21 // - test_thing.count: count = 1 22 // - test_thing.for_each: for_each = { c = "C" } 23 // - module.single: no repetition 24 // - test_thing.single: no repetition 25 // - module.nested_single: no repetition 26 // - module.zero_count: count = 0 27 // - module.count: count = 2 28 // - module.nested_for_each: [0] for_each = {}, [1] for_each = { e = "E" } 29 // - module.for_each: for_each = { a = "A", b = "B" } 30 // - test_thing.count: ["a"] count = 0, ["b"] count = 1 31 exp.SetModuleSingle(addrs.RootModuleInstance, addrs.ModuleCall{Name: "single"}) 32 exp.SetModuleCount(addrs.RootModuleInstance, addrs.ModuleCall{Name: "count"}, 2) 33 exp.SetModuleForEach(addrs.RootModuleInstance, addrs.ModuleCall{Name: "for_each"}, map[string]cty.Value{ 34 "a": cty.StringVal("A"), 35 "b": cty.StringVal("B"), 36 }) 37 exp.SetModuleSingle(addrs.RootModuleInstance.Child("single", addrs.NoKey), addrs.ModuleCall{Name: "nested_single"}) 38 exp.SetModuleForEach(addrs.RootModuleInstance.Child("count", addrs.IntKey(0)), addrs.ModuleCall{Name: "nested_for_each"}, nil) 39 exp.SetModuleForEach(addrs.RootModuleInstance.Child("count", addrs.IntKey(1)), addrs.ModuleCall{Name: "nested_for_each"}, map[string]cty.Value{ 40 "e": cty.StringVal("E"), 41 }) 42 exp.SetModuleCount( 43 addrs.RootModuleInstance.Child("single", addrs.NoKey).Child("nested_single", addrs.NoKey), 44 addrs.ModuleCall{Name: "zero_count"}, 45 0, 46 ) 47 48 rAddr := func(name string) addrs.Resource { 49 return addrs.Resource{ 50 Mode: addrs.ManagedResourceMode, 51 Type: "test_thing", 52 Name: name, 53 } 54 } 55 exp.SetResourceSingle(addrs.RootModuleInstance, rAddr("single")) 56 exp.SetResourceCount(addrs.RootModuleInstance, rAddr("count"), 1) 57 exp.SetResourceForEach(addrs.RootModuleInstance, rAddr("for_each"), map[string]cty.Value{ 58 "c": cty.StringVal("C"), 59 }) 60 exp.SetResourceSingle(addrs.RootModuleInstance.Child("single", addrs.NoKey), rAddr("single")) 61 exp.SetResourceCount(addrs.RootModuleInstance.Child("for_each", addrs.StringKey("a")), rAddr("count"), 0) 62 exp.SetResourceCount(addrs.RootModuleInstance.Child("for_each", addrs.StringKey("b")), rAddr("count"), 1) 63 64 set := exp.AllInstances() 65 66 // HasModuleInstance tests 67 if input := addrs.RootModuleInstance; !set.HasModuleInstance(input) { 68 t.Errorf("missing %T %s", input, input.String()) 69 } 70 if input := addrs.RootModuleInstance.Child("single", addrs.NoKey); !set.HasModuleInstance(input) { 71 t.Errorf("missing %T %s", input, input.String()) 72 } 73 if input := addrs.RootModuleInstance.Child("single", addrs.NoKey).Child("nested_single", addrs.NoKey); !set.HasModuleInstance(input) { 74 t.Errorf("missing %T %s", input, input.String()) 75 } 76 if input := addrs.RootModuleInstance.Child("count", addrs.IntKey(0)); !set.HasModuleInstance(input) { 77 t.Errorf("missing %T %s", input, input.String()) 78 } 79 if input := addrs.RootModuleInstance.Child("count", addrs.IntKey(1)); !set.HasModuleInstance(input) { 80 t.Errorf("missing %T %s", input, input.String()) 81 } 82 if input := addrs.RootModuleInstance.Child("count", addrs.IntKey(1)).Child("nested_for_each", addrs.StringKey("e")); !set.HasModuleInstance(input) { 83 t.Errorf("missing %T %s", input, input.String()) 84 } 85 if input := addrs.RootModuleInstance.Child("for_each", addrs.StringKey("a")); !set.HasModuleInstance(input) { 86 t.Errorf("missing %T %s", input, input.String()) 87 } 88 if input := addrs.RootModuleInstance.Child("for_each", addrs.StringKey("b")); !set.HasModuleInstance(input) { 89 t.Errorf("missing %T %s", input, input.String()) 90 } 91 if input := addrs.RootModuleInstance.Child("single", addrs.IntKey(0)); set.HasModuleInstance(input) { 92 t.Errorf("unexpected %T %s", input, input.String()) 93 } 94 if input := addrs.RootModuleInstance.Child("single", addrs.StringKey("a")); set.HasModuleInstance(input) { 95 t.Errorf("unexpected %T %s", input, input.String()) 96 } 97 if input := addrs.RootModuleInstance.Child("single", addrs.NoKey).Child("nonexist", addrs.NoKey); set.HasModuleInstance(input) { 98 t.Errorf("unexpected %T %s", input, input.String()) 99 } 100 if input := addrs.RootModuleInstance.Child("count", addrs.NoKey); set.HasModuleInstance(input) { 101 t.Errorf("unexpected %T %s", input, input.String()) 102 } 103 if input := addrs.RootModuleInstance.Child("count", addrs.IntKey(2)); set.HasModuleInstance(input) { 104 t.Errorf("unexpected %T %s", input, input.String()) 105 } 106 if input := addrs.RootModuleInstance.Child("count", addrs.StringKey("a")); set.HasModuleInstance(input) { 107 t.Errorf("unexpected %T %s", input, input.String()) 108 } 109 if input := addrs.RootModuleInstance.Child("count", addrs.IntKey(0)).Child("nested_for_each", addrs.StringKey("e")); set.HasModuleInstance(input) { 110 t.Errorf("unexpected %T %s", input, input.String()) 111 } 112 if input := addrs.RootModuleInstance.Child("single", addrs.NoKey).Child("nested_single", addrs.NoKey).Child("zero_count", addrs.NoKey); set.HasModuleInstance(input) { 113 t.Errorf("unexpected %T %s", input, input.String()) 114 } 115 if input := addrs.RootModuleInstance.Child("single", addrs.NoKey).Child("nested_single", addrs.NoKey).Child("zero_count", addrs.IntKey(0)); set.HasModuleInstance(input) { 116 t.Errorf("unexpected %T %s", input, input.String()) 117 } 118 119 // HasModuleCall tests 120 if input := addrs.RootModuleInstance.ChildCall("single"); !set.HasModuleCall(input) { 121 t.Errorf("missing %T %s", input, input.String()) 122 } 123 if input := addrs.RootModuleInstance.Child("single", addrs.NoKey).ChildCall("nested_single"); !set.HasModuleCall(input) { 124 t.Errorf("missing %T %s", input, input.String()) 125 } 126 if input := addrs.RootModuleInstance.ChildCall("count"); !set.HasModuleCall(input) { 127 t.Errorf("missing %T %s", input, input.String()) 128 } 129 if input := addrs.RootModuleInstance.Child("count", addrs.IntKey(0)).ChildCall("nested_for_each"); !set.HasModuleCall(input) { 130 t.Errorf("missing %T %s", input, input.String()) 131 } 132 if input := addrs.RootModuleInstance.Child("count", addrs.IntKey(1)).ChildCall("nested_for_each"); !set.HasModuleCall(input) { 133 t.Errorf("missing %T %s", input, input.String()) 134 } 135 if input := addrs.RootModuleInstance.ChildCall("for_each"); !set.HasModuleCall(input) { 136 t.Errorf("missing %T %s", input, input.String()) 137 } 138 if input := addrs.RootModuleInstance.Child("single", addrs.NoKey).Child("nested_single", addrs.NoKey).ChildCall("zero_count"); !set.HasModuleCall(input) { 139 t.Errorf("missing %T %s", input, input.String()) 140 } 141 if input := addrs.RootModuleInstance.ChildCall("nonexist"); set.HasModuleCall(input) { 142 t.Errorf("unexpected %T %s", input, input.String()) 143 } 144 if input := addrs.RootModuleInstance.Child("single", addrs.NoKey).ChildCall("nonexist"); set.HasModuleCall(input) { 145 t.Errorf("unexpected %T %s", input, input.String()) 146 } 147 148 // HasResourceInstance tests 149 if input := rAddr("single").Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance); !set.HasResourceInstance(input) { 150 t.Errorf("missing %T %s", input, input.String()) 151 } 152 if input := rAddr("count").Instance(addrs.IntKey(0)).Absolute(addrs.RootModuleInstance); !set.HasResourceInstance(input) { 153 t.Errorf("missing %T %s", input, input.String()) 154 } 155 if input := rAddr("for_each").Instance(addrs.StringKey("c")).Absolute(addrs.RootModuleInstance); !set.HasResourceInstance(input) { 156 t.Errorf("missing %T %s", input, input.String()) 157 } 158 if input := rAddr("single").Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance.Child("single", addrs.NoKey)); !set.HasResourceInstance(input) { 159 t.Errorf("missing %T %s", input, input.String()) 160 } 161 if input := rAddr("count").Instance(addrs.IntKey(0)).Absolute(addrs.RootModuleInstance.Child("for_each", addrs.StringKey("b"))); !set.HasResourceInstance(input) { 162 t.Errorf("missing %T %s", input, input.String()) 163 } 164 if input := rAddr("single").Instance(addrs.IntKey(0)).Absolute(addrs.RootModuleInstance); set.HasResourceInstance(input) { 165 t.Errorf("unexpected %T %s", input, input.String()) 166 } 167 if input := rAddr("single").Instance(addrs.StringKey("")).Absolute(addrs.RootModuleInstance); set.HasResourceInstance(input) { 168 t.Errorf("unexpected %T %s", input, input.String()) 169 } 170 if input := rAddr("count").Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance); set.HasResourceInstance(input) { 171 t.Errorf("unexpected %T %s", input, input.String()) 172 } 173 if input := rAddr("count").Instance(addrs.StringKey("")).Absolute(addrs.RootModuleInstance); set.HasResourceInstance(input) { 174 t.Errorf("unexpected %T %s", input, input.String()) 175 } 176 if input := rAddr("count").Instance(addrs.IntKey(1)).Absolute(addrs.RootModuleInstance); set.HasResourceInstance(input) { 177 t.Errorf("unexpected %T %s", input, input.String()) 178 } 179 if input := rAddr("single").Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance.Child("single", addrs.IntKey(0))); set.HasResourceInstance(input) { 180 t.Errorf("unexpected %T %s", input, input.String()) 181 } 182 if input := rAddr("count").Instance(addrs.IntKey(0)).Absolute(addrs.RootModuleInstance.Child("for_each", addrs.StringKey("a"))); set.HasResourceInstance(input) { 183 t.Errorf("unexpected %T %s", input, input.String()) 184 } 185 186 // HasResource tests 187 if input := rAddr("single").Absolute(addrs.RootModuleInstance); !set.HasResource(input) { 188 t.Errorf("missing %T %s", input, input.String()) 189 } 190 if input := rAddr("count").Absolute(addrs.RootModuleInstance); !set.HasResource(input) { 191 t.Errorf("missing %T %s", input, input.String()) 192 } 193 if input := rAddr("for_each").Absolute(addrs.RootModuleInstance); !set.HasResource(input) { 194 t.Errorf("missing %T %s", input, input.String()) 195 } 196 if input := rAddr("single").Absolute(addrs.RootModuleInstance.Child("single", addrs.NoKey)); !set.HasResource(input) { 197 t.Errorf("missing %T %s", input, input.String()) 198 } 199 if input := rAddr("count").Absolute(addrs.RootModuleInstance.Child("for_each", addrs.StringKey("a"))); !set.HasResource(input) { 200 t.Errorf("missing %T %s", input, input.String()) 201 } 202 if input := rAddr("count").Absolute(addrs.RootModuleInstance.Child("for_each", addrs.StringKey("b"))); !set.HasResource(input) { 203 t.Errorf("missing %T %s", input, input.String()) 204 } 205 if input := rAddr("nonexist").Absolute(addrs.RootModuleInstance); set.HasResource(input) { 206 t.Errorf("unexpected %T %s", input, input.String()) 207 } 208 if input := rAddr("count").Absolute(addrs.RootModuleInstance.Child("for_each", addrs.StringKey("nonexist"))); set.HasResource(input) { 209 t.Errorf("unexpected %T %s", input, input.String()) 210 } 211 212 // ensure we can lookup non-existent addrs in a set without panic 213 if set.InstancesForModule(addrs.RootModule.Child("missing")) != nil { 214 t.Error("unexpected instances from missing module") 215 } 216 }