2015-12-23 16:07:39 +01:00
|
|
|
package aws
|
|
|
|
|
|
|
|
import (
|
2016-12-12 18:40:59 +01:00
|
|
|
"fmt"
|
2016-02-22 22:05:55 +01:00
|
|
|
"strings"
|
2015-12-23 16:07:39 +01:00
|
|
|
"testing"
|
2016-12-08 11:59:13 +01:00
|
|
|
|
|
|
|
"github.com/aws/aws-sdk-go/service/s3"
|
2015-12-23 16:07:39 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestValidateEcrRepositoryName(t *testing.T) {
|
|
|
|
validNames := []string{
|
|
|
|
"nginx-web-app",
|
|
|
|
"project-a/nginx-web-app",
|
|
|
|
"domain.ltd/nginx-web-app",
|
|
|
|
"3chosome-thing.com/01different-pattern",
|
|
|
|
"0123456789/999999999",
|
|
|
|
"double/forward/slash",
|
|
|
|
"000000000000000",
|
|
|
|
}
|
|
|
|
for _, v := range validNames {
|
|
|
|
_, errors := validateEcrRepositoryName(v, "name")
|
|
|
|
if len(errors) != 0 {
|
|
|
|
t.Fatalf("%q should be a valid ECR repository name: %q", v, errors)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
invalidNames := []string{
|
|
|
|
// length > 256
|
|
|
|
"3cho_some-thing.com/01different.-_pattern01different.-_pattern01diff" +
|
|
|
|
"erent.-_pattern01different.-_pattern01different.-_pattern01different" +
|
|
|
|
".-_pattern01different.-_pattern01different.-_pattern01different.-_pa" +
|
|
|
|
"ttern01different.-_pattern01different.-_pattern234567",
|
|
|
|
// length < 2
|
|
|
|
"i",
|
|
|
|
"special@character",
|
|
|
|
"different+special=character",
|
|
|
|
"double//slash",
|
|
|
|
"double..dot",
|
|
|
|
"/slash-at-the-beginning",
|
|
|
|
"slash-at-the-end/",
|
|
|
|
}
|
|
|
|
for _, v := range invalidNames {
|
|
|
|
_, errors := validateEcrRepositoryName(v, "name")
|
|
|
|
if len(errors) == 0 {
|
|
|
|
t.Fatalf("%q should be an invalid ECR repository name", v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-01-29 20:13:52 +01:00
|
|
|
|
|
|
|
func TestValidateCloudWatchEventRuleName(t *testing.T) {
|
|
|
|
validNames := []string{
|
|
|
|
"HelloWorl_d",
|
|
|
|
"hello-world",
|
|
|
|
"hello.World0125",
|
|
|
|
}
|
|
|
|
for _, v := range validNames {
|
|
|
|
_, errors := validateCloudWatchEventRuleName(v, "name")
|
|
|
|
if len(errors) != 0 {
|
|
|
|
t.Fatalf("%q should be a valid CW event rule name: %q", v, errors)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
invalidNames := []string{
|
|
|
|
"special@character",
|
|
|
|
"slash/in-the-middle",
|
|
|
|
// Length > 64
|
|
|
|
"TooLooooooooooooooooooooooooooooooooooooooooooooooooooooooongName",
|
|
|
|
}
|
|
|
|
for _, v := range invalidNames {
|
|
|
|
_, errors := validateCloudWatchEventRuleName(v, "name")
|
|
|
|
if len(errors) == 0 {
|
|
|
|
t.Fatalf("%q should be an invalid CW event rule name", v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-01-26 11:38:00 +01:00
|
|
|
|
|
|
|
func TestValidateLambdaFunctionName(t *testing.T) {
|
|
|
|
validNames := []string{
|
|
|
|
"arn:aws:lambda:us-west-2:123456789012:function:ThumbNail",
|
2017-01-23 17:30:28 +01:00
|
|
|
"arn:aws-us-gov:lambda:us-west-2:123456789012:function:ThumbNail",
|
2016-01-26 11:38:00 +01:00
|
|
|
"FunctionName",
|
|
|
|
"function-name",
|
|
|
|
}
|
|
|
|
for _, v := range validNames {
|
|
|
|
_, errors := validateLambdaFunctionName(v, "name")
|
|
|
|
if len(errors) != 0 {
|
|
|
|
t.Fatalf("%q should be a valid Lambda function name: %q", v, errors)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
invalidNames := []string{
|
|
|
|
"/FunctionNameWithSlash",
|
|
|
|
"function.name.with.dots",
|
2016-09-12 08:14:24 +02:00
|
|
|
// length > 140
|
2016-01-26 11:38:00 +01:00
|
|
|
"arn:aws:lambda:us-west-2:123456789012:function:TooLoooooo" +
|
|
|
|
"ooooooooooooooooooooooooooooooooooooooooooooooooooooooo" +
|
|
|
|
"ooooooooooooooooongFunctionName",
|
|
|
|
}
|
|
|
|
for _, v := range invalidNames {
|
|
|
|
_, errors := validateLambdaFunctionName(v, "name")
|
|
|
|
if len(errors) == 0 {
|
|
|
|
t.Fatalf("%q should be an invalid Lambda function name", v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestValidateLambdaQualifier(t *testing.T) {
|
|
|
|
validNames := []string{
|
|
|
|
"123",
|
|
|
|
"prod",
|
|
|
|
"PROD",
|
|
|
|
"MyTestEnv",
|
|
|
|
"$LATEST",
|
|
|
|
}
|
|
|
|
for _, v := range validNames {
|
|
|
|
_, errors := validateLambdaQualifier(v, "name")
|
|
|
|
if len(errors) != 0 {
|
|
|
|
t.Fatalf("%q should be a valid Lambda function qualifier: %q", v, errors)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
invalidNames := []string{
|
|
|
|
// No ARNs allowed
|
|
|
|
"arn:aws:lambda:us-west-2:123456789012:function:prod",
|
2016-09-12 08:14:24 +02:00
|
|
|
// length > 128
|
2016-01-26 11:38:00 +01:00
|
|
|
"TooLooooooooooooooooooooooooooooooooooooooooooooooooooo" +
|
|
|
|
"ooooooooooooooooooooooooooooooooooooooooooooooooooo" +
|
|
|
|
"oooooooooooongQualifier",
|
|
|
|
}
|
|
|
|
for _, v := range invalidNames {
|
|
|
|
_, errors := validateLambdaQualifier(v, "name")
|
|
|
|
if len(errors) == 0 {
|
|
|
|
t.Fatalf("%q should be an invalid Lambda function qualifier", v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestValidateLambdaPermissionAction(t *testing.T) {
|
|
|
|
validNames := []string{
|
|
|
|
"lambda:*",
|
|
|
|
"lambda:InvokeFunction",
|
|
|
|
"*",
|
|
|
|
}
|
|
|
|
for _, v := range validNames {
|
|
|
|
_, errors := validateLambdaPermissionAction(v, "action")
|
|
|
|
if len(errors) != 0 {
|
|
|
|
t.Fatalf("%q should be a valid Lambda permission action: %q", v, errors)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
invalidNames := []string{
|
|
|
|
"yada",
|
|
|
|
"lambda:123",
|
|
|
|
"*:*",
|
|
|
|
"lambda:Invoke*",
|
|
|
|
}
|
|
|
|
for _, v := range invalidNames {
|
|
|
|
_, errors := validateLambdaPermissionAction(v, "action")
|
|
|
|
if len(errors) == 0 {
|
|
|
|
t.Fatalf("%q should be an invalid Lambda permission action", v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestValidateAwsAccountId(t *testing.T) {
|
|
|
|
validNames := []string{
|
|
|
|
"123456789012",
|
|
|
|
"999999999999",
|
|
|
|
}
|
|
|
|
for _, v := range validNames {
|
|
|
|
_, errors := validateAwsAccountId(v, "account_id")
|
|
|
|
if len(errors) != 0 {
|
|
|
|
t.Fatalf("%q should be a valid AWS Account ID: %q", v, errors)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
invalidNames := []string{
|
|
|
|
"12345678901", // too short
|
|
|
|
"1234567890123", // too long
|
|
|
|
"invalid",
|
|
|
|
"x123456789012",
|
|
|
|
}
|
|
|
|
for _, v := range invalidNames {
|
|
|
|
_, errors := validateAwsAccountId(v, "account_id")
|
|
|
|
if len(errors) == 0 {
|
|
|
|
t.Fatalf("%q should be an invalid AWS Account ID", v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestValidateArn(t *testing.T) {
|
2016-12-27 21:52:22 +01:00
|
|
|
v := ""
|
|
|
|
_, errors := validateArn(v, "arn")
|
|
|
|
if len(errors) != 0 {
|
|
|
|
t.Fatalf("%q should not be validated as an ARN: %q", v, errors)
|
|
|
|
}
|
|
|
|
|
2016-01-26 11:38:00 +01:00
|
|
|
validNames := []string{
|
|
|
|
"arn:aws:elasticbeanstalk:us-east-1:123456789012:environment/My App/MyEnvironment", // Beanstalk
|
|
|
|
"arn:aws:iam::123456789012:user/David", // IAM User
|
|
|
|
"arn:aws:rds:eu-west-1:123456789012:db:mysql-db", // RDS
|
|
|
|
"arn:aws:s3:::my_corporate_bucket/exampleobject.png", // S3 object
|
|
|
|
"arn:aws:events:us-east-1:319201112229:rule/rule_name", // CloudWatch Rule
|
|
|
|
"arn:aws:lambda:eu-west-1:319201112229:function:myCustomFunction", // Lambda function
|
|
|
|
"arn:aws:lambda:eu-west-1:319201112229:function:myCustomFunction:Qualifier", // Lambda func qualifier
|
2017-01-23 17:30:28 +01:00
|
|
|
"arn:aws-us-gov:s3:::corp_bucket/object.png", // GovCloud ARN
|
2016-01-26 11:38:00 +01:00
|
|
|
}
|
|
|
|
for _, v := range validNames {
|
|
|
|
_, errors := validateArn(v, "arn")
|
|
|
|
if len(errors) != 0 {
|
|
|
|
t.Fatalf("%q should be a valid ARN: %q", v, errors)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
invalidNames := []string{
|
|
|
|
"arn",
|
|
|
|
"123456789012",
|
|
|
|
"arn:aws",
|
|
|
|
"arn:aws:logs",
|
|
|
|
"arn:aws:logs:region:*:*",
|
|
|
|
}
|
|
|
|
for _, v := range invalidNames {
|
|
|
|
_, errors := validateArn(v, "arn")
|
|
|
|
if len(errors) == 0 {
|
|
|
|
t.Fatalf("%q should be an invalid ARN", v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestValidatePolicyStatementId(t *testing.T) {
|
|
|
|
validNames := []string{
|
|
|
|
"YadaHereAndThere",
|
|
|
|
"Valid-5tatement_Id",
|
|
|
|
"1234",
|
|
|
|
}
|
|
|
|
for _, v := range validNames {
|
|
|
|
_, errors := validatePolicyStatementId(v, "statement_id")
|
|
|
|
if len(errors) != 0 {
|
|
|
|
t.Fatalf("%q should be a valid Statement ID: %q", v, errors)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
invalidNames := []string{
|
|
|
|
"Invalid/StatementId/with/slashes",
|
|
|
|
"InvalidStatementId.with.dots",
|
|
|
|
// length > 100
|
|
|
|
"TooooLoooooooooooooooooooooooooooooooooooooooooooo" +
|
|
|
|
"ooooooooooooooooooooooooooooooooooooooooStatementId",
|
|
|
|
}
|
|
|
|
for _, v := range invalidNames {
|
|
|
|
_, errors := validatePolicyStatementId(v, "statement_id")
|
|
|
|
if len(errors) == 0 {
|
|
|
|
t.Fatalf("%q should be an invalid Statement ID", v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-02-22 22:05:55 +01:00
|
|
|
|
|
|
|
func TestValidateCIDRNetworkAddress(t *testing.T) {
|
|
|
|
cases := []struct {
|
|
|
|
CIDR string
|
|
|
|
ExpectedErrSubstr string
|
|
|
|
}{
|
|
|
|
{"notacidr", `must contain a valid CIDR`},
|
|
|
|
{"10.0.1.0/16", `must contain a valid network CIDR`},
|
|
|
|
{"10.0.1.0/24", ``},
|
|
|
|
}
|
|
|
|
|
|
|
|
for i, tc := range cases {
|
|
|
|
_, errs := validateCIDRNetworkAddress(tc.CIDR, "foo")
|
|
|
|
if tc.ExpectedErrSubstr == "" {
|
|
|
|
if len(errs) != 0 {
|
|
|
|
t.Fatalf("%d/%d: Expected no error, got errs: %#v",
|
|
|
|
i+1, len(cases), errs)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if len(errs) != 1 {
|
|
|
|
t.Fatalf("%d/%d: Expected 1 err containing %q, got %d errs",
|
|
|
|
i+1, len(cases), tc.ExpectedErrSubstr, len(errs))
|
|
|
|
}
|
|
|
|
if !strings.Contains(errs[0].Error(), tc.ExpectedErrSubstr) {
|
|
|
|
t.Fatalf("%d/%d: Expected err: %q, to include %q",
|
|
|
|
i+1, len(cases), errs[0], tc.ExpectedErrSubstr)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-03-05 23:15:22 +01:00
|
|
|
|
|
|
|
func TestValidateHTTPMethod(t *testing.T) {
|
2016-10-10 19:41:05 +02:00
|
|
|
type testCases struct {
|
|
|
|
Value string
|
|
|
|
ErrCount int
|
|
|
|
}
|
|
|
|
|
|
|
|
invalidCases := []testCases{
|
|
|
|
{
|
|
|
|
Value: "incorrect",
|
|
|
|
ErrCount: 1,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Value: "delete",
|
|
|
|
ErrCount: 1,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range invalidCases {
|
|
|
|
_, errors := validateHTTPMethod(tc.Value, "http_method")
|
|
|
|
if len(errors) != tc.ErrCount {
|
|
|
|
t.Fatalf("Expected %q to trigger a validation error.", tc.Value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
validCases := []testCases{
|
|
|
|
{
|
|
|
|
Value: "ANY",
|
|
|
|
ErrCount: 0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Value: "DELETE",
|
|
|
|
ErrCount: 0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Value: "OPTIONS",
|
|
|
|
ErrCount: 0,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range validCases {
|
|
|
|
_, errors := validateHTTPMethod(tc.Value, "http_method")
|
|
|
|
if len(errors) != tc.ErrCount {
|
|
|
|
t.Fatalf("Expected %q not to trigger a validation error.", tc.Value)
|
2016-03-05 23:15:22 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-03-05 17:37:45 +01:00
|
|
|
|
|
|
|
func TestValidateLogMetricFilterName(t *testing.T) {
|
|
|
|
validNames := []string{
|
|
|
|
"YadaHereAndThere",
|
|
|
|
"Valid-5Metric_Name",
|
|
|
|
"This . is also %% valid@!)+(",
|
|
|
|
"1234",
|
|
|
|
strings.Repeat("W", 512),
|
|
|
|
}
|
|
|
|
for _, v := range validNames {
|
|
|
|
_, errors := validateLogMetricFilterName(v, "name")
|
|
|
|
if len(errors) != 0 {
|
|
|
|
t.Fatalf("%q should be a valid Log Metric Filter Name: %q", v, errors)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
invalidNames := []string{
|
|
|
|
"Here is a name with: colon",
|
|
|
|
"and here is another * invalid name",
|
|
|
|
"*",
|
|
|
|
// length > 512
|
|
|
|
strings.Repeat("W", 513),
|
|
|
|
}
|
|
|
|
for _, v := range invalidNames {
|
|
|
|
_, errors := validateLogMetricFilterName(v, "name")
|
|
|
|
if len(errors) == 0 {
|
|
|
|
t.Fatalf("%q should be an invalid Log Metric Filter Name", v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestValidateLogMetricTransformationName(t *testing.T) {
|
|
|
|
validNames := []string{
|
|
|
|
"YadaHereAndThere",
|
|
|
|
"Valid-5Metric_Name",
|
|
|
|
"This . is also %% valid@!)+(",
|
|
|
|
"1234",
|
|
|
|
"",
|
|
|
|
strings.Repeat("W", 255),
|
|
|
|
}
|
|
|
|
for _, v := range validNames {
|
|
|
|
_, errors := validateLogMetricFilterTransformationName(v, "name")
|
|
|
|
if len(errors) != 0 {
|
|
|
|
t.Fatalf("%q should be a valid Log Metric Filter Transformation Name: %q", v, errors)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
invalidNames := []string{
|
|
|
|
"Here is a name with: colon",
|
|
|
|
"and here is another * invalid name",
|
|
|
|
"also $ invalid",
|
|
|
|
"*",
|
|
|
|
// length > 255
|
|
|
|
strings.Repeat("W", 256),
|
|
|
|
}
|
|
|
|
for _, v := range invalidNames {
|
|
|
|
_, errors := validateLogMetricFilterTransformationName(v, "name")
|
|
|
|
if len(errors) == 0 {
|
|
|
|
t.Fatalf("%q should be an invalid Log Metric Filter Transformation Name", v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestValidateLogGroupName(t *testing.T) {
|
|
|
|
validNames := []string{
|
|
|
|
"ValidLogGroupName",
|
|
|
|
"ValidLogGroup.Name",
|
|
|
|
"valid/Log-group",
|
|
|
|
"1234",
|
|
|
|
"YadaValid#0123",
|
|
|
|
"Also_valid-name",
|
|
|
|
strings.Repeat("W", 512),
|
|
|
|
}
|
|
|
|
for _, v := range validNames {
|
|
|
|
_, errors := validateLogGroupName(v, "name")
|
|
|
|
if len(errors) != 0 {
|
|
|
|
t.Fatalf("%q should be a valid Log Metric Filter Transformation Name: %q", v, errors)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
invalidNames := []string{
|
|
|
|
"Here is a name with: colon",
|
|
|
|
"and here is another * invalid name",
|
|
|
|
"also $ invalid",
|
|
|
|
"This . is also %% invalid@!)+(",
|
|
|
|
"*",
|
|
|
|
"",
|
|
|
|
// length > 512
|
|
|
|
strings.Repeat("W", 513),
|
|
|
|
}
|
|
|
|
for _, v := range invalidNames {
|
|
|
|
_, errors := validateLogGroupName(v, "name")
|
|
|
|
if len(errors) == 0 {
|
|
|
|
t.Fatalf("%q should be an invalid Log Metric Filter Transformation Name", v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-04-20 12:16:14 +02:00
|
|
|
|
|
|
|
func TestValidateS3BucketLifecycleTimestamp(t *testing.T) {
|
|
|
|
validDates := []string{
|
|
|
|
"2016-01-01",
|
|
|
|
"2006-01-02",
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, v := range validDates {
|
|
|
|
_, errors := validateS3BucketLifecycleTimestamp(v, "date")
|
|
|
|
if len(errors) != 0 {
|
|
|
|
t.Fatalf("%q should be valid date: %q", v, errors)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
invalidDates := []string{
|
|
|
|
"Jan 01 2016",
|
|
|
|
"20160101",
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, v := range invalidDates {
|
|
|
|
_, errors := validateS3BucketLifecycleTimestamp(v, "date")
|
|
|
|
if len(errors) == 0 {
|
|
|
|
t.Fatalf("%q should be invalid date", v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestValidateS3BucketLifecycleStorageClass(t *testing.T) {
|
|
|
|
validStorageClass := []string{
|
|
|
|
"STANDARD_IA",
|
|
|
|
"GLACIER",
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, v := range validStorageClass {
|
|
|
|
_, errors := validateS3BucketLifecycleStorageClass(v, "storage_class")
|
|
|
|
if len(errors) != 0 {
|
|
|
|
t.Fatalf("%q should be valid storage class: %q", v, errors)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
invalidStorageClass := []string{
|
|
|
|
"STANDARD",
|
|
|
|
"1234",
|
|
|
|
}
|
|
|
|
for _, v := range invalidStorageClass {
|
|
|
|
_, errors := validateS3BucketLifecycleStorageClass(v, "storage_class")
|
|
|
|
if len(errors) == 0 {
|
|
|
|
t.Fatalf("%q should be invalid storage class", v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-08 11:59:13 +01:00
|
|
|
func TestValidateS3BucketReplicationRuleId(t *testing.T) {
|
|
|
|
validId := []string{
|
|
|
|
"YadaHereAndThere",
|
|
|
|
"Valid-5Rule_ID",
|
|
|
|
"This . is also %% valid@!)+*(:ID",
|
|
|
|
"1234",
|
|
|
|
strings.Repeat("W", 255),
|
|
|
|
}
|
|
|
|
for _, v := range validId {
|
|
|
|
_, errors := validateS3BucketReplicationRuleId(v, "id")
|
|
|
|
if len(errors) != 0 {
|
|
|
|
t.Fatalf("%q should be a valid lifecycle rule id: %q", v, errors)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
invalidId := []string{
|
|
|
|
// length > 255
|
|
|
|
strings.Repeat("W", 256),
|
|
|
|
}
|
|
|
|
for _, v := range invalidId {
|
|
|
|
_, errors := validateS3BucketReplicationRuleId(v, "id")
|
|
|
|
if len(errors) == 0 {
|
|
|
|
t.Fatalf("%q should be an invalid replication configuration rule id", v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestValidateS3BucketReplicationRulePrefix(t *testing.T) {
|
|
|
|
validId := []string{
|
|
|
|
"YadaHereAndThere",
|
|
|
|
"Valid-5Rule_ID",
|
|
|
|
"This . is also %% valid@!)+*(:ID",
|
|
|
|
"1234",
|
|
|
|
strings.Repeat("W", 1024),
|
|
|
|
}
|
|
|
|
for _, v := range validId {
|
|
|
|
_, errors := validateS3BucketReplicationRulePrefix(v, "id")
|
|
|
|
if len(errors) != 0 {
|
|
|
|
t.Fatalf("%q should be a valid lifecycle rule id: %q", v, errors)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
invalidId := []string{
|
|
|
|
// length > 1024
|
|
|
|
strings.Repeat("W", 1025),
|
|
|
|
}
|
|
|
|
for _, v := range invalidId {
|
|
|
|
_, errors := validateS3BucketReplicationRulePrefix(v, "id")
|
|
|
|
if len(errors) == 0 {
|
|
|
|
t.Fatalf("%q should be an invalid replication configuration rule id", v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestValidateS3BucketReplicationDestinationStorageClass(t *testing.T) {
|
|
|
|
validStorageClass := []string{
|
|
|
|
s3.StorageClassStandard,
|
|
|
|
s3.StorageClassStandardIa,
|
|
|
|
s3.StorageClassReducedRedundancy,
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, v := range validStorageClass {
|
|
|
|
_, errors := validateS3BucketReplicationDestinationStorageClass(v, "storage_class")
|
|
|
|
if len(errors) != 0 {
|
|
|
|
t.Fatalf("%q should be valid storage class: %q", v, errors)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
invalidStorageClass := []string{
|
|
|
|
"FOO",
|
|
|
|
"1234",
|
|
|
|
}
|
|
|
|
for _, v := range invalidStorageClass {
|
|
|
|
_, errors := validateS3BucketReplicationDestinationStorageClass(v, "storage_class")
|
|
|
|
if len(errors) == 0 {
|
|
|
|
t.Fatalf("%q should be invalid storage class", v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestValidateS3BucketReplicationRuleStatus(t *testing.T) {
|
|
|
|
validRuleStatuses := []string{
|
|
|
|
s3.ReplicationRuleStatusEnabled,
|
|
|
|
s3.ReplicationRuleStatusDisabled,
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, v := range validRuleStatuses {
|
|
|
|
_, errors := validateS3BucketReplicationRuleStatus(v, "status")
|
|
|
|
if len(errors) != 0 {
|
|
|
|
t.Fatalf("%q should be valid rule status: %q", v, errors)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
invalidRuleStatuses := []string{
|
|
|
|
"FOO",
|
|
|
|
"1234",
|
|
|
|
}
|
|
|
|
for _, v := range invalidRuleStatuses {
|
|
|
|
_, errors := validateS3BucketReplicationRuleStatus(v, "status")
|
|
|
|
if len(errors) == 0 {
|
|
|
|
t.Fatalf("%q should be invalid rule status", v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-20 12:16:14 +02:00
|
|
|
func TestValidateS3BucketLifecycleRuleId(t *testing.T) {
|
|
|
|
validId := []string{
|
|
|
|
"YadaHereAndThere",
|
|
|
|
"Valid-5Rule_ID",
|
|
|
|
"This . is also %% valid@!)+*(:ID",
|
|
|
|
"1234",
|
|
|
|
strings.Repeat("W", 255),
|
|
|
|
}
|
|
|
|
for _, v := range validId {
|
|
|
|
_, errors := validateS3BucketLifecycleRuleId(v, "id")
|
|
|
|
if len(errors) != 0 {
|
|
|
|
t.Fatalf("%q should be a valid lifecycle rule id: %q", v, errors)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
invalidId := []string{
|
|
|
|
// length > 255
|
|
|
|
strings.Repeat("W", 256),
|
|
|
|
}
|
|
|
|
for _, v := range invalidId {
|
|
|
|
_, errors := validateS3BucketLifecycleRuleId(v, "id")
|
|
|
|
if len(errors) == 0 {
|
|
|
|
t.Fatalf("%q should be an invalid lifecycle rule id", v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-04-25 13:22:37 +02:00
|
|
|
|
|
|
|
func TestValidateIntegerInRange(t *testing.T) {
|
|
|
|
validIntegers := []int{-259, 0, 1, 5, 999}
|
|
|
|
min := -259
|
|
|
|
max := 999
|
|
|
|
for _, v := range validIntegers {
|
|
|
|
_, errors := validateIntegerInRange(min, max)(v, "name")
|
|
|
|
if len(errors) != 0 {
|
|
|
|
t.Fatalf("%q should be an integer in range (%d, %d): %q", v, min, max, errors)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
invalidIntegers := []int{-260, -99999, 1000, 25678}
|
|
|
|
for _, v := range invalidIntegers {
|
|
|
|
_, errors := validateIntegerInRange(min, max)(v, "name")
|
|
|
|
if len(errors) == 0 {
|
|
|
|
t.Fatalf("%q should be an integer outside range (%d, %d)", v, min, max)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-04-25 22:44:55 +02:00
|
|
|
|
|
|
|
func TestResourceAWSElastiCacheClusterIdValidation(t *testing.T) {
|
|
|
|
cases := []struct {
|
|
|
|
Value string
|
|
|
|
ErrCount int
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
Value: "tEsting",
|
|
|
|
ErrCount: 1,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Value: "t.sting",
|
|
|
|
ErrCount: 1,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Value: "t--sting",
|
|
|
|
ErrCount: 1,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Value: "1testing",
|
|
|
|
ErrCount: 1,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Value: "testing-",
|
|
|
|
ErrCount: 1,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Value: randomString(65),
|
|
|
|
ErrCount: 1,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range cases {
|
|
|
|
_, errors := validateElastiCacheClusterId(tc.Value, "aws_elasticache_cluster_cluster_id")
|
|
|
|
|
|
|
|
if len(errors) != tc.ErrCount {
|
|
|
|
t.Fatalf("Expected the ElastiCache Cluster cluster_id to trigger a validation error")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-05-05 12:14:25 +02:00
|
|
|
|
|
|
|
func TestValidateDbEventSubscriptionName(t *testing.T) {
|
|
|
|
validNames := []string{
|
|
|
|
"valid-name",
|
|
|
|
"valid02-name",
|
|
|
|
"Valid-Name1",
|
|
|
|
}
|
|
|
|
for _, v := range validNames {
|
|
|
|
_, errors := validateDbEventSubscriptionName(v, "name")
|
|
|
|
if len(errors) != 0 {
|
|
|
|
t.Fatalf("%q should be a valid RDS Event Subscription Name: %q", v, errors)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
invalidNames := []string{
|
|
|
|
"Here is a name with: colon",
|
|
|
|
"and here is another * invalid name",
|
|
|
|
"also $ invalid",
|
|
|
|
"This . is also %% invalid@!)+(",
|
|
|
|
"*",
|
|
|
|
"",
|
|
|
|
" ",
|
|
|
|
"_",
|
|
|
|
// length > 255
|
|
|
|
strings.Repeat("W", 256),
|
|
|
|
}
|
|
|
|
for _, v := range invalidNames {
|
|
|
|
_, errors := validateDbEventSubscriptionName(v, "name")
|
|
|
|
if len(errors) == 0 {
|
|
|
|
t.Fatalf("%q should be an invalid RDS Event Subscription Name", v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-09-17 20:50:38 +02:00
|
|
|
|
|
|
|
func TestValidateJsonString(t *testing.T) {
|
|
|
|
type testCases struct {
|
|
|
|
Value string
|
|
|
|
ErrCount int
|
|
|
|
}
|
|
|
|
|
|
|
|
invalidCases := []testCases{
|
|
|
|
{
|
|
|
|
Value: `{0:"1"}`,
|
|
|
|
ErrCount: 1,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Value: `{'abc':1}`,
|
|
|
|
ErrCount: 1,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Value: `{"def":}`,
|
|
|
|
ErrCount: 1,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Value: `{"xyz":[}}`,
|
|
|
|
ErrCount: 1,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range invalidCases {
|
|
|
|
_, errors := validateJsonString(tc.Value, "json")
|
|
|
|
if len(errors) != tc.ErrCount {
|
|
|
|
t.Fatalf("Expected %q to trigger a validation error.", tc.Value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
validCases := []testCases{
|
|
|
|
{
|
|
|
|
Value: ``,
|
|
|
|
ErrCount: 0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Value: `{}`,
|
|
|
|
ErrCount: 0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Value: `{"abc":["1","2"]}`,
|
|
|
|
ErrCount: 0,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range validCases {
|
|
|
|
_, errors := validateJsonString(tc.Value, "json")
|
|
|
|
if len(errors) != tc.ErrCount {
|
|
|
|
t.Fatalf("Expected %q not to trigger a validation error.", tc.Value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-10-10 19:41:05 +02:00
|
|
|
|
2017-01-20 15:00:32 +01:00
|
|
|
func TestValidateCloudFormationTemplate(t *testing.T) {
|
|
|
|
type testCases struct {
|
|
|
|
Value string
|
|
|
|
ErrCount int
|
|
|
|
}
|
|
|
|
|
|
|
|
invalidCases := []testCases{
|
|
|
|
{
|
|
|
|
Value: `{"abc":"`,
|
|
|
|
ErrCount: 1,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Value: "abc: [",
|
|
|
|
ErrCount: 1,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range invalidCases {
|
|
|
|
_, errors := validateCloudFormationTemplate(tc.Value, "template")
|
|
|
|
if len(errors) != tc.ErrCount {
|
|
|
|
t.Fatalf("Expected %q to trigger a validation error.", tc.Value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
validCases := []testCases{
|
|
|
|
{
|
|
|
|
Value: `{"abc":"1"}`,
|
|
|
|
ErrCount: 0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Value: `abc: 1`,
|
|
|
|
ErrCount: 0,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range validCases {
|
|
|
|
_, errors := validateCloudFormationTemplate(tc.Value, "template")
|
|
|
|
if len(errors) != tc.ErrCount {
|
|
|
|
t.Fatalf("Expected %q not to trigger a validation error.", tc.Value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-10 19:41:05 +02:00
|
|
|
func TestValidateApiGatewayIntegrationType(t *testing.T) {
|
|
|
|
type testCases struct {
|
|
|
|
Value string
|
|
|
|
ErrCount int
|
|
|
|
}
|
|
|
|
|
|
|
|
invalidCases := []testCases{
|
|
|
|
{
|
|
|
|
Value: "incorrect",
|
|
|
|
ErrCount: 1,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Value: "aws_proxy",
|
|
|
|
ErrCount: 1,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range invalidCases {
|
|
|
|
_, errors := validateApiGatewayIntegrationType(tc.Value, "types")
|
|
|
|
if len(errors) != tc.ErrCount {
|
|
|
|
t.Fatalf("Expected %q to trigger a validation error.", tc.Value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
validCases := []testCases{
|
|
|
|
{
|
|
|
|
Value: "MOCK",
|
|
|
|
ErrCount: 0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Value: "AWS_PROXY",
|
|
|
|
ErrCount: 0,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range validCases {
|
|
|
|
_, errors := validateApiGatewayIntegrationType(tc.Value, "types")
|
|
|
|
if len(errors) != tc.ErrCount {
|
|
|
|
t.Fatalf("Expected %q not to trigger a validation error.", tc.Value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-12-12 18:40:59 +01:00
|
|
|
|
|
|
|
func TestValidateSQSQueueName(t *testing.T) {
|
|
|
|
validNames := []string{
|
|
|
|
"valid-name",
|
|
|
|
"valid02-name",
|
|
|
|
"Valid-Name1",
|
|
|
|
"_",
|
|
|
|
"-",
|
|
|
|
strings.Repeat("W", 80),
|
|
|
|
}
|
|
|
|
for _, v := range validNames {
|
|
|
|
if errors := validateSQSQueueName(v, "name"); len(errors) > 0 {
|
|
|
|
t.Fatalf("%q should be a valid SQS queue Name", v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
invalidNames := []string{
|
|
|
|
"Here is a name with: colon",
|
|
|
|
"another * invalid name",
|
|
|
|
"also $ invalid",
|
|
|
|
"This . is also %% invalid@!)+(",
|
|
|
|
"*",
|
|
|
|
"",
|
|
|
|
" ",
|
|
|
|
".",
|
|
|
|
strings.Repeat("W", 81), // length > 80
|
|
|
|
}
|
|
|
|
for _, v := range invalidNames {
|
|
|
|
if errors := validateSQSQueueName(v, "name"); len(errors) == 0 {
|
|
|
|
t.Fatalf("%q should be an invalid SQS queue Name", v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestValidateSQSFifoQueueName(t *testing.T) {
|
|
|
|
validNames := []string{
|
|
|
|
"valid-name.fifo",
|
|
|
|
"valid02-name.fifo",
|
|
|
|
"Valid-Name1.fifo",
|
|
|
|
"_.fifo",
|
|
|
|
"a.fifo",
|
|
|
|
"A.fifo",
|
|
|
|
"9.fifo",
|
|
|
|
"-.fifo",
|
|
|
|
fmt.Sprintf("%s.fifo", strings.Repeat("W", 75)),
|
|
|
|
}
|
|
|
|
for _, v := range validNames {
|
|
|
|
if errors := validateSQSFifoQueueName(v, "name"); len(errors) > 0 {
|
|
|
|
t.Fatalf("%q should be a valid SQS FIFO queue Name: %v", v, errors)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
invalidNames := []string{
|
|
|
|
"Here is a name with: colon",
|
|
|
|
"another * invalid name",
|
|
|
|
"also $ invalid",
|
|
|
|
"This . is also %% invalid@!)+(",
|
|
|
|
".fifo",
|
|
|
|
"*",
|
|
|
|
"",
|
|
|
|
" ",
|
|
|
|
".",
|
|
|
|
strings.Repeat("W", 81), // length > 80
|
|
|
|
}
|
|
|
|
for _, v := range invalidNames {
|
|
|
|
if errors := validateSQSFifoQueueName(v, "name"); len(errors) == 0 {
|
|
|
|
t.Fatalf("%q should be an invalid SQS FIFO queue Name: %v", v, errors)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-12-13 17:54:52 +01:00
|
|
|
|
|
|
|
func TestValidateSNSSubscriptionProtocol(t *testing.T) {
|
|
|
|
validProtocols := []string{
|
|
|
|
"lambda",
|
|
|
|
"sqs",
|
|
|
|
"sqs",
|
|
|
|
"application",
|
|
|
|
"http",
|
|
|
|
"https",
|
|
|
|
}
|
|
|
|
for _, v := range validProtocols {
|
|
|
|
if _, errors := validateSNSSubscriptionProtocol(v, "protocol"); len(errors) > 0 {
|
|
|
|
t.Fatalf("%q should be a valid SNS Subscription protocol: %v", v, errors)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
invalidProtocols := []string{
|
|
|
|
"Email",
|
|
|
|
"email",
|
|
|
|
"Email-JSON",
|
|
|
|
"email-json",
|
|
|
|
"SMS",
|
|
|
|
"sms",
|
|
|
|
}
|
|
|
|
for _, v := range invalidProtocols {
|
|
|
|
if _, errors := validateSNSSubscriptionProtocol(v, "protocol"); len(errors) == 0 {
|
|
|
|
t.Fatalf("%q should be an invalid SNS Subscription protocol: %v", v, errors)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-12-30 01:26:01 +01:00
|
|
|
|
|
|
|
func TestValidateSecurityRuleType(t *testing.T) {
|
|
|
|
validTypes := []string{
|
|
|
|
"ingress",
|
|
|
|
"egress",
|
|
|
|
}
|
|
|
|
for _, v := range validTypes {
|
|
|
|
if _, errors := validateSecurityRuleType(v, "type"); len(errors) > 0 {
|
|
|
|
t.Fatalf("%q should be a valid Security Group Rule type: %v", v, errors)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
invalidTypes := []string{
|
|
|
|
"foo",
|
|
|
|
"ingresss",
|
|
|
|
}
|
|
|
|
for _, v := range invalidTypes {
|
|
|
|
if _, errors := validateSecurityRuleType(v, "type"); len(errors) == 0 {
|
|
|
|
t.Fatalf("%q should be an invalid Security Group Rule type: %v", v, errors)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-01-09 14:12:07 +01:00
|
|
|
|
|
|
|
func TestValidateOnceAWeekWindowFormat(t *testing.T) {
|
|
|
|
cases := []struct {
|
|
|
|
Value string
|
|
|
|
ErrCount int
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
// once a day window format
|
|
|
|
Value: "04:00-05:00",
|
|
|
|
ErrCount: 1,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
// invalid day of week
|
|
|
|
Value: "san:04:00-san:05:00",
|
|
|
|
ErrCount: 1,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
// invalid hour
|
|
|
|
Value: "sun:24:00-san:25:00",
|
|
|
|
ErrCount: 1,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
// invalid min
|
|
|
|
Value: "sun:04:00-sun:04:60",
|
|
|
|
ErrCount: 1,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
// valid format
|
|
|
|
Value: "sun:04:00-sun:05:00",
|
|
|
|
ErrCount: 0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
// "Sun" can also be used
|
|
|
|
Value: "Sun:04:00-Sun:05:00",
|
|
|
|
ErrCount: 0,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range cases {
|
|
|
|
_, errors := validateOnceAWeekWindowFormat(tc.Value, "maintenance_window")
|
|
|
|
|
|
|
|
if len(errors) != tc.ErrCount {
|
|
|
|
t.Fatalf("Expected %d validation errors, But got %d errors for \"%s\"", tc.ErrCount, len(errors), tc.Value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestValidateOnceADayWindowFormat(t *testing.T) {
|
|
|
|
cases := []struct {
|
|
|
|
Value string
|
|
|
|
ErrCount int
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
// once a week window format
|
|
|
|
Value: "sun:04:00-sun:05:00",
|
|
|
|
ErrCount: 1,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
// invalid hour
|
|
|
|
Value: "24:00-25:00",
|
|
|
|
ErrCount: 1,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
// invalid min
|
|
|
|
Value: "04:00-04:60",
|
|
|
|
ErrCount: 1,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
// valid format
|
|
|
|
Value: "04:00-05:00",
|
|
|
|
ErrCount: 0,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range cases {
|
|
|
|
_, errors := validateOnceADayWindowFormat(tc.Value, "backup_window")
|
|
|
|
|
|
|
|
if len(errors) != tc.ErrCount {
|
|
|
|
t.Fatalf("Expected %d validation errors, But got %d errors for \"%s\"", tc.ErrCount, len(errors), tc.Value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-01-09 21:45:26 +01:00
|
|
|
|
|
|
|
func TestValidateRoute53RecordType(t *testing.T) {
|
|
|
|
validTypes := []string{
|
|
|
|
"AAAA",
|
|
|
|
"SOA",
|
|
|
|
"A",
|
|
|
|
"TXT",
|
|
|
|
"CNAME",
|
|
|
|
"MX",
|
|
|
|
"NAPTR",
|
|
|
|
"PTR",
|
|
|
|
"SPF",
|
|
|
|
"SRV",
|
|
|
|
"NS",
|
|
|
|
}
|
|
|
|
|
|
|
|
invalidTypes := []string{
|
|
|
|
"a",
|
|
|
|
"alias",
|
|
|
|
"SpF",
|
|
|
|
"Txt",
|
|
|
|
"AaAA",
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, v := range validTypes {
|
|
|
|
_, errors := validateRoute53RecordType(v, "route53_record")
|
|
|
|
if len(errors) != 0 {
|
|
|
|
t.Fatalf("%q should be a valid Route53 record type: %v", v, errors)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, v := range invalidTypes {
|
|
|
|
_, errors := validateRoute53RecordType(v, "route53_record")
|
|
|
|
if len(errors) == 0 {
|
|
|
|
t.Fatalf("%q should not be a valid Route53 record type", v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-01-19 23:54:52 +01:00
|
|
|
|
|
|
|
func TestValidateEcsPlacementConstraint(t *testing.T) {
|
|
|
|
cases := []struct {
|
|
|
|
constType string
|
|
|
|
constExpr string
|
|
|
|
Err bool
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
constType: "distinctInstance",
|
|
|
|
constExpr: "",
|
|
|
|
Err: false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
constType: "memberOf",
|
|
|
|
constExpr: "",
|
|
|
|
Err: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
constType: "distinctInstance",
|
|
|
|
constExpr: "expression",
|
|
|
|
Err: false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
constType: "memberOf",
|
|
|
|
constExpr: "expression",
|
|
|
|
Err: false,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range cases {
|
|
|
|
if err := validateAwsEcsPlacementConstraint(tc.constType, tc.constExpr); err != nil && !tc.Err {
|
|
|
|
t.Fatalf("Unexpected validation error for \"%s:%s\": %s",
|
|
|
|
tc.constType, tc.constExpr, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestValidateEcsPlacementStrategy(t *testing.T) {
|
|
|
|
cases := []struct {
|
|
|
|
stratType string
|
|
|
|
stratField string
|
|
|
|
Err bool
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
stratType: "random",
|
|
|
|
stratField: "",
|
|
|
|
Err: false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
stratType: "spread",
|
|
|
|
stratField: "instanceID",
|
|
|
|
Err: false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
stratType: "binpack",
|
|
|
|
stratField: "cpu",
|
|
|
|
Err: false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
stratType: "binpack",
|
|
|
|
stratField: "memory",
|
|
|
|
Err: false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
stratType: "binpack",
|
|
|
|
stratField: "disk",
|
|
|
|
Err: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
stratType: "fakeType",
|
|
|
|
stratField: "",
|
|
|
|
Err: true,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range cases {
|
|
|
|
if err := validateAwsEcsPlacementStrategy(tc.stratType, tc.stratField); err != nil && !tc.Err {
|
|
|
|
t.Fatalf("Unexpected validation error for \"%s:%s\": %s",
|
|
|
|
tc.stratType, tc.stratField, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|