Skip to content
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

Merged
merged 6 commits into from
Sep 24, 2018
Merged

Add validation unit tests for empty and malformed queries (#33095) #33862

merged 6 commits into from
Sep 24, 2018

Conversation

cbismuth
Copy link
Contributor

This pull request adds unit tests to leverage REST query validation action logic. It checks for ParsingException when malformed or empty queries are sent.

Copy link
Member

@javanna javanna left a 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);
}

Copy link
Member

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?

Copy link
Contributor Author

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<>())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use Collections.emptyMap() instead?

Copy link
Contributor Author

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) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could this be static?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes 👍

Copy link
Contributor Author

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))));
Copy link
Member

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?

Copy link
Contributor Author

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.

@cbismuth
Copy link
Contributor Author

cbismuth commented Sep 19, 2018

@javanna I've updated test cases to maximize coverage.

I had to disable o.e.c.IndicesAdminClient#validateQuery() validation API in tests, as it would require an integration test to get a live IndicesAdminClient instance. Do you think we should develop such a test?

Copy link
Member

@javanna javanna left a 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));
Copy link
Member

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.

Copy link
Contributor Author

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 {
Copy link
Member

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Totally 👍

@cbismuth
Copy link
Contributor Author

PR updated with suggested changes, thank you @javanna 👍

Copy link
Member

@javanna javanna left a 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);
Copy link
Member

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.

Copy link
Contributor Author

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());
Copy link
Member

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.

Copy link
Contributor Author

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));
Copy link
Member

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you're right.

@cbismuth
Copy link
Contributor Author

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);
Copy link
Member

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?

Copy link
Contributor Author

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;
Copy link
Member

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?

Copy link
Contributor Author

@cbismuth cbismuth Sep 21, 2018

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.

Copy link
Contributor Author

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.

@cbismuth
Copy link
Contributor Author

PR updated, thank you @javanna.

Copy link
Member

@javanna javanna left a 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.

@javanna
Copy link
Member

javanna commented Sep 21, 2018

test this please

@cbismuth
Copy link
Contributor Author

Great! Thank you very much for your time and comments @javanna, they will help me a lot to make new contributions.

@javanna
Copy link
Member

javanna commented Sep 21, 2018

test this please

@javanna javanna merged commit 47ed6c7 into elastic:master Sep 24, 2018
@javanna
Copy link
Member

javanna commented Sep 24, 2018

thanks @cbismuth !

@javanna javanna added the :Search/Search Search-related issues that do not fall into other categories label Sep 24, 2018
@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-search-aggs

@javanna javanna added >enhancement >test Issues or PRs that are addressing/adding tests v7.0.0 v6.5.0 backport pending and removed >enhancement labels Sep 24, 2018
@cbismuth
Copy link
Contributor Author

Thank you @javanna 😉

@cbismuth cbismuth deleted the 33095_add_rest_validate_query_action_tests branch October 25, 2018 17:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
:Search/Search Search-related issues that do not fall into other categories >test Issues or PRs that are addressing/adding tests v6.5.0 v7.0.0-beta1
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants