github.com/jpreese/tflint@v0.19.2-0.20200908152133-b01686250fb6/tflint/config_test.go (about) 1 package tflint 2 3 import ( 4 "errors" 5 "fmt" 6 "os" 7 "path/filepath" 8 "testing" 9 10 "github.com/google/go-cmp/cmp" 11 "github.com/google/go-cmp/cmp/cmpopts" 12 hcl "github.com/hashicorp/hcl/v2" 13 "github.com/hashicorp/hcl/v2/hclsyntax" 14 tfplugin "github.com/terraform-linters/tflint-plugin-sdk/tflint" 15 "github.com/terraform-linters/tflint/client" 16 ) 17 18 func Test_LoadConfig(t *testing.T) { 19 currentDir, err := os.Getwd() 20 if err != nil { 21 t.Fatal(err) 22 } 23 24 cases := []struct { 25 Name string 26 File string 27 Fallback string 28 Expected *Config 29 }{ 30 { 31 Name: "load file", 32 File: filepath.Join(currentDir, "test-fixtures", "config", "config.hcl"), 33 Expected: &Config{ 34 Module: true, 35 DeepCheck: true, 36 Force: true, 37 AwsCredentials: client.AwsCredentials{ 38 AccessKey: "AWS_ACCESS_KEY", 39 SecretKey: "AWS_SECRET_KEY", 40 Region: "us-east-1", 41 Profile: "production", 42 CredsFile: "~/.aws/myapp", 43 }, 44 IgnoreModules: map[string]bool{ 45 "github.com/terraform-linters/example-module": true, 46 }, 47 Varfiles: []string{"example1.tfvars", "example2.tfvars"}, 48 Variables: []string{"foo=bar", "bar=['foo']"}, 49 DisabledByDefault: false, 50 Rules: map[string]*RuleConfig{ 51 "aws_instance_invalid_type": { 52 Name: "aws_instance_invalid_type", 53 Enabled: false, 54 }, 55 "aws_instance_previous_type": { 56 Name: "aws_instance_previous_type", 57 Enabled: false, 58 }, 59 }, 60 Plugins: map[string]*PluginConfig{ 61 "foo": { 62 Name: "foo", 63 Enabled: true, 64 }, 65 "bar": { 66 Name: "bar", 67 Enabled: false, 68 }, 69 }, 70 }, 71 }, 72 { 73 Name: "empty file", 74 File: filepath.Join(currentDir, "test-fixtures", "config", "empty.hcl"), 75 Expected: EmptyConfig(), 76 }, 77 { 78 Name: "fallback", 79 File: filepath.Join(currentDir, "test-fixtures", "config", "not_found.hcl"), 80 Fallback: filepath.Join(currentDir, "test-fixtures", "config", "fallback.hcl"), 81 Expected: &Config{ 82 Module: false, 83 DeepCheck: true, 84 Force: true, 85 AwsCredentials: client.AwsCredentials{ 86 AccessKey: "AWS_ACCESS_KEY", 87 SecretKey: "AWS_SECRET_KEY", 88 Region: "us-east-1", 89 }, 90 IgnoreModules: map[string]bool{}, 91 Varfiles: []string{}, 92 Variables: []string{}, 93 DisabledByDefault: true, 94 Rules: map[string]*RuleConfig{}, 95 Plugins: map[string]*PluginConfig{}, 96 }, 97 }, 98 { 99 Name: "fallback file not found", 100 File: filepath.Join(currentDir, "test-fixtures", "config", "not_found.hcl"), 101 Fallback: filepath.Join(currentDir, "test-fixtures", "config", "fallback_not_found.hcl"), 102 Expected: EmptyConfig(), 103 }, 104 } 105 106 for _, tc := range cases { 107 originalDefault := defaultConfigFile 108 defaultConfigFile = filepath.Join(currentDir, "test-fixtures", "config", "not_found.hcl") 109 originalFallback := fallbackConfigFile 110 fallbackConfigFile = tc.Fallback 111 112 ret, err := LoadConfig(tc.File) 113 if err != nil { 114 t.Fatalf("Failed `%s` test: Unexpected error occurred: %s", tc.Name, err) 115 } 116 117 opts := []cmp.Option{ 118 cmpopts.IgnoreFields(RuleConfig{}, "Body"), 119 } 120 if !cmp.Equal(tc.Expected, ret, opts...) { 121 t.Fatalf("Failed `%s` test: diff=%s", tc.Name, cmp.Diff(tc.Expected, ret)) 122 } 123 124 defaultConfigFile = originalDefault 125 fallbackConfigFile = originalFallback 126 } 127 } 128 129 func Test_LoadConfig_error(t *testing.T) { 130 currentDir, err := os.Getwd() 131 if err != nil { 132 t.Fatal(err) 133 } 134 135 cases := []struct { 136 Name string 137 File string 138 Expected string 139 }{ 140 { 141 Name: "file not found", 142 File: filepath.Join(currentDir, "test-fixtures", "config", "not_found.hcl"), 143 Expected: fmt.Sprintf( 144 "`%s` is not found", 145 filepath.Join(currentDir, "test-fixtures", "config", "not_found.hcl"), 146 ), 147 }, 148 { 149 Name: "syntax error", 150 File: filepath.Join(currentDir, "test-fixtures", "config", "syntax_error.hcl"), 151 Expected: fmt.Sprintf( 152 "%s:1,1-2: Invalid character; The \"`\" character is not valid. To create a multi-line string, use the \"heredoc\" syntax, like \"<<EOT\"., and 1 other diagnostic(s)", 153 filepath.Join(currentDir, "test-fixtures", "config", "syntax_error.hcl"), 154 ), 155 }, 156 { 157 Name: "invalid config", 158 File: filepath.Join(currentDir, "test-fixtures", "config", "invalid.hcl"), 159 Expected: fmt.Sprintf( 160 "%s:1,34-42: Extraneous label for rule; Only 1 labels (name) are expected for rule blocks.", 161 filepath.Join(currentDir, "test-fixtures", "config", "invalid.hcl"), 162 ), 163 }, 164 { 165 Name: "terraform_version", 166 File: filepath.Join(currentDir, "test-fixtures", "config", "terraform_version.hcl"), 167 Expected: "`terraform_version` was removed in v0.9.0 because the option is no longer used", 168 }, 169 { 170 Name: "ignore_rule", 171 File: filepath.Join(currentDir, "test-fixtures", "config", "ignore_rule.hcl"), 172 Expected: "`ignore_rule` was removed in v0.12.0. Please define `rule` block with `enabled = false` instead", 173 }, 174 } 175 176 for _, tc := range cases { 177 _, err := LoadConfig(tc.File) 178 if err == nil { 179 t.Fatalf("Failed `%s` test: Expected error does not occurred", tc.Name) 180 } 181 182 if err.Error() != tc.Expected { 183 t.Fatalf("Failed `%s` test: expected error is `%s`, but get `%s`", tc.Name, tc.Expected, err.Error()) 184 } 185 } 186 } 187 188 func Test_Merge(t *testing.T) { 189 file1, diags := hclsyntax.ParseConfig([]byte(`foo = "bar"`), "test.hcl", hcl.Pos{}) 190 if diags.HasErrors() { 191 t.Fatalf("Failed to parse test config: %s", diags) 192 } 193 file2, diags := hclsyntax.ParseConfig([]byte(`bar = "baz"`), "test2.hcl", hcl.Pos{}) 194 if diags.HasErrors() { 195 t.Fatalf("Failed to parse test config: %s", diags) 196 } 197 198 cfg := &Config{ 199 Module: true, 200 DeepCheck: true, 201 Force: true, 202 AwsCredentials: client.AwsCredentials{ 203 AccessKey: "access_key", 204 SecretKey: "secret_key", 205 Region: "us-east-1", 206 }, 207 IgnoreModules: map[string]bool{ 208 "github.com/terraform-linters/example-1": true, 209 "github.com/terraform-linters/example-2": false, 210 }, 211 Varfiles: []string{"example1.tfvars", "example2.tfvars"}, 212 Variables: []string{"foo=bar"}, 213 DisabledByDefault: false, 214 Rules: map[string]*RuleConfig{ 215 "aws_instance_invalid_type": { 216 Name: "aws_instance_invalid_type", 217 Enabled: false, 218 Body: file1.Body, 219 }, 220 "aws_instance_invalid_ami": { 221 Name: "aws_instance_invalid_ami", 222 Enabled: true, 223 Body: file2.Body, 224 }, 225 }, 226 Plugins: map[string]*PluginConfig{}, 227 } 228 229 cases := []struct { 230 Name string 231 Base *Config 232 Other *Config 233 Expected *Config 234 }{ 235 { 236 Name: "empty", 237 Base: EmptyConfig(), 238 Other: EmptyConfig(), 239 Expected: EmptyConfig(), 240 }, 241 { 242 Name: "prefer base", 243 Base: cfg, 244 Other: EmptyConfig(), 245 Expected: cfg, 246 }, 247 { 248 Name: "prefer other", 249 Base: EmptyConfig(), 250 Other: cfg, 251 Expected: cfg, 252 }, 253 { 254 Name: "override and merge", 255 Base: &Config{ 256 Module: true, 257 DeepCheck: true, 258 Force: false, 259 AwsCredentials: client.AwsCredentials{ 260 AccessKey: "access_key", 261 SecretKey: "secret_key", 262 Profile: "production", 263 Region: "us-east-1", 264 }, 265 IgnoreModules: map[string]bool{ 266 "github.com/terraform-linters/example-1": true, 267 "github.com/terraform-linters/example-2": false, 268 }, 269 Varfiles: []string{"example1.tfvars", "example2.tfvars"}, 270 Variables: []string{"foo=bar"}, 271 DisabledByDefault: false, 272 Rules: map[string]*RuleConfig{ 273 "aws_instance_invalid_type": { 274 Name: "aws_instance_invalid_type", 275 Enabled: false, 276 Body: file1.Body, 277 }, 278 "aws_instance_invalid_ami": { 279 Name: "aws_instance_invalid_ami", 280 Enabled: true, 281 Body: file1.Body, 282 }, 283 }, 284 Plugins: map[string]*PluginConfig{ 285 "foo": { 286 Name: "foo", 287 Enabled: true, 288 }, 289 "bar": { 290 Name: "bar", 291 Enabled: false, 292 }, 293 }, 294 }, 295 Other: &Config{ 296 Module: false, 297 DeepCheck: false, 298 Force: true, 299 AwsCredentials: client.AwsCredentials{ 300 AccessKey: "ACCESS_KEY", 301 SecretKey: "SECRET_KEY", 302 Region: "ap-northeast-1", 303 CredsFile: "~/.aws/myapp", 304 }, 305 IgnoreModules: map[string]bool{ 306 "github.com/terraform-linters/example-2": true, 307 "github.com/terraform-linters/example-3": false, 308 }, 309 Varfiles: []string{"example3.tfvars"}, 310 Variables: []string{"bar=baz"}, 311 DisabledByDefault: false, 312 Rules: map[string]*RuleConfig{ 313 "aws_instance_invalid_ami": { 314 Name: "aws_instance_invalid_ami", 315 Enabled: false, 316 Body: file2.Body, 317 }, 318 "aws_instance_previous_type": { 319 Name: "aws_instance_previous_type", 320 Enabled: false, 321 Body: file2.Body, 322 }, 323 }, 324 Plugins: map[string]*PluginConfig{ 325 "baz": { 326 Name: "baz", 327 Enabled: true, 328 }, 329 "bar": { 330 Name: "bar", 331 Enabled: true, 332 }, 333 }, 334 }, 335 Expected: &Config{ 336 Module: true, 337 DeepCheck: true, // DeepCheck will not override 338 Force: true, 339 AwsCredentials: client.AwsCredentials{ 340 AccessKey: "ACCESS_KEY", 341 SecretKey: "SECRET_KEY", 342 Profile: "production", 343 Region: "ap-northeast-1", 344 CredsFile: "~/.aws/myapp", 345 }, 346 IgnoreModules: map[string]bool{ 347 "github.com/terraform-linters/example-1": true, 348 "github.com/terraform-linters/example-2": true, 349 "github.com/terraform-linters/example-3": false, 350 }, 351 Varfiles: []string{"example1.tfvars", "example2.tfvars", "example3.tfvars"}, 352 Variables: []string{"foo=bar", "bar=baz"}, 353 DisabledByDefault: false, 354 Rules: map[string]*RuleConfig{ 355 "aws_instance_invalid_type": { 356 Name: "aws_instance_invalid_type", 357 Enabled: false, 358 Body: file1.Body, 359 }, 360 "aws_instance_invalid_ami": { 361 Name: "aws_instance_invalid_ami", 362 Enabled: false, 363 Body: file2.Body, 364 }, 365 "aws_instance_previous_type": { 366 Name: "aws_instance_previous_type", 367 Enabled: false, 368 Body: file2.Body, 369 }, 370 }, 371 Plugins: map[string]*PluginConfig{ 372 "foo": { 373 Name: "foo", 374 Enabled: true, 375 }, 376 "bar": { 377 Name: "bar", 378 Enabled: true, 379 }, 380 "baz": { 381 Name: "baz", 382 Enabled: true, 383 }, 384 }, 385 }, 386 }, 387 { 388 Name: "CLI --only argument and merge", 389 Base: &Config{ 390 Module: true, 391 DeepCheck: true, 392 Force: false, 393 AwsCredentials: client.AwsCredentials{ 394 AccessKey: "access_key", 395 SecretKey: "secret_key", 396 Profile: "production", 397 Region: "us-east-1", 398 }, 399 IgnoreModules: map[string]bool{ 400 "github.com/terraform-linters/example-1": true, 401 "github.com/terraform-linters/example-2": false, 402 }, 403 Varfiles: []string{"example1.tfvars", "example2.tfvars"}, 404 Variables: []string{"foo=bar"}, 405 DisabledByDefault: false, 406 Rules: map[string]*RuleConfig{ 407 "aws_instance_invalid_type": { 408 Name: "aws_instance_invalid_type", 409 Enabled: false, 410 Body: file1.Body, 411 }, 412 "aws_instance_invalid_ami": { 413 Name: "aws_instance_invalid_ami", 414 Enabled: true, 415 Body: file1.Body, 416 }, 417 }, 418 Plugins: map[string]*PluginConfig{ 419 "foo": { 420 Name: "foo", 421 Enabled: true, 422 }, 423 "bar": { 424 Name: "bar", 425 Enabled: false, 426 }, 427 }, 428 }, 429 Other: &Config{ 430 Module: false, 431 DeepCheck: false, 432 Force: true, 433 AwsCredentials: client.AwsCredentials{ 434 AccessKey: "ACCESS_KEY", 435 SecretKey: "SECRET_KEY", 436 Region: "ap-northeast-1", 437 CredsFile: "~/.aws/myapp", 438 }, 439 IgnoreModules: map[string]bool{ 440 "github.com/terraform-linters/example-2": true, 441 "github.com/terraform-linters/example-3": false, 442 }, 443 Varfiles: []string{"example3.tfvars"}, 444 Variables: []string{"bar=baz"}, 445 DisabledByDefault: true, 446 Rules: map[string]*RuleConfig{ 447 "aws_instance_invalid_type": { 448 Name: "aws_instance_invalid_type", 449 Enabled: true, 450 Body: hcl.EmptyBody(), 451 }, 452 "aws_instance_previous_type": { 453 Name: "aws_instance_previous_type", 454 Enabled: true, 455 Body: hcl.EmptyBody(), // Will not attach, missing config 456 }, 457 }, 458 Plugins: map[string]*PluginConfig{ 459 "baz": { 460 Name: "baz", 461 Enabled: true, 462 }, 463 "bar": { 464 Name: "bar", 465 Enabled: true, 466 }, 467 }, 468 }, 469 Expected: &Config{ 470 Module: true, 471 DeepCheck: true, // DeepCheck will not override 472 Force: true, 473 AwsCredentials: client.AwsCredentials{ 474 AccessKey: "ACCESS_KEY", 475 SecretKey: "SECRET_KEY", 476 Profile: "production", 477 Region: "ap-northeast-1", 478 CredsFile: "~/.aws/myapp", 479 }, 480 IgnoreModules: map[string]bool{ 481 "github.com/terraform-linters/example-1": true, 482 "github.com/terraform-linters/example-2": true, 483 "github.com/terraform-linters/example-3": false, 484 }, 485 Varfiles: []string{"example1.tfvars", "example2.tfvars", "example3.tfvars"}, 486 Variables: []string{"foo=bar", "bar=baz"}, 487 DisabledByDefault: true, 488 Rules: map[string]*RuleConfig{ 489 "aws_instance_invalid_type": { 490 Name: "aws_instance_invalid_type", 491 Enabled: true, // Passing an --only rule from CLI will always enable 492 Body: file1.Body, 493 }, 494 "aws_instance_previous_type": { 495 Name: "aws_instance_previous_type", 496 Enabled: true, 497 Body: hcl.EmptyBody(), 498 }, 499 }, 500 Plugins: map[string]*PluginConfig{ 501 "foo": { 502 Name: "foo", 503 Enabled: true, 504 }, 505 "bar": { 506 Name: "bar", 507 Enabled: true, 508 }, 509 "baz": { 510 Name: "baz", 511 Enabled: true, 512 }, 513 }, 514 }, 515 }, 516 { 517 Name: "merge rule config with CLI-based config", 518 Base: &Config{ 519 Module: false, 520 DeepCheck: false, 521 Force: false, 522 AwsCredentials: client.AwsCredentials{}, 523 IgnoreModules: map[string]bool{}, 524 Varfiles: []string{}, 525 Variables: []string{}, 526 DisabledByDefault: false, 527 Rules: map[string]*RuleConfig{ 528 "aws_instance_invalid_type": { 529 Name: "aws_instance_invalid_type", 530 Enabled: false, 531 Body: file1.Body, 532 }, 533 }, 534 Plugins: map[string]*PluginConfig{}, 535 }, 536 Other: &Config{ 537 Module: false, 538 DeepCheck: false, 539 Force: false, 540 AwsCredentials: client.AwsCredentials{}, 541 IgnoreModules: map[string]bool{}, 542 Varfiles: []string{}, 543 Variables: []string{}, 544 DisabledByDefault: false, 545 Rules: map[string]*RuleConfig{ 546 "aws_instance_invalid_type": { 547 Name: "aws_instance_invalid_type", 548 Enabled: true, 549 Body: hcl.EmptyBody(), 550 }, 551 }, 552 Plugins: map[string]*PluginConfig{}, 553 }, 554 Expected: &Config{ 555 Module: false, 556 DeepCheck: false, 557 Force: false, 558 AwsCredentials: client.AwsCredentials{}, 559 IgnoreModules: map[string]bool{}, 560 Varfiles: []string{}, 561 Variables: []string{}, 562 DisabledByDefault: false, 563 Rules: map[string]*RuleConfig{ 564 "aws_instance_invalid_type": { 565 Name: "aws_instance_invalid_type", 566 Enabled: true, // overridden 567 Body: file1.Body, // keep 568 }, 569 }, 570 Plugins: map[string]*PluginConfig{}, 571 }, 572 }, 573 } 574 575 for _, tc := range cases { 576 ret := tc.Base.Merge(tc.Other) 577 578 opts := []cmp.Option{ 579 cmpopts.IgnoreUnexported(hclsyntax.Body{}), 580 cmpopts.IgnoreFields(hclsyntax.Body{}, "Attributes", "Blocks"), 581 } 582 if !cmp.Equal(tc.Expected, ret, opts...) { 583 t.Fatalf("Failed `%s` test: diff=%s", tc.Name, cmp.Diff(tc.Expected, ret, opts...)) 584 } 585 } 586 } 587 588 func Test_ToPluginConfig(t *testing.T) { 589 config := &Config{ 590 Rules: map[string]*RuleConfig{ 591 "aws_instance_invalid_type": { 592 Name: "aws_instance_invalid_type", 593 Enabled: false, 594 }, 595 "aws_instance_invalid_ami": { 596 Name: "aws_instance_invalid_ami", 597 Enabled: true, 598 }, 599 }, 600 DisabledByDefault: true, 601 } 602 603 ret := config.ToPluginConfig() 604 expected := &tfplugin.Config{ 605 Rules: map[string]*tfplugin.RuleConfig{ 606 "aws_instance_invalid_type": { 607 Name: "aws_instance_invalid_type", 608 Enabled: false, 609 }, 610 "aws_instance_invalid_ami": { 611 Name: "aws_instance_invalid_ami", 612 Enabled: true, 613 }, 614 }, 615 DisabledByDefault: true, 616 } 617 if !cmp.Equal(expected, ret) { 618 t.Fatalf("Failed to match: %s", cmp.Diff(expected, ret)) 619 } 620 } 621 622 type ruleSetA struct{} 623 624 func (*ruleSetA) RuleSetName() (string, error) { 625 return "ruleSetA", nil 626 } 627 func (*ruleSetA) RuleSetVersion() (string, error) { 628 return "0.1.0", nil 629 } 630 func (*ruleSetA) RuleNames() ([]string, error) { 631 return []string{"aws_instance_invalid_type"}, nil 632 } 633 634 type ruleSetB struct{} 635 636 func (*ruleSetB) RuleSetName() (string, error) { 637 return "ruleSetB", nil 638 } 639 func (*ruleSetB) RuleSetVersion() (string, error) { 640 return "0.1.0", nil 641 } 642 func (*ruleSetB) RuleNames() ([]string, error) { 643 return []string{"aws_instance_invalid_ami"}, nil 644 } 645 646 func Test_ValidateRules(t *testing.T) { 647 config := &Config{ 648 Rules: map[string]*RuleConfig{ 649 "aws_instance_invalid_type": { 650 Name: "aws_instance_invalid_type", 651 Enabled: false, 652 }, 653 "aws_instance_invalid_ami": { 654 Name: "aws_instance_invalid_ami", 655 Enabled: true, 656 }, 657 }, 658 } 659 660 cases := []struct { 661 Name string 662 Config *Config 663 RuleSets []RuleSet 664 Err error 665 }{ 666 { 667 Name: "valid", 668 Config: config, 669 RuleSets: []RuleSet{&ruleSetA{}, &ruleSetB{}}, 670 Err: nil, 671 }, 672 { 673 Name: "duplicate", 674 Config: config, 675 RuleSets: []RuleSet{&ruleSetA{}, &ruleSetB{}, &ruleSetB{}}, 676 Err: errors.New("`aws_instance_invalid_ami` is duplicated in ruleSetB and ruleSetB"), 677 }, 678 { 679 Name: "not found", 680 Config: config, 681 RuleSets: []RuleSet{&ruleSetB{}}, 682 Err: errors.New("Rule not found: aws_instance_invalid_type"), 683 }, 684 { 685 Name: "removed rule", 686 Config: &Config{ 687 Rules: map[string]*RuleConfig{ 688 "terraform_dash_in_resource_name": { 689 Name: "terraform_dash_in_resource_name", 690 Enabled: true, 691 }, 692 }, 693 }, 694 RuleSets: []RuleSet{&ruleSetA{}, &ruleSetB{}}, 695 Err: errors.New("`terraform_dash_in_resource_name` rule was removed in v0.16.0. Please use `terraform_naming_convention` rule instead"), 696 }, 697 } 698 699 for _, tc := range cases { 700 err := tc.Config.ValidateRules(tc.RuleSets...) 701 702 if tc.Err == nil { 703 if err != nil { 704 t.Fatalf("Failed %s: Unexpected error occurred: %s", tc.Name, err) 705 } 706 } else { 707 if err == nil { 708 t.Fatalf("Failed %s: Error should have occurred, but didn't", tc.Name) 709 } 710 if err.Error() != tc.Err.Error() { 711 t.Fatalf("Failed %s: error message is not matched: want=%s got=%s", tc.Name, tc.Err, err) 712 } 713 } 714 } 715 } 716 717 func Test_copy(t *testing.T) { 718 cfg := &Config{ 719 Module: true, 720 DeepCheck: true, 721 Force: true, 722 AwsCredentials: client.AwsCredentials{ 723 AccessKey: "access_key", 724 SecretKey: "secret_key", 725 Region: "us-east-1", 726 }, 727 IgnoreModules: map[string]bool{ 728 "github.com/terraform-linters/example-1": true, 729 "github.com/terraform-linters/example-2": false, 730 }, 731 Varfiles: []string{"example1.tfvars", "example2.tfvars"}, 732 Variables: []string{}, 733 DisabledByDefault: true, 734 Rules: map[string]*RuleConfig{ 735 "aws_instance_invalid_type": { 736 Name: "aws_instance_invalid_type", 737 Enabled: false, 738 }, 739 "aws_instance_invalid_ami": { 740 Name: "aws_instance_invalid_ami", 741 Enabled: true, 742 }, 743 }, 744 Plugins: map[string]*PluginConfig{ 745 "foo": { 746 Name: "foo", 747 Enabled: true, 748 }, 749 "bar": { 750 Name: "bar", 751 Enabled: false, 752 }, 753 }, 754 } 755 756 cases := []struct { 757 Name string 758 SideEffect func(*Config) 759 }{ 760 { 761 Name: "Module", 762 SideEffect: func(c *Config) { 763 c.Module = false 764 }, 765 }, 766 { 767 Name: "DeepCheck", 768 SideEffect: func(c *Config) { 769 c.DeepCheck = false 770 }, 771 }, 772 { 773 Name: "Force", 774 SideEffect: func(c *Config) { 775 c.Force = false 776 }, 777 }, 778 { 779 Name: "DisabledByDefault", 780 SideEffect: func(c *Config) { 781 c.DisabledByDefault = false 782 }, 783 }, 784 { 785 Name: "AwsCredentials", 786 SideEffect: func(c *Config) { 787 c.AwsCredentials = client.AwsCredentials{ 788 Profile: "production", 789 Region: "us-east-1", 790 } 791 }, 792 }, 793 { 794 Name: "IgnoreModules", 795 SideEffect: func(c *Config) { 796 c.IgnoreModules["github.com/terraform-linters/example-1"] = false 797 }, 798 }, 799 { 800 Name: "Varfiles", 801 SideEffect: func(c *Config) { 802 c.Varfiles = append(c.Varfiles, "new.tfvars") 803 }, 804 }, 805 { 806 Name: "Variables", 807 SideEffect: func(c *Config) { 808 c.Variables = append(c.Variables, "baz=foo") 809 }, 810 }, 811 { 812 Name: "Rules", 813 SideEffect: func(c *Config) { 814 c.Rules["aws_instance_invalid_type"].Enabled = true 815 }, 816 }, 817 { 818 Name: "Plugins", 819 SideEffect: func(c *Config) { 820 c.Plugins["foo"].Enabled = false 821 }, 822 }, 823 } 824 825 for _, tc := range cases { 826 ret := cfg.copy() 827 if !cmp.Equal(cfg, ret) { 828 t.Fatalf("The copied config doesn't match original: Diff=%s", cmp.Diff(cfg, ret)) 829 } 830 831 tc.SideEffect(ret) 832 if cmp.Equal(cfg, ret) { 833 t.Fatalf("The original was changed when updating `%s`", tc.Name) 834 } 835 } 836 }