func TestAZModeValidate(t *testing.T) { template := &parse.Template{} prop := schema.Schema{} ctx := schema.NewInitialContext(template, schema.NewResourceDefinitions(nil), schema.ValidationOptions{}) singleAZCtx := schema.NewPropertyContext( schema.NewResourceContext(ctx, schema.ResourceWithDefinition{ parse.NewTemplateResource("", map[string]interface{}{ "PreferredAvailabilityZones": []interface{}{"one"}, }), schema.Resource{}, }), prop, ) multiAZCtx := schema.NewPropertyContext( schema.NewResourceContext(ctx, schema.ResourceWithDefinition{ parse.NewTemplateResource("", map[string]interface{}{ "PreferredAvailabilityZones": []interface{}{"one", "two"}, }), schema.Resource{}, }), prop) if _, errs := azModeValidate("cross-az", singleAZCtx); errs == nil { t.Error("Should fail if cross-az with single availability zone", errs) } if _, errs := azModeValidate("cross-az", multiAZCtx); errs != nil { t.Error("Should pass if cross-az with multiple availability zones", errs) } }
func (c ValidateCommand) Run(args []string) int { var warningsAsErrors bool var format string var experimentDisableObjectArrayCoercion bool cmdFlags := flag.NewFlagSet("validate", flag.ContinueOnError) cmdFlags.BoolVar(&warningsAsErrors, "warnings-as-errors", false, "Treats any warnings as errors and fails the validation") cmdFlags.BoolVar(&experimentDisableObjectArrayCoercion, "experiment:disable-object-array-coercion", false, "(Experimental) Fail when objects are used in properties which expect an array") cmdFlags.StringVar(&format, "format", "oneline", "Output formatting (online|grouped|machine)") if err := cmdFlags.Parse(args); err != nil { return 1 } args = cmdFlags.Args() stream, err := getReadStream(args) if err != nil { fmt.Println(err) return 1 } bytes, err := ioutil.ReadAll(stream) if err != nil { fmt.Println("Error reading JSON from Stdin") return 1 } template, err := parse.ParseTemplateJSON(bytes) if err != nil { fmt.Println("Error parsing JSON:", err) return 1 } _, reports := schema.TemplateValidate( template, schema.NewResourceDefinitions(resources.AwsTypes), schema.ValidationOptions{ schema.OptionExperimentDisableObjectArrayCoercion: experimentDisableObjectArrayCoercion, }, ) stats := reports.Stats() if format == "grouped" { printGroupedReports(reports) } else if format == "machine" { printTabbed(reports) } else { printReports(reports) } if warningsAsErrors || stats.Failures > 0 { fmt.Printf("Fail: %d failures, %d warnings\n", stats.Failures, stats.Warnings) return 1 } fmt.Printf("Pass: %d failures, %d warnings\n", stats.Failures, stats.Warnings) return 0 }
func TestGeoLocationSubdivisionCodeValidation(t *testing.T) { template := &parse.Template{} res := schema.Resource{ Properties: schema.Properties{ "GeoLocation": schema.Schema{ Type: geoLocation, }, }, } ctx := schema.NewInitialContext(template, schema.NewResourceDefinitions(map[string]schema.Resource{ "TestResource": res, }), schema.ValidationOptions{}) badCountryCtx := schema.NewResourceContext(ctx, schema.ResourceWithDefinition{ parse.NewTemplateResource("TestResource", map[string]interface{}{ "GeoLocation": map[string]interface{}{ "SubdivisionCode": "AK", "CountryCode": "AU", }, }), res, }) badSubdivisionCtx := schema.NewResourceContext(ctx, schema.ResourceWithDefinition{ parse.NewTemplateResource("TestResource", map[string]interface{}{ "GeoLocation": map[string]interface{}{ "SubdivisionCode": "NSW", "CountryCode": "US", }, }), res, }) goodCombinationCtx := schema.NewResourceContext(ctx, schema.ResourceWithDefinition{ parse.NewTemplateResource("TestResource", map[string]interface{}{ "GeoLocation": map[string]interface{}{ "SubdivisionCode": "AK", "CountryCode": "US", }, }), res, }) if _, errs := res.Validate(goodCombinationCtx); errs != nil { t.Error("Period should pass on a valid state with US as the country", errs) } if _, errs := res.Validate(badSubdivisionCtx); errs == nil { t.Error("Period should fail on an invalid subdivision with US as the country") } if _, errs := res.Validate(badCountryCtx); errs == nil { t.Error("Period should fail when subdivision set without US as the country") } }
func TestAllowedMethodsFixedArrays(t *testing.T) { res := Distribution template := &parse.Template{} ctx := schema.NewInitialContext(template, schema.NewResourceDefinitions(map[string]schema.Resource{ "TestResource": res, }), schema.ValidationOptions{}) testCFDistribution := func(allowedMethods []interface{}) schema.ResourceContext { return schema.NewResourceContext(ctx, schema.ResourceWithDefinition{ parse.NewTemplateResource("TestResource", map[string]interface{}{ "DistributionConfig": map[string]interface{}{ "Enabled": true, "DefaultCacheBehavior": map[string]interface{}{ "AllowedMethods": allowedMethods, "TargetOriginId": "test", "ViewerProtocolPolicy": "test", "ForwardedValues": map[string]interface{}{ "QueryString": true, }, }, "Origins": []interface{}{ map[string]interface{}{ "Id": "test", "DomainName": "test", "CustomOriginConfig": map[string]interface{}{ "OriginProtocolPolicy": "test", }, }, }, }, }), res, }) } if _, errs := res.Validate(testCFDistribution([]interface{}{"HEAD", "GET"})); errs != nil { t.Error("Should pass with expected array", errs) } if _, errs := res.Validate(testCFDistribution([]interface{}{"GET", "HEAD"})); errs != nil { t.Error("Should pass with expected array in different order", errs) } if _, errs := res.Validate(testCFDistribution([]interface{}{"DELETE", "GET", "HEAD"})); errs == nil { t.Error("Should fail with random subset") } if _, errs := res.Validate(testCFDistribution([]interface{}{"GET", "HEAD", "somethingElse"})); errs == nil { t.Error("Should fail with unexpected item") } }
func TestNumCacheNodesValidate(t *testing.T) { template := &parse.Template{} prop := schema.Schema{} ctx := schema.NewInitialContext(template, schema.NewResourceDefinitions(nil), schema.ValidationOptions{}) redisCtx := schema.NewPropertyContext( schema.NewResourceContext(ctx, schema.ResourceWithDefinition{ parse.NewTemplateResource("", map[string]interface{}{ "Engine": "redis", }), schema.Resource{}, }), prop) memcachedCtx := schema.NewPropertyContext( schema.NewResourceContext(ctx, schema.ResourceWithDefinition{ parse.NewTemplateResource("", map[string]interface{}{ "Engine": "memcached", }), schema.Resource{}, }), prop) if _, errs := numCacheNodesValidate(float64(1), redisCtx); errs != nil { t.Error("Should pass with 1 redis node", errs) } if _, errs := numCacheNodesValidate(float64(2), redisCtx); errs == nil { t.Error("Should fail with more than 1 redis node", errs) } if _, errs := numCacheNodesValidate(float64(1), memcachedCtx); errs != nil { t.Error("Should pass with 1 memcached node", errs) } if _, errs := numCacheNodesValidate(float64(20), memcachedCtx); errs != nil { t.Error("Should pass with 20 memcached nodes", errs) } if _, errs := numCacheNodesValidate(float64(21), memcachedCtx); errs == nil { t.Error("Should fail with 21 memcached nodes", errs) } }
func TestAutomaticFailoverEnabled(t *testing.T) { template := &parse.Template{} res := ReplicationGroup ctx := schema.NewInitialContext(template, schema.NewResourceDefinitions(map[string]schema.Resource{ "TestResource": res, }), schema.ValidationOptions{}) badVersionCtx := schema.NewPropertyContext( schema.NewResourceContext(ctx, schema.ResourceWithDefinition{ parse.NewTemplateResource("TestResource", map[string]interface{}{ "EngineVersion": "2.7", "CacheNodeType": "cache.m3.medium", }), res, }), schema.Schema{}) badNodeTypeT1Ctx := schema.NewPropertyContext( schema.NewResourceContext(ctx, schema.ResourceWithDefinition{ parse.NewTemplateResource("TestResource", map[string]interface{}{ "EngineVersion": "2.8", "CacheNodeType": "cache.t1.micro", }), res, }), schema.Schema{}) badNodeTypeT2Ctx := schema.NewPropertyContext( schema.NewResourceContext(ctx, schema.ResourceWithDefinition{ parse.NewTemplateResource("TestResource", map[string]interface{}{ "EngineVersion": "2.8", "CacheNodeType": "cache.t2.micro", }), res, }), schema.Schema{}) goodCtx := schema.NewPropertyContext( schema.NewResourceContext(ctx, schema.ResourceWithDefinition{ parse.NewTemplateResource("TestResource", map[string]interface{}{ "EngineVersion": "2.8", "CacheNodeType": "cache.m3.medium", }), res, }), schema.Schema{}) if _, errs := automaticFailoverEnabledValidation(true, badVersionCtx); errs == nil { t.Error("Should fail if has engine less than 2.8") } if _, errs := automaticFailoverEnabledValidation(true, badNodeTypeT1Ctx); errs == nil { t.Error("Should fail if has node type of t1 or t2") } if _, errs := automaticFailoverEnabledValidation(true, badNodeTypeT2Ctx); errs == nil { t.Error("Should fail if has node type of t1 or t2") } if _, errs := automaticFailoverEnabledValidation(true, goodCtx); errs != nil { t.Error("Should pass if engine is 2.8 or above and node type isn't t1 or t2") } }