Skip to content

Commit 036eb50

Browse files
Fix Route.ID() returns conflicting IDs (prometheus#3803)
* Update TestRouteID tests This commit updates the TestRouteID tests to be more simple without reducing test coverage. It also adds new cases that show a bug in the existing code where conflicting IDs can be returned. Signed-off-by: George Robinson <[email protected]> * Fix Route.ID() returns conflicting IDs This commit fixes a bug where Route.ID() returns conflicting IDs. For example, the configuration: receiver: test routes: - matchers: - foo=bar continue: true routes: - matchers: - bar=baz - matchers: - foo=bar continue: true routes: - matchers: - bar=baz Gives the following Route IDs: {} {}/{foo="bar"}/0 {}/{foo="bar"}/{bar="baz"}/0 {}/{foo="bar"}/1 {}/{foo="bar"}/{bar="baz"}/0 When it should give these Route IDs: {} {}/{foo="bar"}/0 {}/{foo="bar"}/0/{bar="baz"}/0 {}/{foo="bar"}/1 {}/{foo="bar"}/1/{bar="baz"}/0 Signed-off-by: George Robinson <[email protected]> --------- Signed-off-by: George Robinson <[email protected]>
1 parent fc8c7d1 commit 036eb50

File tree

2 files changed

+65
-64
lines changed

2 files changed

+65
-64
lines changed

dispatch/route.go

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
"encoding/json"
1818
"fmt"
1919
"sort"
20+
"strconv"
2021
"strings"
2122
"time"
2223

@@ -184,22 +185,23 @@ func (r *Route) Key() string {
184185
func (r *Route) ID() string {
185186
b := strings.Builder{}
186187

187-
position := -1
188188
if r.parent != nil {
189-
// Find the position in the same level leaf.
190-
for i, cr := range r.parent.Routes {
191-
if cr == r {
192-
position = i
189+
b.WriteString(r.parent.ID())
190+
b.WriteRune('/')
191+
}
192+
193+
b.WriteString(r.Matchers.String())
194+
195+
if r.parent != nil {
196+
for i := range r.parent.Routes {
197+
if r == r.parent.Routes[i] {
198+
b.WriteRune('/')
199+
b.WriteString(strconv.Itoa(i))
193200
break
194201
}
195202
}
196203
}
197-
b.WriteString(r.Key())
198204

199-
if position > -1 {
200-
b.WriteRune('/')
201-
b.WriteString(fmt.Sprint(position))
202-
}
203205
return b.String()
204206
}
205207

dispatch/route_test.go

Lines changed: 53 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -856,68 +856,67 @@ routes:
856856

857857
func TestRouteID(t *testing.T) {
858858
in := `
859-
receiver: 'notify-def'
860-
859+
receiver: default
861860
routes:
862-
- matchers: ['{owner="team-A"}', '{level!="critical"}']
863-
receiver: 'notify-D'
864-
group_by: [...]
865-
continue: true
866-
- matchers: ['{owner="team-A"}', '{level!="critical"}']
867-
receiver: 'notify-A'
861+
- continue: true
862+
matchers:
863+
- foo=bar
864+
receiver: test1
868865
routes:
869-
- matchers: ['{env="testing"}', '{baz!~".*quux"}']
870-
receiver: 'notify-testing'
871-
group_by: [...]
872-
- match:
873-
env: "production"
874-
receiver: 'notify-productionA'
875-
group_wait: 1m
876-
continue: true
877-
- matchers: [ env=~"produ.*", job=~".*"]
878-
receiver: 'notify-productionB'
879-
group_wait: 30s
880-
group_interval: 5m
881-
repeat_interval: 1h
882-
group_by: ['job']
883-
- match_re:
884-
owner: 'team-(B|C)'
885-
group_by: ['foo', 'bar']
886-
group_wait: 2m
887-
receiver: 'notify-BC'
888-
- matchers: [group_by="role"]
889-
group_by: ['role']
866+
- matchers:
867+
- bar=baz
868+
- continue: true
869+
matchers:
870+
- foo=bar
871+
receiver: test1
890872
routes:
891-
- matchers: ['{env="testing"}']
892-
receiver: 'notify-testing'
893-
routes:
894-
- matchers: [wait="long"]
895-
group_wait: 2m
873+
- matchers:
874+
- bar=baz
875+
- continue: true
876+
matchers:
877+
- foo=bar
878+
receiver: test2
879+
routes:
880+
- matchers:
881+
- bar=baz
882+
- continue: true
883+
matchers:
884+
- bar=baz
885+
receiver: test3
886+
routes:
887+
- matchers:
888+
- baz=qux
889+
- matchers:
890+
- qux=corge
891+
- continue: true
892+
matchers:
893+
- qux=~"[a-zA-Z0-9]+"
894+
- continue: true
895+
matchers:
896+
- corge!~"[0-9]+"
896897
`
897-
898-
var ctree config.Route
899-
if err := yaml.UnmarshalStrict([]byte(in), &ctree); err != nil {
900-
t.Fatal(err)
901-
}
902-
tree := NewRoute(&ctree, nil)
898+
cr := config.Route{}
899+
require.NoError(t, yaml.Unmarshal([]byte(in), &cr))
900+
r := NewRoute(&cr, nil)
903901

904902
expected := []string{
905903
"{}",
906-
"{}/{level!=\"critical\",owner=\"team-A\"}/0",
907-
"{}/{level!=\"critical\",owner=\"team-A\"}/1",
908-
"{}/{level!=\"critical\",owner=\"team-A\"}/{baz!~\".*quux\",env=\"testing\"}/0",
909-
"{}/{level!=\"critical\",owner=\"team-A\"}/{env=\"production\"}/1",
910-
"{}/{level!=\"critical\",owner=\"team-A\"}/{env=~\"produ.*\",job=~\".*\"}/2",
911-
"{}/{owner=~\"^(?:team-(B|C))$\"}/2",
912-
"{}/{group_by=\"role\"}/3",
913-
"{}/{group_by=\"role\"}/{env=\"testing\"}/0",
914-
"{}/{group_by=\"role\"}/{env=\"testing\"}/{wait=\"long\"}/0",
904+
"{}/{foo=\"bar\"}/0",
905+
"{}/{foo=\"bar\"}/0/{bar=\"baz\"}/0",
906+
"{}/{foo=\"bar\"}/1",
907+
"{}/{foo=\"bar\"}/1/{bar=\"baz\"}/0",
908+
"{}/{foo=\"bar\"}/2",
909+
"{}/{foo=\"bar\"}/2/{bar=\"baz\"}/0",
910+
"{}/{bar=\"baz\"}/3",
911+
"{}/{bar=\"baz\"}/3/{baz=\"qux\"}/0",
912+
"{}/{bar=\"baz\"}/3/{qux=\"corge\"}/1",
913+
"{}/{qux=~\"[a-zA-Z0-9]+\"}/4",
914+
"{}/{corge!~\"[0-9]+\"}/5",
915915
}
916916

917-
var got []string
918-
tree.Walk(func(r *Route) {
919-
got = append(got, r.ID())
917+
var actual []string
918+
r.Walk(func(r *Route) {
919+
actual = append(actual, r.ID())
920920
})
921-
922-
require.ElementsMatch(t, got, expected)
921+
require.ElementsMatch(t, actual, expected)
923922
}

0 commit comments

Comments
 (0)