Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PromethizeTagValue panic on empty value fix #833

Merged
merged 1 commit into from
Aug 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 30 additions & 17 deletions zipper/protocols/prometheus/helpers/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,29 +139,42 @@ func AdjustStep(start, stop, maxPointsPerQuery, minStep int64, forceMinStepInter
// PromethizeTagValue - accept 'Tag=value' or 'Tag=~value' string and return sanitized version of it
func PromethizeTagValue(tagValue string) (string, types.Tag) {
// Handle = and =~
t := types.Tag{}
idx := strings.Index(tagValue, "=")
if idx != -1 {
if tagValue[idx+1] == '~' {
var (
t types.Tag
tagName string
idx = strings.Index(tagValue, "=")
Civil marked this conversation as resolved.
Show resolved Hide resolved
)

if idx < 0 {
return tagName, t
}

if idx > 0 && tagValue[idx-1] == '!' {
t.OP = "!"
tagName = tagValue[:idx-1]
} else {
tagName = tagValue[:idx]
}

switch {
case idx+1 == len(tagValue): // != or = with empty value
t.OP += "="
case tagValue[idx+1] == '~':
if len(t.OP) > 0 { // !=~
t.OP += "~"
} else { // =~
t.OP = "=~"
t.TagValue = tagValue[idx+2:]
} else {
t.OP = "="
t.TagValue = tagValue[idx+1:]
}
} else {
// Handle != and !=~
idx = strings.Index(tagValue, "!")
if tagValue[idx+2] == '~' {
t.OP = "!~"
t.TagValue = tagValue[idx+3:]
} else {
t.OP = "!="

if idx+2 < len(tagValue) { // check is not empty value
t.TagValue = tagValue[idx+2:]
}
default: // != or = with value
t.OP += "="
t.TagValue = tagValue[idx+1:]
}

return tagValue[:idx], t
return tagName, t
}

// SplitTagValues - For given tag-value list converts it to more usable map[string]Tag, where string is TagName
Expand Down
89 changes: 89 additions & 0 deletions zipper/protocols/prometheus/helpers/helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/go-graphite/carbonapi/tests/compare"
"github.com/go-graphite/carbonapi/zipper/protocols/prometheus/types"
"github.com/stretchr/testify/assert"
)

func TestAlignValues(t *testing.T) {
Expand Down Expand Up @@ -161,3 +162,91 @@ func TestAdjustStep(t *testing.T) {
})
}
}

func TestPromethizeTagValue(t *testing.T) {
testCases := []struct {
name string
tagValue string
wantName string
wantTag types.Tag
}{
{
name: "empty string",
},
{
name: "string without '='",
tagValue: "test>test",
},
{
name: "check '='",
tagValue: "name=1",
wantName: "name",
wantTag: types.Tag{OP: "=", TagValue: "1"},
},
{
name: "check '!='",
tagValue: "name!=1",
wantName: "name",
wantTag: types.Tag{OP: "!=", TagValue: "1"},
},
{
name: "check '=~'",
tagValue: "name=~1",
wantName: "name",
wantTag: types.Tag{OP: "=~", TagValue: "1"},
},
{
name: "check '!=~'",
tagValue: "name!=~1",
wantName: "name",
wantTag: types.Tag{OP: "!~", TagValue: "1"},
},
{
name: "check '!=~' with empty name",
tagValue: "!=~1",
wantName: "",
wantTag: types.Tag{OP: "!~", TagValue: "1"},
},
{
name: "check '=~' with empty name",
tagValue: "=~1",
wantName: "",
wantTag: types.Tag{OP: "=~", TagValue: "1"},
},
{
name: "check '=' with empty value",
tagValue: "name=",
wantName: "name",
wantTag: types.Tag{OP: "="},
},
{
name: "check '!=' with empty value",
tagValue: "name!=",
wantName: "name",
wantTag: types.Tag{OP: "!="},
},
{
name: "check '!=~' with empty value",
tagValue: "name!=~",
wantName: "name",
wantTag: types.Tag{OP: "!~"},
},
{
name: "check '=~' with empty value",
tagValue: "name=~",
wantName: "name",
wantTag: types.Tag{OP: "=~"},
},
}

for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
gotName, gotTag := PromethizeTagValue(tt.tagValue)

assert.Equal(t, tt.wantName, gotName)
assert.Equal(t, tt.wantTag, gotTag)
})

}

}
Loading