315 lines
7.9 KiB
Go
315 lines
7.9 KiB
Go
package tsdb
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/davecgh/go-spew/spew"
|
|
"github.com/influxdata/influxdb/v2/models"
|
|
"github.com/influxdata/influxql"
|
|
)
|
|
|
|
func TestGuard(t *testing.T) {
|
|
tests := []struct {
|
|
min, max int64
|
|
names []string
|
|
expr string
|
|
point string
|
|
matches bool
|
|
}{
|
|
{ // in time matching
|
|
min: 0, max: 1000,
|
|
point: "cpu value=1 100",
|
|
matches: true,
|
|
},
|
|
{ // out of time range doesn't match
|
|
min: 0, max: 10,
|
|
names: []string{"cpu"},
|
|
point: "cpu value=1 100",
|
|
matches: false,
|
|
},
|
|
{ // measurement name matches
|
|
min: 0, max: 1000,
|
|
names: []string{"cpu"},
|
|
point: "cpu value=1 100",
|
|
matches: true,
|
|
},
|
|
{ // measurement doesn't match
|
|
min: 0, max: 1000,
|
|
names: []string{"mem"},
|
|
point: "cpu value=1 100",
|
|
matches: false,
|
|
},
|
|
{ // basic expression matching
|
|
min: 0, max: 1000,
|
|
point: "cpu,host=server1 value=1 100",
|
|
expr: "host = 'server1'",
|
|
matches: true,
|
|
},
|
|
{ // basic expression matching
|
|
min: 0, max: 1000,
|
|
point: "cpu,host=server1 value=1 100",
|
|
expr: "host != 'server2'",
|
|
matches: true,
|
|
},
|
|
{ // basic expression mismatch
|
|
min: 0, max: 1000,
|
|
point: "cpu,host=server1 value=1 100",
|
|
expr: "host = 'server2'",
|
|
matches: false,
|
|
},
|
|
{ // basic expression mismatch
|
|
min: 0, max: 1000,
|
|
point: "cpu,host=server1 value=1 100",
|
|
expr: "host != 'server1'",
|
|
matches: false,
|
|
},
|
|
{ // parenthesis unwrap
|
|
min: 0, max: 1000,
|
|
point: "cpu,host=server1 value=1 100",
|
|
expr: "(host = 'server1')",
|
|
matches: true,
|
|
},
|
|
{ // compound expression matching
|
|
min: 0, max: 1000,
|
|
point: "cpu,host=server1 value=1 100",
|
|
expr: "host = 'server2' or host = 'server1'",
|
|
matches: true,
|
|
},
|
|
{ // compound expression mismatch
|
|
min: 0, max: 1000,
|
|
point: "cpu,host=server1 value=1 100",
|
|
expr: "host = 'server1' and host = 'server2'",
|
|
matches: false,
|
|
},
|
|
{ // regex expression matching
|
|
min: 0, max: 1000,
|
|
point: "cpu,host=server1 value=1 100",
|
|
expr: "host =~ /server1/",
|
|
matches: true,
|
|
},
|
|
{ // regex expression mismatch
|
|
min: 0, max: 1000,
|
|
point: "cpu,foo=server1 value=1 100",
|
|
expr: "host =~ /server1/",
|
|
matches: false,
|
|
},
|
|
{ // regex over-approximation
|
|
min: 0, max: 1000,
|
|
point: "cpu,host=server1 value=1 100",
|
|
expr: "host =~ /server2/",
|
|
matches: true,
|
|
},
|
|
{ // regex over-approximation
|
|
min: 0, max: 1000,
|
|
point: "cpu,host=server1 value=1 100",
|
|
expr: "host !~ /server1/",
|
|
matches: true,
|
|
},
|
|
{ // key doesn't have to come first
|
|
min: 0, max: 1000,
|
|
point: "cpu,host=server1 value=1 100",
|
|
expr: "'server1' = host",
|
|
matches: true,
|
|
},
|
|
{ // key doesn't have to come first
|
|
min: 0, max: 1000,
|
|
point: "cpu,host=server1 value=1 100",
|
|
expr: "'server2' = host",
|
|
matches: false,
|
|
},
|
|
{ // conservative on no var refs
|
|
min: 0, max: 1000,
|
|
point: "cpu,host=server1 value=1 100",
|
|
expr: "1 = 2",
|
|
matches: true,
|
|
},
|
|
{ // expr matches measurement
|
|
min: 0, max: 1000,
|
|
point: "cpu,host=server1 value=1 100",
|
|
expr: "_name = 'cpu'",
|
|
matches: true,
|
|
},
|
|
{ // expr mismatches measurement
|
|
min: 0, max: 1000,
|
|
point: "cpu,host=server1 value=1 100",
|
|
expr: "_name = 'mem'",
|
|
matches: false,
|
|
},
|
|
{ // expr conservative on dual var ref
|
|
min: 0, max: 1000,
|
|
point: "cpu,host=server1 value=1 100",
|
|
expr: "host = test",
|
|
matches: true,
|
|
},
|
|
{ // expr conservative on dual var ref mismatches
|
|
min: 0, max: 1000,
|
|
point: "cpu,host=server1 value=1 100",
|
|
expr: "foo = bar",
|
|
matches: false,
|
|
},
|
|
{ // expr conservative on dual var ref involving measurement
|
|
min: 0, max: 1000,
|
|
point: "cpu,host=server1 value=1 100",
|
|
expr: "_name = host",
|
|
matches: true,
|
|
},
|
|
{ // expr conservative on dual var ref involving measurement
|
|
min: 0, max: 1000,
|
|
point: "cpu,host=server1 value=1 100",
|
|
expr: "host = _name",
|
|
matches: true,
|
|
},
|
|
{ // boolean literal matches
|
|
min: 0, max: 1000,
|
|
point: "cpu,host=server1 value=1 100",
|
|
expr: "true",
|
|
matches: true,
|
|
},
|
|
{ // boolean literal mismatches
|
|
min: 0, max: 1000,
|
|
point: "cpu,host=server1 value=1 100",
|
|
expr: "false",
|
|
matches: false,
|
|
},
|
|
{ // reduce and
|
|
min: 0, max: 1000,
|
|
point: "cpu,host=server1 value=1 100",
|
|
expr: "true and host = 'server1'",
|
|
matches: true,
|
|
},
|
|
{ // reduce and
|
|
min: 0, max: 1000,
|
|
point: "cpu,host=server1 value=1 100",
|
|
expr: "host = 'server1' and true",
|
|
matches: true,
|
|
},
|
|
{ // reduce or
|
|
min: 0, max: 1000,
|
|
point: "cpu,host=server1 value=1 100",
|
|
expr: "false or host = 'server1'",
|
|
matches: true,
|
|
},
|
|
{ // reduce or
|
|
min: 0, max: 1000,
|
|
point: "cpu,host=server1 value=1 100",
|
|
expr: "host = 'server1' or false",
|
|
matches: true,
|
|
},
|
|
{ // short circuit and
|
|
min: 0, max: 1000,
|
|
point: "cpu,host=server1 value=1 100",
|
|
expr: "false and host = 'server1'",
|
|
matches: false,
|
|
},
|
|
{ // short circuit and
|
|
min: 0, max: 1000,
|
|
point: "cpu,host=server1 value=1 100",
|
|
expr: "host = 'server1' and false",
|
|
matches: false,
|
|
},
|
|
{ // short circuit or
|
|
min: 0, max: 1000,
|
|
point: "cpu,host=server1 value=1 100",
|
|
expr: "true or host = 'server2'",
|
|
matches: true,
|
|
},
|
|
{ // short circuit or
|
|
min: 0, max: 1000,
|
|
point: "cpu,host=server1 value=1 100",
|
|
expr: "host = 'server2' or true",
|
|
matches: true,
|
|
},
|
|
{ // conservative match weird exprs
|
|
min: 0, max: 1000,
|
|
point: "cpu,host=server1 value=1 100",
|
|
expr: "'wierd'",
|
|
matches: true,
|
|
},
|
|
{ // conservative match weird exprs
|
|
min: 0, max: 1000,
|
|
point: "cpu,host=server1 value=1 100",
|
|
expr: "value::field = '1'",
|
|
matches: true,
|
|
},
|
|
{ // conservative match weird exprs
|
|
min: 0, max: 1000,
|
|
point: "cpu,host=server1 value=1 100",
|
|
expr: "host <= 'aaa'",
|
|
matches: true,
|
|
},
|
|
{ // conservative match weird exprs
|
|
min: 0, max: 1000,
|
|
point: "cpu,host=server1 value=1 100",
|
|
expr: "host = ('server2')",
|
|
matches: true,
|
|
},
|
|
}
|
|
|
|
for i, test := range tests {
|
|
var expr influxql.Expr
|
|
if test.expr != "" {
|
|
var err error
|
|
expr, err = influxql.ParseExpr(test.expr)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
points, err := models.ParsePointsString(test.point)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
guard := newGuard(test.min, test.max, test.names, expr)
|
|
|
|
if guard.Matches(points) != test.matches {
|
|
t.Errorf("%d: expected matching %q with time:[%d, %d] measurements:%v expr:%q to be %t",
|
|
i, test.point, test.min, test.max, test.names, test.expr, test.matches)
|
|
cs := &spew.ConfigState{DisableMethods: true, SpewKeys: true, Indent: " "}
|
|
t.Errorf("%d: expr: %s", i, cs.Sdump(expr))
|
|
t.Errorf("%d: guard: %s", i, cs.Sdump(guard.expr))
|
|
}
|
|
}
|
|
}
|
|
|
|
func BenchmarkGuard(b *testing.B) {
|
|
tag := func(key, value string) models.Tag {
|
|
return models.Tag{Key: []byte(key), Value: []byte(value)}
|
|
}
|
|
|
|
run := func(b *testing.B, g *guard) {
|
|
run := func(b *testing.B, batch int) {
|
|
points := make([]models.Point, batch)
|
|
for i := range points {
|
|
points[i] = models.MustNewPoint("cpu", models.Tags{
|
|
tag("t0", "v0"), tag("t1", "v1"), tag("t2", "v2"),
|
|
tag("t3", "v3"), tag("t4", "v4"), tag("t5", "v5"),
|
|
tag("t6", "v6"), tag("t7", "v7"), tag("t8", "v8"),
|
|
}, models.Fields{"value": 100}, time.Unix(0, 50))
|
|
}
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
if g.Matches(points) {
|
|
b.Fatal("matched")
|
|
}
|
|
}
|
|
}
|
|
|
|
b.Run("1", func(b *testing.B) { run(b, 1) })
|
|
b.Run("100", func(b *testing.B) { run(b, 100) })
|
|
b.Run("10000", func(b *testing.B) { run(b, 10000) })
|
|
}
|
|
|
|
b.Run("Time Filtered", func(b *testing.B) {
|
|
run(b, newGuard(0, 10, nil, nil))
|
|
})
|
|
|
|
b.Run("Measurement Filtered", func(b *testing.B) {
|
|
run(b, newGuard(0, 100, []string{"mem"}, nil))
|
|
})
|
|
|
|
b.Run("Tag Filtered", func(b *testing.B) {
|
|
expr, _ := influxql.ParseExpr("t4 = 'v5'")
|
|
run(b, newGuard(0, 100, []string{"cpu"}, expr))
|
|
})
|
|
}
|