blob: d74bc1f944096d053ce609ea50d0e2a6ece4fc49 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.ignite.client.handler;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.ignite.client.proto.query.JdbcQueryEventHandler;
import org.apache.ignite.client.proto.query.event.BatchExecuteRequest;
import org.apache.ignite.client.proto.query.event.BatchExecuteResult;
import org.apache.ignite.client.proto.query.event.Query;
import org.apache.ignite.client.proto.query.event.QueryCloseRequest;
import org.apache.ignite.client.proto.query.event.QueryCloseResult;
import org.apache.ignite.client.proto.query.event.QueryExecuteRequest;
import org.apache.ignite.client.proto.query.event.QueryExecuteResult;
import org.apache.ignite.client.proto.query.event.QueryFetchRequest;
import org.apache.ignite.client.proto.query.event.QueryFetchResult;
import org.apache.ignite.client.proto.query.event.QuerySingleResult;
import org.apache.ignite.internal.processors.query.calcite.QueryProcessor;
import org.apache.ignite.internal.processors.query.calcite.SqlCursor;
import org.apache.ignite.internal.processors.query.calcite.SqlQueryType;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.apache.ignite.client.proto.query.IgniteQueryErrorCode.UNSUPPORTED_OPERATION;
import static org.apache.ignite.client.proto.query.event.Response.STATUS_FAILED;
import static org.apache.ignite.client.proto.query.event.Response.STATUS_SUCCESS;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.when;
/**
* Test QueryEventHandler implementation with various request types.
* */
@ExtendWith(MockitoExtension.class)
public class QueryEventHandlerTest {
/**
* Mocked query processor.
*/
@Mock
private QueryProcessor processor;
/**
* Mocked sql cursor.
*/
@Mock
private SqlCursor<List<?>> cursor;
/**
* Test multiple select query request.
*/
@Test
public void testSelectQueryRequestMultipleStatements() {
int cursorSize = 10;
JdbcQueryEventHandler hnd = prepareHandlerForMultiState(cursorSize);
QueryExecuteRequest qryReq = getJdbcQueryExecuteRequest(10);
QueryExecuteResult res = hnd.query(qryReq);
assertEquals(res.status(), STATUS_SUCCESS);
assertNull(res.err());
assertEquals(res.results().size(), cursorSize);
for (int i = 0; i < res.results().size(); i++) {
QuerySingleResult singleRes = res.results().get(i);
assertTrue(singleRes.isQuery());
assertFalse(singleRes.last());
assertEquals(singleRes.cursorId(), i);
assertEquals(singleRes.items().size(), 10);
assertEquals(singleRes.items().get(0).size(), 1);
assertEquals(singleRes.items().get(0).get(0), "42");
}
}
/**
* Prepare cursors and processor for multiple select query request.
*
* @param cursorSize Size of the cursors array.
* @return Query event handler.
*/
private JdbcQueryEventHandler prepareHandlerForMultiState(int cursorSize) {
when(cursor.getQueryType()).thenReturn(SqlQueryType.QUERY);
when(cursor.hasNext()).thenReturn(true);
doReturn(Collections.singletonList("42")).when(cursor).next();
List<SqlCursor<List<?>>> cursors = new ArrayList<>(cursorSize);
for (int i = 0; i < cursorSize; i++)
cursors.add(cursor);
when(processor.query(anyString(), anyString(), any())).thenReturn(cursors);
return new JdbcQueryEventHandlerImpl(processor);
}
/**
* Test fetch query request.
*/
@Test
public void testFetchQueryRequest() {
JdbcQueryEventHandler hnd = getHandler(SqlQueryType.QUERY, "42");
QueryExecuteRequest qryReq = getJdbcQueryExecuteRequest(10);
QueryExecuteResult qryRes = hnd.query(qryReq);
var fetchReq = new QueryFetchRequest(qryRes.results().get(0).cursorId(), 10);
QueryFetchResult fetchRes = hnd.fetch(fetchReq);
assertEquals(fetchRes.status(), STATUS_SUCCESS);
assertNull(fetchRes.err());
assertEquals(fetchRes.items().size(), 10);
assertEquals(fetchRes.items().get(0).get(0), "42");
}
/**
* Test dml query request.
*/
@Test
public void testDMLQuery() {
JdbcQueryEventHandler hnd = getHandler(SqlQueryType.DML, 1L);
when(cursor.hasNext()).thenReturn(true).thenReturn(false);
QueryExecuteRequest qryReq = getJdbcQueryExecuteRequest(10);
QueryExecuteResult res = hnd.query(qryReq);
assertEquals(res.status(), STATUS_SUCCESS);
assertNull(res.err());
assertEquals(res.results().size(), 1);
QuerySingleResult singleRes = res.results().get(0);
assertEquals(singleRes.updateCount(), 1L);
assertFalse(singleRes.isQuery());
assertTrue(singleRes.last());
}
/**
* Test batch query request.
*/
@Test
public void testBatchQuery() {
JdbcQueryEventHandler hnd = new JdbcQueryEventHandlerImpl(processor);
var req = new BatchExecuteRequest(
"PUBLIC",
Collections.singletonList(new Query("INSERT INTRO test VALUES (1);", null)),
false);
BatchExecuteResult batch = hnd.batch(req);
assertEquals(batch.status(), UNSUPPORTED_OPERATION);
assertNotNull(batch.err());
}
/**
* Test error cases for select query request.
*/
@Test
public void testSelectQueryBadRequest() {
JdbcQueryEventHandler hnd = new JdbcQueryEventHandlerImpl(processor);
QueryExecuteRequest qryReq = getJdbcQueryExecuteRequest(10);
QueryExecuteResult res1 = hnd.query(qryReq);
assertEquals(res1.status(), STATUS_FAILED);
assertNotNull(res1.err());
QueryExecuteRequest req2 = getJdbcQueryExecuteRequest(10);
when(processor.query(anyString(), anyString(), any())).thenReturn(Collections.emptyList());
QueryExecuteResult res2 = hnd.query(req2);
assertEquals(res2.status(), STATUS_FAILED);
assertNotNull(res2.err());
when(cursor.hasNext()).thenReturn(true);
when(cursor.next()).thenThrow(RuntimeException.class);
when(processor.query(anyString(), anyString(), any())).thenReturn(Collections.singletonList(cursor));
QueryExecuteResult res3 = hnd.query(req2);
assertEquals(res3.status(), STATUS_FAILED);
assertNotNull(res3.err());
}
/**
* Test error cases for fetch query request.
*/
@Test
public void testFetchQueryBadRequests() {
JdbcQueryEventHandler hnd = getHandler(SqlQueryType.QUERY, "42");
QueryExecuteRequest qryReq = getJdbcQueryExecuteRequest(1);
QueryExecuteResult qryRes = hnd.query(qryReq);
var fetchReq = new QueryFetchRequest(qryRes.results().get(0).cursorId(), -1);
QueryFetchResult fetchRes = hnd.fetch(fetchReq);
assertEquals(fetchRes.status(), STATUS_FAILED);
assertNotNull(fetchRes.err());
fetchReq = new QueryFetchRequest(Integer.MAX_VALUE, 1);
fetchRes = hnd.fetch(fetchReq);
assertEquals(fetchRes.status(), STATUS_FAILED);
assertNotNull(fetchRes.err());
}
/**
* Test close cursor request.
*/
@Test
public void testCloseRequest() {
JdbcQueryEventHandler hnd = getHandler(SqlQueryType.QUERY, "42");
QueryExecuteRequest qryReq = getJdbcQueryExecuteRequest(1);
QueryExecuteResult qryRes = hnd.query(qryReq);
var closeReq = new QueryCloseRequest(qryRes.results().get(0).cursorId());
QueryCloseResult closeRes = hnd.close(closeReq);
assertEquals(closeRes.status(), STATUS_SUCCESS);
closeRes = hnd.close(closeReq);
assertEquals(closeRes.status(), STATUS_FAILED);
assertNotNull(closeRes.err());
}
/**
* Prepare getJdbcQueryExecuteRequest.
*
* @param pageSize Size of result set in response.
* @return JdbcQueryExecuteRequest.
*/
private QueryExecuteRequest getJdbcQueryExecuteRequest(int pageSize) {
return new QueryExecuteRequest("PUBLIC", pageSize, 3, "SELECT * FROM Test;", null);
}
/**
* Prepare cursor and processor for multiple select query request.
*
* @param type Expected sql query type.
* @param val Value in result set.
* @return Query event handler.
*/
private JdbcQueryEventHandler getHandler(SqlQueryType type, Object val) {
when(cursor.getQueryType()).thenReturn(type);
when(cursor.hasNext()).thenReturn(true);
doReturn(Collections.singletonList(val)).when(cursor).next();
when(processor.query(anyString(), anyString(), any())).thenReturn(Collections.singletonList(cursor));
return new JdbcQueryEventHandlerImpl(processor);
}
}