This is an automated email from the ASF dual-hosted git repository. timoninmaxim pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/ignite.git
The following commit(s) were added to refs/heads/master by this push: new dfff5d7675e IGNITE-22140 Add test for IndexQuery pagination (#11350) dfff5d7675e is described below commit dfff5d7675ec30deba1b09acb388efdb7edc6da3 Author: oleg-vlsk <153691984+oleg-v...@users.noreply.github.com> AuthorDate: Mon Jun 3 18:08:22 2024 +1000 IGNITE-22140 Add test for IndexQuery pagination (#11350) --- .../cache/query/IndexQueryPaginationTest.java | 159 +++++++++++++++++++++ .../ignite/cache/query/IndexQueryTestSuite.java | 3 +- .../cache/query/ThinClientIndexQueryTest.java | 2 +- 3 files changed, 162 insertions(+), 2 deletions(-) diff --git a/modules/indexing/src/test/java/org/apache/ignite/cache/query/IndexQueryPaginationTest.java b/modules/indexing/src/test/java/org/apache/ignite/cache/query/IndexQueryPaginationTest.java new file mode 100644 index 00000000000..1e20a7b5b67 --- /dev/null +++ b/modules/indexing/src/test/java/org/apache/ignite/cache/query/IndexQueryPaginationTest.java @@ -0,0 +1,159 @@ +/* + * 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.cache.query; + +import java.util.ArrayList; +import java.util.List; +import javax.cache.Cache; +import org.apache.ignite.Ignite; +import org.apache.ignite.IgniteCache; +import org.apache.ignite.IgniteDataStreamer; +import org.apache.ignite.cache.CacheMode; +import org.apache.ignite.cache.query.annotations.QuerySqlField; +import org.apache.ignite.configuration.CacheConfiguration; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.internal.TestRecordingCommunicationSpi; +import org.apache.ignite.internal.processors.cache.query.GridCacheQueryRequest; +import org.apache.ignite.internal.processors.cache.query.GridCacheQueryResponse; +import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +import static org.apache.ignite.cache.query.ThinClientIndexQueryTest.getFilteredMessages; + +/** */ +@RunWith(Parameterized.class) +public class IndexQueryPaginationTest extends GridCommonAbstractTest { + /** */ + private static final int PAGE_SIZE = 512; + + /** */ + private static final int NODES = 2; + + /** */ + private Ignite grid; + + /** */ + private IgniteCache<Integer, Person> cache; + + /** */ + @Parameterized.Parameter + public int entries; + + /** */ + @Parameterized.Parameters(name = "entries={0}") + public static Object[] params() { + return new Object[] {100, 1000, 5000, 10_000, 50_000, 100_000}; + } + + /** {@inheritDoc} */ + @Override protected void beforeTest() throws Exception { + grid = startGrids(NODES); + + cache = grid.cache("cache"); + + insertData(grid, cache, entries); + } + + /** {@inheritDoc} */ + @Override protected void afterTest() throws Exception { + stopAllGrids(); + } + + /** {@inheritDoc} */ + @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception { + CacheConfiguration<Integer, Person> ccfg = new CacheConfiguration<Integer, Person>("cache") + .setIndexedTypes(Integer.class, Person.class) + .setCacheMode(CacheMode.PARTITIONED); + + return super.getConfiguration(igniteInstanceName) + .setCommunicationSpi(new TestRecordingCommunicationSpi()) + .setCacheConfiguration(ccfg); + } + + /** + * Insert data into a cache. + * + * @param ignite Ignite instance. + * @param cache Cache. + * @param entries Number of entries. + */ + private void insertData(Ignite ignite, IgniteCache<Integer, Person> cache, int entries) { + try (IgniteDataStreamer<Integer, Person> streamer = ignite.dataStreamer(cache.getName())) { + for (int i = 0; i < entries; i++) + streamer.addData(i, new Person(i)); + } + } + + /** + * Check if the number and the size of next page requests and responses are correct while executing an index query. + */ + @Test + public void nextPageTest() { + int locNodeEntries = cache.query(new ScanQuery<Integer, Person>().setLocal(true)).getAll().size(); + int remNodeEntries = entries - locNodeEntries; + + int reqsExpected = (remNodeEntries + PAGE_SIZE - 1) / PAGE_SIZE; + + int remNodeLastPageEntries = remNodeEntries % PAGE_SIZE; + + for (int i = 0; i < NODES; i++) + TestRecordingCommunicationSpi.spi(grid(i)).record(GridCacheQueryRequest.class, GridCacheQueryResponse.class); + + QueryCursor<Cache.Entry<Integer, Person>> cursor = cache.query( + new IndexQuery<Integer, Person>(Person.class).setPageSize(PAGE_SIZE)); + + assert entries == cursor.getAll().size(); + + List<Object> msgs = new ArrayList<>(); + + for (int i = 0; i < NODES; i++) + msgs.addAll(TestRecordingCommunicationSpi.spi(grid(i)).recordedMessages(true)); + + List<GridCacheQueryRequest> reqs = getFilteredMessages(msgs, GridCacheQueryRequest.class); + List<GridCacheQueryResponse> resp = getFilteredMessages(msgs, GridCacheQueryResponse.class); + + int reqsSize = reqs.size(); + + assert reqsSize == reqsExpected && reqsSize == resp.size(); + + for (int i = 0; i < reqsSize; i++) { + int reqPage = reqs.get(i).pageSize(); + int respData = resp.get(i).data().size(); + + assert reqPage == PAGE_SIZE; + + if (i == reqsSize - 1 && remNodeLastPageEntries != 0) + assert respData == remNodeLastPageEntries; + else + assert respData == reqPage; + } + } + + /** */ + private static class Person { + /** */ + @QuerySqlField(index = true) final int id; + + /** */ + Person(int id) { + this.id = id; + } + } +} diff --git a/modules/indexing/src/test/java/org/apache/ignite/cache/query/IndexQueryTestSuite.java b/modules/indexing/src/test/java/org/apache/ignite/cache/query/IndexQueryTestSuite.java index 8bb75faddad..906b2e2b673 100644 --- a/modules/indexing/src/test/java/org/apache/ignite/cache/query/IndexQueryTestSuite.java +++ b/modules/indexing/src/test/java/org/apache/ignite/cache/query/IndexQueryTestSuite.java @@ -47,7 +47,8 @@ import org.junit.runners.Suite; RepeatedFieldIndexQueryTest.class, IndexQueryInCriterionTest.class, IndexQueryInCriterionDescTest.class, - IndexQueryLimitTest.class + IndexQueryLimitTest.class, + IndexQueryPaginationTest.class }) public class IndexQueryTestSuite { } diff --git a/modules/indexing/src/test/java/org/apache/ignite/cache/query/ThinClientIndexQueryTest.java b/modules/indexing/src/test/java/org/apache/ignite/cache/query/ThinClientIndexQueryTest.java index 0d9ffed37b5..d7dfb3b75af 100644 --- a/modules/indexing/src/test/java/org/apache/ignite/cache/query/ThinClientIndexQueryTest.java +++ b/modules/indexing/src/test/java/org/apache/ignite/cache/query/ThinClientIndexQueryTest.java @@ -492,7 +492,7 @@ public class ThinClientIndexQueryTest extends GridCommonAbstractTest { * @param cls Class of messages that need to be filtered. * @return List of messages filtered by the specified class. */ - public <T> List<T> getFilteredMessages(List<Object> msgs, Class<T> cls) { + public static <T> List<T> getFilteredMessages(List<Object> msgs, Class<T> cls) { return msgs.stream() .filter(msg -> msg.getClass().equals(cls)) .map(msg -> (T)msg)