Skip to content
This repository has been archived by the owner on Oct 17, 2018. It is now read-only.

Commit

Permalink
Improve test coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
xichen2020 committed May 11, 2017
1 parent 1c9df0a commit 4951004
Show file tree
Hide file tree
Showing 6 changed files with 294 additions and 9 deletions.
10 changes: 8 additions & 2 deletions filters/tags_filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,14 @@ func (f *tagsFilter) Matches(id []byte) bool {
if err != nil {
return false
}
if f.nameFilter != nil && !f.nameFilter.Matches(name) {
return false
if f.nameFilter != nil {
match := f.nameFilter.Matches(name)
if match && f.op == Disjunction {
return true
}
if !match && f.op == Conjunction {
return false
}
}

iter := f.opts.SortedTagIteratorFn(tags)
Expand Down
72 changes: 70 additions & 2 deletions filters/tags_filter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
package filters

import (
"bytes"
"errors"
"testing"

"github.com/stretchr/testify/require"
Expand All @@ -32,7 +34,7 @@ func TestEmptyTagsFilterMatches(t *testing.T) {
require.True(t, f.Matches([]byte("foo")))
}

func TestTagsFilterMatches(t *testing.T) {
func TestTagsFilterMatchesNoNameTag(t *testing.T) {
filters := map[string]string{
"tagName1": "tagValue1",
"tagName2": "tagValue2",
Expand Down Expand Up @@ -68,7 +70,44 @@ func TestTagsFilterMatches(t *testing.T) {
}
}

func TestTagsFilterString(t *testing.T) {
func TestTagsFilterMatchesWithNameTag(t *testing.T) {
filters := map[string]string{
"name": "foo",
"tagName1": "tagValue1",
"tagName2": "tagValue2",
}

f, err := NewTagsFilter(filters, Conjunction, testTagsFilterOptionsWithNameTag())
require.NoError(t, err)
inputs := []mockFilterData{
{val: "foo+tagName0=tagValue0,tagName1=tagValue1,tagName2=tagValue2", match: true},
{val: "tagName1=tagValue1,tagName2=tagValue2", match: false},
{val: "foo+tagName1=tagValue1", match: false},
{val: "foo+tagName1=tagValue2,tagName2=tagValue1", match: false},
}
for _, input := range inputs {
require.Equal(t, input.match, f.Matches([]byte(input.val)))
}

f, err = NewTagsFilter(filters, Disjunction, testTagsFilterOptionsWithNameTag())
require.NoError(t, err)
inputs = []mockFilterData{
{val: "foo+tagName1=tagValue1,tagName2=tagValue2", match: true},
{val: "foo+tagName1=tagValue2,tagName2=tagValue2", match: true},
{val: "bar+tagName1=tagValue1", match: true},
{val: "foo+tagName1=tagValue2", match: true},
{val: "foo+tagName2=tagValue1", match: true},
{val: "foo+tagName15=tagValue2,tagName3=tagValue2", match: true},
{val: "tagName1=tagValue1,tagName2=tagValue2", match: false},
{val: "bar+tagName1=tagValue2,tagName2=tagValue1", match: false},
{val: "bar+tagName3=tagValue3", match: false},
}
for _, input := range inputs {
require.Equal(t, input.match, f.Matches([]byte(input.val)))
}
}

func TestTagsFilterStringNoNameTag(t *testing.T) {
filters := map[string]string{
"tagName1": "tagValue1",
"tagName2": "tagValue2",
Expand All @@ -82,10 +121,39 @@ func TestTagsFilterString(t *testing.T) {
require.Equal(t, `tagName1:Equals("tagValue1") || tagName2:Equals("tagValue2")`, f.String())
}

func TestTagsFilterStringWithNameTag(t *testing.T) {
filters := map[string]string{
"name": "foo",
"tagName1": "tagValue1",
"tagName2": "tagValue2",
}
f, err := NewTagsFilter(filters, Conjunction, testTagsFilterOptionsWithNameTag())
require.NoError(t, err)
require.Equal(t, `name:Equals("foo") && tagName1:Equals("tagValue1") && tagName2:Equals("tagValue2")`, f.String())

f, err = NewTagsFilter(filters, Disjunction, testTagsFilterOptionsWithNameTag())
require.NoError(t, err)
require.Equal(t, `name:Equals("foo") || tagName1:Equals("tagValue1") || tagName2:Equals("tagValue2")`, f.String())
}

func testTagsFilterOptions() TagsFilterOptions {
return TagsFilterOptions{
NameTagKey: []byte("name"),
NameAndTagsFn: func(b []byte) ([]byte, []byte, error) { return nil, b, nil },
SortedTagIteratorFn: NewMockSortedTagIterator,
}
}

func testTagsFilterOptionsWithNameTag() TagsFilterOptions {
return TagsFilterOptions{
NameTagKey: []byte("name"),
NameAndTagsFn: func(b []byte) ([]byte, []byte, error) {
idx := bytes.IndexByte(b, '+')
if idx == -1 {
return nil, nil, errors.New("invalid metric")
}
return b[:idx], b[idx+1:], nil
},
SortedTagIteratorFn: NewMockSortedTagIterator,
}
}
8 changes: 4 additions & 4 deletions metric/id/m3/id.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2016 Uber Technologies, Inc.
// Copyright (c) 2017 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -33,7 +33,7 @@ package m3

import (
"bytes"
"fmt"
"errors"
"sort"

"github.com/m3db/m3metrics/metric/id"
Expand All @@ -46,7 +46,7 @@ const (
)

var (
errInvalidM3Metric = fmt.Errorf("invalid m3 metric")
errInvalidM3Metric = errors.New("invalid m3 metric")
m3Prefix = []byte("m3+")
rollupTagPair = id.TagPair{
Name: []byte("m3_rollup"),
Expand Down Expand Up @@ -173,7 +173,7 @@ func (it *sortedTagIterator) Next() bool {
}
it.tagName = it.sortedTagPairs[it.idx:nameSplitterIdx]
it.tagValue = it.sortedTagPairs[nameSplitterIdx+1 : pairSplitterIdx]
it.idx = pairSplitterIdx
it.idx = pairSplitterIdx + 1
return true
}

Expand Down
172 changes: 172 additions & 0 deletions metric/id/m3/id_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
// Copyright (c) 2017 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package m3

import (
"testing"

"github.com/m3db/m3metrics/metric/id"

"github.com/stretchr/testify/require"
)

func TestNewRollupID(t *testing.T) {
var (
name = []byte("foo")
tagPairs = []id.TagPair{
{Name: []byte("tagName1"), Value: []byte("tagValue1")},
{Name: []byte("tagName2"), Value: []byte("tagValue2")},
{Name: []byte("tagName0"), Value: []byte("tagValue0")},
}
)
expected := []byte("m3+foo+m3_rollup=true,tagName0=tagValue0,tagName1=tagValue1,tagName2=tagValue2")
require.Equal(t, expected, NewRollupID(name, tagPairs))
}

func TestMetricIDTagValue(t *testing.T) {
iterPool := id.NewSortedTagIteratorPool(nil)
iterPool.Init(func() id.SortedTagIterator {
return NewPooledSortedTagIterator(nil, iterPool)
})
inputs := []struct {
id id.ID
tagName []byte
expectedValue []byte
expectedFound bool
}{
{
id: NewID([]byte("m3+foo+tagName1=tagValue1,tagName2=tagValue2"), iterPool),
tagName: []byte("tagName1"),
expectedValue: []byte("tagValue1"),
expectedFound: true,
},
{
id: NewID([]byte("m3+foo+tagName1=tagValue1,tagName2=tagValue2"), iterPool),
tagName: []byte("tagName2"),
expectedValue: []byte("tagValue2"),
expectedFound: true,
},
{
id: NewID([]byte("m3+foo+tagName1=tagValue1,tagName2=tagValue2"), iterPool),
tagName: []byte("tagName3"),
expectedValue: nil,
expectedFound: false,
},
{
id: NewID([]byte("illformed+tagName1=tagValue1,tagName2=tagValue2"), iterPool),
tagName: []byte("tagName1"),
expectedValue: nil,
expectedFound: false,
},
}
for _, input := range inputs {
value, found := input.id.TagValue(input.tagName)
require.Equal(t, input.expectedValue, value)
require.Equal(t, input.expectedFound, found)
}
}

func TestNameAndTags(t *testing.T) {
inputs := []struct {
id []byte
expectedName []byte
expectedTags []byte
expectedErr error
}{
{
id: []byte("m3+foo+tagName1=tagValue1"),
expectedName: []byte("foo"),
expectedTags: []byte("tagName1=tagValue1"),
expectedErr: nil,
},
{
id: []byte("m3+foo+tagName1=tagValue1,tagName2=tagValue2"),
expectedName: []byte("foo"),
expectedTags: []byte("tagName1=tagValue1,tagName2=tagValue2"),
expectedErr: nil,
},
{
id: []byte("illformed"),
expectedName: nil,
expectedTags: nil,
expectedErr: errInvalidM3Metric,
},
{
id: []byte("m3+illformed"),
expectedName: nil,
expectedTags: nil,
expectedErr: errInvalidM3Metric,
},
{
id: []byte("m3+illformed+tagName1,"),
expectedName: []byte("illformed"),
expectedTags: []byte("tagName1,"),
expectedErr: nil,
},
}
for _, input := range inputs {
name, tags, err := NameAndTags(input.id)
require.Equal(t, input.expectedName, name)
require.Equal(t, input.expectedTags, tags)
require.Equal(t, input.expectedErr, err)
}
}

func TestSortedTagIterator(t *testing.T) {
inputs := []struct {
sortedTagPairs []byte
expectedPairs []id.TagPair
expectedErr error
}{
{
sortedTagPairs: []byte("tagName1=tagValue1"),
expectedPairs: []id.TagPair{
{Name: []byte("tagName1"), Value: []byte("tagValue1")},
},
expectedErr: nil,
},
{
sortedTagPairs: []byte("tagName1=tagValue1,tagName2=tagValue2,tagName3=tagValue3"),
expectedPairs: []id.TagPair{
{Name: []byte("tagName1"), Value: []byte("tagValue1")},
{Name: []byte("tagName2"), Value: []byte("tagValue2")},
{Name: []byte("tagName3"), Value: []byte("tagValue3")},
},
expectedErr: nil,
},
{
sortedTagPairs: []byte("tagName1"),
expectedPairs: nil,
expectedErr: errInvalidM3Metric,
},
}

for _, input := range inputs {
it := NewSortedTagIterator(input.sortedTagPairs)
var result []id.TagPair
for it.Next() {
name, value := it.Current()
result = append(result, id.TagPair{Name: name, Value: value})
}
require.Equal(t, input.expectedErr, it.Err())
require.Equal(t, input.expectedPairs, result)
}
}
2 changes: 1 addition & 1 deletion metric/id/tag.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2016 Uber Technologies, Inc.
// Copyright (c) 2017 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
Expand Down
39 changes: 39 additions & 0 deletions metric/id/tag_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright (c) 2017 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package id

import (
"sort"
"testing"

"github.com/stretchr/testify/require"
)

func TestTagPairsByNameAsc(t *testing.T) {
inputs := []TagPair{
{Name: []byte("baz"), Value: []byte("first")},
{Name: []byte("foo"), Value: []byte("second")},
{Name: []byte("bar"), Value: []byte("third")},
}
expected := []TagPair{inputs[2], inputs[0], inputs[1]}
sort.Sort(TagPairsByNameAsc(inputs))
require.Equal(t, expected, inputs)
}

0 comments on commit 4951004

Please sign in to comment.