drop regex group in source priority sorting #89

This commit is contained in:
Umputun 2021-06-08 15:32:35 -05:00
parent 22dc84b924
commit 503f0b6dca
2 changed files with 65 additions and 6 deletions

View File

@ -74,6 +74,8 @@ const (
PIConsulCatalog ProviderID = "consul-catalog"
)
var reGroup = regexp.MustCompile(`(^.*)/\(.*\)`) // capture regex group lil (anything) from src like /blah/foo/(.*)
// MatchType defines the type of mapper (rule)
type MatchType int
@ -327,9 +329,13 @@ func (s *Service) mergeLists() (res []URLMapper) {
// sort rules to make assets last and prioritize longer rules first
sort.Slice(res, func(i, j int) bool {
src1 := reGroup.ReplaceAllString(res[i].SrcMatch.String(), "$1")
src2 := reGroup.ReplaceAllString(res[j].SrcMatch.String(), "$1")
// sort by len first, to make longer matches first
if len(res[i].SrcMatch.String()) != len(res[j].SrcMatch.String()) {
return len(res[i].SrcMatch.String()) > len(res[j].SrcMatch.String())
if len(src1) != len(src2) {
return len(src1) > len(src2)
}
// if len identical sort by SrcMatch string to keep same SrcMatch grouped together
return res[i].SrcMatch.String() < res[j].SrcMatch.String()

View File

@ -62,10 +62,10 @@ func TestService_Run(t *testing.T) {
assert.Equal(t, context.DeadlineExceeded, err)
mappers := svc.Mappers()
assert.Equal(t, 3, len(mappers))
assert.Equal(t, PIFile, mappers[0].ProviderID)
assert.Equal(t, "*", mappers[0].Server)
assert.Equal(t, "^/api/svc1/(.*)", mappers[0].SrcMatch.String())
assert.Equal(t, "http://127.0.0.1:8080/blah1/$1", mappers[0].Dst)
assert.Equal(t, PIDocker, mappers[0].ProviderID)
assert.Equal(t, "localhost", mappers[0].Server)
assert.Equal(t, "/api/svc3/xyz", mappers[0].SrcMatch.String())
assert.Equal(t, "http://127.0.0.3:8080/blah3/xyz", mappers[0].Dst)
assert.Equal(t, 1, len(p1.EventsCalls()))
assert.Equal(t, 1, len(p2.EventsCalls()))
@ -173,6 +173,59 @@ func TestService_Match(t *testing.T) {
}
}
func TestService_MatchConflictRegex(t *testing.T) {
p1 := &ProviderMock{
EventsFunc: func(ctx context.Context) <-chan ProviderID {
res := make(chan ProviderID, 1)
res <- PIFile
return res
},
ListFunc: func() ([]URLMapper, error) {
return []URLMapper{
{SrcMatch: *regexp.MustCompile("^/api/svc1/(.*)"), Dst: "http://127.0.0.1:8080/blah/$1", ProviderID: PIFile},
{SrcMatch: *regexp.MustCompile("^/api/svc1/cat"), Dst: "http://127.0.0.2:8080/cat", ProviderID: PIFile},
{SrcMatch: *regexp.MustCompile("^/api/svc1/abcd"), Dst: "http://127.0.0.3:8080/abcd", ProviderID: PIFile},
}, nil
},
}
svc := NewService([]Provider{p1}, time.Millisecond*100)
ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
defer cancel()
err := svc.Run(ctx)
require.Error(t, err)
assert.Equal(t, context.DeadlineExceeded, err)
assert.Equal(t, 3, len(svc.Mappers()))
tbl := []struct {
server, src string
res Matches
}{
{"example.com", "/api/svc1/xyz/something", Matches{MTProxy, []MatchedRoute{
{Destination: "http://127.0.0.1:8080/blah/xyz/something", Alive: true}}}},
{"example.com", "/api/svc1/something", Matches{MTProxy, []MatchedRoute{
{Destination: "http://127.0.0.1:8080/blah/something", Alive: true}}}},
{"example.com", "/api/svc1/cat", Matches{MTProxy, []MatchedRoute{
{Destination: "http://127.0.0.2:8080/cat", Alive: true}}}},
{"example.com", "/api/svc1/abcd", Matches{MTProxy, []MatchedRoute{
{Destination: "http://127.0.0.3:8080/abcd", Alive: true}}}},
}
for i, tt := range tbl {
tt := tt
t.Run(strconv.Itoa(i), func(t *testing.T) {
res := svc.Match(tt.server, tt.src)
require.Equal(t, len(tt.res.Routes), len(res.Routes), res.Routes)
for i := 0; i < len(res.Routes); i++ {
assert.Equal(t, tt.res.Routes[i].Alive, res.Routes[i].Alive)
assert.Equal(t, tt.res.Routes[i].Destination, res.Routes[i].Destination)
}
assert.Equal(t, tt.res.MatchType, res.MatchType)
})
}
}
func TestService_Servers(t *testing.T) {
p1 := &ProviderMock{
EventsFunc: func(ctx context.Context) <-chan ProviderID {