github.com/muratcelep/terraform@v1.1.0-beta2-not-internal-4/not-internal/terraform/transform_orphan_resource_test.go (about) 1 package terraform 2 3 import ( 4 "fmt" 5 "strings" 6 "testing" 7 8 "github.com/muratcelep/terraform/not-internal/addrs" 9 "github.com/muratcelep/terraform/not-internal/dag" 10 "github.com/muratcelep/terraform/not-internal/states" 11 ) 12 13 func TestOrphanResourceInstanceTransformer(t *testing.T) { 14 mod := testModule(t, "transform-orphan-basic") 15 16 state := states.BuildState(func(s *states.SyncState) { 17 s.SetResourceInstanceCurrent( 18 addrs.Resource{ 19 Mode: addrs.ManagedResourceMode, 20 Type: "aws_instance", 21 Name: "web", 22 }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance), 23 &states.ResourceInstanceObjectSrc{ 24 AttrsFlat: map[string]string{ 25 "id": "foo", 26 }, 27 Status: states.ObjectReady, 28 }, 29 addrs.AbsProviderConfig{ 30 Provider: addrs.NewDefaultProvider("aws"), 31 Module: addrs.RootModule, 32 }, 33 ) 34 35 // The orphan 36 s.SetResourceInstanceCurrent( 37 addrs.Resource{ 38 Mode: addrs.ManagedResourceMode, 39 Type: "aws_instance", 40 Name: "db", 41 }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance), 42 &states.ResourceInstanceObjectSrc{ 43 AttrsFlat: map[string]string{ 44 "id": "foo", 45 }, 46 Status: states.ObjectReady, 47 }, 48 addrs.AbsProviderConfig{ 49 Provider: addrs.NewDefaultProvider("aws"), 50 Module: addrs.RootModule, 51 }, 52 ) 53 54 // A deposed orphan should not be handled by this transformer 55 s.SetResourceInstanceDeposed( 56 addrs.Resource{ 57 Mode: addrs.ManagedResourceMode, 58 Type: "test_instance", 59 Name: "deposed", 60 }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance), 61 states.NewDeposedKey(), 62 &states.ResourceInstanceObjectSrc{ 63 AttrsFlat: map[string]string{ 64 "id": "foo", 65 }, 66 Status: states.ObjectReady, 67 }, 68 addrs.AbsProviderConfig{ 69 Provider: addrs.NewDefaultProvider("test"), 70 Module: addrs.RootModule, 71 }, 72 ) 73 }) 74 75 g := Graph{Path: addrs.RootModuleInstance} 76 { 77 tf := &ConfigTransformer{Config: mod} 78 if err := tf.Transform(&g); err != nil { 79 t.Fatalf("err: %s", err) 80 } 81 } 82 83 { 84 tf := &OrphanResourceInstanceTransformer{ 85 Concrete: testOrphanResourceConcreteFunc, 86 State: state, 87 Config: mod, 88 } 89 if err := tf.Transform(&g); err != nil { 90 t.Fatalf("err: %s", err) 91 } 92 } 93 94 actual := strings.TrimSpace(g.String()) 95 expected := strings.TrimSpace(testTransformOrphanResourceBasicStr) 96 if actual != expected { 97 t.Fatalf("bad:\n\n%s", actual) 98 } 99 } 100 101 func TestOrphanResourceInstanceTransformer_countGood(t *testing.T) { 102 mod := testModule(t, "transform-orphan-count") 103 104 state := states.BuildState(func(s *states.SyncState) { 105 s.SetResourceInstanceCurrent( 106 addrs.Resource{ 107 Mode: addrs.ManagedResourceMode, 108 Type: "aws_instance", 109 Name: "foo", 110 }.Instance(addrs.IntKey(0)).Absolute(addrs.RootModuleInstance), 111 &states.ResourceInstanceObjectSrc{ 112 AttrsFlat: map[string]string{ 113 "id": "foo", 114 }, 115 Status: states.ObjectReady, 116 }, 117 addrs.AbsProviderConfig{ 118 Provider: addrs.NewDefaultProvider("aws"), 119 Module: addrs.RootModule, 120 }, 121 ) 122 s.SetResourceInstanceCurrent( 123 addrs.Resource{ 124 Mode: addrs.ManagedResourceMode, 125 Type: "aws_instance", 126 Name: "foo", 127 }.Instance(addrs.IntKey(1)).Absolute(addrs.RootModuleInstance), 128 &states.ResourceInstanceObjectSrc{ 129 AttrsFlat: map[string]string{ 130 "id": "foo", 131 }, 132 Status: states.ObjectReady, 133 }, 134 addrs.AbsProviderConfig{ 135 Provider: addrs.NewDefaultProvider("aws"), 136 Module: addrs.RootModule, 137 }, 138 ) 139 }) 140 141 g := Graph{Path: addrs.RootModuleInstance} 142 { 143 tf := &ConfigTransformer{Config: mod} 144 if err := tf.Transform(&g); err != nil { 145 t.Fatalf("err: %s", err) 146 } 147 } 148 149 { 150 tf := &OrphanResourceInstanceTransformer{ 151 Concrete: testOrphanResourceConcreteFunc, 152 State: state, 153 Config: mod, 154 } 155 if err := tf.Transform(&g); err != nil { 156 t.Fatalf("err: %s", err) 157 } 158 } 159 160 actual := strings.TrimSpace(g.String()) 161 expected := strings.TrimSpace(testTransformOrphanResourceCountStr) 162 if actual != expected { 163 t.Fatalf("bad:\n\n%s", actual) 164 } 165 } 166 167 func TestOrphanResourceInstanceTransformer_countBad(t *testing.T) { 168 mod := testModule(t, "transform-orphan-count-empty") 169 state := states.BuildState(func(s *states.SyncState) { 170 s.SetResourceInstanceCurrent( 171 addrs.Resource{ 172 Mode: addrs.ManagedResourceMode, 173 Type: "aws_instance", 174 Name: "foo", 175 }.Instance(addrs.IntKey(0)).Absolute(addrs.RootModuleInstance), 176 &states.ResourceInstanceObjectSrc{ 177 AttrsFlat: map[string]string{ 178 "id": "foo", 179 }, 180 Status: states.ObjectReady, 181 }, 182 addrs.AbsProviderConfig{ 183 Provider: addrs.NewDefaultProvider("aws"), 184 Module: addrs.RootModule, 185 }, 186 ) 187 s.SetResourceInstanceCurrent( 188 addrs.Resource{ 189 Mode: addrs.ManagedResourceMode, 190 Type: "aws_instance", 191 Name: "foo", 192 }.Instance(addrs.IntKey(1)).Absolute(addrs.RootModuleInstance), 193 &states.ResourceInstanceObjectSrc{ 194 AttrsFlat: map[string]string{ 195 "id": "foo", 196 }, 197 Status: states.ObjectReady, 198 }, 199 addrs.AbsProviderConfig{ 200 Provider: addrs.NewDefaultProvider("aws"), 201 Module: addrs.RootModule, 202 }, 203 ) 204 }) 205 206 g := Graph{Path: addrs.RootModuleInstance} 207 { 208 tf := &ConfigTransformer{Config: mod} 209 if err := tf.Transform(&g); err != nil { 210 t.Fatalf("err: %s", err) 211 } 212 } 213 214 { 215 tf := &OrphanResourceInstanceTransformer{ 216 Concrete: testOrphanResourceConcreteFunc, 217 State: state, 218 Config: mod, 219 } 220 if err := tf.Transform(&g); err != nil { 221 t.Fatalf("err: %s", err) 222 } 223 } 224 225 actual := strings.TrimSpace(g.String()) 226 expected := strings.TrimSpace(testTransformOrphanResourceCountBadStr) 227 if actual != expected { 228 t.Fatalf("bad:\n\n%s", actual) 229 } 230 } 231 232 func TestOrphanResourceInstanceTransformer_modules(t *testing.T) { 233 mod := testModule(t, "transform-orphan-modules") 234 state := states.BuildState(func(s *states.SyncState) { 235 s.SetResourceInstanceCurrent( 236 addrs.Resource{ 237 Mode: addrs.ManagedResourceMode, 238 Type: "aws_instance", 239 Name: "foo", 240 }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance), 241 &states.ResourceInstanceObjectSrc{ 242 AttrsFlat: map[string]string{ 243 "id": "foo", 244 }, 245 Status: states.ObjectReady, 246 }, 247 addrs.AbsProviderConfig{ 248 Provider: addrs.NewDefaultProvider("aws"), 249 Module: addrs.RootModule, 250 }, 251 ) 252 s.SetResourceInstanceCurrent( 253 addrs.Resource{ 254 Mode: addrs.ManagedResourceMode, 255 Type: "aws_instance", 256 Name: "web", 257 }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance.Child("child", addrs.NoKey)), 258 &states.ResourceInstanceObjectSrc{ 259 AttrsFlat: map[string]string{ 260 "id": "foo", 261 }, 262 Status: states.ObjectReady, 263 }, 264 addrs.AbsProviderConfig{ 265 Provider: addrs.NewDefaultProvider("aws"), 266 Module: addrs.RootModule, 267 }, 268 ) 269 }) 270 271 g := Graph{Path: addrs.RootModuleInstance} 272 { 273 tf := &ConfigTransformer{Config: mod} 274 if err := tf.Transform(&g); err != nil { 275 t.Fatalf("err: %s", err) 276 } 277 } 278 279 { 280 tf := &OrphanResourceInstanceTransformer{ 281 Concrete: testOrphanResourceConcreteFunc, 282 State: state, 283 Config: mod, 284 } 285 if err := tf.Transform(&g); err != nil { 286 t.Fatalf("err: %s", err) 287 } 288 } 289 290 got := strings.TrimSpace(g.String()) 291 want := strings.TrimSpace(testTransformOrphanResourceModulesStr) 292 if got != want { 293 t.Fatalf("wrong state result\ngot:\n%s\n\nwant:\n%s", got, want) 294 } 295 } 296 297 const testTransformOrphanResourceBasicStr = ` 298 aws_instance.db (orphan) 299 aws_instance.web 300 ` 301 302 const testTransformOrphanResourceCountStr = ` 303 aws_instance.foo 304 ` 305 306 const testTransformOrphanResourceCountBadStr = ` 307 aws_instance.foo[0] (orphan) 308 aws_instance.foo[1] (orphan) 309 ` 310 311 const testTransformOrphanResourceModulesStr = ` 312 aws_instance.foo 313 module.child.aws_instance.web (orphan) 314 ` 315 316 func testOrphanResourceConcreteFunc(a *NodeAbstractResourceInstance) dag.Vertex { 317 return &testOrphanResourceInstanceConcrete{a} 318 } 319 320 type testOrphanResourceInstanceConcrete struct { 321 *NodeAbstractResourceInstance 322 } 323 324 func (n *testOrphanResourceInstanceConcrete) Name() string { 325 return fmt.Sprintf("%s (orphan)", n.NodeAbstractResourceInstance.Name()) 326 }