Skip to content

Commit 9db2379

Browse files
committed
EQL: Change query folding spec from new lines to ;
The usage of blank lines as separator between tests can be tricky to deal with in case of merges where such lines can be added by accident. Further more counting non-consecutive lines is non-intuitive. The tests have been aligned to use ; at the end of the query and exceptions so that the presence or absence of empty lines is irrelevant. The parsing of the spec has been changed to perform validation to not allow invalid/incomplete specs to cause exceptions.
1 parent 2bd0510 commit 9db2379

File tree

2 files changed

+88
-56
lines changed

2 files changed

+88
-56
lines changed

x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/planner/QueryFolderOkTests.java

Lines changed: 50 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
package org.elasticsearch.xpack.eql.planner;
88

99
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
10+
1011
import org.elasticsearch.common.Strings;
1112
import org.elasticsearch.xpack.eql.plan.physical.EsQueryExec;
1213
import org.elasticsearch.xpack.eql.plan.physical.PhysicalPlan;
@@ -15,6 +16,8 @@
1516
import java.io.InputStreamReader;
1617
import java.nio.charset.StandardCharsets;
1718
import java.util.ArrayList;
19+
import java.util.LinkedHashMap;
20+
import java.util.Map;
1821

1922
import static org.elasticsearch.xpack.ql.type.DataTypes.KEYWORD;
2023
import static org.hamcrest.Matchers.containsString;
@@ -33,54 +36,73 @@ public QueryFolderOkTests(String name, String query, Object expect) {
3336

3437
@ParametersFactory(shuffle = false, argumentFormatting = "%1$s")
3538
public static Iterable<Object[]> parameters() throws Exception {
39+
return readSpec("/queryfolder_tests.txt");
40+
}
41+
42+
public static Iterable<Object[]> readSpec(String url) throws Exception {
3643
ArrayList<Object[]> arr = new ArrayList<>();
44+
Map<String, Integer> testNames = new LinkedHashMap<>();
45+
3746
try (BufferedReader reader = new BufferedReader(new InputStreamReader(
38-
QueryFolderOkTests.class.getResourceAsStream("/queryfolder_tests.txt"), StandardCharsets.UTF_8))) {
47+
QueryFolderOkTests.class.getResourceAsStream(url), StandardCharsets.UTF_8))) {
48+
int lineNumber = 0;
3949
String line;
4050
String name = null;
4151
String query = null;
42-
ArrayList<Object> expectations = null;
43-
int newLineCount = 0;
52+
ArrayList<Object> expectations = new ArrayList<>(8);
4453

45-
while ((line = reader.readLine()) != null) {
46-
if (line.startsWith("//")) {
47-
continue;
48-
}
54+
StringBuilder sb = new StringBuilder();
4955

56+
while ((line = reader.readLine()) != null) {
57+
lineNumber++;
5058
line = line.trim();
51-
if (Strings.isEmpty(line)) {
52-
if (name != null) {
53-
newLineCount++;
54-
}
55-
if (newLineCount >= 2) {
56-
// Add and zero out for the next spec
57-
addSpec(arr, name, query, expectations == null ? null : expectations.toArray());
58-
name = null;
59-
query = null;
60-
expectations = null;
61-
newLineCount = 0;
62-
}
59+
60+
if (line.isEmpty() || line.startsWith("//")) {
6361
continue;
6462
}
6563

6664
if (name == null) {
6765
name = line;
68-
continue;
66+
Integer previousName = testNames.put(name, lineNumber);
67+
if (previousName != null) {
68+
throw new IllegalArgumentException("Duplicate test name '" + line + "' at line " + lineNumber
69+
+ " (previously seen at line " + previousName + ")");
70+
}
6971
}
7072

71-
if (query == null) {
72-
query = line;
73-
continue;
73+
else if (query == null) {
74+
sb.append(line);
75+
if (line.endsWith(";")) {
76+
sb.setLength(sb.length() - 1);
77+
query = sb.toString();
78+
sb.setLength(0);
79+
}
7480
}
7581

76-
if (line.equals("null") == false) { // special case for no expectations
77-
if (expectations == null) {
78-
expectations = new ArrayList<>();
82+
else {
83+
boolean done = false;
84+
if (line.endsWith(";")) {
85+
line = line.substring(0, line.length() - 1);
86+
done = true;
87+
}
88+
// no expectation
89+
if (line.equals("null") == false) {
90+
expectations.add(line);
91+
}
92+
93+
if (done) {
94+
// Add and zero out for the next spec
95+
addSpec(arr, name, query, expectations.isEmpty() ? null : expectations.toArray());
96+
name = null;
97+
query = null;
98+
expectations.clear();
7999
}
80-
expectations.add(line);
81100
}
82101
}
83-
addSpec(arr, name, query, expectations.toArray());
102+
103+
if (name != null) {
104+
throw new IllegalStateException("Read a test [" + name + "] without a body at the end of [" + url + "]");
105+
}
84106
}
85107
return arr;
86108
}

x-pack/plugin/eql/src/test/resources/queryfolder_tests.txt

Lines changed: 38 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -10,113 +10,123 @@
1010

1111

1212
basic
13-
process where true
13+
process where true;
1414
null
15-
15+
;
1616

1717
singleNumericFilterEquals
18-
process where serial_event_id = 1
18+
process where serial_event_id = 1;
1919
"term":{"serial_event_id":{"value":1
20-
20+
;
2121

2222
singleNumericFilterLess
23-
process where serial_event_id < 4
23+
process where serial_event_id < 4;
2424
"range":{"serial_event_id":{"from":null,"to":4,"include_lower":false,"include_upper":false
25-
25+
;
2626

2727
singleNumericFilterLessEquals
28-
process where serial_event_id <= 4
28+
process where serial_event_id <= 4;
2929
"range":{"serial_event_id":{"from":null,"to":4,"include_lower":false,"include_upper":true
30-
30+
;
3131

3232
singleNumericFilterGreater
33-
process where serial_event_id > 4
33+
process where serial_event_id > 4;
3434
"range":{"serial_event_id":{"from":4,"to":null,"include_lower":false,"include_upper":false
35-
35+
;
3636

3737
singleNumericFilterGreaterEquals
38-
process where serial_event_id >= 4
38+
process where serial_event_id >= 4;
3939
"range":{"serial_event_id":{"from":4,"to":null,"include_lower":true,"include_upper":false
40-
40+
;
4141

4242
mixedTypeFilter
43-
process where process_name == "notepad.exe" or (serial_event_id < 4.5 and serial_event_id >= 3.1)
43+
process where process_name == "notepad.exe" or (serial_event_id < 4.5 and serial_event_id >= 3.1);
4444
"term":{"process_name":{"value":"notepad.exe"
4545
"range":{"serial_event_id":{"from":3.1,"to":4.5,"include_lower":true,"include_upper":false
46-
46+
;
4747

4848
notFilter
49-
process where not (exit_code > -1)
49+
process where not (exit_code > -1);
5050
"range":{"exit_code":{"from":null,"to":-1,"include_lower":false,"include_upper":true
51-
51+
;
5252

5353
inFilter
54-
process where process_name in ("python.exe", "SMSS.exe", "explorer.exe")
54+
process where process_name in ("python.exe", "SMSS.exe", "explorer.exe");
5555
"terms":{"process_name":["python.exe","SMSS.exe","explorer.exe"],
56-
56+
;
5757

5858
equalsAndInFilter
5959
process where process_path == "*\\red_ttp\\wininit.*" and opcode in (0,1,2,3)
60+
;
6061
"wildcard":{"process_path":{"wildcard":"*\\\\red_ttp\\\\wininit.*"
6162
{"terms":{"opcode":[0,1,2,3]
62-
63+
;
6364

6465
endsWithFunction
6566
process where endsWith(user_name, 'c')
67+
;
6668
"script":{"source":"InternalQlScriptUtils.nullSafeFilter(InternalEqlScriptUtils.endsWith(
6769
InternalQlScriptUtils.docValue(doc,params.v0),params.v1))",
6870
"params":{"v0":"user_name","v1":"c"}
69-
71+
;
7072

7173
lengthFunctionWithExactSubField
7274
process where length(file_name) > 0
75+
;
7376
"script":{"source":"InternalQlScriptUtils.nullSafeFilter(InternalQlScriptUtils.gt(
7477
InternalEqlScriptUtils.length(InternalQlScriptUtils.docValue(doc,params.v0)),params.v1))",
7578
"params":{"v0":"file_name.keyword","v1":0}
76-
79+
;
7780

7881
lengthFunctionWithExactField
7982
process where 12 == length(user_name)
83+
;
8084
"script":{"source":"InternalQlScriptUtils.nullSafeFilter(InternalQlScriptUtils.eq(
8185
InternalEqlScriptUtils.length(InternalQlScriptUtils.docValue(doc,params.v0)),params.v1))",
8286
"params":{"v0":"user_name","v1":12}
83-
87+
;
8488

8589
lengthFunctionWithConstantKeyword
8690
process where 5 > length(constant_keyword)
91+
;
8792
"script":{"source":"InternalQlScriptUtils.nullSafeFilter(InternalQlScriptUtils.lt(
8893
InternalEqlScriptUtils.length(InternalQlScriptUtils.docValue(doc,params.v0)),params.v1))",
8994
"params":{"v0":"constant_keyword","v1":5}
90-
95+
;
9196

9297
startsWithFunction
9398
process where startsWith(user_name, 'A')
99+
;
94100
"script":{"source":"InternalQlScriptUtils.nullSafeFilter(InternalEqlScriptUtils.startsWith(
95101
InternalQlScriptUtils.docValue(doc,params.v0),params.v1))",
96102
"params":{"v0":"user_name","v1":"A"}
97-
103+
;
98104

99105
substringFunction
100106
process where substring(file_name, -4) == '.exe'
107+
;
101108
"script":{"source":"InternalQlScriptUtils.nullSafeFilter(InternalQlScriptUtils.eq(
102109
InternalEqlScriptUtils.substring(InternalQlScriptUtils.docValue(doc,params.v0),params.v1,params.v2),params.v3))",
103110
"params":{"v0":"file_name.keyword","v1":-4,"v2":null,"v3":".exe"}
104-
111+
;
105112

106113
wildcardFunctionSingleArgument
107114
process where wildcard(process_path, "*\\red_ttp\\wininit.*")
115+
;
108116
"wildcard":{"process_path":{"wildcard":"*\\\\red_ttp\\\\wininit.*"
109-
117+
;
110118

111119
wildcardFunctionTwoArguments
112120
process where wildcard(process_path, "*\\red_ttp\\wininit.*", "*\\abc\\*")
121+
;
113122
"wildcard":{"process_path":{"wildcard":"*\\\\red_ttp\\\\wininit.*"
114123
"wildcard":{"process_path":{"wildcard":"*\\\\abc\\\\*"
115-
124+
;
116125

117126
wildcardFunctionThreeArguments
118127
process where wildcard(process_path, "*\\red_ttp\\wininit.*", "*\\abc\\*", "*def*")
128+
;
119129
"wildcard":{"process_path":{"wildcard":"*\\\\red_ttp\\\\wininit.*"
120130
"wildcard":{"process_path":{"wildcard":"*\\\\abc\\\\*"
121131
"wildcard":{"process_path":{"wildcard":"*def*"
122-
132+
;

0 commit comments

Comments
 (0)