github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/aws/validators_test.go (about) 1 package aws 2 3 import ( 4 "fmt" 5 "strings" 6 "testing" 7 8 "github.com/aws/aws-sdk-go/service/s3" 9 ) 10 11 func TestValidateEcrRepositoryName(t *testing.T) { 12 validNames := []string{ 13 "nginx-web-app", 14 "project-a/nginx-web-app", 15 "domain.ltd/nginx-web-app", 16 "3chosome-thing.com/01different-pattern", 17 "0123456789/999999999", 18 "double/forward/slash", 19 "000000000000000", 20 } 21 for _, v := range validNames { 22 _, errors := validateEcrRepositoryName(v, "name") 23 if len(errors) != 0 { 24 t.Fatalf("%q should be a valid ECR repository name: %q", v, errors) 25 } 26 } 27 28 invalidNames := []string{ 29 // length > 256 30 "3cho_some-thing.com/01different.-_pattern01different.-_pattern01diff" + 31 "erent.-_pattern01different.-_pattern01different.-_pattern01different" + 32 ".-_pattern01different.-_pattern01different.-_pattern01different.-_pa" + 33 "ttern01different.-_pattern01different.-_pattern234567", 34 // length < 2 35 "i", 36 "special@character", 37 "different+special=character", 38 "double//slash", 39 "double..dot", 40 "/slash-at-the-beginning", 41 "slash-at-the-end/", 42 } 43 for _, v := range invalidNames { 44 _, errors := validateEcrRepositoryName(v, "name") 45 if len(errors) == 0 { 46 t.Fatalf("%q should be an invalid ECR repository name", v) 47 } 48 } 49 } 50 51 func TestValidateCloudWatchEventRuleName(t *testing.T) { 52 validNames := []string{ 53 "HelloWorl_d", 54 "hello-world", 55 "hello.World0125", 56 } 57 for _, v := range validNames { 58 _, errors := validateCloudWatchEventRuleName(v, "name") 59 if len(errors) != 0 { 60 t.Fatalf("%q should be a valid CW event rule name: %q", v, errors) 61 } 62 } 63 64 invalidNames := []string{ 65 "special@character", 66 "slash/in-the-middle", 67 // Length > 64 68 "TooLooooooooooooooooooooooooooooooooooooooooooooooooooooooongName", 69 } 70 for _, v := range invalidNames { 71 _, errors := validateCloudWatchEventRuleName(v, "name") 72 if len(errors) == 0 { 73 t.Fatalf("%q should be an invalid CW event rule name", v) 74 } 75 } 76 } 77 78 func TestValidateLambdaFunctionName(t *testing.T) { 79 validNames := []string{ 80 "arn:aws:lambda:us-west-2:123456789012:function:ThumbNail", 81 "arn:aws-us-gov:lambda:us-west-2:123456789012:function:ThumbNail", 82 "FunctionName", 83 "function-name", 84 } 85 for _, v := range validNames { 86 _, errors := validateLambdaFunctionName(v, "name") 87 if len(errors) != 0 { 88 t.Fatalf("%q should be a valid Lambda function name: %q", v, errors) 89 } 90 } 91 92 invalidNames := []string{ 93 "/FunctionNameWithSlash", 94 "function.name.with.dots", 95 // length > 140 96 "arn:aws:lambda:us-west-2:123456789012:function:TooLoooooo" + 97 "ooooooooooooooooooooooooooooooooooooooooooooooooooooooo" + 98 "ooooooooooooooooongFunctionName", 99 } 100 for _, v := range invalidNames { 101 _, errors := validateLambdaFunctionName(v, "name") 102 if len(errors) == 0 { 103 t.Fatalf("%q should be an invalid Lambda function name", v) 104 } 105 } 106 } 107 108 func TestValidateLambdaQualifier(t *testing.T) { 109 validNames := []string{ 110 "123", 111 "prod", 112 "PROD", 113 "MyTestEnv", 114 "contains-dashes", 115 "contains_underscores", 116 "$LATEST", 117 } 118 for _, v := range validNames { 119 _, errors := validateLambdaQualifier(v, "name") 120 if len(errors) != 0 { 121 t.Fatalf("%q should be a valid Lambda function qualifier: %q", v, errors) 122 } 123 } 124 125 invalidNames := []string{ 126 // No ARNs allowed 127 "arn:aws:lambda:us-west-2:123456789012:function:prod", 128 // length > 128 129 "TooLooooooooooooooooooooooooooooooooooooooooooooooooooo" + 130 "ooooooooooooooooooooooooooooooooooooooooooooooooooo" + 131 "oooooooooooongQualifier", 132 } 133 for _, v := range invalidNames { 134 _, errors := validateLambdaQualifier(v, "name") 135 if len(errors) == 0 { 136 t.Fatalf("%q should be an invalid Lambda function qualifier", v) 137 } 138 } 139 } 140 141 func TestValidateLambdaPermissionAction(t *testing.T) { 142 validNames := []string{ 143 "lambda:*", 144 "lambda:InvokeFunction", 145 "*", 146 } 147 for _, v := range validNames { 148 _, errors := validateLambdaPermissionAction(v, "action") 149 if len(errors) != 0 { 150 t.Fatalf("%q should be a valid Lambda permission action: %q", v, errors) 151 } 152 } 153 154 invalidNames := []string{ 155 "yada", 156 "lambda:123", 157 "*:*", 158 "lambda:Invoke*", 159 } 160 for _, v := range invalidNames { 161 _, errors := validateLambdaPermissionAction(v, "action") 162 if len(errors) == 0 { 163 t.Fatalf("%q should be an invalid Lambda permission action", v) 164 } 165 } 166 } 167 168 func TestValidateAwsAccountId(t *testing.T) { 169 validNames := []string{ 170 "123456789012", 171 "999999999999", 172 } 173 for _, v := range validNames { 174 _, errors := validateAwsAccountId(v, "account_id") 175 if len(errors) != 0 { 176 t.Fatalf("%q should be a valid AWS Account ID: %q", v, errors) 177 } 178 } 179 180 invalidNames := []string{ 181 "12345678901", // too short 182 "1234567890123", // too long 183 "invalid", 184 "x123456789012", 185 } 186 for _, v := range invalidNames { 187 _, errors := validateAwsAccountId(v, "account_id") 188 if len(errors) == 0 { 189 t.Fatalf("%q should be an invalid AWS Account ID", v) 190 } 191 } 192 } 193 194 func TestValidateArn(t *testing.T) { 195 v := "" 196 _, errors := validateArn(v, "arn") 197 if len(errors) != 0 { 198 t.Fatalf("%q should not be validated as an ARN: %q", v, errors) 199 } 200 201 validNames := []string{ 202 "arn:aws:elasticbeanstalk:us-east-1:123456789012:environment/My App/MyEnvironment", // Beanstalk 203 "arn:aws:iam::123456789012:user/David", // IAM User 204 "arn:aws:rds:eu-west-1:123456789012:db:mysql-db", // RDS 205 "arn:aws:s3:::my_corporate_bucket/exampleobject.png", // S3 object 206 "arn:aws:events:us-east-1:319201112229:rule/rule_name", // CloudWatch Rule 207 "arn:aws:lambda:eu-west-1:319201112229:function:myCustomFunction", // Lambda function 208 "arn:aws:lambda:eu-west-1:319201112229:function:myCustomFunction:Qualifier", // Lambda func qualifier 209 "arn:aws-us-gov:s3:::corp_bucket/object.png", // GovCloud ARN 210 "arn:aws-us-gov:kms:us-gov-west-1:123456789012:key/some-uuid-abc123", // GovCloud KMS ARN 211 } 212 for _, v := range validNames { 213 _, errors := validateArn(v, "arn") 214 if len(errors) != 0 { 215 t.Fatalf("%q should be a valid ARN: %q", v, errors) 216 } 217 } 218 219 invalidNames := []string{ 220 "arn", 221 "123456789012", 222 "arn:aws", 223 "arn:aws:logs", 224 "arn:aws:logs:region:*:*", 225 } 226 for _, v := range invalidNames { 227 _, errors := validateArn(v, "arn") 228 if len(errors) == 0 { 229 t.Fatalf("%q should be an invalid ARN", v) 230 } 231 } 232 } 233 234 func TestValidatePolicyStatementId(t *testing.T) { 235 validNames := []string{ 236 "YadaHereAndThere", 237 "Valid-5tatement_Id", 238 "1234", 239 } 240 for _, v := range validNames { 241 _, errors := validatePolicyStatementId(v, "statement_id") 242 if len(errors) != 0 { 243 t.Fatalf("%q should be a valid Statement ID: %q", v, errors) 244 } 245 } 246 247 invalidNames := []string{ 248 "Invalid/StatementId/with/slashes", 249 "InvalidStatementId.with.dots", 250 // length > 100 251 "TooooLoooooooooooooooooooooooooooooooooooooooooooo" + 252 "ooooooooooooooooooooooooooooooooooooooooStatementId", 253 } 254 for _, v := range invalidNames { 255 _, errors := validatePolicyStatementId(v, "statement_id") 256 if len(errors) == 0 { 257 t.Fatalf("%q should be an invalid Statement ID", v) 258 } 259 } 260 } 261 262 func TestValidateCIDRNetworkAddress(t *testing.T) { 263 cases := []struct { 264 CIDR string 265 ExpectedErrSubstr string 266 }{ 267 {"notacidr", `must contain a valid CIDR`}, 268 {"10.0.1.0/16", `must contain a valid network CIDR`}, 269 {"10.0.1.0/24", ``}, 270 } 271 272 for i, tc := range cases { 273 _, errs := validateCIDRNetworkAddress(tc.CIDR, "foo") 274 if tc.ExpectedErrSubstr == "" { 275 if len(errs) != 0 { 276 t.Fatalf("%d/%d: Expected no error, got errs: %#v", 277 i+1, len(cases), errs) 278 } 279 } else { 280 if len(errs) != 1 { 281 t.Fatalf("%d/%d: Expected 1 err containing %q, got %d errs", 282 i+1, len(cases), tc.ExpectedErrSubstr, len(errs)) 283 } 284 if !strings.Contains(errs[0].Error(), tc.ExpectedErrSubstr) { 285 t.Fatalf("%d/%d: Expected err: %q, to include %q", 286 i+1, len(cases), errs[0], tc.ExpectedErrSubstr) 287 } 288 } 289 } 290 } 291 292 func TestValidateHTTPMethod(t *testing.T) { 293 type testCases struct { 294 Value string 295 ErrCount int 296 } 297 298 invalidCases := []testCases{ 299 { 300 Value: "incorrect", 301 ErrCount: 1, 302 }, 303 { 304 Value: "delete", 305 ErrCount: 1, 306 }, 307 } 308 309 for _, tc := range invalidCases { 310 _, errors := validateHTTPMethod(tc.Value, "http_method") 311 if len(errors) != tc.ErrCount { 312 t.Fatalf("Expected %q to trigger a validation error.", tc.Value) 313 } 314 } 315 316 validCases := []testCases{ 317 { 318 Value: "ANY", 319 ErrCount: 0, 320 }, 321 { 322 Value: "DELETE", 323 ErrCount: 0, 324 }, 325 { 326 Value: "OPTIONS", 327 ErrCount: 0, 328 }, 329 } 330 331 for _, tc := range validCases { 332 _, errors := validateHTTPMethod(tc.Value, "http_method") 333 if len(errors) != tc.ErrCount { 334 t.Fatalf("Expected %q not to trigger a validation error.", tc.Value) 335 } 336 } 337 } 338 339 func TestValidateLogMetricFilterName(t *testing.T) { 340 validNames := []string{ 341 "YadaHereAndThere", 342 "Valid-5Metric_Name", 343 "This . is also %% valid@!)+(", 344 "1234", 345 strings.Repeat("W", 512), 346 } 347 for _, v := range validNames { 348 _, errors := validateLogMetricFilterName(v, "name") 349 if len(errors) != 0 { 350 t.Fatalf("%q should be a valid Log Metric Filter Name: %q", v, errors) 351 } 352 } 353 354 invalidNames := []string{ 355 "Here is a name with: colon", 356 "and here is another * invalid name", 357 "*", 358 // length > 512 359 strings.Repeat("W", 513), 360 } 361 for _, v := range invalidNames { 362 _, errors := validateLogMetricFilterName(v, "name") 363 if len(errors) == 0 { 364 t.Fatalf("%q should be an invalid Log Metric Filter Name", v) 365 } 366 } 367 } 368 369 func TestValidateLogMetricTransformationName(t *testing.T) { 370 validNames := []string{ 371 "YadaHereAndThere", 372 "Valid-5Metric_Name", 373 "This . is also %% valid@!)+(", 374 "1234", 375 "", 376 strings.Repeat("W", 255), 377 } 378 for _, v := range validNames { 379 _, errors := validateLogMetricFilterTransformationName(v, "name") 380 if len(errors) != 0 { 381 t.Fatalf("%q should be a valid Log Metric Filter Transformation Name: %q", v, errors) 382 } 383 } 384 385 invalidNames := []string{ 386 "Here is a name with: colon", 387 "and here is another * invalid name", 388 "also $ invalid", 389 "*", 390 // length > 255 391 strings.Repeat("W", 256), 392 } 393 for _, v := range invalidNames { 394 _, errors := validateLogMetricFilterTransformationName(v, "name") 395 if len(errors) == 0 { 396 t.Fatalf("%q should be an invalid Log Metric Filter Transformation Name", v) 397 } 398 } 399 } 400 401 func TestValidateLogGroupName(t *testing.T) { 402 validNames := []string{ 403 "ValidLogGroupName", 404 "ValidLogGroup.Name", 405 "valid/Log-group", 406 "1234", 407 "YadaValid#0123", 408 "Also_valid-name", 409 strings.Repeat("W", 512), 410 } 411 for _, v := range validNames { 412 _, errors := validateLogGroupName(v, "name") 413 if len(errors) != 0 { 414 t.Fatalf("%q should be a valid Log Group name: %q", v, errors) 415 } 416 } 417 418 invalidNames := []string{ 419 "Here is a name with: colon", 420 "and here is another * invalid name", 421 "also $ invalid", 422 "This . is also %% invalid@!)+(", 423 "*", 424 "", 425 // length > 512 426 strings.Repeat("W", 513), 427 } 428 for _, v := range invalidNames { 429 _, errors := validateLogGroupName(v, "name") 430 if len(errors) == 0 { 431 t.Fatalf("%q should be an invalid Log Group name", v) 432 } 433 } 434 } 435 436 func TestValidateLogGroupNamePrefix(t *testing.T) { 437 validNames := []string{ 438 "ValidLogGroupName", 439 "ValidLogGroup.Name", 440 "valid/Log-group", 441 "1234", 442 "YadaValid#0123", 443 "Also_valid-name", 444 strings.Repeat("W", 483), 445 } 446 for _, v := range validNames { 447 _, errors := validateLogGroupNamePrefix(v, "name_prefix") 448 if len(errors) != 0 { 449 t.Fatalf("%q should be a valid Log Group name prefix: %q", v, errors) 450 } 451 } 452 453 invalidNames := []string{ 454 "Here is a name with: colon", 455 "and here is another * invalid name", 456 "also $ invalid", 457 "This . is also %% invalid@!)+(", 458 "*", 459 "", 460 // length > 483 461 strings.Repeat("W", 484), 462 } 463 for _, v := range invalidNames { 464 _, errors := validateLogGroupNamePrefix(v, "name_prefix") 465 if len(errors) == 0 { 466 t.Fatalf("%q should be an invalid Log Group name prefix", v) 467 } 468 } 469 } 470 471 func TestValidateS3BucketLifecycleTimestamp(t *testing.T) { 472 validDates := []string{ 473 "2016-01-01", 474 "2006-01-02", 475 } 476 477 for _, v := range validDates { 478 _, errors := validateS3BucketLifecycleTimestamp(v, "date") 479 if len(errors) != 0 { 480 t.Fatalf("%q should be valid date: %q", v, errors) 481 } 482 } 483 484 invalidDates := []string{ 485 "Jan 01 2016", 486 "20160101", 487 } 488 489 for _, v := range invalidDates { 490 _, errors := validateS3BucketLifecycleTimestamp(v, "date") 491 if len(errors) == 0 { 492 t.Fatalf("%q should be invalid date", v) 493 } 494 } 495 } 496 497 func TestValidateS3BucketLifecycleStorageClass(t *testing.T) { 498 validStorageClass := []string{ 499 "STANDARD_IA", 500 "GLACIER", 501 } 502 503 for _, v := range validStorageClass { 504 _, errors := validateS3BucketLifecycleStorageClass(v, "storage_class") 505 if len(errors) != 0 { 506 t.Fatalf("%q should be valid storage class: %q", v, errors) 507 } 508 } 509 510 invalidStorageClass := []string{ 511 "STANDARD", 512 "1234", 513 } 514 for _, v := range invalidStorageClass { 515 _, errors := validateS3BucketLifecycleStorageClass(v, "storage_class") 516 if len(errors) == 0 { 517 t.Fatalf("%q should be invalid storage class", v) 518 } 519 } 520 } 521 522 func TestValidateS3BucketReplicationRuleId(t *testing.T) { 523 validId := []string{ 524 "YadaHereAndThere", 525 "Valid-5Rule_ID", 526 "This . is also %% valid@!)+*(:ID", 527 "1234", 528 strings.Repeat("W", 255), 529 } 530 for _, v := range validId { 531 _, errors := validateS3BucketReplicationRuleId(v, "id") 532 if len(errors) != 0 { 533 t.Fatalf("%q should be a valid lifecycle rule id: %q", v, errors) 534 } 535 } 536 537 invalidId := []string{ 538 // length > 255 539 strings.Repeat("W", 256), 540 } 541 for _, v := range invalidId { 542 _, errors := validateS3BucketReplicationRuleId(v, "id") 543 if len(errors) == 0 { 544 t.Fatalf("%q should be an invalid replication configuration rule id", v) 545 } 546 } 547 } 548 549 func TestValidateS3BucketReplicationRulePrefix(t *testing.T) { 550 validId := []string{ 551 "YadaHereAndThere", 552 "Valid-5Rule_ID", 553 "This . is also %% valid@!)+*(:ID", 554 "1234", 555 strings.Repeat("W", 1024), 556 } 557 for _, v := range validId { 558 _, errors := validateS3BucketReplicationRulePrefix(v, "id") 559 if len(errors) != 0 { 560 t.Fatalf("%q should be a valid lifecycle rule id: %q", v, errors) 561 } 562 } 563 564 invalidId := []string{ 565 // length > 1024 566 strings.Repeat("W", 1025), 567 } 568 for _, v := range invalidId { 569 _, errors := validateS3BucketReplicationRulePrefix(v, "id") 570 if len(errors) == 0 { 571 t.Fatalf("%q should be an invalid replication configuration rule id", v) 572 } 573 } 574 } 575 576 func TestValidateS3BucketReplicationDestinationStorageClass(t *testing.T) { 577 validStorageClass := []string{ 578 s3.StorageClassStandard, 579 s3.StorageClassStandardIa, 580 s3.StorageClassReducedRedundancy, 581 } 582 583 for _, v := range validStorageClass { 584 _, errors := validateS3BucketReplicationDestinationStorageClass(v, "storage_class") 585 if len(errors) != 0 { 586 t.Fatalf("%q should be valid storage class: %q", v, errors) 587 } 588 } 589 590 invalidStorageClass := []string{ 591 "FOO", 592 "1234", 593 } 594 for _, v := range invalidStorageClass { 595 _, errors := validateS3BucketReplicationDestinationStorageClass(v, "storage_class") 596 if len(errors) == 0 { 597 t.Fatalf("%q should be invalid storage class", v) 598 } 599 } 600 } 601 602 func TestValidateS3BucketReplicationRuleStatus(t *testing.T) { 603 validRuleStatuses := []string{ 604 s3.ReplicationRuleStatusEnabled, 605 s3.ReplicationRuleStatusDisabled, 606 } 607 608 for _, v := range validRuleStatuses { 609 _, errors := validateS3BucketReplicationRuleStatus(v, "status") 610 if len(errors) != 0 { 611 t.Fatalf("%q should be valid rule status: %q", v, errors) 612 } 613 } 614 615 invalidRuleStatuses := []string{ 616 "FOO", 617 "1234", 618 } 619 for _, v := range invalidRuleStatuses { 620 _, errors := validateS3BucketReplicationRuleStatus(v, "status") 621 if len(errors) == 0 { 622 t.Fatalf("%q should be invalid rule status", v) 623 } 624 } 625 } 626 627 func TestValidateS3BucketLifecycleRuleId(t *testing.T) { 628 validId := []string{ 629 "YadaHereAndThere", 630 "Valid-5Rule_ID", 631 "This . is also %% valid@!)+*(:ID", 632 "1234", 633 strings.Repeat("W", 255), 634 } 635 for _, v := range validId { 636 _, errors := validateS3BucketLifecycleRuleId(v, "id") 637 if len(errors) != 0 { 638 t.Fatalf("%q should be a valid lifecycle rule id: %q", v, errors) 639 } 640 } 641 642 invalidId := []string{ 643 // length > 255 644 strings.Repeat("W", 256), 645 } 646 for _, v := range invalidId { 647 _, errors := validateS3BucketLifecycleRuleId(v, "id") 648 if len(errors) == 0 { 649 t.Fatalf("%q should be an invalid lifecycle rule id", v) 650 } 651 } 652 } 653 654 func TestValidateIntegerInRange(t *testing.T) { 655 validIntegers := []int{-259, 0, 1, 5, 999} 656 min := -259 657 max := 999 658 for _, v := range validIntegers { 659 _, errors := validateIntegerInRange(min, max)(v, "name") 660 if len(errors) != 0 { 661 t.Fatalf("%q should be an integer in range (%d, %d): %q", v, min, max, errors) 662 } 663 } 664 665 invalidIntegers := []int{-260, -99999, 1000, 25678} 666 for _, v := range invalidIntegers { 667 _, errors := validateIntegerInRange(min, max)(v, "name") 668 if len(errors) == 0 { 669 t.Fatalf("%q should be an integer outside range (%d, %d)", v, min, max) 670 } 671 } 672 } 673 674 func TestResourceAWSElastiCacheClusterIdValidation(t *testing.T) { 675 cases := []struct { 676 Value string 677 ErrCount int 678 }{ 679 { 680 Value: "tEsting", 681 ErrCount: 1, 682 }, 683 { 684 Value: "t.sting", 685 ErrCount: 1, 686 }, 687 { 688 Value: "t--sting", 689 ErrCount: 1, 690 }, 691 { 692 Value: "1testing", 693 ErrCount: 1, 694 }, 695 { 696 Value: "testing-", 697 ErrCount: 1, 698 }, 699 { 700 Value: randomString(65), 701 ErrCount: 1, 702 }, 703 } 704 705 for _, tc := range cases { 706 _, errors := validateElastiCacheClusterId(tc.Value, "aws_elasticache_cluster_cluster_id") 707 708 if len(errors) != tc.ErrCount { 709 t.Fatalf("Expected the ElastiCache Cluster cluster_id to trigger a validation error") 710 } 711 } 712 } 713 714 func TestValidateDbEventSubscriptionName(t *testing.T) { 715 validNames := []string{ 716 "valid-name", 717 "valid02-name", 718 "Valid-Name1", 719 } 720 for _, v := range validNames { 721 _, errors := validateDbEventSubscriptionName(v, "name") 722 if len(errors) != 0 { 723 t.Fatalf("%q should be a valid RDS Event Subscription Name: %q", v, errors) 724 } 725 } 726 727 invalidNames := []string{ 728 "Here is a name with: colon", 729 "and here is another * invalid name", 730 "also $ invalid", 731 "This . is also %% invalid@!)+(", 732 "*", 733 "", 734 " ", 735 "_", 736 // length > 255 737 strings.Repeat("W", 256), 738 } 739 for _, v := range invalidNames { 740 _, errors := validateDbEventSubscriptionName(v, "name") 741 if len(errors) == 0 { 742 t.Fatalf("%q should be an invalid RDS Event Subscription Name", v) 743 } 744 } 745 } 746 747 func TestValidateJsonString(t *testing.T) { 748 type testCases struct { 749 Value string 750 ErrCount int 751 } 752 753 invalidCases := []testCases{ 754 { 755 Value: `{0:"1"}`, 756 ErrCount: 1, 757 }, 758 { 759 Value: `{'abc':1}`, 760 ErrCount: 1, 761 }, 762 { 763 Value: `{"def":}`, 764 ErrCount: 1, 765 }, 766 { 767 Value: `{"xyz":[}}`, 768 ErrCount: 1, 769 }, 770 } 771 772 for _, tc := range invalidCases { 773 _, errors := validateJsonString(tc.Value, "json") 774 if len(errors) != tc.ErrCount { 775 t.Fatalf("Expected %q to trigger a validation error.", tc.Value) 776 } 777 } 778 779 validCases := []testCases{ 780 { 781 Value: ``, 782 ErrCount: 0, 783 }, 784 { 785 Value: `{}`, 786 ErrCount: 0, 787 }, 788 { 789 Value: `{"abc":["1","2"]}`, 790 ErrCount: 0, 791 }, 792 } 793 794 for _, tc := range validCases { 795 _, errors := validateJsonString(tc.Value, "json") 796 if len(errors) != tc.ErrCount { 797 t.Fatalf("Expected %q not to trigger a validation error.", tc.Value) 798 } 799 } 800 } 801 802 func TestValidateCloudFormationTemplate(t *testing.T) { 803 type testCases struct { 804 Value string 805 ErrCount int 806 } 807 808 invalidCases := []testCases{ 809 { 810 Value: `{"abc":"`, 811 ErrCount: 1, 812 }, 813 { 814 Value: "abc: [", 815 ErrCount: 1, 816 }, 817 } 818 819 for _, tc := range invalidCases { 820 _, errors := validateCloudFormationTemplate(tc.Value, "template") 821 if len(errors) != tc.ErrCount { 822 t.Fatalf("Expected %q to trigger a validation error.", tc.Value) 823 } 824 } 825 826 validCases := []testCases{ 827 { 828 Value: `{"abc":"1"}`, 829 ErrCount: 0, 830 }, 831 { 832 Value: `abc: 1`, 833 ErrCount: 0, 834 }, 835 } 836 837 for _, tc := range validCases { 838 _, errors := validateCloudFormationTemplate(tc.Value, "template") 839 if len(errors) != tc.ErrCount { 840 t.Fatalf("Expected %q not to trigger a validation error.", tc.Value) 841 } 842 } 843 } 844 845 func TestValidateApiGatewayIntegrationType(t *testing.T) { 846 type testCases struct { 847 Value string 848 ErrCount int 849 } 850 851 invalidCases := []testCases{ 852 { 853 Value: "incorrect", 854 ErrCount: 1, 855 }, 856 { 857 Value: "aws_proxy", 858 ErrCount: 1, 859 }, 860 } 861 862 for _, tc := range invalidCases { 863 _, errors := validateApiGatewayIntegrationType(tc.Value, "types") 864 if len(errors) != tc.ErrCount { 865 t.Fatalf("Expected %q to trigger a validation error.", tc.Value) 866 } 867 } 868 869 validCases := []testCases{ 870 { 871 Value: "MOCK", 872 ErrCount: 0, 873 }, 874 { 875 Value: "AWS_PROXY", 876 ErrCount: 0, 877 }, 878 } 879 880 for _, tc := range validCases { 881 _, errors := validateApiGatewayIntegrationType(tc.Value, "types") 882 if len(errors) != tc.ErrCount { 883 t.Fatalf("Expected %q not to trigger a validation error.", tc.Value) 884 } 885 } 886 } 887 888 func TestValidateSQSQueueName(t *testing.T) { 889 validNames := []string{ 890 "valid-name", 891 "valid02-name", 892 "Valid-Name1", 893 "_", 894 "-", 895 strings.Repeat("W", 80), 896 } 897 for _, v := range validNames { 898 if errors := validateSQSQueueName(v, "name"); len(errors) > 0 { 899 t.Fatalf("%q should be a valid SQS queue Name", v) 900 } 901 } 902 903 invalidNames := []string{ 904 "Here is a name with: colon", 905 "another * invalid name", 906 "also $ invalid", 907 "This . is also %% invalid@!)+(", 908 "*", 909 "", 910 " ", 911 ".", 912 strings.Repeat("W", 81), // length > 80 913 } 914 for _, v := range invalidNames { 915 if errors := validateSQSQueueName(v, "name"); len(errors) == 0 { 916 t.Fatalf("%q should be an invalid SQS queue Name", v) 917 } 918 } 919 } 920 921 func TestValidateSQSFifoQueueName(t *testing.T) { 922 validNames := []string{ 923 "valid-name.fifo", 924 "valid02-name.fifo", 925 "Valid-Name1.fifo", 926 "_.fifo", 927 "a.fifo", 928 "A.fifo", 929 "9.fifo", 930 "-.fifo", 931 fmt.Sprintf("%s.fifo", strings.Repeat("W", 75)), 932 } 933 for _, v := range validNames { 934 if errors := validateSQSFifoQueueName(v, "name"); len(errors) > 0 { 935 t.Fatalf("%q should be a valid SQS FIFO queue Name: %v", v, errors) 936 } 937 } 938 939 invalidNames := []string{ 940 "Here is a name with: colon", 941 "another * invalid name", 942 "also $ invalid", 943 "This . is also %% invalid@!)+(", 944 ".fifo", 945 "*", 946 "", 947 " ", 948 ".", 949 strings.Repeat("W", 81), // length > 80 950 } 951 for _, v := range invalidNames { 952 if errors := validateSQSFifoQueueName(v, "name"); len(errors) == 0 { 953 t.Fatalf("%q should be an invalid SQS FIFO queue Name: %v", v, errors) 954 } 955 } 956 } 957 958 func TestValidateSNSSubscriptionProtocol(t *testing.T) { 959 validProtocols := []string{ 960 "lambda", 961 "sqs", 962 "sqs", 963 "application", 964 "http", 965 "https", 966 } 967 for _, v := range validProtocols { 968 if _, errors := validateSNSSubscriptionProtocol(v, "protocol"); len(errors) > 0 { 969 t.Fatalf("%q should be a valid SNS Subscription protocol: %v", v, errors) 970 } 971 } 972 973 invalidProtocols := []string{ 974 "Email", 975 "email", 976 "Email-JSON", 977 "email-json", 978 "SMS", 979 "sms", 980 } 981 for _, v := range invalidProtocols { 982 if _, errors := validateSNSSubscriptionProtocol(v, "protocol"); len(errors) == 0 { 983 t.Fatalf("%q should be an invalid SNS Subscription protocol: %v", v, errors) 984 } 985 } 986 } 987 988 func TestValidateSecurityRuleType(t *testing.T) { 989 validTypes := []string{ 990 "ingress", 991 "egress", 992 } 993 for _, v := range validTypes { 994 if _, errors := validateSecurityRuleType(v, "type"); len(errors) > 0 { 995 t.Fatalf("%q should be a valid Security Group Rule type: %v", v, errors) 996 } 997 } 998 999 invalidTypes := []string{ 1000 "foo", 1001 "ingresss", 1002 } 1003 for _, v := range invalidTypes { 1004 if _, errors := validateSecurityRuleType(v, "type"); len(errors) == 0 { 1005 t.Fatalf("%q should be an invalid Security Group Rule type: %v", v, errors) 1006 } 1007 } 1008 } 1009 1010 func TestValidateOnceAWeekWindowFormat(t *testing.T) { 1011 cases := []struct { 1012 Value string 1013 ErrCount int 1014 }{ 1015 { 1016 // once a day window format 1017 Value: "04:00-05:00", 1018 ErrCount: 1, 1019 }, 1020 { 1021 // invalid day of week 1022 Value: "san:04:00-san:05:00", 1023 ErrCount: 1, 1024 }, 1025 { 1026 // invalid hour 1027 Value: "sun:24:00-san:25:00", 1028 ErrCount: 1, 1029 }, 1030 { 1031 // invalid min 1032 Value: "sun:04:00-sun:04:60", 1033 ErrCount: 1, 1034 }, 1035 { 1036 // valid format 1037 Value: "sun:04:00-sun:05:00", 1038 ErrCount: 0, 1039 }, 1040 { 1041 // "Sun" can also be used 1042 Value: "Sun:04:00-Sun:05:00", 1043 ErrCount: 0, 1044 }, 1045 { 1046 // valid format 1047 Value: "", 1048 ErrCount: 0, 1049 }, 1050 } 1051 1052 for _, tc := range cases { 1053 _, errors := validateOnceAWeekWindowFormat(tc.Value, "maintenance_window") 1054 1055 if len(errors) != tc.ErrCount { 1056 t.Fatalf("Expected %d validation errors, But got %d errors for \"%s\"", tc.ErrCount, len(errors), tc.Value) 1057 } 1058 } 1059 } 1060 1061 func TestValidateOnceADayWindowFormat(t *testing.T) { 1062 cases := []struct { 1063 Value string 1064 ErrCount int 1065 }{ 1066 { 1067 // once a week window format 1068 Value: "sun:04:00-sun:05:00", 1069 ErrCount: 1, 1070 }, 1071 { 1072 // invalid hour 1073 Value: "24:00-25:00", 1074 ErrCount: 1, 1075 }, 1076 { 1077 // invalid min 1078 Value: "04:00-04:60", 1079 ErrCount: 1, 1080 }, 1081 { 1082 // valid format 1083 Value: "04:00-05:00", 1084 ErrCount: 0, 1085 }, 1086 { 1087 // valid format 1088 Value: "", 1089 ErrCount: 0, 1090 }, 1091 } 1092 1093 for _, tc := range cases { 1094 _, errors := validateOnceADayWindowFormat(tc.Value, "backup_window") 1095 1096 if len(errors) != tc.ErrCount { 1097 t.Fatalf("Expected %d validation errors, But got %d errors for \"%s\"", tc.ErrCount, len(errors), tc.Value) 1098 } 1099 } 1100 } 1101 1102 func TestValidateRoute53RecordType(t *testing.T) { 1103 validTypes := []string{ 1104 "AAAA", 1105 "SOA", 1106 "A", 1107 "TXT", 1108 "CNAME", 1109 "MX", 1110 "NAPTR", 1111 "PTR", 1112 "SPF", 1113 "SRV", 1114 "NS", 1115 } 1116 1117 invalidTypes := []string{ 1118 "a", 1119 "alias", 1120 "SpF", 1121 "Txt", 1122 "AaAA", 1123 } 1124 1125 for _, v := range validTypes { 1126 _, errors := validateRoute53RecordType(v, "route53_record") 1127 if len(errors) != 0 { 1128 t.Fatalf("%q should be a valid Route53 record type: %v", v, errors) 1129 } 1130 } 1131 1132 for _, v := range invalidTypes { 1133 _, errors := validateRoute53RecordType(v, "route53_record") 1134 if len(errors) == 0 { 1135 t.Fatalf("%q should not be a valid Route53 record type", v) 1136 } 1137 } 1138 } 1139 1140 func TestValidateEcsPlacementConstraint(t *testing.T) { 1141 cases := []struct { 1142 constType string 1143 constExpr string 1144 Err bool 1145 }{ 1146 { 1147 constType: "distinctInstance", 1148 constExpr: "", 1149 Err: false, 1150 }, 1151 { 1152 constType: "memberOf", 1153 constExpr: "", 1154 Err: true, 1155 }, 1156 { 1157 constType: "distinctInstance", 1158 constExpr: "expression", 1159 Err: false, 1160 }, 1161 { 1162 constType: "memberOf", 1163 constExpr: "expression", 1164 Err: false, 1165 }, 1166 } 1167 1168 for _, tc := range cases { 1169 if err := validateAwsEcsPlacementConstraint(tc.constType, tc.constExpr); err != nil && !tc.Err { 1170 t.Fatalf("Unexpected validation error for \"%s:%s\": %s", 1171 tc.constType, tc.constExpr, err) 1172 } 1173 1174 } 1175 } 1176 1177 func TestValidateEcsPlacementStrategy(t *testing.T) { 1178 cases := []struct { 1179 stratType string 1180 stratField string 1181 Err bool 1182 }{ 1183 { 1184 stratType: "random", 1185 stratField: "", 1186 Err: false, 1187 }, 1188 { 1189 stratType: "spread", 1190 stratField: "instanceID", 1191 Err: false, 1192 }, 1193 { 1194 stratType: "binpack", 1195 stratField: "cpu", 1196 Err: false, 1197 }, 1198 { 1199 stratType: "binpack", 1200 stratField: "memory", 1201 Err: false, 1202 }, 1203 { 1204 stratType: "binpack", 1205 stratField: "disk", 1206 Err: true, 1207 }, 1208 { 1209 stratType: "fakeType", 1210 stratField: "", 1211 Err: true, 1212 }, 1213 } 1214 1215 for _, tc := range cases { 1216 if err := validateAwsEcsPlacementStrategy(tc.stratType, tc.stratField); err != nil && !tc.Err { 1217 t.Fatalf("Unexpected validation error for \"%s:%s\": %s", 1218 tc.stratType, tc.stratField, err) 1219 } 1220 } 1221 } 1222 1223 func TestValidateStepFunctionActivityName(t *testing.T) { 1224 validTypes := []string{ 1225 "foo", 1226 "FooBar123", 1227 } 1228 1229 invalidTypes := []string{ 1230 strings.Repeat("W", 81), // length > 80 1231 } 1232 1233 for _, v := range validTypes { 1234 _, errors := validateSfnActivityName(v, "name") 1235 if len(errors) != 0 { 1236 t.Fatalf("%q should be a valid Step Function Activity name: %v", v, errors) 1237 } 1238 } 1239 1240 for _, v := range invalidTypes { 1241 _, errors := validateSfnActivityName(v, "name") 1242 if len(errors) == 0 { 1243 t.Fatalf("%q should not be a valid Step Function Activity name", v) 1244 } 1245 } 1246 } 1247 1248 func TestValidateStepFunctionStateMachineDefinition(t *testing.T) { 1249 validDefinitions := []string{ 1250 "foobar", 1251 strings.Repeat("W", 1048576), 1252 } 1253 1254 invalidDefinitions := []string{ 1255 strings.Repeat("W", 1048577), // length > 1048576 1256 } 1257 1258 for _, v := range validDefinitions { 1259 _, errors := validateSfnStateMachineDefinition(v, "definition") 1260 if len(errors) != 0 { 1261 t.Fatalf("%q should be a valid Step Function State Machine definition: %v", v, errors) 1262 } 1263 } 1264 1265 for _, v := range invalidDefinitions { 1266 _, errors := validateSfnStateMachineDefinition(v, "definition") 1267 if len(errors) == 0 { 1268 t.Fatalf("%q should not be a valid Step Function State Machine definition", v) 1269 } 1270 } 1271 } 1272 1273 func TestValidateStepFunctionStateMachineName(t *testing.T) { 1274 validTypes := []string{ 1275 "foo", 1276 "BAR", 1277 "FooBar123", 1278 "FooBar123Baz-_", 1279 } 1280 1281 invalidTypes := []string{ 1282 "foo bar", 1283 "foo<bar>", 1284 "foo{bar}", 1285 "foo[bar]", 1286 "foo*bar", 1287 "foo?bar", 1288 "foo#bar", 1289 "foo%bar", 1290 "foo\bar", 1291 "foo^bar", 1292 "foo|bar", 1293 "foo~bar", 1294 "foo$bar", 1295 "foo&bar", 1296 "foo,bar", 1297 "foo:bar", 1298 "foo;bar", 1299 "foo/bar", 1300 strings.Repeat("W", 81), // length > 80 1301 } 1302 1303 for _, v := range validTypes { 1304 _, errors := validateSfnStateMachineName(v, "name") 1305 if len(errors) != 0 { 1306 t.Fatalf("%q should be a valid Step Function State Machine name: %v", v, errors) 1307 } 1308 } 1309 1310 for _, v := range invalidTypes { 1311 _, errors := validateSfnStateMachineName(v, "name") 1312 if len(errors) == 0 { 1313 t.Fatalf("%q should not be a valid Step Function State Machine name", v) 1314 } 1315 } 1316 } 1317 1318 func TestValidateEmrEbsVolumeType(t *testing.T) { 1319 cases := []struct { 1320 VolType string 1321 ErrCount int 1322 }{ 1323 { 1324 VolType: "gp2", 1325 ErrCount: 0, 1326 }, 1327 { 1328 VolType: "io1", 1329 ErrCount: 0, 1330 }, 1331 { 1332 VolType: "standard", 1333 ErrCount: 0, 1334 }, 1335 { 1336 VolType: "stand", 1337 ErrCount: 1, 1338 }, 1339 { 1340 VolType: "io", 1341 ErrCount: 1, 1342 }, 1343 { 1344 VolType: "gp1", 1345 ErrCount: 1, 1346 }, 1347 { 1348 VolType: "fast-disk", 1349 ErrCount: 1, 1350 }, 1351 } 1352 1353 for _, tc := range cases { 1354 _, errors := validateAwsEmrEbsVolumeType(tc.VolType, "volume") 1355 1356 if len(errors) != tc.ErrCount { 1357 t.Fatalf("Expected %d errors, got %d: %s", tc.ErrCount, len(errors), errors) 1358 } 1359 } 1360 } 1361 1362 func TestValidateAppautoscalingScalableDimension(t *testing.T) { 1363 cases := []struct { 1364 Value string 1365 ErrCount int 1366 }{ 1367 { 1368 Value: "ecs:service:DesiredCount", 1369 ErrCount: 0, 1370 }, 1371 { 1372 Value: "ec2:spot-fleet-request:TargetCapacity", 1373 ErrCount: 0, 1374 }, 1375 { 1376 Value: "ec2:service:DesiredCount", 1377 ErrCount: 1, 1378 }, 1379 { 1380 Value: "ecs:spot-fleet-request:TargetCapacity", 1381 ErrCount: 1, 1382 }, 1383 { 1384 Value: "", 1385 ErrCount: 1, 1386 }, 1387 } 1388 1389 for _, tc := range cases { 1390 _, errors := validateAppautoscalingScalableDimension(tc.Value, "scalable_dimension") 1391 if len(errors) != tc.ErrCount { 1392 t.Fatalf("Scalable Dimension validation failed for value %q: %q", tc.Value, errors) 1393 } 1394 } 1395 } 1396 1397 func TestValidateAppautoscalingServiceNamespace(t *testing.T) { 1398 cases := []struct { 1399 Value string 1400 ErrCount int 1401 }{ 1402 { 1403 Value: "ecs", 1404 ErrCount: 0, 1405 }, 1406 { 1407 Value: "ec2", 1408 ErrCount: 0, 1409 }, 1410 { 1411 Value: "autoscaling", 1412 ErrCount: 1, 1413 }, 1414 { 1415 Value: "s3", 1416 ErrCount: 1, 1417 }, 1418 { 1419 Value: "es", 1420 ErrCount: 1, 1421 }, 1422 { 1423 Value: "", 1424 ErrCount: 1, 1425 }, 1426 } 1427 1428 for _, tc := range cases { 1429 _, errors := validateAppautoscalingServiceNamespace(tc.Value, "service_namespace") 1430 if len(errors) != tc.ErrCount { 1431 t.Fatalf("Service Namespace validation failed for value %q: %q", tc.Value, errors) 1432 } 1433 } 1434 } 1435 1436 func TestValidateDmsEndpointId(t *testing.T) { 1437 validIds := []string{ 1438 "tf-test-endpoint-1", 1439 "tfTestEndpoint", 1440 } 1441 1442 for _, s := range validIds { 1443 _, errors := validateDmsEndpointId(s, "endpoint_id") 1444 if len(errors) > 0 { 1445 t.Fatalf("%q should be a valid endpoint id: %v", s, errors) 1446 } 1447 } 1448 1449 invalidIds := []string{ 1450 "tf_test_endpoint_1", 1451 "tf.test.endpoint.1", 1452 "tf test endpoint 1", 1453 "tf-test-endpoint-1!", 1454 "tf-test-endpoint-1-", 1455 "tf-test-endpoint--1", 1456 "tf-test-endpoint-1tf-test-endpoint-1tf-test-endpoint-1tf-test-endpoint-1tf-test-endpoint-1tf-test-endpoint-1tf-test-endpoint-1tf-test-endpoint-1tf-test-endpoint-1tf-test-endpoint-1tf-test-endpoint-1tf-test-endpoint-1tf-test-endpoint-1tf-test-endpoint-1tf-test-endpoint-1", 1457 } 1458 1459 for _, s := range invalidIds { 1460 _, errors := validateDmsEndpointId(s, "endpoint_id") 1461 if len(errors) == 0 { 1462 t.Fatalf("%q should not be a valid endpoint id: %v", s, errors) 1463 } 1464 } 1465 } 1466 1467 func TestValidateDmsCertificateId(t *testing.T) { 1468 validIds := []string{ 1469 "tf-test-certificate-1", 1470 "tfTestEndpoint", 1471 } 1472 1473 for _, s := range validIds { 1474 _, errors := validateDmsCertificateId(s, "certificate_id") 1475 if len(errors) > 0 { 1476 t.Fatalf("%q should be a valid certificate id: %v", s, errors) 1477 } 1478 } 1479 1480 invalidIds := []string{ 1481 "tf_test_certificate_1", 1482 "tf.test.certificate.1", 1483 "tf test certificate 1", 1484 "tf-test-certificate-1!", 1485 "tf-test-certificate-1-", 1486 "tf-test-certificate--1", 1487 "tf-test-certificate-1tf-test-certificate-1tf-test-certificate-1tf-test-certificate-1tf-test-certificate-1tf-test-certificate-1tf-test-certificate-1tf-test-certificate-1tf-test-certificate-1tf-test-certificate-1tf-test-certificate-1tf-test-certificate-1tf-test-certificate-1tf-test-certificate-1tf-test-certificate-1", 1488 } 1489 1490 for _, s := range invalidIds { 1491 _, errors := validateDmsEndpointId(s, "certificate_id") 1492 if len(errors) == 0 { 1493 t.Fatalf("%q should not be a valid certificate id: %v", s, errors) 1494 } 1495 } 1496 } 1497 1498 func TestValidateDmsReplicationInstanceId(t *testing.T) { 1499 validIds := []string{ 1500 "tf-test-replication-instance-1", 1501 "tfTestReplicaitonInstance", 1502 } 1503 1504 for _, s := range validIds { 1505 _, errors := validateDmsReplicationInstanceId(s, "replicaiton_instance_id") 1506 if len(errors) > 0 { 1507 t.Fatalf("%q should be a valid replication instance id: %v", s, errors) 1508 } 1509 } 1510 1511 invalidIds := []string{ 1512 "tf_test_replication-instance_1", 1513 "tf.test.replication.instance.1", 1514 "tf test replication instance 1", 1515 "tf-test-replication-instance-1!", 1516 "tf-test-replication-instance-1-", 1517 "tf-test-replication-instance--1", 1518 "tf-test-replication-instance-1tf-test-replication-instance-1tf-test-replication-instance-1", 1519 } 1520 1521 for _, s := range invalidIds { 1522 _, errors := validateDmsReplicationInstanceId(s, "replication_instance_id") 1523 if len(errors) == 0 { 1524 t.Fatalf("%q should not be a valid replication instance id: %v", s, errors) 1525 } 1526 } 1527 } 1528 1529 func TestValidateDmsReplicationSubnetGroupId(t *testing.T) { 1530 validIds := []string{ 1531 "tf-test-replication-subnet-group-1", 1532 "tf_test_replication_subnet_group_1", 1533 "tf.test.replication.subnet.group.1", 1534 "tf test replication subnet group 1", 1535 "tfTestReplicationSubnetGroup", 1536 } 1537 1538 for _, s := range validIds { 1539 _, errors := validateDmsReplicationSubnetGroupId(s, "replication_subnet_group_id") 1540 if len(errors) > 0 { 1541 t.Fatalf("%q should be a valid replication subnet group id: %v", s, errors) 1542 } 1543 } 1544 1545 invalidIds := []string{ 1546 "default", 1547 "tf-test-replication-subnet-group-1!", 1548 "tf-test-replication-subnet-group-1tf-test-replication-subnet-group-1tf-test-replication-subnet-group-1tf-test-replication-subnet-group-1tf-test-replication-subnet-group-1tf-test-replication-subnet-group-1tf-test-replication-subnet-group-1tf-test-replication-subnet-group-1", 1549 } 1550 1551 for _, s := range invalidIds { 1552 _, errors := validateDmsReplicationSubnetGroupId(s, "replication_subnet_group_id") 1553 if len(errors) == 0 { 1554 t.Fatalf("%q should not be a valid replication subnet group id: %v", s, errors) 1555 } 1556 } 1557 } 1558 1559 func TestValidateDmsReplicationTaskId(t *testing.T) { 1560 validIds := []string{ 1561 "tf-test-replication-task-1", 1562 "tfTestReplicationTask", 1563 } 1564 1565 for _, s := range validIds { 1566 _, errors := validateDmsReplicationTaskId(s, "replication_task_id") 1567 if len(errors) > 0 { 1568 t.Fatalf("%q should be a valid replication task id: %v", s, errors) 1569 } 1570 } 1571 1572 invalidIds := []string{ 1573 "tf_test_replication_task_1", 1574 "tf.test.replication.task.1", 1575 "tf test replication task 1", 1576 "tf-test-replication-task-1!", 1577 "tf-test-replication-task-1-", 1578 "tf-test-replication-task--1", 1579 "tf-test-replication-task-1tf-test-replication-task-1tf-test-replication-task-1tf-test-replication-task-1tf-test-replication-task-1tf-test-replication-task-1tf-test-replication-task-1tf-test-replication-task-1tf-test-replication-task-1tf-test-replication-task-1", 1580 } 1581 1582 for _, s := range invalidIds { 1583 _, errors := validateDmsReplicationTaskId(s, "replication_task_id") 1584 if len(errors) == 0 { 1585 t.Fatalf("%q should not be a valid replication task id: %v", s, errors) 1586 } 1587 } 1588 } 1589 1590 func TestValidateAccountAlias(t *testing.T) { 1591 validAliases := []string{ 1592 "tf-alias", 1593 "0tf-alias1", 1594 } 1595 1596 for _, s := range validAliases { 1597 _, errors := validateAccountAlias(s, "account_alias") 1598 if len(errors) > 0 { 1599 t.Fatalf("%q should be a valid account alias: %v", s, errors) 1600 } 1601 } 1602 1603 invalidAliases := []string{ 1604 "tf", 1605 "-tf", 1606 "tf-", 1607 "TF-Alias", 1608 "tf-alias-tf-alias-tf-alias-tf-alias-tf-alias-tf-alias-tf-alias-tf-alias", 1609 } 1610 1611 for _, s := range invalidAliases { 1612 _, errors := validateAccountAlias(s, "account_alias") 1613 if len(errors) == 0 { 1614 t.Fatalf("%q should not be a valid account alias: %v", s, errors) 1615 } 1616 } 1617 } 1618 1619 func TestValidateIamRoleProfileName(t *testing.T) { 1620 validNames := []string{ 1621 "tf-test-role-profile-1", 1622 } 1623 1624 for _, s := range validNames { 1625 _, errors := validateIamRolePolicyName(s, "name") 1626 if len(errors) > 0 { 1627 t.Fatalf("%q should be a valid IAM role policy name: %v", s, errors) 1628 } 1629 } 1630 1631 invalidNames := []string{ 1632 "invalid#name", 1633 "this-is-a-very-long-role-policy-name-this-is-a-very-long-role-policy-name-this-is-a-very-long-role-policy-name-this-is-a-very-long", 1634 } 1635 1636 for _, s := range invalidNames { 1637 _, errors := validateIamRolePolicyName(s, "name") 1638 if len(errors) == 0 { 1639 t.Fatalf("%q should not be a valid IAM role policy name: %v", s, errors) 1640 } 1641 } 1642 } 1643 1644 func TestValidateIamRoleProfileNamePrefix(t *testing.T) { 1645 validNamePrefixes := []string{ 1646 "tf-test-role-profile-", 1647 } 1648 1649 for _, s := range validNamePrefixes { 1650 _, errors := validateIamRolePolicyNamePrefix(s, "name_prefix") 1651 if len(errors) > 0 { 1652 t.Fatalf("%q should be a valid IAM role policy name prefix: %v", s, errors) 1653 } 1654 } 1655 1656 invalidNamePrefixes := []string{ 1657 "invalid#name_prefix", 1658 "this-is-a-very-long-role-policy-name-prefix-this-is-a-very-long-role-policy-name-prefix-this-is-a-very-", 1659 } 1660 1661 for _, s := range invalidNamePrefixes { 1662 _, errors := validateIamRolePolicyNamePrefix(s, "name_prefix") 1663 if len(errors) == 0 { 1664 t.Fatalf("%q should not be a valid IAM role policy name prefix: %v", s, errors) 1665 } 1666 } 1667 } 1668 1669 func TestValidateApiGatewayUsagePlanQuotaSettingsPeriod(t *testing.T) { 1670 validEntries := []string{ 1671 "DAY", 1672 "WEEK", 1673 "MONTH", 1674 } 1675 1676 invalidEntries := []string{ 1677 "fooBAR", 1678 "foobar45Baz", 1679 "foobar45Baz@!", 1680 } 1681 1682 for _, v := range validEntries { 1683 _, errors := validateApiGatewayUsagePlanQuotaSettingsPeriod(v, "name") 1684 if len(errors) != 0 { 1685 t.Fatalf("%q should be a valid API Gateway Quota Settings Period: %v", v, errors) 1686 } 1687 } 1688 1689 for _, v := range invalidEntries { 1690 _, errors := validateApiGatewayUsagePlanQuotaSettingsPeriod(v, "name") 1691 if len(errors) == 0 { 1692 t.Fatalf("%q should not be a API Gateway Quota Settings Period", v) 1693 } 1694 } 1695 } 1696 1697 func TestValidateApiGatewayUsagePlanQuotaSettings(t *testing.T) { 1698 cases := []struct { 1699 Offset int 1700 Period string 1701 ErrCount int 1702 }{ 1703 { 1704 Offset: 0, 1705 Period: "DAY", 1706 ErrCount: 0, 1707 }, 1708 { 1709 Offset: -1, 1710 Period: "DAY", 1711 ErrCount: 1, 1712 }, 1713 { 1714 Offset: 1, 1715 Period: "DAY", 1716 ErrCount: 1, 1717 }, 1718 { 1719 Offset: 0, 1720 Period: "WEEK", 1721 ErrCount: 0, 1722 }, 1723 { 1724 Offset: 6, 1725 Period: "WEEK", 1726 ErrCount: 0, 1727 }, 1728 { 1729 Offset: -1, 1730 Period: "WEEK", 1731 ErrCount: 1, 1732 }, 1733 { 1734 Offset: 7, 1735 Period: "WEEK", 1736 ErrCount: 1, 1737 }, 1738 { 1739 Offset: 0, 1740 Period: "MONTH", 1741 ErrCount: 0, 1742 }, 1743 { 1744 Offset: 27, 1745 Period: "MONTH", 1746 ErrCount: 0, 1747 }, 1748 { 1749 Offset: -1, 1750 Period: "MONTH", 1751 ErrCount: 1, 1752 }, 1753 { 1754 Offset: 28, 1755 Period: "MONTH", 1756 ErrCount: 1, 1757 }, 1758 } 1759 1760 for _, tc := range cases { 1761 m := make(map[string]interface{}) 1762 m["offset"] = tc.Offset 1763 m["period"] = tc.Period 1764 1765 errors := validateApiGatewayUsagePlanQuotaSettings(m) 1766 if len(errors) != tc.ErrCount { 1767 t.Fatalf("API Gateway Usage Plan Quota Settings validation failed: %v", errors) 1768 } 1769 } 1770 } 1771 1772 func TestValidateElbName(t *testing.T) { 1773 validNames := []string{ 1774 "tf-test-elb", 1775 } 1776 1777 for _, s := range validNames { 1778 _, errors := validateElbName(s, "name") 1779 if len(errors) > 0 { 1780 t.Fatalf("%q should be a valid ELB name: %v", s, errors) 1781 } 1782 } 1783 1784 invalidNames := []string{ 1785 "tf.test.elb.1", 1786 "tf-test-elb-tf-test-elb-tf-test-elb", 1787 "-tf-test-elb", 1788 "tf-test-elb-", 1789 } 1790 1791 for _, s := range invalidNames { 1792 _, errors := validateElbName(s, "name") 1793 if len(errors) == 0 { 1794 t.Fatalf("%q should not be a valid ELB name: %v", s, errors) 1795 } 1796 } 1797 } 1798 1799 func TestValidateElbNamePrefix(t *testing.T) { 1800 validNamePrefixes := []string{ 1801 "test-", 1802 } 1803 1804 for _, s := range validNamePrefixes { 1805 _, errors := validateElbNamePrefix(s, "name_prefix") 1806 if len(errors) > 0 { 1807 t.Fatalf("%q should be a valid ELB name prefix: %v", s, errors) 1808 } 1809 } 1810 1811 invalidNamePrefixes := []string{ 1812 "tf.test.elb.", 1813 "tf-test", 1814 "-test", 1815 } 1816 1817 for _, s := range invalidNamePrefixes { 1818 _, errors := validateElbNamePrefix(s, "name_prefix") 1819 if len(errors) == 0 { 1820 t.Fatalf("%q should not be a valid ELB name prefix: %v", s, errors) 1821 } 1822 } 1823 } 1824 1825 func TestValidateDbSubnetGroupName(t *testing.T) { 1826 cases := []struct { 1827 Value string 1828 ErrCount int 1829 }{ 1830 { 1831 Value: "tEsting", 1832 ErrCount: 1, 1833 }, 1834 { 1835 Value: "testing?", 1836 ErrCount: 1, 1837 }, 1838 { 1839 Value: "default", 1840 ErrCount: 1, 1841 }, 1842 { 1843 Value: randomString(300), 1844 ErrCount: 1, 1845 }, 1846 } 1847 1848 for _, tc := range cases { 1849 _, errors := validateDbSubnetGroupName(tc.Value, "aws_db_subnet_group") 1850 1851 if len(errors) != tc.ErrCount { 1852 t.Fatalf("Expected the DB Subnet Group name to trigger a validation error") 1853 } 1854 } 1855 } 1856 1857 func TestValidateDbSubnetGroupNamePrefix(t *testing.T) { 1858 cases := []struct { 1859 Value string 1860 ErrCount int 1861 }{ 1862 { 1863 Value: "tEsting", 1864 ErrCount: 1, 1865 }, 1866 { 1867 Value: "testing?", 1868 ErrCount: 1, 1869 }, 1870 { 1871 Value: randomString(230), 1872 ErrCount: 1, 1873 }, 1874 } 1875 1876 for _, tc := range cases { 1877 _, errors := validateDbSubnetGroupNamePrefix(tc.Value, "aws_db_subnet_group") 1878 1879 if len(errors) != tc.ErrCount { 1880 t.Fatalf("Expected the DB Subnet Group name prefix to trigger a validation error") 1881 } 1882 } 1883 } 1884 1885 func TestValidateDbOptionGroupName(t *testing.T) { 1886 cases := []struct { 1887 Value string 1888 ErrCount int 1889 }{ 1890 { 1891 Value: "testing123!", 1892 ErrCount: 1, 1893 }, 1894 { 1895 Value: "1testing123", 1896 ErrCount: 1, 1897 }, 1898 { 1899 Value: "testing--123", 1900 ErrCount: 1, 1901 }, 1902 { 1903 Value: "testing123-", 1904 ErrCount: 1, 1905 }, 1906 { 1907 Value: randomString(256), 1908 ErrCount: 1, 1909 }, 1910 } 1911 1912 for _, tc := range cases { 1913 _, errors := validateDbOptionGroupName(tc.Value, "aws_db_option_group_name") 1914 1915 if len(errors) != tc.ErrCount { 1916 t.Fatalf("Expected the DB Option Group Name to trigger a validation error") 1917 } 1918 } 1919 } 1920 1921 func TestValidateDbOptionGroupNamePrefix(t *testing.T) { 1922 cases := []struct { 1923 Value string 1924 ErrCount int 1925 }{ 1926 { 1927 Value: "testing123!", 1928 ErrCount: 1, 1929 }, 1930 { 1931 Value: "1testing123", 1932 ErrCount: 1, 1933 }, 1934 { 1935 Value: "testing--123", 1936 ErrCount: 1, 1937 }, 1938 { 1939 Value: randomString(230), 1940 ErrCount: 1, 1941 }, 1942 } 1943 1944 for _, tc := range cases { 1945 _, errors := validateDbOptionGroupNamePrefix(tc.Value, "aws_db_option_group_name") 1946 1947 if len(errors) != tc.ErrCount { 1948 t.Fatalf("Expected the DB Option Group name prefix to trigger a validation error") 1949 } 1950 } 1951 } 1952 1953 func TestValidateOpenIdURL(t *testing.T) { 1954 cases := []struct { 1955 Value string 1956 ErrCount int 1957 }{ 1958 { 1959 Value: "http://wrong.scheme.com", 1960 ErrCount: 1, 1961 }, 1962 { 1963 Value: "ftp://wrong.scheme.co.uk", 1964 ErrCount: 1, 1965 }, 1966 { 1967 Value: "%@invalidUrl", 1968 ErrCount: 1, 1969 }, 1970 { 1971 Value: "https://example.com/?query=param", 1972 ErrCount: 1, 1973 }, 1974 } 1975 1976 for _, tc := range cases { 1977 _, errors := validateOpenIdURL(tc.Value, "url") 1978 1979 if len(errors) != tc.ErrCount { 1980 t.Fatalf("Expected %d of OpenID URL validation errors, got %d", tc.ErrCount, len(errors)) 1981 } 1982 } 1983 } 1984 1985 func TestValidateAwsKmsName(t *testing.T) { 1986 cases := []struct { 1987 Value string 1988 ErrCount int 1989 }{ 1990 { 1991 Value: "alias/aws/s3", 1992 ErrCount: 0, 1993 }, 1994 { 1995 Value: "alias/hashicorp", 1996 ErrCount: 0, 1997 }, 1998 { 1999 Value: "hashicorp", 2000 ErrCount: 1, 2001 }, 2002 { 2003 Value: "hashicorp/terraform", 2004 ErrCount: 1, 2005 }, 2006 } 2007 2008 for _, tc := range cases { 2009 _, errors := validateAwsKmsName(tc.Value, "name") 2010 if len(errors) != tc.ErrCount { 2011 t.Fatalf("AWS KMS Alias Name validation failed: %v", errors) 2012 } 2013 } 2014 } 2015 2016 func TestValidateCognitoIdentityPoolName(t *testing.T) { 2017 validValues := []string{ 2018 "123", 2019 "1 2 3", 2020 "foo", 2021 "foo bar", 2022 "foo_bar", 2023 "1foo 2bar 3", 2024 } 2025 2026 for _, s := range validValues { 2027 _, errors := validateCognitoIdentityPoolName(s, "identity_pool_name") 2028 if len(errors) > 0 { 2029 t.Fatalf("%q should be a valid Cognito Identity Pool Name: %v", s, errors) 2030 } 2031 } 2032 2033 invalidValues := []string{ 2034 "1-2-3", 2035 "foo!", 2036 "foo-bar", 2037 "foo-bar", 2038 "foo1-bar2", 2039 } 2040 2041 for _, s := range invalidValues { 2042 _, errors := validateCognitoIdentityPoolName(s, "identity_pool_name") 2043 if len(errors) == 0 { 2044 t.Fatalf("%q should not be a valid Cognito Identity Pool Name: %v", s, errors) 2045 } 2046 } 2047 } 2048 2049 func TestValidateCognitoProviderDeveloperName(t *testing.T) { 2050 validValues := []string{ 2051 "1", 2052 "foo", 2053 "1.2", 2054 "foo1-bar2-baz3", 2055 "foo_bar", 2056 } 2057 2058 for _, s := range validValues { 2059 _, errors := validateCognitoProviderDeveloperName(s, "developer_provider_name") 2060 if len(errors) > 0 { 2061 t.Fatalf("%q should be a valid Cognito Provider Developer Name: %v", s, errors) 2062 } 2063 } 2064 2065 invalidValues := []string{ 2066 "foo!", 2067 "foo:bar", 2068 "foo/bar", 2069 "foo;bar", 2070 } 2071 2072 for _, s := range invalidValues { 2073 _, errors := validateCognitoProviderDeveloperName(s, "developer_provider_name") 2074 if len(errors) == 0 { 2075 t.Fatalf("%q should not be a valid Cognito Provider Developer Name: %v", s, errors) 2076 } 2077 } 2078 } 2079 2080 func TestValidateCognitoSupportedLoginProviders(t *testing.T) { 2081 validValues := []string{ 2082 "foo", 2083 "7346241598935552", 2084 "123456789012.apps.googleusercontent.com", 2085 "foo_bar", 2086 "foo;bar", 2087 "foo/bar", 2088 "foo-bar", 2089 "xvz1evFS4wEEPTGEFPHBog;kAcSOqF21Fu85e7zjz7ZN2U4ZRhfV3WpwPAoE3Z7kBw", 2090 strings.Repeat("W", 128), 2091 } 2092 2093 for _, s := range validValues { 2094 _, errors := validateCognitoSupportedLoginProviders(s, "supported_login_providers") 2095 if len(errors) > 0 { 2096 t.Fatalf("%q should be a valid Cognito Supported Login Providers: %v", s, errors) 2097 } 2098 } 2099 2100 invalidValues := []string{ 2101 "", 2102 strings.Repeat("W", 129), // > 128 2103 "foo:bar_baz", 2104 "foobar,foobaz", 2105 "foobar=foobaz", 2106 } 2107 2108 for _, s := range invalidValues { 2109 _, errors := validateCognitoSupportedLoginProviders(s, "supported_login_providers") 2110 if len(errors) == 0 { 2111 t.Fatalf("%q should not be a valid Cognito Supported Login Providers: %v", s, errors) 2112 } 2113 } 2114 } 2115 2116 func TestValidateCognitoIdentityProvidersClientId(t *testing.T) { 2117 validValues := []string{ 2118 "7lhlkkfbfb4q5kpp90urffao", 2119 "12345678", 2120 "foo_123", 2121 strings.Repeat("W", 128), 2122 } 2123 2124 for _, s := range validValues { 2125 _, errors := validateCognitoIdentityProvidersClientId(s, "client_id") 2126 if len(errors) > 0 { 2127 t.Fatalf("%q should be a valid Cognito Identity Provider Client ID: %v", s, errors) 2128 } 2129 } 2130 2131 invalidValues := []string{ 2132 "", 2133 strings.Repeat("W", 129), // > 128 2134 "foo-bar", 2135 "foo:bar", 2136 "foo;bar", 2137 } 2138 2139 for _, s := range invalidValues { 2140 _, errors := validateCognitoIdentityProvidersClientId(s, "client_id") 2141 if len(errors) == 0 { 2142 t.Fatalf("%q should not be a valid Cognito Identity Provider Client ID: %v", s, errors) 2143 } 2144 } 2145 } 2146 2147 func TestValidateCognitoIdentityProvidersProviderName(t *testing.T) { 2148 validValues := []string{ 2149 "foo", 2150 "7346241598935552", 2151 "foo_bar", 2152 "foo:bar", 2153 "foo/bar", 2154 "foo-bar", 2155 "cognito-idp.us-east-1.amazonaws.com/us-east-1_Zr231apJu", 2156 strings.Repeat("W", 128), 2157 } 2158 2159 for _, s := range validValues { 2160 _, errors := validateCognitoIdentityProvidersProviderName(s, "provider_name") 2161 if len(errors) > 0 { 2162 t.Fatalf("%q should be a valid Cognito Identity Provider Name: %v", s, errors) 2163 } 2164 } 2165 2166 invalidValues := []string{ 2167 "", 2168 strings.Repeat("W", 129), // > 128 2169 "foo;bar_baz", 2170 "foobar,foobaz", 2171 "foobar=foobaz", 2172 } 2173 2174 for _, s := range invalidValues { 2175 _, errors := validateCognitoIdentityProvidersProviderName(s, "provider_name") 2176 if len(errors) == 0 { 2177 t.Fatalf("%q should not be a valid Cognito Identity Provider Name: %v", s, errors) 2178 } 2179 } 2180 } 2181 2182 func TestValidateWafMetricName(t *testing.T) { 2183 validNames := []string{ 2184 "testrule", 2185 "testRule", 2186 "testRule123", 2187 } 2188 for _, v := range validNames { 2189 _, errors := validateWafMetricName(v, "name") 2190 if len(errors) != 0 { 2191 t.Fatalf("%q should be a valid WAF metric name: %q", v, errors) 2192 } 2193 } 2194 2195 invalidNames := []string{ 2196 "!", 2197 "/", 2198 " ", 2199 ":", 2200 ";", 2201 "white space", 2202 "/slash-at-the-beginning", 2203 "slash-at-the-end/", 2204 } 2205 for _, v := range invalidNames { 2206 _, errors := validateWafMetricName(v, "name") 2207 if len(errors) == 0 { 2208 t.Fatalf("%q should be an invalid WAF metric name", v) 2209 } 2210 } 2211 }