Skip to content

Commit

Permalink
fix moreThanRegex + testing
Browse files Browse the repository at this point in the history
  • Loading branch information
jpinsonneau committed Jul 28, 2023
1 parent 85b371e commit 7c0dbe8
Show file tree
Hide file tree
Showing 2 changed files with 137 additions and 30 deletions.
91 changes: 61 additions & 30 deletions pkg/loki/filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package loki

import (
"fmt"
"math"
"strconv"
"strings"
)
Expand Down Expand Up @@ -190,6 +191,65 @@ func notContainsKeyLineFilter(key string) lineFilter {
}
}

func moreThanRegex(sb *strings.Builder, value string) {
// match each number greater than specified value using regex
// example for 123:
// ^ ( 12[3-9] | 1[3-9][0-9]+ | [2-9][0-9]+ | [1-9][0-9]{3,} )
// | | | |
// | | | ↪ match number more than 1000
// | | |
// | | ↪ match number from 200 to 999
// | |
// | ↪ match numbers from 130 to 199
// |
// ↪ match any number from 123 to 129

sb.WriteString("^(")
for i, r := range value {
if i < len(value)-1 {
sb.WriteRune(r)
} else {
sb.WriteRune('[')
sb.WriteRune(r)
sb.WriteString("-9]")
}
}

intVal, _ := strconv.Atoi(value)
for i := 1; i < len(value); i++ {
nextMin := int((intVal / int(math.Pow10(i))) + 1)
nextMinStr := fmt.Sprintf("%d", nextMin)

sb.WriteRune('|')
if nextMin >= 10 {
sb.WriteString(nextMinStr[0 : len(nextMinStr)-1])
} else if i < len(value)-1 {
sb.WriteString(value[0 : len(value)-1-i])
}

nextMinRune := nextMinStr[len(nextMinStr)-1:]
if nextMin%9 != 0 {
sb.WriteRune('[')
sb.WriteString(nextMinRune)
sb.WriteString("-9]")
} else {
sb.WriteString(nextMinRune)
}

sb.WriteString("[0-9]")

if i > 1 {
sb.WriteString("{")
sb.WriteString(fmt.Sprintf("%d", i))
sb.WriteString(",}")
}
}

sb.WriteString("|[1-9][0-9]{")
sb.WriteString(fmt.Sprintf("%d", len(value)))
sb.WriteString(",})")
}

// writeInto transforms a lineFilter to its corresponding part of a LogQL query
// under construction (contained in the provided strings.Builder)
func (f *lineFilter) writeInto(sb *strings.Builder) {
Expand Down Expand Up @@ -239,36 +299,7 @@ func (f *lineFilter) writeInto(sb *strings.Builder) {
switch v.valueType {
case typeNumber, typeRegex:
if f.moreThan {
// match each number greater than specified value using regex
// ie example for 23+ you should get:
// ([2-9][3-9] | [3-9][0-9]+?)
// | |
// | ↪ match numbers >= 30
// |
// ↪ match any number from 23 to 29
sb.WriteRune('(')
for _, r := range v.value {
sb.WriteRune('[')
sb.WriteRune(r)
if r != '9' {
sb.WriteString("-9]")
} else {
sb.WriteRune(']')
}
}
intVal, _ := strconv.Atoi(v.value)
nextMatch := fmt.Sprintf("%d", (int((intVal/10)+1) * 10))
sb.WriteRune('|')
for _, r := range nextMatch {
sb.WriteRune('[')
sb.WriteRune(r)
if r != '9' {
sb.WriteString("-9]")
} else {
sb.WriteRune(']')
}
}
sb.WriteString("+?)")
moreThanRegex(sb, v.value)
} else {
sb.WriteString(v.value)
}
Expand Down
76 changes: 76 additions & 0 deletions pkg/loki/filter_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package loki

import (
"fmt"
"regexp"
"strconv"
"strings"
"testing"

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

func TestWriteInto_1(t *testing.T) {
sb := strings.Builder{}
moreThanRegex(&sb, "1")
result := sb.String()
assert.Equal(t, result, "^([1-9]|[1-9][0-9]{1,})")
reg := regexp.MustCompile(result)
fmt.Printf("\nRegex: %s", result)
for _, i := range []int{-1, 0, 1, 2, 3, 10, 100} {
val := strconv.Itoa(i)
assert.Equal(t, reg.MatchString(val), i >= 1, fmt.Sprintf("Value: %d", i))
}
}

func TestWriteInto_7(t *testing.T) {
sb := strings.Builder{}
moreThanRegex(&sb, "7")
result := sb.String()
assert.Equal(t, result, "^([7-9]|[1-9][0-9]{1,})")
reg := regexp.MustCompile(result)
fmt.Printf("\nRegex: %s", result)
for _, i := range []int{-1, 0, 1, 3, 7, 10, 11, 100} {
val := strconv.Itoa(i)
assert.Equal(t, reg.MatchString(val), i >= 7, fmt.Sprintf("Value: %d", i))
}
}

func TestWriteInto_15(t *testing.T) {
sb := strings.Builder{}
moreThanRegex(&sb, "15")
result := sb.String()
assert.Equal(t, result, "^(1[5-9]|[2-9][0-9]|[1-9][0-9]{2,})")
reg := regexp.MustCompile(result)
fmt.Printf("\nRegex: %s", result)
for _, i := range []int{-1, 0, 1, 5, 14, 15, 16, 150, 1050} {
val := strconv.Itoa(i)
assert.Equal(t, reg.MatchString(val), i >= 15, fmt.Sprintf("Value: %d", i))
}
}

func TestWriteInto_123(t *testing.T) {
sb := strings.Builder{}
moreThanRegex(&sb, "123")
result := sb.String()
assert.Equal(t, result, "^(12[3-9]|1[3-9][0-9]|[2-9][0-9]{2,}|[1-9][0-9]{3,})")
reg := regexp.MustCompile(result)
fmt.Printf("\nRegex: %s", result)
for _, i := range []int{-123, 0, 1, 10, 100, 115, 123, 124, 150, 200, 1230} {
val := strconv.Itoa(i)
assert.Equal(t, reg.MatchString(val), i >= 123, fmt.Sprintf("Value: %d", i))
}
}

func TestWriteInto_7654(t *testing.T) {
sb := strings.Builder{}
moreThanRegex(&sb, "7654")
result := sb.String()
assert.Equal(t, result, "^(765[4-9]|76[6-9][0-9]|7[7-9][0-9]{2,}|[8-9][0-9]{3,}|[1-9][0-9]{4,})")
reg := regexp.MustCompile(result)
fmt.Printf("\nRegex: %s", result)
for _, i := range []int{0, 1, 1000, 7654, 7655, 10000} {
val := strconv.Itoa(i)
assert.Equal(t, reg.MatchString(val), i >= 7654, fmt.Sprintf("Value: %d", i))
}
}

0 comments on commit 7c0dbe8

Please sign in to comment.