-
Notifications
You must be signed in to change notification settings - Fork 25k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
EQL: Add case-sensitive and insensitive integration tests #57323
Conversation
Pinging @elastic/es-ql (:Query Languages/EQL) |
|
||
|
||
########################## | ||
# FAILING SEQUENCE TESTS # |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@costin do you have any guesses why some of these sequence tests were failing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe it's because of the tie breaker - the logic only looks at the timestamp but since it's the same for all events, it fails to order it by the seq_number
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be fixed now that the tiebreaker is in. It is disabled by default however our tests make use of it.
client/rest-high-level/src/main/java/org/elasticsearch/client/eql/EqlSearchRequest.java
Outdated
Show resolved
Hide resolved
|
||
public class EqlSpec { | ||
private String description; | ||
private String note; | ||
private String[] tags; | ||
private String query; | ||
private Boolean caseSensitiveOnly; | ||
private Boolean caseInsensitiveOnly; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can use boolean? or need 'null' for any reason?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This class is similar to that in #57568, I wonder if the TOML code could be reused. It's not a lot but not too little either. Between the spec, boilerplate code in the test for reading the spec there is something that potentially (not right now) can be placed in a separate, small utility project.
It's a bit overheard but medium term could simplify dependency management.
Either way a comment pointing out the relationship between the two would be useful so that any updates happening on one end would be useful in the other.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
switched to boolean
, thanks @aleksmaus. I handle null => false
within the SpecLoader.
I'm not sure the ideal solution to avoid reuse while keeping it fairly simple. at the least, I can add a comment like you suggest for both classes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will leave this PR as is, and update in #57568
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM in general. Left some comments, though.
client/rest-high-level/src/main/java/org/elasticsearch/client/eql/EqlSearchRequest.java
Outdated
Show resolved
Hide resolved
@@ -195,8 +202,8 @@ else if (hits.sequences() != null) { | |||
} | |||
} | |||
|
|||
protected EqlSearchResponse runQuery(String index, String query) throws Exception { | |||
EqlSearchRequest request = new EqlSearchRequest(testIndexName, query); | |||
protected EqlSearchResponse runQuery(String index, String query, boolean isCaseSensitive) throws Exception { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe add two more methods - runQueryCaseSensitive
and runQueryCaseInsensitive
- that should "hide" the boolean parameter choice and call these instead of runQuery(...., true/false)
?
x-pack/plugin/eql/qa/common/src/main/java/org/elasticsearch/test/eql/EqlSpecLoader.java
Outdated
Show resolved
Hide resolved
@@ -55,6 +55,14 @@ private static String getTrimmedString(TomlTable table, String key) { | |||
spec.note(getTrimmedString(table, "note")); | |||
spec.description(getTrimmedString(table, "description")); | |||
|
|||
// default these values to false | |||
spec.caseSensitiveOnly(Boolean.TRUE.equals(table.getBoolean("case_sensitive"))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I find the "parameter" from the TOML tests a bit confusing. At Java level it's caseSensitiveOnly
and in tests is case_sensitive
. Imo, it's an important difference between something being "case sensitive ONLY" and "case sensitive".
A test that is "case sensitive" can, also, be "case insensitive", meaning a test that doesn't care about case sensitivity at all. For example, a test where no string functions are involved: this one could run in whatever configuration. My suggestion is to have in .toml
files the only
bit added to parameters to make a bit more clear.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in 254b5c3, I removed the implicit behavior for and the concept of "case (in)sensitive only".
now every test requires case_sensitive=true
and case_insensitive=true
if it should be tested with both
x-pack/plugin/eql/qa/common/src/main/java/org/elasticsearch/test/eql/EqlSpecLoader.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, left a comment
client/rest-high-level/src/main/java/org/elasticsearch/client/eql/EqlSearchRequest.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couple of nits, otherwise LGTM
|
||
return Objects.equals(this.query(), that.query()) | ||
&& Objects.equals(this.caseSensitive, that.caseSensitive) | ||
&& Objects.equals(this.caseInsensitive, that.caseInsensitive); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: missing description, expectedEventIds?
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(this.query, this.caseSensitive, this.caseInsensitive); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same nit as above
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the flags aren't set, then the test is assumed to work with both. case_insensitive=true and case_sensitive=true are mutually exclusive.
Looking at the case, this doesn't seem to be the case. A lot of tests have both parameters specified, that shouldn't be the case though.
} | ||
if (Strings.isNullOrEmpty(name)) { | ||
name = "" + (counter.get() + 1); | ||
else if (Strings.isNullOrEmpty(spec.note()) == false) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unless all tests have a note, please keep the name counter since otherwise the name becomes the query which makes it impossible to rerun the test (since it's not a correct method name).
private boolean caseSensitive = false; | ||
private boolean caseInsensitive = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As on the previous issue, having a Boolean
object should cover all the cases.
TRUE
- sensitive, FALSE
- insensitive, null
- unspecified (apply both).
if (spec.caseInsensitive() == false && spec.caseSensitive() == false) { | ||
throw new IllegalArgumentException("Test must support case-sensitivity or case-insensitivity for test: " + spec.toString()); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of forcing each query to specify a case sensitivity, the default should be missing an argument means that parameter is true
.
That is instead of specifying:
case_sensitive = true
case_insensitive = true
don't specify anything. If something is just case sensitive, it means it's insensitive and vice-versa and when none is specified, apply both (case irrelevant).
This makes the test declaration easier.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sounds like what I used to have, and simplified writing the tests but the behavior didn't seem to be well liked within EqlSpec.
Instead of forcing each query to specify a case sensitivity, the default should be missing an argument means that parameter is true.
This was the original behavior
[[queries]]
# this was an error
case_sensitive = true
case_insensitive = true
[[queries]]
# test will be checked with case sensitive mode only
case_sensitive = true
[[queries]]
# test will be checked with case insensitive mode only
case_insensitive = true
[[queries]]
# test will be checked with both case sensitive and case-insensitive mode
# case_sensitive = null
# case_insensitive = null
But if missing an argument "means that parameter is true
", then you basically are inverting the flags. Then you have to negate the logic to denote which tests are not allowed
[[queries]]
# the only way to run a test as case-insensitive only
case_sensitive = false
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the most desired behavior is this?
If both case_sensitive
and case_insensitive
are null
, then set them to both to true
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the most desired behavior is this?
If bothcase_sensitive
andcase_insensitive
arenull
, then set them to both totrue
Correct. Looking at the individual properties in isolation and setting them to true won't work since they both have to be missing.
Superseded by #58624 |
Part of #57313
Closes #56754
Pulled over the latest TOML integration tests from Python, which have case (in)sensitive toggles.
There's a handful more tests added, and I noticed that some of the sequence tests are failing, so I left those in the exclusions list. Also updated the HLRC to include case sensitive toggles, which was needed for the tests.
Basically to mark a test as case-sensitive only, add this to the TOML
or this to make a test case-insensitive only.
If the flags aren't set, then the test is assumed to work with both.
case_insensitive=true
andcase_sensitive=true
are mutually exclusive.