Repository navigation
Expand file tree
/
Copy pathaggregation_test.go
More file actions
104 lines (100 loc) · 3.36 KB
/
Copy pathaggregation_test.go
File metadata and controls
104 lines (100 loc) · 3.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package spl
import (
"reflect"
"testing"
)
func TestExtractConditions_StatsAggregations(t *testing.T) {
tests := []struct {
name string
query string
expected []Aggregation
}{
{
name: "default count column",
query: `index=main action=failure | stats count by user | where count > 5`,
expected: []Aggregation{{Command: "stats", Function: "count", Column: "count"}},
},
{
name: "alias",
query: `index=main action=failure | stats count as Failed by user | where Failed > 5`,
expected: []Aggregation{{Command: "stats", Function: "count", Column: "Failed"}},
},
{
name: "default column of an aggregated field",
query: `index=main | stats dc(src) by user`,
expected: []Aggregation{{Command: "stats", Function: "dc", Field: "src", Column: "dc(src)"}},
},
{
name: "several aggregations",
query: `index=main | stats dc(src) as Sources, sum(bytes) as "Total Bytes" by user`,
expected: []Aggregation{
{Command: "stats", Function: "dc", Field: "src", Column: "Sources"},
{Command: "stats", Function: "sum", Field: "bytes", Column: "Total Bytes"},
},
},
{
name: "expression argument",
query: `index=main | stats count(eval(action="failure")) as failures by user`,
expected: []Aggregation{{Command: "stats", Function: "count", Column: "failures"}},
},
{
name: "eventstats",
query: `index=main | eventstats count by user | where count > 5`,
expected: []Aggregation{{Command: "eventstats", Function: "count", Column: "count"}},
},
{
name: "top",
query: `index=main | top user | where count > 5`,
expected: []Aggregation{
{Command: "top", Function: "count", Column: "count"},
{Command: "top", Function: "percent", Column: "percent"},
},
},
{
name: "subsearch aggregation belongs to the subsearch",
query: `index=main [search index=other | stats count by user | fields user]`,
expected: nil,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := ExtractConditions(tt.query)
got := make([]Aggregation, len(result.Aggregations))
for i, aggregation := range result.Aggregations {
aggregation.PipeStage = 0
got[i] = aggregation
}
if len(got) == 0 {
got = nil
}
if !reflect.DeepEqual(got, tt.expected) {
t.Fatalf("aggregations = %+v, want %+v", result.Aggregations, tt.expected)
}
})
}
}
func TestExtractConditions_FilterOnStatsDefaultColumn(t *testing.T) {
for _, command := range []string{"where", "search"} {
t.Run(command, func(t *testing.T) {
result := ExtractConditions(`index=main action=failure | stats count by user | ` + command + ` count > 5`)
if len(result.Aggregations) != 1 {
t.Fatalf("expected one aggregation, got %+v", result.Aggregations)
}
stage := result.Aggregations[0].PipeStage
for _, condition := range result.Conditions {
switch condition.Field {
case "action":
if condition.PipeStage >= stage {
t.Errorf("filter before stats has stage %d, aggregation stage %d", condition.PipeStage, stage)
}
case "count":
if condition.Operator != ">" || condition.Value != "5" || condition.PipeStage <= stage {
t.Errorf("unexpected filter on the count column: %+v (aggregation stage %d)", condition, stage)
}
return
}
}
t.Fatalf("filter on the count column was not extracted: %+v", result.Conditions)
})
}
}