github.com/turtlemonvh/terraform@v0.6.9-0.20151204001754-8e40b6b855e8/terraform/graph_builder_test.go (about) 1 package terraform 2 3 import ( 4 "reflect" 5 "strings" 6 "testing" 7 8 "github.com/hashicorp/terraform/dag" 9 ) 10 11 func TestBasicGraphBuilder_impl(t *testing.T) { 12 var _ GraphBuilder = new(BasicGraphBuilder) 13 } 14 15 func TestBasicGraphBuilder(t *testing.T) { 16 b := &BasicGraphBuilder{ 17 Steps: []GraphTransformer{ 18 &testBasicGraphBuilderTransform{1}, 19 }, 20 } 21 22 g, err := b.Build(RootModulePath) 23 if err != nil { 24 t.Fatalf("err: %s", err) 25 } 26 27 if !reflect.DeepEqual(g.Path, RootModulePath) { 28 t.Fatalf("bad: %#v", g.Path) 29 } 30 31 actual := strings.TrimSpace(g.String()) 32 expected := strings.TrimSpace(testBasicGraphBuilderStr) 33 if actual != expected { 34 t.Fatalf("bad: %s", actual) 35 } 36 } 37 38 func TestBasicGraphBuilder_validate(t *testing.T) { 39 b := &BasicGraphBuilder{ 40 Steps: []GraphTransformer{ 41 &testBasicGraphBuilderTransform{1}, 42 &testBasicGraphBuilderTransform{2}, 43 }, 44 Validate: true, 45 } 46 47 _, err := b.Build(RootModulePath) 48 if err == nil { 49 t.Fatal("should error") 50 } 51 } 52 53 func TestBasicGraphBuilder_validateOff(t *testing.T) { 54 b := &BasicGraphBuilder{ 55 Steps: []GraphTransformer{ 56 &testBasicGraphBuilderTransform{1}, 57 &testBasicGraphBuilderTransform{2}, 58 }, 59 Validate: false, 60 } 61 62 _, err := b.Build(RootModulePath) 63 if err != nil { 64 t.Fatalf("expected no error, got: %s", err) 65 } 66 } 67 68 func TestBuiltinGraphBuilder_impl(t *testing.T) { 69 var _ GraphBuilder = new(BuiltinGraphBuilder) 70 } 71 72 // This test is not meant to test all the transforms but rather just 73 // to verify we get some basic sane graph out. Special tests to ensure 74 // specific ordering of steps should be added in other tests. 75 func TestBuiltinGraphBuilder(t *testing.T) { 76 b := &BuiltinGraphBuilder{ 77 Root: testModule(t, "graph-builder-basic"), 78 Validate: true, 79 } 80 81 g, err := b.Build(RootModulePath) 82 if err != nil { 83 t.Fatalf("err: %s", err) 84 } 85 86 actual := strings.TrimSpace(g.String()) 87 expected := strings.TrimSpace(testBuiltinGraphBuilderBasicStr) 88 if actual != expected { 89 t.Fatalf("bad: %s", actual) 90 } 91 } 92 93 func TestBuiltinGraphBuilder_Verbose(t *testing.T) { 94 b := &BuiltinGraphBuilder{ 95 Root: testModule(t, "graph-builder-basic"), 96 Validate: true, 97 Verbose: true, 98 } 99 100 g, err := b.Build(RootModulePath) 101 if err != nil { 102 t.Fatalf("err: %s", err) 103 } 104 105 actual := strings.TrimSpace(g.String()) 106 expected := strings.TrimSpace(testBuiltinGraphBuilderVerboseStr) 107 if actual != expected { 108 t.Fatalf("bad: %s", actual) 109 } 110 } 111 112 // This tests a cycle we got when a CBD resource depends on a non-CBD 113 // resource. This cycle shouldn't happen in the general case anymore. 114 func TestBuiltinGraphBuilder_cbdDepNonCbd(t *testing.T) { 115 b := &BuiltinGraphBuilder{ 116 Root: testModule(t, "graph-builder-cbd-non-cbd"), 117 Validate: true, 118 } 119 120 _, err := b.Build(RootModulePath) 121 if err != nil { 122 t.Fatalf("err: %s", err) 123 } 124 } 125 126 func TestBuiltinGraphBuilder_cbdDepNonCbd_errorsWhenVerbose(t *testing.T) { 127 b := &BuiltinGraphBuilder{ 128 Root: testModule(t, "graph-builder-cbd-non-cbd"), 129 Validate: true, 130 Verbose: true, 131 } 132 133 _, err := b.Build(RootModulePath) 134 if err == nil { 135 t.Fatalf("expected err, got none") 136 } 137 } 138 139 func TestBuiltinGraphBuilder_multiLevelModule(t *testing.T) { 140 b := &BuiltinGraphBuilder{ 141 Root: testModule(t, "graph-builder-multi-level-module"), 142 Validate: true, 143 } 144 145 g, err := b.Build(RootModulePath) 146 if err != nil { 147 t.Fatalf("err: %s", err) 148 } 149 150 actual := strings.TrimSpace(g.String()) 151 expected := strings.TrimSpace(testBuiltinGraphBuilderMultiLevelStr) 152 if actual != expected { 153 t.Fatalf("bad: %s", actual) 154 } 155 } 156 157 func TestBuiltinGraphBuilder_orphanDeps(t *testing.T) { 158 state := &State{ 159 Modules: []*ModuleState{ 160 &ModuleState{ 161 Path: rootModulePath, 162 Resources: map[string]*ResourceState{ 163 "aws_instance.foo": &ResourceState{ 164 Type: "aws_instance", 165 Primary: &InstanceState{ 166 ID: "foo", 167 }, 168 }, 169 170 "aws_instance.bar": &ResourceState{ 171 Type: "aws_instance", 172 Dependencies: []string{"aws_instance.foo"}, 173 Primary: &InstanceState{ 174 ID: "bar", 175 }, 176 }, 177 }, 178 }, 179 }, 180 } 181 182 b := &BuiltinGraphBuilder{ 183 Root: testModule(t, "graph-builder-orphan-deps"), 184 State: state, 185 Validate: true, 186 } 187 188 g, err := b.Build(RootModulePath) 189 if err != nil { 190 t.Fatalf("err: %s", err) 191 } 192 193 actual := strings.TrimSpace(g.String()) 194 expected := strings.TrimSpace(testBuiltinGraphBuilderOrphanDepsStr) 195 if actual != expected { 196 t.Fatalf("bad: %s", actual) 197 } 198 } 199 200 /* 201 TODO: This exposes a really bad bug we need to fix after we merge 202 the f-ast-branch. This bug still exists in master. 203 204 // This test tests that the graph builder properly expands modules. 205 func TestBuiltinGraphBuilder_modules(t *testing.T) { 206 b := &BuiltinGraphBuilder{ 207 Root: testModule(t, "graph-builder-modules"), 208 } 209 210 g, err := b.Build(RootModulePath) 211 if err != nil { 212 t.Fatalf("err: %s", err) 213 } 214 215 actual := strings.TrimSpace(g.String()) 216 expected := strings.TrimSpace(testBuiltinGraphBuilderModuleStr) 217 if actual != expected { 218 t.Fatalf("bad: %s", actual) 219 } 220 } 221 */ 222 223 type testBasicGraphBuilderTransform struct { 224 V dag.Vertex 225 } 226 227 func (t *testBasicGraphBuilderTransform) Transform(g *Graph) error { 228 g.Add(t.V) 229 return nil 230 } 231 232 const testBasicGraphBuilderStr = ` 233 1 234 ` 235 236 const testBuiltinGraphBuilderBasicStr = ` 237 aws_instance.db 238 provider.aws 239 aws_instance.web 240 aws_instance.db 241 provider.aws 242 provider.aws (close) 243 aws_instance.web 244 ` 245 246 const testBuiltinGraphBuilderVerboseStr = ` 247 aws_instance.db 248 aws_instance.db (destroy tainted) 249 aws_instance.db (destroy) 250 aws_instance.db (destroy tainted) 251 aws_instance.web (destroy tainted) 252 aws_instance.db (destroy) 253 aws_instance.web (destroy) 254 aws_instance.web 255 aws_instance.db 256 aws_instance.web (destroy tainted) 257 provider.aws 258 aws_instance.web (destroy) 259 provider.aws 260 provider.aws 261 provider.aws (close) 262 aws_instance.web 263 ` 264 265 const testBuiltinGraphBuilderMultiLevelStr = ` 266 module.foo.module.bar.output.value 267 module.foo.module.bar.var.bar 268 module.foo.module.bar.plan-destroy 269 module.foo.module.bar.var.bar 270 module.foo.var.foo 271 module.foo.plan-destroy 272 module.foo.var.foo 273 root 274 module.foo.module.bar.output.value 275 module.foo.module.bar.plan-destroy 276 module.foo.plan-destroy 277 ` 278 279 const testBuiltinGraphBuilderOrphanDepsStr = ` 280 aws_instance.bar (orphan) 281 provider.aws 282 aws_instance.foo (orphan) 283 aws_instance.bar (orphan) 284 provider.aws 285 provider.aws (close) 286 aws_instance.foo (orphan) 287 ` 288 289 /* 290 TODO: Commented out this const as it's likely this needs to 291 be updated when the TestBuiltinGraphBuilder_modules test is 292 enabled again. 293 const testBuiltinGraphBuilderModuleStr = ` 294 aws_instance.web 295 aws_instance.web (destroy) 296 aws_instance.web (destroy) 297 aws_security_group.firewall 298 module.consul (expanded) 299 provider.aws 300 aws_security_group.firewall 301 aws_security_group.firewall (destroy) 302 aws_security_group.firewall (destroy) 303 provider.aws 304 module.consul (expanded) 305 aws_security_group.firewall 306 provider.aws 307 provider.aws 308 ` 309 */