/** * Copyright (C) 2014-2016 LinkedIn Corp. (pinot-core@linkedin.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.linkedin.pinot.broker.broker; import com.linkedin.pinot.broker.requesthandler.BrokerRequestHandler; import com.linkedin.pinot.common.request.BrokerRequest; import com.linkedin.pinot.pql.parsers.Pql2Compiler; import java.io.File; import org.apache.commons.configuration.PropertiesConfiguration; import org.testng.Assert; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; /** * Test for BrokerRequest Validation: * - Ensures query response limit is honored while validating a request. */ public class BrokerRequestValidationTest { private static final int QUERY_RESPONSE_LIMIT = 100; private static final String QUERY_RESPONSE_LIMIT_CONFIG = "pinot.broker.query.response.limit"; private static final CharSequence LIMIT_VALIDATION_STRING = "exceeded maximum allowed value"; private BrokerServerBuilder brokerBuilder; /** * Setup method to start the broker. Stars the broker with * a query response limit of {@value QUERY_RESPONSE_LIMIT} * @return * @throws Exception */ @BeforeClass public BrokerServerBuilder setup() throws Exception { // Read default configurations. PropertiesConfiguration config = new PropertiesConfiguration( new File(BrokerServerBuilderTest.class.getClassLoader().getResource("broker.properties").toURI())); // Set the value for query response limit. config.addProperty(QUERY_RESPONSE_LIMIT_CONFIG, QUERY_RESPONSE_LIMIT); brokerBuilder = new BrokerServerBuilder(config, null, null, null); brokerBuilder.buildNetwork(); brokerBuilder.buildHTTP(); brokerBuilder.start(); return brokerBuilder; } /** * Teardown method to stop the broker. * * @throws Exception */ @AfterClass public void tearDown() throws Exception { brokerBuilder.stop(); } /** * Test to ensure that values for 'TOP' smaller than or equal to the * configured query response limit are validated, and others are not. * * @throws Exception */ @Test public void testTop() throws Exception { String baseQuery = "select count(*) from myTable group by myColumn TOP "; String query = baseQuery + QUERY_RESPONSE_LIMIT; String exceptionMessage = runQuery(query); Assert.assertNull(exceptionMessage); query = baseQuery + (QUERY_RESPONSE_LIMIT + 1); exceptionMessage = runQuery(query); Assert.assertTrue((exceptionMessage != null) && exceptionMessage.contains(LIMIT_VALIDATION_STRING)); } /** * Test to ensure that values for 'TOP' smaller than or equal to the * configured query response limit are validated, and others are not. * * @throws Exception */ @Test public void testLimit() throws Exception { String baseQuery = "select * from myTable limit "; String query = baseQuery + QUERY_RESPONSE_LIMIT; String exceptionMessage = runQuery(query); Assert.assertNull(exceptionMessage); query = baseQuery + (QUERY_RESPONSE_LIMIT + 1); exceptionMessage = runQuery(query); Assert.assertTrue((exceptionMessage != null) && exceptionMessage.contains(LIMIT_VALIDATION_STRING)); } /** * Helper method to run the query. * * @param query * @return Returns exception string if any, null otherwise. * @throws Exception */ private String runQuery(String query) throws Exception { BrokerRequestHandler brokerRequestHandler = brokerBuilder.getBrokerRequestHandler(); Pql2Compiler compiler = new Pql2Compiler(); BrokerRequest brokerRequest = compiler.compileToBrokerRequest(query); String exceptionMessage = null; try { brokerRequestHandler.validateRequest(brokerRequest); } catch (Exception e) { exceptionMessage = e.getMessage(); } return exceptionMessage; } }