github.com/ojiry/terraform@v0.8.2-0.20161218223921-e50cec712c4a/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  		"FunctionName",
    82  		"function-name",
    83  	}
    84  	for _, v := range validNames {
    85  		_, errors := validateLambdaFunctionName(v, "name")
    86  		if len(errors) != 0 {
    87  			t.Fatalf("%q should be a valid Lambda function name: %q", v, errors)
    88  		}
    89  	}
    90  
    91  	invalidNames := []string{
    92  		"/FunctionNameWithSlash",
    93  		"function.name.with.dots",
    94  		// length > 140
    95  		"arn:aws:lambda:us-west-2:123456789012:function:TooLoooooo" +
    96  			"ooooooooooooooooooooooooooooooooooooooooooooooooooooooo" +
    97  			"ooooooooooooooooongFunctionName",
    98  	}
    99  	for _, v := range invalidNames {
   100  		_, errors := validateLambdaFunctionName(v, "name")
   101  		if len(errors) == 0 {
   102  			t.Fatalf("%q should be an invalid Lambda function name", v)
   103  		}
   104  	}
   105  }
   106  
   107  func TestValidateLambdaQualifier(t *testing.T) {
   108  	validNames := []string{
   109  		"123",
   110  		"prod",
   111  		"PROD",
   112  		"MyTestEnv",
   113  		"$LATEST",
   114  	}
   115  	for _, v := range validNames {
   116  		_, errors := validateLambdaQualifier(v, "name")
   117  		if len(errors) != 0 {
   118  			t.Fatalf("%q should be a valid Lambda function qualifier: %q", v, errors)
   119  		}
   120  	}
   121  
   122  	invalidNames := []string{
   123  		// No ARNs allowed
   124  		"arn:aws:lambda:us-west-2:123456789012:function:prod",
   125  		// length > 128
   126  		"TooLooooooooooooooooooooooooooooooooooooooooooooooooooo" +
   127  			"ooooooooooooooooooooooooooooooooooooooooooooooooooo" +
   128  			"oooooooooooongQualifier",
   129  	}
   130  	for _, v := range invalidNames {
   131  		_, errors := validateLambdaQualifier(v, "name")
   132  		if len(errors) == 0 {
   133  			t.Fatalf("%q should be an invalid Lambda function qualifier", v)
   134  		}
   135  	}
   136  }
   137  
   138  func TestValidateLambdaPermissionAction(t *testing.T) {
   139  	validNames := []string{
   140  		"lambda:*",
   141  		"lambda:InvokeFunction",
   142  		"*",
   143  	}
   144  	for _, v := range validNames {
   145  		_, errors := validateLambdaPermissionAction(v, "action")
   146  		if len(errors) != 0 {
   147  			t.Fatalf("%q should be a valid Lambda permission action: %q", v, errors)
   148  		}
   149  	}
   150  
   151  	invalidNames := []string{
   152  		"yada",
   153  		"lambda:123",
   154  		"*:*",
   155  		"lambda:Invoke*",
   156  	}
   157  	for _, v := range invalidNames {
   158  		_, errors := validateLambdaPermissionAction(v, "action")
   159  		if len(errors) == 0 {
   160  			t.Fatalf("%q should be an invalid Lambda permission action", v)
   161  		}
   162  	}
   163  }
   164  
   165  func TestValidateAwsAccountId(t *testing.T) {
   166  	validNames := []string{
   167  		"123456789012",
   168  		"999999999999",
   169  	}
   170  	for _, v := range validNames {
   171  		_, errors := validateAwsAccountId(v, "account_id")
   172  		if len(errors) != 0 {
   173  			t.Fatalf("%q should be a valid AWS Account ID: %q", v, errors)
   174  		}
   175  	}
   176  
   177  	invalidNames := []string{
   178  		"12345678901",   // too short
   179  		"1234567890123", // too long
   180  		"invalid",
   181  		"x123456789012",
   182  	}
   183  	for _, v := range invalidNames {
   184  		_, errors := validateAwsAccountId(v, "account_id")
   185  		if len(errors) == 0 {
   186  			t.Fatalf("%q should be an invalid AWS Account ID", v)
   187  		}
   188  	}
   189  }
   190  
   191  func TestValidateArn(t *testing.T) {
   192  	validNames := []string{
   193  		"arn:aws:elasticbeanstalk:us-east-1:123456789012:environment/My App/MyEnvironment", // Beanstalk
   194  		"arn:aws:iam::123456789012:user/David",                                             // IAM User
   195  		"arn:aws:rds:eu-west-1:123456789012:db:mysql-db",                                   // RDS
   196  		"arn:aws:s3:::my_corporate_bucket/exampleobject.png",                               // S3 object
   197  		"arn:aws:events:us-east-1:319201112229:rule/rule_name",                             // CloudWatch Rule
   198  		"arn:aws:lambda:eu-west-1:319201112229:function:myCustomFunction",                  // Lambda function
   199  		"arn:aws:lambda:eu-west-1:319201112229:function:myCustomFunction:Qualifier",        // Lambda func qualifier
   200  	}
   201  	for _, v := range validNames {
   202  		_, errors := validateArn(v, "arn")
   203  		if len(errors) != 0 {
   204  			t.Fatalf("%q should be a valid ARN: %q", v, errors)
   205  		}
   206  	}
   207  
   208  	invalidNames := []string{
   209  		"arn",
   210  		"123456789012",
   211  		"arn:aws",
   212  		"arn:aws:logs",
   213  		"arn:aws:logs:region:*:*",
   214  	}
   215  	for _, v := range invalidNames {
   216  		_, errors := validateArn(v, "arn")
   217  		if len(errors) == 0 {
   218  			t.Fatalf("%q should be an invalid ARN", v)
   219  		}
   220  	}
   221  }
   222  
   223  func TestValidatePolicyStatementId(t *testing.T) {
   224  	validNames := []string{
   225  		"YadaHereAndThere",
   226  		"Valid-5tatement_Id",
   227  		"1234",
   228  	}
   229  	for _, v := range validNames {
   230  		_, errors := validatePolicyStatementId(v, "statement_id")
   231  		if len(errors) != 0 {
   232  			t.Fatalf("%q should be a valid Statement ID: %q", v, errors)
   233  		}
   234  	}
   235  
   236  	invalidNames := []string{
   237  		"Invalid/StatementId/with/slashes",
   238  		"InvalidStatementId.with.dots",
   239  		// length > 100
   240  		"TooooLoooooooooooooooooooooooooooooooooooooooooooo" +
   241  			"ooooooooooooooooooooooooooooooooooooooooStatementId",
   242  	}
   243  	for _, v := range invalidNames {
   244  		_, errors := validatePolicyStatementId(v, "statement_id")
   245  		if len(errors) == 0 {
   246  			t.Fatalf("%q should be an invalid Statement ID", v)
   247  		}
   248  	}
   249  }
   250  
   251  func TestValidateCIDRNetworkAddress(t *testing.T) {
   252  	cases := []struct {
   253  		CIDR              string
   254  		ExpectedErrSubstr string
   255  	}{
   256  		{"notacidr", `must contain a valid CIDR`},
   257  		{"10.0.1.0/16", `must contain a valid network CIDR`},
   258  		{"10.0.1.0/24", ``},
   259  	}
   260  
   261  	for i, tc := range cases {
   262  		_, errs := validateCIDRNetworkAddress(tc.CIDR, "foo")
   263  		if tc.ExpectedErrSubstr == "" {
   264  			if len(errs) != 0 {
   265  				t.Fatalf("%d/%d: Expected no error, got errs: %#v",
   266  					i+1, len(cases), errs)
   267  			}
   268  		} else {
   269  			if len(errs) != 1 {
   270  				t.Fatalf("%d/%d: Expected 1 err containing %q, got %d errs",
   271  					i+1, len(cases), tc.ExpectedErrSubstr, len(errs))
   272  			}
   273  			if !strings.Contains(errs[0].Error(), tc.ExpectedErrSubstr) {
   274  				t.Fatalf("%d/%d: Expected err: %q, to include %q",
   275  					i+1, len(cases), errs[0], tc.ExpectedErrSubstr)
   276  			}
   277  		}
   278  	}
   279  }
   280  
   281  func TestValidateHTTPMethod(t *testing.T) {
   282  	type testCases struct {
   283  		Value    string
   284  		ErrCount int
   285  	}
   286  
   287  	invalidCases := []testCases{
   288  		{
   289  			Value:    "incorrect",
   290  			ErrCount: 1,
   291  		},
   292  		{
   293  			Value:    "delete",
   294  			ErrCount: 1,
   295  		},
   296  	}
   297  
   298  	for _, tc := range invalidCases {
   299  		_, errors := validateHTTPMethod(tc.Value, "http_method")
   300  		if len(errors) != tc.ErrCount {
   301  			t.Fatalf("Expected %q to trigger a validation error.", tc.Value)
   302  		}
   303  	}
   304  
   305  	validCases := []testCases{
   306  		{
   307  			Value:    "ANY",
   308  			ErrCount: 0,
   309  		},
   310  		{
   311  			Value:    "DELETE",
   312  			ErrCount: 0,
   313  		},
   314  		{
   315  			Value:    "OPTIONS",
   316  			ErrCount: 0,
   317  		},
   318  	}
   319  
   320  	for _, tc := range validCases {
   321  		_, errors := validateHTTPMethod(tc.Value, "http_method")
   322  		if len(errors) != tc.ErrCount {
   323  			t.Fatalf("Expected %q not to trigger a validation error.", tc.Value)
   324  		}
   325  	}
   326  }
   327  
   328  func TestValidateLogMetricFilterName(t *testing.T) {
   329  	validNames := []string{
   330  		"YadaHereAndThere",
   331  		"Valid-5Metric_Name",
   332  		"This . is also %% valid@!)+(",
   333  		"1234",
   334  		strings.Repeat("W", 512),
   335  	}
   336  	for _, v := range validNames {
   337  		_, errors := validateLogMetricFilterName(v, "name")
   338  		if len(errors) != 0 {
   339  			t.Fatalf("%q should be a valid Log Metric Filter Name: %q", v, errors)
   340  		}
   341  	}
   342  
   343  	invalidNames := []string{
   344  		"Here is a name with: colon",
   345  		"and here is another * invalid name",
   346  		"*",
   347  		// length > 512
   348  		strings.Repeat("W", 513),
   349  	}
   350  	for _, v := range invalidNames {
   351  		_, errors := validateLogMetricFilterName(v, "name")
   352  		if len(errors) == 0 {
   353  			t.Fatalf("%q should be an invalid Log Metric Filter Name", v)
   354  		}
   355  	}
   356  }
   357  
   358  func TestValidateLogMetricTransformationName(t *testing.T) {
   359  	validNames := []string{
   360  		"YadaHereAndThere",
   361  		"Valid-5Metric_Name",
   362  		"This . is also %% valid@!)+(",
   363  		"1234",
   364  		"",
   365  		strings.Repeat("W", 255),
   366  	}
   367  	for _, v := range validNames {
   368  		_, errors := validateLogMetricFilterTransformationName(v, "name")
   369  		if len(errors) != 0 {
   370  			t.Fatalf("%q should be a valid Log Metric Filter Transformation Name: %q", v, errors)
   371  		}
   372  	}
   373  
   374  	invalidNames := []string{
   375  		"Here is a name with: colon",
   376  		"and here is another * invalid name",
   377  		"also $ invalid",
   378  		"*",
   379  		// length > 255
   380  		strings.Repeat("W", 256),
   381  	}
   382  	for _, v := range invalidNames {
   383  		_, errors := validateLogMetricFilterTransformationName(v, "name")
   384  		if len(errors) == 0 {
   385  			t.Fatalf("%q should be an invalid Log Metric Filter Transformation Name", v)
   386  		}
   387  	}
   388  }
   389  
   390  func TestValidateLogGroupName(t *testing.T) {
   391  	validNames := []string{
   392  		"ValidLogGroupName",
   393  		"ValidLogGroup.Name",
   394  		"valid/Log-group",
   395  		"1234",
   396  		"YadaValid#0123",
   397  		"Also_valid-name",
   398  		strings.Repeat("W", 512),
   399  	}
   400  	for _, v := range validNames {
   401  		_, errors := validateLogGroupName(v, "name")
   402  		if len(errors) != 0 {
   403  			t.Fatalf("%q should be a valid Log Metric Filter Transformation Name: %q", v, errors)
   404  		}
   405  	}
   406  
   407  	invalidNames := []string{
   408  		"Here is a name with: colon",
   409  		"and here is another * invalid name",
   410  		"also $ invalid",
   411  		"This . is also %% invalid@!)+(",
   412  		"*",
   413  		"",
   414  		// length > 512
   415  		strings.Repeat("W", 513),
   416  	}
   417  	for _, v := range invalidNames {
   418  		_, errors := validateLogGroupName(v, "name")
   419  		if len(errors) == 0 {
   420  			t.Fatalf("%q should be an invalid Log Metric Filter Transformation Name", v)
   421  		}
   422  	}
   423  }
   424  
   425  func TestValidateS3BucketLifecycleTimestamp(t *testing.T) {
   426  	validDates := []string{
   427  		"2016-01-01",
   428  		"2006-01-02",
   429  	}
   430  
   431  	for _, v := range validDates {
   432  		_, errors := validateS3BucketLifecycleTimestamp(v, "date")
   433  		if len(errors) != 0 {
   434  			t.Fatalf("%q should be valid date: %q", v, errors)
   435  		}
   436  	}
   437  
   438  	invalidDates := []string{
   439  		"Jan 01 2016",
   440  		"20160101",
   441  	}
   442  
   443  	for _, v := range invalidDates {
   444  		_, errors := validateS3BucketLifecycleTimestamp(v, "date")
   445  		if len(errors) == 0 {
   446  			t.Fatalf("%q should be invalid date", v)
   447  		}
   448  	}
   449  }
   450  
   451  func TestValidateS3BucketLifecycleStorageClass(t *testing.T) {
   452  	validStorageClass := []string{
   453  		"STANDARD_IA",
   454  		"GLACIER",
   455  	}
   456  
   457  	for _, v := range validStorageClass {
   458  		_, errors := validateS3BucketLifecycleStorageClass(v, "storage_class")
   459  		if len(errors) != 0 {
   460  			t.Fatalf("%q should be valid storage class: %q", v, errors)
   461  		}
   462  	}
   463  
   464  	invalidStorageClass := []string{
   465  		"STANDARD",
   466  		"1234",
   467  	}
   468  	for _, v := range invalidStorageClass {
   469  		_, errors := validateS3BucketLifecycleStorageClass(v, "storage_class")
   470  		if len(errors) == 0 {
   471  			t.Fatalf("%q should be invalid storage class", v)
   472  		}
   473  	}
   474  }
   475  
   476  func TestValidateS3BucketReplicationRuleId(t *testing.T) {
   477  	validId := []string{
   478  		"YadaHereAndThere",
   479  		"Valid-5Rule_ID",
   480  		"This . is also %% valid@!)+*(:ID",
   481  		"1234",
   482  		strings.Repeat("W", 255),
   483  	}
   484  	for _, v := range validId {
   485  		_, errors := validateS3BucketReplicationRuleId(v, "id")
   486  		if len(errors) != 0 {
   487  			t.Fatalf("%q should be a valid lifecycle rule id: %q", v, errors)
   488  		}
   489  	}
   490  
   491  	invalidId := []string{
   492  		// length > 255
   493  		strings.Repeat("W", 256),
   494  	}
   495  	for _, v := range invalidId {
   496  		_, errors := validateS3BucketReplicationRuleId(v, "id")
   497  		if len(errors) == 0 {
   498  			t.Fatalf("%q should be an invalid replication configuration rule id", v)
   499  		}
   500  	}
   501  }
   502  
   503  func TestValidateS3BucketReplicationRulePrefix(t *testing.T) {
   504  	validId := []string{
   505  		"YadaHereAndThere",
   506  		"Valid-5Rule_ID",
   507  		"This . is also %% valid@!)+*(:ID",
   508  		"1234",
   509  		strings.Repeat("W", 1024),
   510  	}
   511  	for _, v := range validId {
   512  		_, errors := validateS3BucketReplicationRulePrefix(v, "id")
   513  		if len(errors) != 0 {
   514  			t.Fatalf("%q should be a valid lifecycle rule id: %q", v, errors)
   515  		}
   516  	}
   517  
   518  	invalidId := []string{
   519  		// length > 1024
   520  		strings.Repeat("W", 1025),
   521  	}
   522  	for _, v := range invalidId {
   523  		_, errors := validateS3BucketReplicationRulePrefix(v, "id")
   524  		if len(errors) == 0 {
   525  			t.Fatalf("%q should be an invalid replication configuration rule id", v)
   526  		}
   527  	}
   528  }
   529  
   530  func TestValidateS3BucketReplicationDestinationStorageClass(t *testing.T) {
   531  	validStorageClass := []string{
   532  		s3.StorageClassStandard,
   533  		s3.StorageClassStandardIa,
   534  		s3.StorageClassReducedRedundancy,
   535  	}
   536  
   537  	for _, v := range validStorageClass {
   538  		_, errors := validateS3BucketReplicationDestinationStorageClass(v, "storage_class")
   539  		if len(errors) != 0 {
   540  			t.Fatalf("%q should be valid storage class: %q", v, errors)
   541  		}
   542  	}
   543  
   544  	invalidStorageClass := []string{
   545  		"FOO",
   546  		"1234",
   547  	}
   548  	for _, v := range invalidStorageClass {
   549  		_, errors := validateS3BucketReplicationDestinationStorageClass(v, "storage_class")
   550  		if len(errors) == 0 {
   551  			t.Fatalf("%q should be invalid storage class", v)
   552  		}
   553  	}
   554  }
   555  
   556  func TestValidateS3BucketReplicationRuleStatus(t *testing.T) {
   557  	validRuleStatuses := []string{
   558  		s3.ReplicationRuleStatusEnabled,
   559  		s3.ReplicationRuleStatusDisabled,
   560  	}
   561  
   562  	for _, v := range validRuleStatuses {
   563  		_, errors := validateS3BucketReplicationRuleStatus(v, "status")
   564  		if len(errors) != 0 {
   565  			t.Fatalf("%q should be valid rule status: %q", v, errors)
   566  		}
   567  	}
   568  
   569  	invalidRuleStatuses := []string{
   570  		"FOO",
   571  		"1234",
   572  	}
   573  	for _, v := range invalidRuleStatuses {
   574  		_, errors := validateS3BucketReplicationRuleStatus(v, "status")
   575  		if len(errors) == 0 {
   576  			t.Fatalf("%q should be invalid rule status", v)
   577  		}
   578  	}
   579  }
   580  
   581  func TestValidateS3BucketLifecycleRuleId(t *testing.T) {
   582  	validId := []string{
   583  		"YadaHereAndThere",
   584  		"Valid-5Rule_ID",
   585  		"This . is also %% valid@!)+*(:ID",
   586  		"1234",
   587  		strings.Repeat("W", 255),
   588  	}
   589  	for _, v := range validId {
   590  		_, errors := validateS3BucketLifecycleRuleId(v, "id")
   591  		if len(errors) != 0 {
   592  			t.Fatalf("%q should be a valid lifecycle rule id: %q", v, errors)
   593  		}
   594  	}
   595  
   596  	invalidId := []string{
   597  		// length > 255
   598  		strings.Repeat("W", 256),
   599  	}
   600  	for _, v := range invalidId {
   601  		_, errors := validateS3BucketLifecycleRuleId(v, "id")
   602  		if len(errors) == 0 {
   603  			t.Fatalf("%q should be an invalid lifecycle rule id", v)
   604  		}
   605  	}
   606  }
   607  
   608  func TestValidateIntegerInRange(t *testing.T) {
   609  	validIntegers := []int{-259, 0, 1, 5, 999}
   610  	min := -259
   611  	max := 999
   612  	for _, v := range validIntegers {
   613  		_, errors := validateIntegerInRange(min, max)(v, "name")
   614  		if len(errors) != 0 {
   615  			t.Fatalf("%q should be an integer in range (%d, %d): %q", v, min, max, errors)
   616  		}
   617  	}
   618  
   619  	invalidIntegers := []int{-260, -99999, 1000, 25678}
   620  	for _, v := range invalidIntegers {
   621  		_, errors := validateIntegerInRange(min, max)(v, "name")
   622  		if len(errors) == 0 {
   623  			t.Fatalf("%q should be an integer outside range (%d, %d)", v, min, max)
   624  		}
   625  	}
   626  }
   627  
   628  func TestResourceAWSElastiCacheClusterIdValidation(t *testing.T) {
   629  	cases := []struct {
   630  		Value    string
   631  		ErrCount int
   632  	}{
   633  		{
   634  			Value:    "tEsting",
   635  			ErrCount: 1,
   636  		},
   637  		{
   638  			Value:    "t.sting",
   639  			ErrCount: 1,
   640  		},
   641  		{
   642  			Value:    "t--sting",
   643  			ErrCount: 1,
   644  		},
   645  		{
   646  			Value:    "1testing",
   647  			ErrCount: 1,
   648  		},
   649  		{
   650  			Value:    "testing-",
   651  			ErrCount: 1,
   652  		},
   653  		{
   654  			Value:    randomString(65),
   655  			ErrCount: 1,
   656  		},
   657  	}
   658  
   659  	for _, tc := range cases {
   660  		_, errors := validateElastiCacheClusterId(tc.Value, "aws_elasticache_cluster_cluster_id")
   661  
   662  		if len(errors) != tc.ErrCount {
   663  			t.Fatalf("Expected the ElastiCache Cluster cluster_id to trigger a validation error")
   664  		}
   665  	}
   666  }
   667  
   668  func TestValidateDbEventSubscriptionName(t *testing.T) {
   669  	validNames := []string{
   670  		"valid-name",
   671  		"valid02-name",
   672  		"Valid-Name1",
   673  	}
   674  	for _, v := range validNames {
   675  		_, errors := validateDbEventSubscriptionName(v, "name")
   676  		if len(errors) != 0 {
   677  			t.Fatalf("%q should be a valid RDS Event Subscription Name: %q", v, errors)
   678  		}
   679  	}
   680  
   681  	invalidNames := []string{
   682  		"Here is a name with: colon",
   683  		"and here is another * invalid name",
   684  		"also $ invalid",
   685  		"This . is also %% invalid@!)+(",
   686  		"*",
   687  		"",
   688  		" ",
   689  		"_",
   690  		// length > 255
   691  		strings.Repeat("W", 256),
   692  	}
   693  	for _, v := range invalidNames {
   694  		_, errors := validateDbEventSubscriptionName(v, "name")
   695  		if len(errors) == 0 {
   696  			t.Fatalf("%q should be an invalid RDS Event Subscription Name", v)
   697  		}
   698  	}
   699  }
   700  
   701  func TestValidateJsonString(t *testing.T) {
   702  	type testCases struct {
   703  		Value    string
   704  		ErrCount int
   705  	}
   706  
   707  	invalidCases := []testCases{
   708  		{
   709  			Value:    `{0:"1"}`,
   710  			ErrCount: 1,
   711  		},
   712  		{
   713  			Value:    `{'abc':1}`,
   714  			ErrCount: 1,
   715  		},
   716  		{
   717  			Value:    `{"def":}`,
   718  			ErrCount: 1,
   719  		},
   720  		{
   721  			Value:    `{"xyz":[}}`,
   722  			ErrCount: 1,
   723  		},
   724  	}
   725  
   726  	for _, tc := range invalidCases {
   727  		_, errors := validateJsonString(tc.Value, "json")
   728  		if len(errors) != tc.ErrCount {
   729  			t.Fatalf("Expected %q to trigger a validation error.", tc.Value)
   730  		}
   731  	}
   732  
   733  	validCases := []testCases{
   734  		{
   735  			Value:    ``,
   736  			ErrCount: 0,
   737  		},
   738  		{
   739  			Value:    `{}`,
   740  			ErrCount: 0,
   741  		},
   742  		{
   743  			Value:    `{"abc":["1","2"]}`,
   744  			ErrCount: 0,
   745  		},
   746  	}
   747  
   748  	for _, tc := range validCases {
   749  		_, errors := validateJsonString(tc.Value, "json")
   750  		if len(errors) != tc.ErrCount {
   751  			t.Fatalf("Expected %q not to trigger a validation error.", tc.Value)
   752  		}
   753  	}
   754  }
   755  
   756  func TestValidateApiGatewayIntegrationType(t *testing.T) {
   757  	type testCases struct {
   758  		Value    string
   759  		ErrCount int
   760  	}
   761  
   762  	invalidCases := []testCases{
   763  		{
   764  			Value:    "incorrect",
   765  			ErrCount: 1,
   766  		},
   767  		{
   768  			Value:    "aws_proxy",
   769  			ErrCount: 1,
   770  		},
   771  	}
   772  
   773  	for _, tc := range invalidCases {
   774  		_, errors := validateApiGatewayIntegrationType(tc.Value, "types")
   775  		if len(errors) != tc.ErrCount {
   776  			t.Fatalf("Expected %q to trigger a validation error.", tc.Value)
   777  		}
   778  	}
   779  
   780  	validCases := []testCases{
   781  		{
   782  			Value:    "MOCK",
   783  			ErrCount: 0,
   784  		},
   785  		{
   786  			Value:    "AWS_PROXY",
   787  			ErrCount: 0,
   788  		},
   789  	}
   790  
   791  	for _, tc := range validCases {
   792  		_, errors := validateApiGatewayIntegrationType(tc.Value, "types")
   793  		if len(errors) != tc.ErrCount {
   794  			t.Fatalf("Expected %q not to trigger a validation error.", tc.Value)
   795  		}
   796  	}
   797  }
   798  
   799  func TestValidateSQSQueueName(t *testing.T) {
   800  	validNames := []string{
   801  		"valid-name",
   802  		"valid02-name",
   803  		"Valid-Name1",
   804  		"_",
   805  		"-",
   806  		strings.Repeat("W", 80),
   807  	}
   808  	for _, v := range validNames {
   809  		if errors := validateSQSQueueName(v, "name"); len(errors) > 0 {
   810  			t.Fatalf("%q should be a valid SQS queue Name", v)
   811  		}
   812  	}
   813  
   814  	invalidNames := []string{
   815  		"Here is a name with: colon",
   816  		"another * invalid name",
   817  		"also $ invalid",
   818  		"This . is also %% invalid@!)+(",
   819  		"*",
   820  		"",
   821  		" ",
   822  		".",
   823  		strings.Repeat("W", 81), // length > 80
   824  	}
   825  	for _, v := range invalidNames {
   826  		if errors := validateSQSQueueName(v, "name"); len(errors) == 0 {
   827  			t.Fatalf("%q should be an invalid SQS queue Name", v)
   828  		}
   829  	}
   830  }
   831  
   832  func TestValidateSQSFifoQueueName(t *testing.T) {
   833  	validNames := []string{
   834  		"valid-name.fifo",
   835  		"valid02-name.fifo",
   836  		"Valid-Name1.fifo",
   837  		"_.fifo",
   838  		"a.fifo",
   839  		"A.fifo",
   840  		"9.fifo",
   841  		"-.fifo",
   842  		fmt.Sprintf("%s.fifo", strings.Repeat("W", 75)),
   843  	}
   844  	for _, v := range validNames {
   845  		if errors := validateSQSFifoQueueName(v, "name"); len(errors) > 0 {
   846  			t.Fatalf("%q should be a valid SQS FIFO queue Name: %v", v, errors)
   847  		}
   848  	}
   849  
   850  	invalidNames := []string{
   851  		"Here is a name with: colon",
   852  		"another * invalid name",
   853  		"also $ invalid",
   854  		"This . is also %% invalid@!)+(",
   855  		".fifo",
   856  		"*",
   857  		"",
   858  		" ",
   859  		".",
   860  		strings.Repeat("W", 81), // length > 80
   861  	}
   862  	for _, v := range invalidNames {
   863  		if errors := validateSQSFifoQueueName(v, "name"); len(errors) == 0 {
   864  			t.Fatalf("%q should be an invalid SQS FIFO queue Name: %v", v, errors)
   865  		}
   866  	}
   867  }
   868  
   869  func TestValidateSNSSubscriptionProtocol(t *testing.T) {
   870  	validProtocols := []string{
   871  		"lambda",
   872  		"sqs",
   873  		"sqs",
   874  		"application",
   875  		"http",
   876  		"https",
   877  	}
   878  	for _, v := range validProtocols {
   879  		if _, errors := validateSNSSubscriptionProtocol(v, "protocol"); len(errors) > 0 {
   880  			t.Fatalf("%q should be a valid SNS Subscription protocol: %v", v, errors)
   881  		}
   882  	}
   883  
   884  	invalidProtocols := []string{
   885  		"Email",
   886  		"email",
   887  		"Email-JSON",
   888  		"email-json",
   889  		"SMS",
   890  		"sms",
   891  	}
   892  	for _, v := range invalidProtocols {
   893  		if _, errors := validateSNSSubscriptionProtocol(v, "protocol"); len(errors) == 0 {
   894  			t.Fatalf("%q should be an invalid SNS Subscription protocol: %v", v, errors)
   895  		}
   896  	}
   897  }