github.com/medzin/terraform@v0.11.11/config/merge_test.go (about) 1 package config 2 3 import ( 4 "fmt" 5 "reflect" 6 "testing" 7 8 "github.com/davecgh/go-spew/spew" 9 ) 10 11 func TestMerge(t *testing.T) { 12 cases := []struct { 13 c1, c2, result *Config 14 err bool 15 }{ 16 // Normal good case. 17 { 18 &Config{ 19 Atlas: &AtlasConfig{ 20 Name: "foo", 21 }, 22 Modules: []*Module{ 23 &Module{Name: "foo"}, 24 }, 25 Outputs: []*Output{ 26 &Output{Name: "foo"}, 27 }, 28 ProviderConfigs: []*ProviderConfig{ 29 &ProviderConfig{Name: "foo"}, 30 }, 31 Resources: []*Resource{ 32 &Resource{Name: "foo"}, 33 }, 34 Variables: []*Variable{ 35 &Variable{Name: "foo"}, 36 }, 37 Locals: []*Local{ 38 &Local{Name: "foo"}, 39 }, 40 41 unknownKeys: []string{"foo"}, 42 }, 43 44 &Config{ 45 Atlas: &AtlasConfig{ 46 Name: "bar", 47 }, 48 Modules: []*Module{ 49 &Module{Name: "bar"}, 50 }, 51 Outputs: []*Output{ 52 &Output{Name: "bar"}, 53 }, 54 ProviderConfigs: []*ProviderConfig{ 55 &ProviderConfig{Name: "bar"}, 56 }, 57 Resources: []*Resource{ 58 &Resource{Name: "bar"}, 59 }, 60 Variables: []*Variable{ 61 &Variable{Name: "bar"}, 62 }, 63 Locals: []*Local{ 64 &Local{Name: "bar"}, 65 }, 66 67 unknownKeys: []string{"bar"}, 68 }, 69 70 &Config{ 71 Atlas: &AtlasConfig{ 72 Name: "bar", 73 }, 74 Modules: []*Module{ 75 &Module{Name: "foo"}, 76 &Module{Name: "bar"}, 77 }, 78 Outputs: []*Output{ 79 &Output{Name: "foo"}, 80 &Output{Name: "bar"}, 81 }, 82 ProviderConfigs: []*ProviderConfig{ 83 &ProviderConfig{Name: "foo"}, 84 &ProviderConfig{Name: "bar"}, 85 }, 86 Resources: []*Resource{ 87 &Resource{Name: "foo"}, 88 &Resource{Name: "bar"}, 89 }, 90 Variables: []*Variable{ 91 &Variable{Name: "foo"}, 92 &Variable{Name: "bar"}, 93 }, 94 Locals: []*Local{ 95 &Local{Name: "foo"}, 96 &Local{Name: "bar"}, 97 }, 98 99 unknownKeys: []string{"foo", "bar"}, 100 }, 101 102 false, 103 }, 104 105 // Test that when merging duplicates, it merges into the 106 // first, but keeps the duplicates so that errors still 107 // happen. 108 { 109 &Config{ 110 Outputs: []*Output{ 111 &Output{Name: "foo"}, 112 }, 113 ProviderConfigs: []*ProviderConfig{ 114 &ProviderConfig{Name: "foo"}, 115 }, 116 Resources: []*Resource{ 117 &Resource{Name: "foo"}, 118 }, 119 Variables: []*Variable{ 120 &Variable{Name: "foo", Default: "foo"}, 121 &Variable{Name: "foo"}, 122 }, 123 Locals: []*Local{ 124 &Local{Name: "foo"}, 125 }, 126 127 unknownKeys: []string{"foo"}, 128 }, 129 130 &Config{ 131 Outputs: []*Output{ 132 &Output{Name: "bar"}, 133 }, 134 ProviderConfigs: []*ProviderConfig{ 135 &ProviderConfig{Name: "bar"}, 136 }, 137 Resources: []*Resource{ 138 &Resource{Name: "bar"}, 139 }, 140 Variables: []*Variable{ 141 &Variable{Name: "foo", Default: "bar"}, 142 &Variable{Name: "bar"}, 143 }, 144 Locals: []*Local{ 145 &Local{Name: "foo"}, 146 }, 147 148 unknownKeys: []string{"bar"}, 149 }, 150 151 &Config{ 152 Outputs: []*Output{ 153 &Output{Name: "foo"}, 154 &Output{Name: "bar"}, 155 }, 156 ProviderConfigs: []*ProviderConfig{ 157 &ProviderConfig{Name: "foo"}, 158 &ProviderConfig{Name: "bar"}, 159 }, 160 Resources: []*Resource{ 161 &Resource{Name: "foo"}, 162 &Resource{Name: "bar"}, 163 }, 164 Variables: []*Variable{ 165 &Variable{Name: "foo", Default: "bar"}, 166 &Variable{Name: "foo"}, 167 &Variable{Name: "bar"}, 168 }, 169 Locals: []*Local{ 170 &Local{Name: "foo"}, 171 &Local{Name: "foo"}, 172 }, 173 174 unknownKeys: []string{"foo", "bar"}, 175 }, 176 177 false, 178 }, 179 180 // Terraform block 181 { 182 &Config{ 183 Terraform: &Terraform{ 184 RequiredVersion: "A", 185 }, 186 }, 187 &Config{}, 188 &Config{ 189 Terraform: &Terraform{ 190 RequiredVersion: "A", 191 }, 192 }, 193 false, 194 }, 195 196 { 197 &Config{}, 198 &Config{ 199 Terraform: &Terraform{ 200 RequiredVersion: "A", 201 }, 202 }, 203 &Config{ 204 Terraform: &Terraform{ 205 RequiredVersion: "A", 206 }, 207 }, 208 false, 209 }, 210 211 // Provider alias 212 { 213 &Config{ 214 ProviderConfigs: []*ProviderConfig{ 215 &ProviderConfig{Alias: "foo"}, 216 }, 217 }, 218 &Config{}, 219 &Config{ 220 ProviderConfigs: []*ProviderConfig{ 221 &ProviderConfig{Alias: "foo"}, 222 }, 223 }, 224 false, 225 }, 226 227 { 228 &Config{}, 229 &Config{ 230 ProviderConfigs: []*ProviderConfig{ 231 &ProviderConfig{Alias: "foo"}, 232 }, 233 }, 234 &Config{ 235 ProviderConfigs: []*ProviderConfig{ 236 &ProviderConfig{Alias: "foo"}, 237 }, 238 }, 239 false, 240 }, 241 242 { 243 &Config{ 244 ProviderConfigs: []*ProviderConfig{ 245 &ProviderConfig{Alias: "bar"}, 246 }, 247 }, 248 &Config{ 249 ProviderConfigs: []*ProviderConfig{ 250 &ProviderConfig{Alias: "foo"}, 251 }, 252 }, 253 &Config{ 254 ProviderConfigs: []*ProviderConfig{ 255 &ProviderConfig{Alias: "foo"}, 256 }, 257 }, 258 false, 259 }, 260 261 // Variable type 262 { 263 &Config{ 264 Variables: []*Variable{ 265 &Variable{DeclaredType: "foo"}, 266 }, 267 }, 268 &Config{}, 269 &Config{ 270 Variables: []*Variable{ 271 &Variable{DeclaredType: "foo"}, 272 }, 273 }, 274 false, 275 }, 276 277 { 278 &Config{}, 279 &Config{ 280 Variables: []*Variable{ 281 &Variable{DeclaredType: "foo"}, 282 }, 283 }, 284 &Config{ 285 Variables: []*Variable{ 286 &Variable{DeclaredType: "foo"}, 287 }, 288 }, 289 false, 290 }, 291 292 { 293 &Config{ 294 Variables: []*Variable{ 295 &Variable{DeclaredType: "bar"}, 296 }, 297 }, 298 &Config{ 299 Variables: []*Variable{ 300 &Variable{DeclaredType: "foo"}, 301 }, 302 }, 303 &Config{ 304 Variables: []*Variable{ 305 &Variable{DeclaredType: "foo"}, 306 }, 307 }, 308 false, 309 }, 310 311 // Output description 312 { 313 &Config{ 314 Outputs: []*Output{ 315 &Output{Description: "foo"}, 316 }, 317 }, 318 &Config{}, 319 &Config{ 320 Outputs: []*Output{ 321 &Output{Description: "foo"}, 322 }, 323 }, 324 false, 325 }, 326 327 { 328 &Config{}, 329 &Config{ 330 Outputs: []*Output{ 331 &Output{Description: "foo"}, 332 }, 333 }, 334 &Config{ 335 Outputs: []*Output{ 336 &Output{Description: "foo"}, 337 }, 338 }, 339 false, 340 }, 341 342 { 343 &Config{ 344 Outputs: []*Output{ 345 &Output{Description: "bar"}, 346 }, 347 }, 348 &Config{ 349 Outputs: []*Output{ 350 &Output{Description: "foo"}, 351 }, 352 }, 353 &Config{ 354 Outputs: []*Output{ 355 &Output{Description: "foo"}, 356 }, 357 }, 358 false, 359 }, 360 361 // Output depends_on 362 { 363 &Config{ 364 Outputs: []*Output{ 365 &Output{DependsOn: []string{"foo"}}, 366 }, 367 }, 368 &Config{}, 369 &Config{ 370 Outputs: []*Output{ 371 &Output{DependsOn: []string{"foo"}}, 372 }, 373 }, 374 false, 375 }, 376 377 { 378 &Config{}, 379 &Config{ 380 Outputs: []*Output{ 381 &Output{DependsOn: []string{"foo"}}, 382 }, 383 }, 384 &Config{ 385 Outputs: []*Output{ 386 &Output{DependsOn: []string{"foo"}}, 387 }, 388 }, 389 false, 390 }, 391 392 { 393 &Config{ 394 Outputs: []*Output{ 395 &Output{DependsOn: []string{"bar"}}, 396 }, 397 }, 398 &Config{ 399 Outputs: []*Output{ 400 &Output{DependsOn: []string{"foo"}}, 401 }, 402 }, 403 &Config{ 404 Outputs: []*Output{ 405 &Output{DependsOn: []string{"foo"}}, 406 }, 407 }, 408 false, 409 }, 410 411 // Output sensitive 412 { 413 &Config{ 414 Outputs: []*Output{ 415 &Output{Sensitive: true}, 416 }, 417 }, 418 &Config{}, 419 &Config{ 420 Outputs: []*Output{ 421 &Output{Sensitive: true}, 422 }, 423 }, 424 false, 425 }, 426 427 { 428 &Config{}, 429 &Config{ 430 Outputs: []*Output{ 431 &Output{Sensitive: true}, 432 }, 433 }, 434 &Config{ 435 Outputs: []*Output{ 436 &Output{Sensitive: true}, 437 }, 438 }, 439 false, 440 }, 441 442 { 443 &Config{ 444 Outputs: []*Output{ 445 &Output{Sensitive: false}, 446 }, 447 }, 448 &Config{ 449 Outputs: []*Output{ 450 &Output{Sensitive: true}, 451 }, 452 }, 453 &Config{ 454 Outputs: []*Output{ 455 &Output{Sensitive: true}, 456 }, 457 }, 458 false, 459 }, 460 461 // terraform blocks are merged, not overwritten 462 { 463 &Config{ 464 Terraform: &Terraform{ 465 RequiredVersion: "A", 466 }, 467 }, 468 &Config{ 469 Terraform: &Terraform{ 470 Backend: &Backend{ 471 Type: "test", 472 }, 473 }, 474 }, 475 &Config{ 476 Terraform: &Terraform{ 477 RequiredVersion: "A", 478 Backend: &Backend{ 479 Type: "test", 480 }, 481 }, 482 }, 483 false, 484 }, 485 } 486 487 for i, tc := range cases { 488 t.Run(fmt.Sprintf("%02d", i), func(t *testing.T) { 489 actual, err := Merge(tc.c1, tc.c2) 490 if err != nil != tc.err { 491 t.Errorf("unexpected error: %s", err) 492 } 493 494 if !reflect.DeepEqual(actual, tc.result) { 495 t.Errorf("wrong result\ngot: %swant: %s", spew.Sdump(actual), spew.Sdump(tc.result)) 496 } 497 }) 498 } 499 }