github.com/minamijoyo/terraform@v0.7.8-0.20161029001309-18b3736ba44b/builtin/providers/aws/validators_test.go (about)

     1  package aws
     2  
     3  import (
     4  	"strings"
     5  	"testing"
     6  )
     7  
     8  func TestValidateEcrRepositoryName(t *testing.T) {
     9  	validNames := []string{
    10  		"nginx-web-app",
    11  		"project-a/nginx-web-app",
    12  		"domain.ltd/nginx-web-app",
    13  		"3chosome-thing.com/01different-pattern",
    14  		"0123456789/999999999",
    15  		"double/forward/slash",
    16  		"000000000000000",
    17  	}
    18  	for _, v := range validNames {
    19  		_, errors := validateEcrRepositoryName(v, "name")
    20  		if len(errors) != 0 {
    21  			t.Fatalf("%q should be a valid ECR repository name: %q", v, errors)
    22  		}
    23  	}
    24  
    25  	invalidNames := []string{
    26  		// length > 256
    27  		"3cho_some-thing.com/01different.-_pattern01different.-_pattern01diff" +
    28  			"erent.-_pattern01different.-_pattern01different.-_pattern01different" +
    29  			".-_pattern01different.-_pattern01different.-_pattern01different.-_pa" +
    30  			"ttern01different.-_pattern01different.-_pattern234567",
    31  		// length < 2
    32  		"i",
    33  		"special@character",
    34  		"different+special=character",
    35  		"double//slash",
    36  		"double..dot",
    37  		"/slash-at-the-beginning",
    38  		"slash-at-the-end/",
    39  	}
    40  	for _, v := range invalidNames {
    41  		_, errors := validateEcrRepositoryName(v, "name")
    42  		if len(errors) == 0 {
    43  			t.Fatalf("%q should be an invalid ECR repository name", v)
    44  		}
    45  	}
    46  }
    47  
    48  func TestValidateCloudWatchEventRuleName(t *testing.T) {
    49  	validNames := []string{
    50  		"HelloWorl_d",
    51  		"hello-world",
    52  		"hello.World0125",
    53  	}
    54  	for _, v := range validNames {
    55  		_, errors := validateCloudWatchEventRuleName(v, "name")
    56  		if len(errors) != 0 {
    57  			t.Fatalf("%q should be a valid CW event rule name: %q", v, errors)
    58  		}
    59  	}
    60  
    61  	invalidNames := []string{
    62  		"special@character",
    63  		"slash/in-the-middle",
    64  		// Length > 64
    65  		"TooLooooooooooooooooooooooooooooooooooooooooooooooooooooooongName",
    66  	}
    67  	for _, v := range invalidNames {
    68  		_, errors := validateCloudWatchEventRuleName(v, "name")
    69  		if len(errors) == 0 {
    70  			t.Fatalf("%q should be an invalid CW event rule name", v)
    71  		}
    72  	}
    73  }
    74  
    75  func TestValidateLambdaFunctionName(t *testing.T) {
    76  	validNames := []string{
    77  		"arn:aws:lambda:us-west-2:123456789012:function:ThumbNail",
    78  		"FunctionName",
    79  		"function-name",
    80  	}
    81  	for _, v := range validNames {
    82  		_, errors := validateLambdaFunctionName(v, "name")
    83  		if len(errors) != 0 {
    84  			t.Fatalf("%q should be a valid Lambda function name: %q", v, errors)
    85  		}
    86  	}
    87  
    88  	invalidNames := []string{
    89  		"/FunctionNameWithSlash",
    90  		"function.name.with.dots",
    91  		// length > 140
    92  		"arn:aws:lambda:us-west-2:123456789012:function:TooLoooooo" +
    93  			"ooooooooooooooooooooooooooooooooooooooooooooooooooooooo" +
    94  			"ooooooooooooooooongFunctionName",
    95  	}
    96  	for _, v := range invalidNames {
    97  		_, errors := validateLambdaFunctionName(v, "name")
    98  		if len(errors) == 0 {
    99  			t.Fatalf("%q should be an invalid Lambda function name", v)
   100  		}
   101  	}
   102  }
   103  
   104  func TestValidateLambdaQualifier(t *testing.T) {
   105  	validNames := []string{
   106  		"123",
   107  		"prod",
   108  		"PROD",
   109  		"MyTestEnv",
   110  		"$LATEST",
   111  	}
   112  	for _, v := range validNames {
   113  		_, errors := validateLambdaQualifier(v, "name")
   114  		if len(errors) != 0 {
   115  			t.Fatalf("%q should be a valid Lambda function qualifier: %q", v, errors)
   116  		}
   117  	}
   118  
   119  	invalidNames := []string{
   120  		// No ARNs allowed
   121  		"arn:aws:lambda:us-west-2:123456789012:function:prod",
   122  		// length > 128
   123  		"TooLooooooooooooooooooooooooooooooooooooooooooooooooooo" +
   124  			"ooooooooooooooooooooooooooooooooooooooooooooooooooo" +
   125  			"oooooooooooongQualifier",
   126  	}
   127  	for _, v := range invalidNames {
   128  		_, errors := validateLambdaQualifier(v, "name")
   129  		if len(errors) == 0 {
   130  			t.Fatalf("%q should be an invalid Lambda function qualifier", v)
   131  		}
   132  	}
   133  }
   134  
   135  func TestValidateLambdaPermissionAction(t *testing.T) {
   136  	validNames := []string{
   137  		"lambda:*",
   138  		"lambda:InvokeFunction",
   139  		"*",
   140  	}
   141  	for _, v := range validNames {
   142  		_, errors := validateLambdaPermissionAction(v, "action")
   143  		if len(errors) != 0 {
   144  			t.Fatalf("%q should be a valid Lambda permission action: %q", v, errors)
   145  		}
   146  	}
   147  
   148  	invalidNames := []string{
   149  		"yada",
   150  		"lambda:123",
   151  		"*:*",
   152  		"lambda:Invoke*",
   153  	}
   154  	for _, v := range invalidNames {
   155  		_, errors := validateLambdaPermissionAction(v, "action")
   156  		if len(errors) == 0 {
   157  			t.Fatalf("%q should be an invalid Lambda permission action", v)
   158  		}
   159  	}
   160  }
   161  
   162  func TestValidateAwsAccountId(t *testing.T) {
   163  	validNames := []string{
   164  		"123456789012",
   165  		"999999999999",
   166  	}
   167  	for _, v := range validNames {
   168  		_, errors := validateAwsAccountId(v, "account_id")
   169  		if len(errors) != 0 {
   170  			t.Fatalf("%q should be a valid AWS Account ID: %q", v, errors)
   171  		}
   172  	}
   173  
   174  	invalidNames := []string{
   175  		"12345678901",   // too short
   176  		"1234567890123", // too long
   177  		"invalid",
   178  		"x123456789012",
   179  	}
   180  	for _, v := range invalidNames {
   181  		_, errors := validateAwsAccountId(v, "account_id")
   182  		if len(errors) == 0 {
   183  			t.Fatalf("%q should be an invalid AWS Account ID", v)
   184  		}
   185  	}
   186  }
   187  
   188  func TestValidateArn(t *testing.T) {
   189  	validNames := []string{
   190  		"arn:aws:elasticbeanstalk:us-east-1:123456789012:environment/My App/MyEnvironment", // Beanstalk
   191  		"arn:aws:iam::123456789012:user/David",                                             // IAM User
   192  		"arn:aws:rds:eu-west-1:123456789012:db:mysql-db",                                   // RDS
   193  		"arn:aws:s3:::my_corporate_bucket/exampleobject.png",                               // S3 object
   194  		"arn:aws:events:us-east-1:319201112229:rule/rule_name",                             // CloudWatch Rule
   195  		"arn:aws:lambda:eu-west-1:319201112229:function:myCustomFunction",                  // Lambda function
   196  		"arn:aws:lambda:eu-west-1:319201112229:function:myCustomFunction:Qualifier",        // Lambda func qualifier
   197  	}
   198  	for _, v := range validNames {
   199  		_, errors := validateArn(v, "arn")
   200  		if len(errors) != 0 {
   201  			t.Fatalf("%q should be a valid ARN: %q", v, errors)
   202  		}
   203  	}
   204  
   205  	invalidNames := []string{
   206  		"arn",
   207  		"123456789012",
   208  		"arn:aws",
   209  		"arn:aws:logs",
   210  		"arn:aws:logs:region:*:*",
   211  	}
   212  	for _, v := range invalidNames {
   213  		_, errors := validateArn(v, "arn")
   214  		if len(errors) == 0 {
   215  			t.Fatalf("%q should be an invalid ARN", v)
   216  		}
   217  	}
   218  }
   219  
   220  func TestValidatePolicyStatementId(t *testing.T) {
   221  	validNames := []string{
   222  		"YadaHereAndThere",
   223  		"Valid-5tatement_Id",
   224  		"1234",
   225  	}
   226  	for _, v := range validNames {
   227  		_, errors := validatePolicyStatementId(v, "statement_id")
   228  		if len(errors) != 0 {
   229  			t.Fatalf("%q should be a valid Statement ID: %q", v, errors)
   230  		}
   231  	}
   232  
   233  	invalidNames := []string{
   234  		"Invalid/StatementId/with/slashes",
   235  		"InvalidStatementId.with.dots",
   236  		// length > 100
   237  		"TooooLoooooooooooooooooooooooooooooooooooooooooooo" +
   238  			"ooooooooooooooooooooooooooooooooooooooooStatementId",
   239  	}
   240  	for _, v := range invalidNames {
   241  		_, errors := validatePolicyStatementId(v, "statement_id")
   242  		if len(errors) == 0 {
   243  			t.Fatalf("%q should be an invalid Statement ID", v)
   244  		}
   245  	}
   246  }
   247  
   248  func TestValidateCIDRNetworkAddress(t *testing.T) {
   249  	cases := []struct {
   250  		CIDR              string
   251  		ExpectedErrSubstr string
   252  	}{
   253  		{"notacidr", `must contain a valid CIDR`},
   254  		{"10.0.1.0/16", `must contain a valid network CIDR`},
   255  		{"10.0.1.0/24", ``},
   256  	}
   257  
   258  	for i, tc := range cases {
   259  		_, errs := validateCIDRNetworkAddress(tc.CIDR, "foo")
   260  		if tc.ExpectedErrSubstr == "" {
   261  			if len(errs) != 0 {
   262  				t.Fatalf("%d/%d: Expected no error, got errs: %#v",
   263  					i+1, len(cases), errs)
   264  			}
   265  		} else {
   266  			if len(errs) != 1 {
   267  				t.Fatalf("%d/%d: Expected 1 err containing %q, got %d errs",
   268  					i+1, len(cases), tc.ExpectedErrSubstr, len(errs))
   269  			}
   270  			if !strings.Contains(errs[0].Error(), tc.ExpectedErrSubstr) {
   271  				t.Fatalf("%d/%d: Expected err: %q, to include %q",
   272  					i+1, len(cases), errs[0], tc.ExpectedErrSubstr)
   273  			}
   274  		}
   275  	}
   276  }
   277  
   278  func TestValidateHTTPMethod(t *testing.T) {
   279  	type testCases struct {
   280  		Value    string
   281  		ErrCount int
   282  	}
   283  
   284  	invalidCases := []testCases{
   285  		{
   286  			Value:    "incorrect",
   287  			ErrCount: 1,
   288  		},
   289  		{
   290  			Value:    "delete",
   291  			ErrCount: 1,
   292  		},
   293  	}
   294  
   295  	for _, tc := range invalidCases {
   296  		_, errors := validateHTTPMethod(tc.Value, "http_method")
   297  		if len(errors) != tc.ErrCount {
   298  			t.Fatalf("Expected %q to trigger a validation error.", tc.Value)
   299  		}
   300  	}
   301  
   302  	validCases := []testCases{
   303  		{
   304  			Value:    "ANY",
   305  			ErrCount: 0,
   306  		},
   307  		{
   308  			Value:    "DELETE",
   309  			ErrCount: 0,
   310  		},
   311  		{
   312  			Value:    "OPTIONS",
   313  			ErrCount: 0,
   314  		},
   315  	}
   316  
   317  	for _, tc := range validCases {
   318  		_, errors := validateHTTPMethod(tc.Value, "http_method")
   319  		if len(errors) != tc.ErrCount {
   320  			t.Fatalf("Expected %q not to trigger a validation error.", tc.Value)
   321  		}
   322  	}
   323  }
   324  
   325  func TestValidateLogMetricFilterName(t *testing.T) {
   326  	validNames := []string{
   327  		"YadaHereAndThere",
   328  		"Valid-5Metric_Name",
   329  		"This . is also %% valid@!)+(",
   330  		"1234",
   331  		strings.Repeat("W", 512),
   332  	}
   333  	for _, v := range validNames {
   334  		_, errors := validateLogMetricFilterName(v, "name")
   335  		if len(errors) != 0 {
   336  			t.Fatalf("%q should be a valid Log Metric Filter Name: %q", v, errors)
   337  		}
   338  	}
   339  
   340  	invalidNames := []string{
   341  		"Here is a name with: colon",
   342  		"and here is another * invalid name",
   343  		"*",
   344  		// length > 512
   345  		strings.Repeat("W", 513),
   346  	}
   347  	for _, v := range invalidNames {
   348  		_, errors := validateLogMetricFilterName(v, "name")
   349  		if len(errors) == 0 {
   350  			t.Fatalf("%q should be an invalid Log Metric Filter Name", v)
   351  		}
   352  	}
   353  }
   354  
   355  func TestValidateLogMetricTransformationName(t *testing.T) {
   356  	validNames := []string{
   357  		"YadaHereAndThere",
   358  		"Valid-5Metric_Name",
   359  		"This . is also %% valid@!)+(",
   360  		"1234",
   361  		"",
   362  		strings.Repeat("W", 255),
   363  	}
   364  	for _, v := range validNames {
   365  		_, errors := validateLogMetricFilterTransformationName(v, "name")
   366  		if len(errors) != 0 {
   367  			t.Fatalf("%q should be a valid Log Metric Filter Transformation Name: %q", v, errors)
   368  		}
   369  	}
   370  
   371  	invalidNames := []string{
   372  		"Here is a name with: colon",
   373  		"and here is another * invalid name",
   374  		"also $ invalid",
   375  		"*",
   376  		// length > 255
   377  		strings.Repeat("W", 256),
   378  	}
   379  	for _, v := range invalidNames {
   380  		_, errors := validateLogMetricFilterTransformationName(v, "name")
   381  		if len(errors) == 0 {
   382  			t.Fatalf("%q should be an invalid Log Metric Filter Transformation Name", v)
   383  		}
   384  	}
   385  }
   386  
   387  func TestValidateLogGroupName(t *testing.T) {
   388  	validNames := []string{
   389  		"ValidLogGroupName",
   390  		"ValidLogGroup.Name",
   391  		"valid/Log-group",
   392  		"1234",
   393  		"YadaValid#0123",
   394  		"Also_valid-name",
   395  		strings.Repeat("W", 512),
   396  	}
   397  	for _, v := range validNames {
   398  		_, errors := validateLogGroupName(v, "name")
   399  		if len(errors) != 0 {
   400  			t.Fatalf("%q should be a valid Log Metric Filter Transformation Name: %q", v, errors)
   401  		}
   402  	}
   403  
   404  	invalidNames := []string{
   405  		"Here is a name with: colon",
   406  		"and here is another * invalid name",
   407  		"also $ invalid",
   408  		"This . is also %% invalid@!)+(",
   409  		"*",
   410  		"",
   411  		// length > 512
   412  		strings.Repeat("W", 513),
   413  	}
   414  	for _, v := range invalidNames {
   415  		_, errors := validateLogGroupName(v, "name")
   416  		if len(errors) == 0 {
   417  			t.Fatalf("%q should be an invalid Log Metric Filter Transformation Name", v)
   418  		}
   419  	}
   420  }
   421  
   422  func TestValidateS3BucketLifecycleTimestamp(t *testing.T) {
   423  	validDates := []string{
   424  		"2016-01-01",
   425  		"2006-01-02",
   426  	}
   427  
   428  	for _, v := range validDates {
   429  		_, errors := validateS3BucketLifecycleTimestamp(v, "date")
   430  		if len(errors) != 0 {
   431  			t.Fatalf("%q should be valid date: %q", v, errors)
   432  		}
   433  	}
   434  
   435  	invalidDates := []string{
   436  		"Jan 01 2016",
   437  		"20160101",
   438  	}
   439  
   440  	for _, v := range invalidDates {
   441  		_, errors := validateS3BucketLifecycleTimestamp(v, "date")
   442  		if len(errors) == 0 {
   443  			t.Fatalf("%q should be invalid date", v)
   444  		}
   445  	}
   446  }
   447  
   448  func TestValidateS3BucketLifecycleStorageClass(t *testing.T) {
   449  	validStorageClass := []string{
   450  		"STANDARD_IA",
   451  		"GLACIER",
   452  	}
   453  
   454  	for _, v := range validStorageClass {
   455  		_, errors := validateS3BucketLifecycleStorageClass(v, "storage_class")
   456  		if len(errors) != 0 {
   457  			t.Fatalf("%q should be valid storage class: %q", v, errors)
   458  		}
   459  	}
   460  
   461  	invalidStorageClass := []string{
   462  		"STANDARD",
   463  		"1234",
   464  	}
   465  	for _, v := range invalidStorageClass {
   466  		_, errors := validateS3BucketLifecycleStorageClass(v, "storage_class")
   467  		if len(errors) == 0 {
   468  			t.Fatalf("%q should be invalid storage class", v)
   469  		}
   470  	}
   471  }
   472  
   473  func TestValidateS3BucketLifecycleRuleId(t *testing.T) {
   474  	validId := []string{
   475  		"YadaHereAndThere",
   476  		"Valid-5Rule_ID",
   477  		"This . is also %% valid@!)+*(:ID",
   478  		"1234",
   479  		strings.Repeat("W", 255),
   480  	}
   481  	for _, v := range validId {
   482  		_, errors := validateS3BucketLifecycleRuleId(v, "id")
   483  		if len(errors) != 0 {
   484  			t.Fatalf("%q should be a valid lifecycle rule id: %q", v, errors)
   485  		}
   486  	}
   487  
   488  	invalidId := []string{
   489  		// length > 255
   490  		strings.Repeat("W", 256),
   491  	}
   492  	for _, v := range invalidId {
   493  		_, errors := validateS3BucketLifecycleRuleId(v, "id")
   494  		if len(errors) == 0 {
   495  			t.Fatalf("%q should be an invalid lifecycle rule id", v)
   496  		}
   497  	}
   498  }
   499  
   500  func TestValidateIntegerInRange(t *testing.T) {
   501  	validIntegers := []int{-259, 0, 1, 5, 999}
   502  	min := -259
   503  	max := 999
   504  	for _, v := range validIntegers {
   505  		_, errors := validateIntegerInRange(min, max)(v, "name")
   506  		if len(errors) != 0 {
   507  			t.Fatalf("%q should be an integer in range (%d, %d): %q", v, min, max, errors)
   508  		}
   509  	}
   510  
   511  	invalidIntegers := []int{-260, -99999, 1000, 25678}
   512  	for _, v := range invalidIntegers {
   513  		_, errors := validateIntegerInRange(min, max)(v, "name")
   514  		if len(errors) == 0 {
   515  			t.Fatalf("%q should be an integer outside range (%d, %d)", v, min, max)
   516  		}
   517  	}
   518  }
   519  
   520  func TestResourceAWSElastiCacheClusterIdValidation(t *testing.T) {
   521  	cases := []struct {
   522  		Value    string
   523  		ErrCount int
   524  	}{
   525  		{
   526  			Value:    "tEsting",
   527  			ErrCount: 1,
   528  		},
   529  		{
   530  			Value:    "t.sting",
   531  			ErrCount: 1,
   532  		},
   533  		{
   534  			Value:    "t--sting",
   535  			ErrCount: 1,
   536  		},
   537  		{
   538  			Value:    "1testing",
   539  			ErrCount: 1,
   540  		},
   541  		{
   542  			Value:    "testing-",
   543  			ErrCount: 1,
   544  		},
   545  		{
   546  			Value:    randomString(65),
   547  			ErrCount: 1,
   548  		},
   549  	}
   550  
   551  	for _, tc := range cases {
   552  		_, errors := validateElastiCacheClusterId(tc.Value, "aws_elasticache_cluster_cluster_id")
   553  
   554  		if len(errors) != tc.ErrCount {
   555  			t.Fatalf("Expected the ElastiCache Cluster cluster_id to trigger a validation error")
   556  		}
   557  	}
   558  }
   559  
   560  func TestValidateDbEventSubscriptionName(t *testing.T) {
   561  	validNames := []string{
   562  		"valid-name",
   563  		"valid02-name",
   564  		"Valid-Name1",
   565  	}
   566  	for _, v := range validNames {
   567  		_, errors := validateDbEventSubscriptionName(v, "name")
   568  		if len(errors) != 0 {
   569  			t.Fatalf("%q should be a valid RDS Event Subscription Name: %q", v, errors)
   570  		}
   571  	}
   572  
   573  	invalidNames := []string{
   574  		"Here is a name with: colon",
   575  		"and here is another * invalid name",
   576  		"also $ invalid",
   577  		"This . is also %% invalid@!)+(",
   578  		"*",
   579  		"",
   580  		" ",
   581  		"_",
   582  		// length > 255
   583  		strings.Repeat("W", 256),
   584  	}
   585  	for _, v := range invalidNames {
   586  		_, errors := validateDbEventSubscriptionName(v, "name")
   587  		if len(errors) == 0 {
   588  			t.Fatalf("%q should be an invalid RDS Event Subscription Name", v)
   589  		}
   590  	}
   591  }
   592  
   593  func TestValidateJsonString(t *testing.T) {
   594  	type testCases struct {
   595  		Value    string
   596  		ErrCount int
   597  	}
   598  
   599  	invalidCases := []testCases{
   600  		{
   601  			Value:    `{0:"1"}`,
   602  			ErrCount: 1,
   603  		},
   604  		{
   605  			Value:    `{'abc':1}`,
   606  			ErrCount: 1,
   607  		},
   608  		{
   609  			Value:    `{"def":}`,
   610  			ErrCount: 1,
   611  		},
   612  		{
   613  			Value:    `{"xyz":[}}`,
   614  			ErrCount: 1,
   615  		},
   616  	}
   617  
   618  	for _, tc := range invalidCases {
   619  		_, errors := validateJsonString(tc.Value, "json")
   620  		if len(errors) != tc.ErrCount {
   621  			t.Fatalf("Expected %q to trigger a validation error.", tc.Value)
   622  		}
   623  	}
   624  
   625  	validCases := []testCases{
   626  		{
   627  			Value:    ``,
   628  			ErrCount: 0,
   629  		},
   630  		{
   631  			Value:    `{}`,
   632  			ErrCount: 0,
   633  		},
   634  		{
   635  			Value:    `{"abc":["1","2"]}`,
   636  			ErrCount: 0,
   637  		},
   638  	}
   639  
   640  	for _, tc := range validCases {
   641  		_, errors := validateJsonString(tc.Value, "json")
   642  		if len(errors) != tc.ErrCount {
   643  			t.Fatalf("Expected %q not to trigger a validation error.", tc.Value)
   644  		}
   645  	}
   646  }
   647  
   648  func TestValidateApiGatewayIntegrationType(t *testing.T) {
   649  	type testCases struct {
   650  		Value    string
   651  		ErrCount int
   652  	}
   653  
   654  	invalidCases := []testCases{
   655  		{
   656  			Value:    "incorrect",
   657  			ErrCount: 1,
   658  		},
   659  		{
   660  			Value:    "aws_proxy",
   661  			ErrCount: 1,
   662  		},
   663  	}
   664  
   665  	for _, tc := range invalidCases {
   666  		_, errors := validateApiGatewayIntegrationType(tc.Value, "types")
   667  		if len(errors) != tc.ErrCount {
   668  			t.Fatalf("Expected %q to trigger a validation error.", tc.Value)
   669  		}
   670  	}
   671  
   672  	validCases := []testCases{
   673  		{
   674  			Value:    "MOCK",
   675  			ErrCount: 0,
   676  		},
   677  		{
   678  			Value:    "AWS_PROXY",
   679  			ErrCount: 0,
   680  		},
   681  	}
   682  
   683  	for _, tc := range validCases {
   684  		_, errors := validateApiGatewayIntegrationType(tc.Value, "types")
   685  		if len(errors) != tc.ErrCount {
   686  			t.Fatalf("Expected %q not to trigger a validation error.", tc.Value)
   687  		}
   688  	}
   689  }