Skip to content

Commit

Permalink
fix type mixing in matchers for stringified int
Browse files Browse the repository at this point in the history
  • Loading branch information
xchapter7x committed Feb 24, 2019
1 parent 2b000d0 commit 213e27e
Show file tree
Hide file tree
Showing 4 changed files with 167 additions and 7 deletions.
2 changes: 2 additions & 0 deletions cmd/clarity/clarity_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ func FeatureContext(s *godog.Suite) {
s.Step(`^"([^"]*)"$`, noopComment)
s.Step(`^Terraform$`, match.Terraform)
s.Step(`^a "([^"]*)" of type "([^"]*)"$`, match.AOfType)
s.Step(`^attribute "([^"]*)" equals (\d+)$`, match.AttributeEqualsInt)
s.Step(`^attribute "([^"]*)" does not equal (\d+)$`, match.AttributeDoesNotEqualInt)
s.Step(`^attribute "([^"]*)" equals "([^"]*)"$`, match.AttributeEquals)
s.Step(`^attribute "([^"]*)" does not equal "([^"]*)"$`, match.AttributeDoesNotEqual)
s.Step(`^attribute "([^"]*)" exists$`, match.AttributeExists)
Expand Down
73 changes: 66 additions & 7 deletions pkg/matchers/terraform.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,52 @@ func attributeExists(searchName string, attributes []map[string]interface{}) (bo
return false, nil
}

// AttributeEqualsInt will filter on a full match of key value or it will
// return an error
func (m *Match) AttributeEqualsInt(searchKey string, searchValue int) error {
var tmpEntries []HCLEntry
if len(m.MatchingEntries) < 1 {
return fmt.Errorf("no references to find attributes in")
}

for _, entry := range m.MatchingEntries {
exists, attributeValue := attributeExists(searchKey, entry.Attributes.([]map[string]interface{}))
if exists && attributeValue == searchValue {
tmpEntries = append(tmpEntries, entry)
}
}

if len(tmpEntries) < 1 {
entries, _ := json.Marshal(m.MatchingEntries)
return fmt.Errorf("no matches found for attribute %v \n %v", searchValue, string(entries))
}
m.MatchingEntries = tmpEntries
return nil
}

// AttributeDoesNotEqualInt will filter on a full match of key value or it will
// return an error
func (m *Match) AttributeDoesNotEqualInt(searchKey string, searchValue int) error {
var tmpEntries []HCLEntry
if len(m.MatchingEntries) < 1 {
return fmt.Errorf("no references to find attributes in")
}

for _, entry := range m.MatchingEntries {
exists, attributeValue := attributeExists(searchKey, entry.Attributes.([]map[string]interface{}))
if exists && attributeValue != searchValue {
tmpEntries = append(tmpEntries, entry)
}
}

if len(tmpEntries) < 1 {
entries, _ := json.Marshal(m.MatchingEntries)
return fmt.Errorf("no matches found for attribute %v \n %v", searchValue, string(entries))
}
m.MatchingEntries = tmpEntries
return nil
}

// AttributeEquals will filter on a full match of key value or it will
// return an error
func (m *Match) AttributeEquals(searchKey, searchValue string) error {
Expand Down Expand Up @@ -246,10 +292,16 @@ func (m *Match) AttributeGreaterThan(searchKey string, searchValue int) error {
if !exists {
return fmt.Errorf("no attribute found named: %s", searchKey)
}

actualValue, err := strconv.Atoi(attributeValue.(string))
if err != nil {
return fmt.Errorf("could not translate to int: %v", err)
var actualValue int
switch attributeValue := attributeValue.(type) {
case string:
var err error
actualValue, err = strconv.Atoi(attributeValue)
if err != nil {
return fmt.Errorf("could not translate to int: %v", err)
}
case int:
actualValue = attributeValue
}

if exists && actualValue > searchValue {
Expand Down Expand Up @@ -278,9 +330,16 @@ func (m *Match) AttributeLessThan(searchKey string, searchValue int) error {
return fmt.Errorf("no attribute found named: %s", searchKey)
}

actualValue, err := strconv.Atoi(attributeValue.(string))
if err != nil {
return fmt.Errorf("could not translate to int: %v", err)
var actualValue int
switch attributeValue := attributeValue.(type) {
case string:
var err error
actualValue, err = strconv.Atoi(attributeValue)
if err != nil {
return fmt.Errorf("could not translate to int: %v", err)
}
case int:
actualValue = attributeValue
}

if exists && actualValue < searchValue {
Expand Down
95 changes: 95 additions & 0 deletions pkg/matchers/terraform_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,16 @@ func TestMatchers(t *testing.T) {
err = m.AOfType("blah_blah", "resource")
Expect(err).NotTo(HaveOccurred())
Expect(m.AttributeGreaterThan("port", 79)).NotTo(HaveOccurred())
Expect(m.MatchingEntries).To(BeEquivalentTo(controlInstanceMatchIntString()))
})

t.Run("when there are matches with a correct value and the attr value is a int type", func(t *testing.T) {
m := &matchers.Match{}
err := m.ReadTerraform("testdata")
Expect(err).NotTo(HaveOccurred())
err = m.AOfType("foo", "resource")
Expect(err).NotTo(HaveOccurred())
Expect(m.AttributeGreaterThan("port", 79)).NotTo(HaveOccurred())
Expect(m.MatchingEntries).To(BeEquivalentTo(controlInstanceMatchInt()))
})
})
Expand Down Expand Up @@ -196,6 +206,76 @@ func TestMatchers(t *testing.T) {
err = m.AOfType("blah_blah", "resource")
Expect(err).NotTo(HaveOccurred())
Expect(m.AttributeLessThan("port", 81)).NotTo(HaveOccurred())
Expect(m.MatchingEntries).To(BeEquivalentTo(controlInstanceMatchIntString()))
})

t.Run("when there are matches with a correct value and attr value is type int", func(t *testing.T) {
m := &matchers.Match{}
err := m.ReadTerraform("testdata")
Expect(err).NotTo(HaveOccurred())
err = m.AOfType("foo", "resource")
Expect(err).NotTo(HaveOccurred())
Expect(m.AttributeLessThan("port", 81)).NotTo(HaveOccurred())
Expect(m.MatchingEntries).To(BeEquivalentTo(controlInstanceMatchInt()))
})
})

t.Run("m.AttributeEqualsInt", func(t *testing.T) {
t.Run("when there are no matches", func(t *testing.T) {
m := &matchers.Match{}
err := m.ReadTerraform("testdata")
Expect(err).NotTo(HaveOccurred())
err = m.AOfType("foo", "resource")
Expect(err).NotTo(HaveOccurred())
Expect(m.AttributeEqualsInt("bbbbbasdf", 0)).To(HaveOccurred())
})

t.Run("when a valid attribute has non equal value", func(t *testing.T) {
m := &matchers.Match{}
err := m.ReadTerraform("testdata")
Expect(err).NotTo(HaveOccurred())
err = m.AOfType("foo", "resource")
Expect(err).NotTo(HaveOccurred())
Expect(m.AttributeEqualsInt("port", 43)).To(HaveOccurred())
})

t.Run("when there are matches with a correct value", func(t *testing.T) {
m := &matchers.Match{}
err := m.ReadTerraform("testdata")
Expect(err).NotTo(HaveOccurred())
err = m.AOfType("foo", "resource")
Expect(err).NotTo(HaveOccurred())
Expect(m.AttributeEqualsInt("port", 80)).NotTo(HaveOccurred())
Expect(m.MatchingEntries).To(BeEquivalentTo(controlInstanceMatchInt()))
})
})

t.Run("m.AttributeDoesNotEqualInt", func(t *testing.T) {
t.Run("when there are no matches", func(t *testing.T) {
m := &matchers.Match{}
err := m.ReadTerraform("testdata")
Expect(err).NotTo(HaveOccurred())
err = m.AOfType("foo", "resource")
Expect(err).NotTo(HaveOccurred())
Expect(m.AttributeDoesNotEqualInt("bbbbbasdf", 0)).To(HaveOccurred())
})

t.Run("when a valid attribute has non equal value", func(t *testing.T) {
m := &matchers.Match{}
err := m.ReadTerraform("testdata")
Expect(err).NotTo(HaveOccurred())
err = m.AOfType("foo", "resource")
Expect(err).NotTo(HaveOccurred())
Expect(m.AttributeDoesNotEqualInt("port", 80)).To(HaveOccurred())
})

t.Run("when there are matches with a correct value", func(t *testing.T) {
m := &matchers.Match{}
err := m.ReadTerraform("testdata")
Expect(err).NotTo(HaveOccurred())
err = m.AOfType("foo", "resource")
Expect(err).NotTo(HaveOccurred())
Expect(m.AttributeDoesNotEqualInt("port", 81)).NotTo(HaveOccurred())
Expect(m.MatchingEntries).To(BeEquivalentTo(controlInstanceMatchInt()))
})
})
Expand Down Expand Up @@ -277,6 +357,21 @@ func controlInstanceMatch() []matchers.HCLEntry {
}

func controlInstanceMatchInt() []matchers.HCLEntry {
return []matchers.HCLEntry{
matchers.HCLEntry{
HCLType: "resource",
ComponentName: "foo",
InstanceName: "bar",
Attributes: []map[string]interface{}{
map[string]interface{}{
"port": 80,
},
},
},
}
}

func controlInstanceMatchIntString() []matchers.HCLEntry {
return []matchers.HCLEntry{
matchers.HCLEntry{
HCLType: "resource",
Expand Down
4 changes: 4 additions & 0 deletions pkg/matchers/testdata/sample.tf
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ resource "blah_blah" "new_thing" {
port = "80"
}

resource "foo" "bar" {
port = 80
}

resource "google_compute_network" "my-custom-network" {
name = "my-custom-network"
}
Expand Down

0 comments on commit 213e27e

Please sign in to comment.