Skip to content

Commit

Permalink
add value_type integer, improve tests to always use interface{} to ma…
Browse files Browse the repository at this point in the history
…tch JSON parsing results
  • Loading branch information
Larry Hitchon committed Mar 29, 2018
1 parent 69db370 commit 3a204fb
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 36 deletions.
62 changes: 55 additions & 7 deletions assertion/assertion_test.go
Expand Up @@ -37,13 +37,25 @@ func TestCheckAssertion(t *testing.T) {
Properties: map[string]interface{}{
"instance_type": "t2.micro",
"ami": "ami-f2d3638a",
"tags": map[string]string{
"tags": map[string]interface{}{
"Environment": "Development",
"Project": "Web",
},
},
Filename: "test.tf",
}
resourceWithRootVolume := Resource{
ID: "another_test_resource",
Type: "aws_instance",
Properties: map[string]interface{}{
"instance_type": "t2.micro",
"ami": "ami-f2d3638a",
"root_block_device": map[string]interface{}{
"volume_size": "1000",
},
},
Filename: "test.tf",
}

testCases := map[string]AssertionTestCase{
"testEq": {
Expand Down Expand Up @@ -239,7 +251,7 @@ func TestCheckAssertion(t *testing.T) {
simpleTestResource,
"FAILURE",
},
"testResourceCountFails": {
"testSizeFails": {
Rule{
ID: "TESTCOUNT",
Message: "Test Resource Count Fails",
Expand All @@ -257,7 +269,7 @@ func TestCheckAssertion(t *testing.T) {
resourceWithTags,
"FAILURE",
},
"testResourceCountOK": {
"testSizeOK": {
Rule{
ID: "TESTCOUNT",
Message: "Test Resource Count OK",
Expand All @@ -275,6 +287,42 @@ func TestCheckAssertion(t *testing.T) {
resourceWithTags,
"OK",
},
"testIntegerFails": {
Rule{
ID: "TESTCOUNT",
Message: "Test integer Fails",
Severity: "FAILURE",
Resource: "aws_instance",
Assertions: []Assertion{
Assertion{
Key: "root_block_device.volume_size",
ValueType: "integer",
Op: "le",
Value: "500",
},
},
},
resourceWithRootVolume,
"FAILURE",
},
"testIntegerOK": {
Rule{
ID: "TESTCOUNT",
Message: "Test integer OK",
Severity: "FAILURE",
Resource: "aws_instance",
Assertions: []Assertion{
Assertion{
Key: "root_block_device.volume_size",
ValueType: "integer",
Op: "le",
Value: "2000",
},
},
},
resourceWithRootVolume,
"OK",
},
}

for k, tc := range testCases {
Expand Down Expand Up @@ -319,14 +367,14 @@ func TestNestedBooleans(t *testing.T) {
Properties: map[string]interface{}{},
Filename: "test.tf",
}
rulesJSON := `{
resourceJSON := `{
"description": "2017-12-03T03:14:29.856Z",
"groupName": "test-8246",
"ipPermissions": [
{
"fromPort": 22,
"fromPort": "22",
"ipProtocol": "tcp",
"toPort": 22,
"toPort": "22",
"ipv4Ranges": [
{
"cidrIp": "0.0.0.0/0"
Expand All @@ -338,7 +386,7 @@ func TestNestedBooleans(t *testing.T) {
}
]
}`
err := json.Unmarshal([]byte(rulesJSON), &resource.Properties)
err := json.Unmarshal([]byte(resourceJSON), &resource.Properties)
if err != nil {
t.Error("Error parsing resource JSON")
}
Expand Down
26 changes: 17 additions & 9 deletions assertion/compare.go
Expand Up @@ -4,24 +4,32 @@ import (
"strconv"
)

func intCompare(n1 int, n2 int) int {
if n1 < n2 {
return -1
}
if n1 > n2 {
return 1
}
return 0
}

func compare(data interface{}, value string, valueType string) int {
switch valueType {
case "size":
n, _ := strconv.Atoi(value)
l := 0
switch v := data.(type) {
case []string:
case []interface{}:
l = len(v)
case map[string]string:
case map[string]interface{}:
l = len(v)
}
if l < n {
return -1
}
if l > n {
return 1
}
return 0
return intCompare(l, n)
case "integer":
n1, _ := strconv.Atoi(data.(string))
n2, _ := strconv.Atoi(value)
return intCompare(n1, n2)
default:
tmp, _ := JSONStringify(data)
s := unquoted(tmp)
Expand Down
27 changes: 10 additions & 17 deletions assertion/match.go
Expand Up @@ -19,16 +19,6 @@ func convertToString(data interface{}) (string, bool) {
return s, ok
}

func convertToSliceOfStrings(data interface{}) ([]string, bool) {
s, ok := data.([]string)
return s, ok
}

func isObject(data interface{}) bool {
_, ok := data.(map[string]interface{})
return ok
}

func isMatch(data interface{}, op string, value string, valueType string) (bool, error) {
searchResult, err := JSONStringify(data)
if err != nil {
Expand Down Expand Up @@ -94,17 +84,20 @@ func isMatch(data interface{}, op string, value string, valueType string) (bool,
return true, nil
}
case "contains":
if c, isSlice := convertToSlice(data); isSlice {
for _, element := range c {
if stringElement, isString := element.(string); isString {
if stringElement == value {
return true, nil
}
}
}
return false, nil
}
if s, isString := convertToString(data); isString {
if strings.Contains(s, value) {
return true, nil
}
}
if c, isSlice := convertToSliceOfStrings(data); isSlice {
for _, element := range c {
if element == value {
return true, nil
}
}
return false, nil
}
return strings.Contains(searchResult, value), nil
Expand Down
7 changes: 4 additions & 3 deletions assertion/match_test.go
Expand Up @@ -38,8 +38,9 @@ func unmarshal(s string) (interface{}, error) {

func TestIsMatch(t *testing.T) {

sliceOfTags := []string{"Foo", "Bar"}
sliceOfTags := []interface{}{"Foo", "Bar"}
emptySlice := []interface{}{}
anotherSlice := []interface{}{"One", "Two"}

testCases := map[string]MatchTestCase{
"eqTrue": {"Foo", "eq", "Foo", "", true},
Expand Down Expand Up @@ -89,8 +90,8 @@ func TestIsMatch(t *testing.T) {
"notEmptyTrueForSlice": {sliceOfTags, "not-empty", "", "", true},
"intersectTrue": {"[\"one\",\"two\"]", "intersect", "[\"two\",\"three\"]", "", true},
"intersectFalse": {"[\"one\",\"two\"]", "intersect", "[\"three\",\"four\"]", "", false},
"eqSizeTrue": {sliceOfTags, "eq", "2", "size", true},
"eqSizeFalse": {sliceOfTags, "eq", "3", "size", false},
"eqSizeTrue": {anotherSlice, "eq", "2", "size", true},
"eqSizeFalse": {anotherSlice, "eq", "3", "size", false},
}
for k, tc := range testCases {
var b bool
Expand Down

0 comments on commit 3a204fb

Please sign in to comment.