Example #1
0
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)
	}
}
Example #2
0
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
}
Example #3
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")
	}
}
Example #5
0
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")
	}
}