-
Notifications
You must be signed in to change notification settings - Fork 25.1k
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
Add validation unit tests for empty and malformed queries (#33095) #33862
Add validation unit tests for empty and malformed queries (#33095) #33862
Conversation
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 left a couple of small comments, looks good overall. thanks @cbismuth for your contribution.
|
||
expectParsingException(content); | ||
} | ||
|
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 also add a test for a query that is valid?
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.
Yes, I'll add it.
final RestRequest request = new FakeRestRequest | ||
.Builder(xContentRegistry()) | ||
.withPath("index1/type1/_validate/query") | ||
.withParams(new HashMap<>()) |
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.
use Collections.emptyMap() instead?
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.
Sure.
expectParsingException(content); | ||
} | ||
|
||
private void expectParsingException(String content) { |
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.
could this be static?
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.
Yes 👍
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.
Finally no, as xContentRegistry()
method is inherited from ESTestCase
parent test class.
final ValidateQueryRequest validateQueryRequest = new ValidateQueryRequest("index1"); | ||
|
||
expectThrows(ParsingException.class, | ||
() -> request.withContentOrSourceParamParserOrNull(parser -> validateQueryRequest.query(RestActions.getQueryContent(parser)))); |
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 wonder if we want to take this one step further and check that the rest action not only calls this code, but also catches the exception. What do you think?
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 would be better, I'm working on it, thank you @javanna.
@javanna I've updated test cases to maximize coverage. I had to disable |
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 have left two suggestions on how to improve the tests, LGTM otherwise. Thanks @cbismuth !
public void setUp() throws Exception { | ||
super.setUp(); | ||
|
||
doNothing().when(action).validateQuery(eq(client), any(ValidateQueryRequest.class), any(RestChannel.class)); |
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.
what do you think of the following lines instead of adding the validateQuery method to the rest action?
TestThreadPool threadPool = new TestThreadPool(RestValidateQueryActionTests.class.getName());
NodeClient client = new NodeClient(settings, threadPool);
TaskManager taskManager = new TaskManager(Settings.EMPTY, threadPool, Collections.emptySet());
TransportAction transportAction = new TransportAction(Settings.EMPTY, ValidateQueryAction.NAME, new ActionFilters(Collections.emptySet()), taskManager) {
@Override
protected void doExecute(Task task, ActionRequest request, ActionListener listener) {
}
};
Map<Action, TransportAction> actions = new HashMap<>();
actions.put(ValidateQueryAction.INSTANCE, transportAction);
client.initialize(actions, () -> "local", null);
I would do this from a static beforeClass method given that it's the same config for all methods. We need to remember to close the thread pool also at the end.
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 really do prefer your solution, as it doesn't require to modify production code for testing purpose only. Moreover, it's a great pattern to remember! Thank you @javanna 👍
doNothing().when(action).validateQuery(eq(client), any(ValidateQueryRequest.class), any(RestChannel.class)); | ||
} | ||
|
||
public void testRestValidateQueryAction_validQuery() 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.
I think that we don't need to repeat the action name in every method name, leave testValidQuery for this one? Same for the other methods.
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.
Totally 👍
PR updated with suggested changes, thank you @javanna 👍 |
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.
left a couple more comments, thanks again @cbismuth
private static final TestThreadPool threadPool = new TestThreadPool(RestValidateQueryActionTests.class.getName()); | ||
private static final NodeClient client = new NodeClient(settings, threadPool); | ||
|
||
private final UsageService usageService = new UsageService(settings); |
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.
given that it's always the same instances used, maybe we could declare these three static too and initialize them only once.
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.
Totally, thank you.
public class RestValidateQueryActionTests extends AbstractSearchTestCase { | ||
|
||
private static final Settings settings = Settings.EMPTY; | ||
private static final TestThreadPool threadPool = new TestThreadPool(RestValidateQueryActionTests.class.getName()); |
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.
It would be wise to close the threadpool in an afterclass method, also assign all of the static variables to null. We have checks for threads and objects that are left behind which might trip if we are not careful.
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.
Yes 👍
|
||
private final UsageService usageService = new UsageService(settings); | ||
private final RestController controller = new RestController(settings, emptySet(), null, client, null, usageService); | ||
private final RestValidateQueryAction action = spy(new RestValidateQueryAction(settings, controller)); |
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 that you don't need to spy on this anymore.
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.
Yes, you're right.
You're welcome @javanna, PR updated, thank you for your detailed review, I'm learning a lot 👍 |
|
||
@AfterClass | ||
public static void terminateTestThreadPool() throws InterruptedException { | ||
terminate(threadPool); |
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 you assign all of the static variables to null as part of this method?
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.
Oh, yes...
|
||
public class RestValidateQueryActionTests extends AbstractSearchTestCase { | ||
|
||
private static final Settings settings = Settings.EMPTY; |
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 we can remove this given that we always use empty and use empty directly instead?
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 extracted it to not cause hard line break at 140 char line width and please Checkstyle. But I can break lines, no worries.
EDIT no need to break lines.
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.
But you're right non-empty settings would probably be different for each allocated object.
PR updated, thank you @javanna. |
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 thanks @cbismuth I will get this in as soon as I get a green build.
test this please |
Great! Thank you very much for your time and comments @javanna, they will help me a lot to make new contributions. |
test this please |
thanks @cbismuth ! |
Pinging @elastic/es-search-aggs |
Thank you @javanna 😉 |
This pull request adds unit tests to leverage REST query validation action logic. It checks for
ParsingException
when malformed or empty queries are sent.