-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcoverage_test.go
More file actions
102 lines (92 loc) · 2.97 KB
/
Copy pathcoverage_test.go
File metadata and controls
102 lines (92 loc) · 2.97 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
package eql
import "testing"
// Targeted tests for real logic branches that the broad suites don't hit
// directly.
func TestReversedComparisonAllOps(t *testing.T) {
tests := []struct {
query string
want string
}{
{`network where 1024 <= destination.port`, `destination.port >= 1024`},
{`network where 1024 >= destination.port`, `destination.port <= 1024`},
{`network where 1024 > destination.port`, `destination.port < 1024`},
{`network where 1024 < destination.port`, `destination.port > 1024`},
{`network where 443 == destination.port`, `destination.port == 443`},
{`network where 443 != destination.port`, `destination.port != 443`},
}
for _, tt := range tests {
res := ExtractConditions(tt.query)
requireNoErrors(t, res)
if len(res.Conditions) != 1 || condSig(res.Conditions[0]) != tt.want {
t.Errorf("%q → %+v, want %q", tt.query, res.Conditions, tt.want)
}
}
}
func TestEventOfLineage(t *testing.T) {
res := ExtractConditions(`process where event of [process where process.name == "svchost.exe"]`)
requireNoErrors(t, res)
if len(res.Conditions) != 1 || res.Conditions[0].Lineage != "event" {
t.Errorf("conditions = %+v", res.Conditions)
}
}
func TestMaxSpanExoticUnits(t *testing.T) {
tests := []struct {
span string
ms int64
ok bool
}{
{"1000micros", 1, true},
{"1000000nanos", 1, true},
{"2days", 172800000, true},
{"5minutes", 300000, true},
{"3hours", 10800000, true},
{"10", 10000, true}, // bare number defaults to seconds
{"5weeks", 0, false},
}
for _, tt := range tests {
ms, ok := MaxSpanDuration(tt.span)
if ok != tt.ok || (ok && ms != tt.ms) {
t.Errorf("MaxSpanDuration(%q) = %d,%v want %d,%v", tt.span, ms, ok, tt.ms, tt.ok)
}
}
}
func TestParseExpressionTrailingInput(t *testing.T) {
_, err := ParseExpression(`a == 1 garbage trailing`)
if err == nil {
t.Error("expected trailing-input error")
}
}
func TestExprStringNil(t *testing.T) {
if ExprString(nil) != "" {
t.Error("ExprString(nil) should be empty")
}
}
func TestTokenTypeString(t *testing.T) {
if TokenEQ.String() != "==" {
t.Errorf("TokenEQ.String() = %q", TokenEQ.String())
}
// Out-of-range token type falls back to a synthetic name.
if got := TokenType(9999).String(); got == "" {
t.Error("unknown token type should have a name")
}
}
func TestClassifyFieldUsageInPipes(t *testing.T) {
res := ExtractConditions(`process where process.name : "cmd.exe" | unique user.name`)
requireNoErrors(t, res)
u := ClassifyFieldUsage(res, "user.name")
if !u.InPipes {
t.Errorf("user.name should be marked InPipes: %+v", u)
}
}
func TestNotInIsNotLogicalNot(t *testing.T) {
// `not in` must attach to the predicate, not read as logical `not (x in ...)`.
res := ExtractConditions(`process where process.name not in ("a", "b")`)
requireNoErrors(t, res)
if len(res.Conditions) != 1 {
t.Fatalf("conditions = %+v", res.Conditions)
}
c := res.Conditions[0]
if !c.Negated || c.Operator != "in" || len(c.Alternatives) != 2 {
t.Errorf("condition = %+v", c)
}
}