This is an automated email from the ASF dual-hosted git repository. mkevo pushed a commit to branch develop in repository https://gitbox.apache.org/repos/asf/geode.git
The following commit(s) were added to refs/heads/develop by this push: new 67359dc GEODE-9632: Allow INDEX_THRESHOLD_SIZE System property to override CompiledValue.RESULT_LIMIT (#7010) 67359dc is described below commit 67359dcd3eb0f0ea00ea751f7770ecb3b1750386 Author: Mario Kevo <48509719+mk...@users.noreply.github.com> AuthorDate: Mon Nov 15 08:08:09 2021 +0100 GEODE-9632: Allow INDEX_THRESHOLD_SIZE System property to override CompiledValue.RESULT_LIMIT (#7010) * GEODE-9632: fix output for the range query with wildcard character --- .../query/functional/LimitClauseJUnitTest.java | 20 +- .../NonDistinctOrderByReplicatedJUnitTest.java | 2 +- .../functional/OrderByReplicatedJUnitTest.java | 2 +- .../internal/AbstractGroupOrRangeJunction.java | 4 - .../geode/cache/query/internal/QueryUtils.java | 5 + .../query/internal/index/CompactRangeIndex.java | 9 + .../cache/query/internal/index/HashIndex.java | 4 + .../cache/query/internal/index/IndexManager.java | 2 + .../query/internal/index/PrimaryKeyIndex.java | 8 + .../cache/query/internal/index/RangeIndex.java | 4 + .../query/dunit/QueryWithRangeIndexDUnitTest.java | 206 +++++++++++++++++++++ 11 files changed, 250 insertions(+), 16 deletions(-) diff --git a/geode-core/src/integrationTest/java/org/apache/geode/cache/query/functional/LimitClauseJUnitTest.java b/geode-core/src/integrationTest/java/org/apache/geode/cache/query/functional/LimitClauseJUnitTest.java index 6dc3392..688069a 100644 --- a/geode-core/src/integrationTest/java/org/apache/geode/cache/query/functional/LimitClauseJUnitTest.java +++ b/geode-core/src/integrationTest/java/org/apache/geode/cache/query/functional/LimitClauseJUnitTest.java @@ -673,7 +673,7 @@ public class LimitClauseJUnitTest { assertEquals(5, result.size()); SelectResults wrapper = (SelectResults) result; assertEquals(5, wrapper.asSet().size()); - assertTrue(observer.limitAppliedAtIndex); + assertFalse(observer.limitAppliedAtIndex); } catch (Exception e) { CacheUtils.getLogger().error(e); fail(e.toString()); @@ -710,7 +710,7 @@ public class LimitClauseJUnitTest { assertEquals(5, result.size()); SelectResults wrapper = (SelectResults) result; assertEquals(5, wrapper.asSet().size()); - assertTrue(observer.limitAppliedAtIndex); + assertFalse(observer.limitAppliedAtIndex); } catch (Exception e) { CacheUtils.getLogger().error(e); fail(e.toString()); @@ -754,7 +754,7 @@ public class LimitClauseJUnitTest { assertEquals(5, result.size()); SelectResults wrapper = (SelectResults) result; assertEquals(5, wrapper.asSet().size()); - assertTrue(observer.limitAppliedAtIndex); + assertFalse(observer.limitAppliedAtIndex); } catch (Exception e) { CacheUtils.getLogger().error(e); fail(e.toString()); @@ -799,7 +799,7 @@ public class LimitClauseJUnitTest { assertEquals(5, result.size()); SelectResults wrapper = (SelectResults) result; assertEquals(5, wrapper.asSet().size()); - assertTrue(observer.limitAppliedAtIndex); + assertFalse(observer.limitAppliedAtIndex); } catch (Exception e) { CacheUtils.getLogger().error(e); fail(e.toString()); @@ -837,7 +837,7 @@ public class LimitClauseJUnitTest { SelectResults wrapper = (SelectResults) result; assertEquals(5, wrapper.asSet().size()); assertTrue(wrapper.getCollectionType().getElementType() instanceof StructType); - assertTrue(observer.limitAppliedAtIndex); + assertFalse(observer.limitAppliedAtIndex); } catch (Exception e) { CacheUtils.getLogger().error(e); fail(e.toString()); @@ -919,7 +919,7 @@ public class LimitClauseJUnitTest { assertEquals(5, result.size()); SelectResults wrapper = (SelectResults) result; assertEquals(5, wrapper.asSet().size()); - assertTrue(observer.limitAppliedAtIndex); + assertFalse(observer.limitAppliedAtIndex); } catch (Exception e) { CacheUtils.getLogger().error(e); fail(e.toString()); @@ -1051,7 +1051,7 @@ public class LimitClauseJUnitTest { SelectResults wrapper = (SelectResults) result; assertEquals(10, wrapper.asSet().size()); assertFalse(observer.limitAppliedAtIndex && observer.indexName.equals("idIndex")); - assertTrue(observer.limitAppliedAtIndex && observer.indexName.equals("statusIndex")); + assertFalse(observer.limitAppliedAtIndex && observer.indexName.equals("statusIndex")); } catch (Exception e) { CacheUtils.getLogger().error(e); fail(e.toString()); @@ -1130,7 +1130,7 @@ public class LimitClauseJUnitTest { query = qs.newQuery(qstr); result = (SelectResults) query.execute(); assertEquals(10, result.size()); - assertTrue(observer.limitAppliedAtIndex && observer.indexName.equals("statusIndex")); + assertFalse(observer.limitAppliedAtIndex && observer.indexName.equals("statusIndex")); } } catch (Exception e) { CacheUtils.getLogger().error(e); @@ -1528,7 +1528,7 @@ public class LimitClauseJUnitTest { assertNotNull(idIndex); SelectResults resultsWithIndex = (SelectResults) query.execute(); - assertTrue(observer.limitAppliedAtIndex); + assertFalse(observer.limitAppliedAtIndex); assertEquals(5, resultsWithIndex.size()); } @@ -1753,7 +1753,7 @@ public class LimitClauseJUnitTest { assertNotNull(idIndex); SelectResults resultsWithIndex = (SelectResults) query.execute(); - assertTrue(observer.limitAppliedAtIndex); + assertFalse(observer.limitAppliedAtIndex); assertEquals(5, resultsWithIndex.size()); } diff --git a/geode-core/src/integrationTest/java/org/apache/geode/cache/query/functional/NonDistinctOrderByReplicatedJUnitTest.java b/geode-core/src/integrationTest/java/org/apache/geode/cache/query/functional/NonDistinctOrderByReplicatedJUnitTest.java index adf16e6..6dbf923 100644 --- a/geode-core/src/integrationTest/java/org/apache/geode/cache/query/functional/NonDistinctOrderByReplicatedJUnitTest.java +++ b/geode-core/src/integrationTest/java/org/apache/geode/cache/query/functional/NonDistinctOrderByReplicatedJUnitTest.java @@ -190,7 +190,7 @@ public class NonDistinctOrderByReplicatedJUnitTest extends NonDistinctOrderByTes Region r1 = this.createRegion("portfolio1", Portfolio.class); - for (int i = 0; i < 50; i++) { + for (int i = 0; i < 200; i++) { r1.put(i + "", new Portfolio(i)); } diff --git a/geode-core/src/integrationTest/java/org/apache/geode/cache/query/functional/OrderByReplicatedJUnitTest.java b/geode-core/src/integrationTest/java/org/apache/geode/cache/query/functional/OrderByReplicatedJUnitTest.java index 1f9241d..16fbf13 100644 --- a/geode-core/src/integrationTest/java/org/apache/geode/cache/query/functional/OrderByReplicatedJUnitTest.java +++ b/geode-core/src/integrationTest/java/org/apache/geode/cache/query/functional/OrderByReplicatedJUnitTest.java @@ -433,7 +433,7 @@ public class OrderByReplicatedJUnitTest extends OrderByTestImplementation { Region r1 = createRegion("portfolio1", Portfolio.class); - for (int i = 0; i < 50; i++) { + for (int i = 0; i < 200; i++) { r1.put(i + "", new Portfolio(i)); } diff --git a/geode-core/src/main/java/org/apache/geode/cache/query/internal/AbstractGroupOrRangeJunction.java b/geode-core/src/main/java/org/apache/geode/cache/query/internal/AbstractGroupOrRangeJunction.java index f0090ae..832f7c0 100644 --- a/geode-core/src/main/java/org/apache/geode/cache/query/internal/AbstractGroupOrRangeJunction.java +++ b/geode-core/src/main/java/org/apache/geode/cache/query/internal/AbstractGroupOrRangeJunction.java @@ -35,15 +35,11 @@ import org.apache.geode.cache.query.internal.parse.OQLLexerTokenTypes; import org.apache.geode.cache.query.internal.types.StructTypeImpl; import org.apache.geode.cache.query.types.ObjectType; import org.apache.geode.internal.Assert; -import org.apache.geode.util.internal.GeodeGlossary; public abstract class AbstractGroupOrRangeJunction extends AbstractCompiledValue implements Filter, OQLLexerTokenTypes { /** left operand */ final CompiledValue[] _operands; - private static final int INDEX_RESULT_THRESHOLD_DEFAULT = 100; - public static final String INDX_THRESHOLD_PROP_STR = - GeodeGlossary.GEMFIRE_PREFIX + "Query.INDEX_THRESHOLD_SIZE"; private static final int indexThresholdSize = Integer.getInteger(INDX_THRESHOLD_PROP_STR, INDEX_RESULT_THRESHOLD_DEFAULT).intValue(); private int _operator = 0; diff --git a/geode-core/src/main/java/org/apache/geode/cache/query/internal/QueryUtils.java b/geode-core/src/main/java/org/apache/geode/cache/query/internal/QueryUtils.java index 70e956c..d57277f 100644 --- a/geode-core/src/main/java/org/apache/geode/cache/query/internal/QueryUtils.java +++ b/geode-core/src/main/java/org/apache/geode/cache/query/internal/QueryUtils.java @@ -14,6 +14,8 @@ */ package org.apache.geode.cache.query.internal; +import static org.apache.geode.cache.query.internal.CompiledValue.indexThresholdSize; + import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; @@ -669,6 +671,9 @@ public class QueryUtils { limit = context.cacheGet(CompiledValue.RESULT_LIMIT) != null ? (Integer) context.cacheGet(CompiledValue.RESULT_LIMIT) : -1; } + if (limit != -1 && limit < indexThresholdSize) { + limit = indexThresholdSize; + } return limit; } diff --git a/geode-core/src/main/java/org/apache/geode/cache/query/internal/index/CompactRangeIndex.java b/geode-core/src/main/java/org/apache/geode/cache/query/internal/index/CompactRangeIndex.java index 632ea0c..db4b9a09 100644 --- a/geode-core/src/main/java/org/apache/geode/cache/query/internal/index/CompactRangeIndex.java +++ b/geode-core/src/main/java/org/apache/geode/cache/query/internal/index/CompactRangeIndex.java @@ -14,6 +14,8 @@ */ package org.apache.geode.cache.query.internal.index; +import static org.apache.geode.cache.query.internal.CompiledValue.indexThresholdSize; + import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; @@ -95,6 +97,7 @@ public class CompactRangeIndex extends AbstractIndex { private IndexStore indexStore; + @MutableForTesting static boolean TEST_ALWAYS_UPDATE_IN_PROGRESS = false; @@ -483,6 +486,9 @@ public class CompactRangeIndex extends AbstractIndex { Boolean applyLimit = (Boolean) context.cacheGet(CompiledValue.CAN_APPLY_LIMIT_AT_INDEX); if (applyLimit != null && applyLimit) { limit = (Integer) context.cacheGet(CompiledValue.RESULT_LIMIT); + if (limit < indexThresholdSize) { + limit = indexThresholdSize; + } } Boolean orderByClause = (Boolean) context.cacheGet(CompiledValue.CAN_APPLY_ORDER_BY_AT_INDEX); @@ -517,6 +523,9 @@ public class CompactRangeIndex extends AbstractIndex { Boolean applyLimit = (Boolean) context.cacheGet(CompiledValue.CAN_APPLY_LIMIT_AT_INDEX); if (applyLimit != null && applyLimit) { limit = (Integer) context.cacheGet(CompiledValue.RESULT_LIMIT); + if (limit != -1 && limit < indexThresholdSize) { + limit = indexThresholdSize; + } } Boolean orderByClause = (Boolean) context.cacheGet(CompiledValue.CAN_APPLY_ORDER_BY_AT_INDEX); diff --git a/geode-core/src/main/java/org/apache/geode/cache/query/internal/index/HashIndex.java b/geode-core/src/main/java/org/apache/geode/cache/query/internal/index/HashIndex.java index 1bc2591..984a25f 100755 --- a/geode-core/src/main/java/org/apache/geode/cache/query/internal/index/HashIndex.java +++ b/geode-core/src/main/java/org/apache/geode/cache/query/internal/index/HashIndex.java @@ -14,6 +14,7 @@ */ package org.apache.geode.cache.query.internal.index; +import static org.apache.geode.cache.query.internal.CompiledValue.indexThresholdSize; import static org.apache.geode.internal.lang.SystemUtils.getLineSeparator; import java.util.ArrayList; @@ -494,6 +495,9 @@ public class HashIndex extends AbstractIndex { Boolean applyLimit = (Boolean) context.cacheGet(CompiledValue.CAN_APPLY_LIMIT_AT_INDEX); if (applyLimit != null && applyLimit) { limit = (Integer) context.cacheGet(CompiledValue.RESULT_LIMIT); + if (limit != -1 && limit < indexThresholdSize) { + limit = indexThresholdSize; + } } Boolean orderByClause = (Boolean) context.cacheGet(CompiledValue.CAN_APPLY_ORDER_BY_AT_INDEX); diff --git a/geode-core/src/main/java/org/apache/geode/cache/query/internal/index/IndexManager.java b/geode-core/src/main/java/org/apache/geode/cache/query/internal/index/IndexManager.java index e366102..a38d473 100644 --- a/geode-core/src/main/java/org/apache/geode/cache/query/internal/index/IndexManager.java +++ b/geode-core/src/main/java/org/apache/geode/cache/query/internal/index/IndexManager.java @@ -87,6 +87,8 @@ public class IndexManager { public static final int RECREATE_INDEX = 4; private final InternalCache cache; protected final Region region; + String indexThresholdSize = + System.getProperty(GeodeGlossary.GEMFIRE_PREFIX + "Query.INDEX_THRESHOLD_SIZE"); private final boolean isOverFlowToDisk; private final boolean offHeap; diff --git a/geode-core/src/main/java/org/apache/geode/cache/query/internal/index/PrimaryKeyIndex.java b/geode-core/src/main/java/org/apache/geode/cache/query/internal/index/PrimaryKeyIndex.java index 6edcc59..c54aeb2 100644 --- a/geode-core/src/main/java/org/apache/geode/cache/query/internal/index/PrimaryKeyIndex.java +++ b/geode-core/src/main/java/org/apache/geode/cache/query/internal/index/PrimaryKeyIndex.java @@ -14,6 +14,8 @@ */ package org.apache.geode.cache.query.internal.index; +import static org.apache.geode.cache.query.internal.CompiledValue.indexThresholdSize; + import java.util.Collection; import java.util.Iterator; import java.util.List; @@ -105,6 +107,9 @@ public class PrimaryKeyIndex extends AbstractIndex { Boolean applyLimit = (Boolean) context.cacheGet(CompiledValue.CAN_APPLY_LIMIT_AT_INDEX); if (applyLimit != null && applyLimit) { limit = (Integer) context.cacheGet(CompiledValue.RESULT_LIMIT); + if (limit != -1 && limit < indexThresholdSize) { + limit = indexThresholdSize; + } } QueryObserver observer = QueryObserverHolder.getInstance(); if (limit != -1 && results.size() == limit) { @@ -184,6 +189,9 @@ public class PrimaryKeyIndex extends AbstractIndex { if (applyLimit != null && applyLimit.booleanValue()) { limit = ((Integer) context.cacheGet(CompiledValue.RESULT_LIMIT)).intValue(); + if (limit != -1 && limit < indexThresholdSize) { + limit = indexThresholdSize; + } } if (limit != -1 && results.size() == limit) { observer.limitAppliedAtIndexLevel(this, limit, results); diff --git a/geode-core/src/main/java/org/apache/geode/cache/query/internal/index/RangeIndex.java b/geode-core/src/main/java/org/apache/geode/cache/query/internal/index/RangeIndex.java index 5970ec8..c6723bf 100644 --- a/geode-core/src/main/java/org/apache/geode/cache/query/internal/index/RangeIndex.java +++ b/geode-core/src/main/java/org/apache/geode/cache/query/internal/index/RangeIndex.java @@ -16,6 +16,7 @@ package org.apache.geode.cache.query.internal.index; import static java.lang.Integer.MAX_VALUE; import static java.lang.Integer.valueOf; +import static org.apache.geode.cache.query.internal.CompiledValue.indexThresholdSize; import java.util.ArrayList; import java.util.Collection; @@ -1195,6 +1196,9 @@ public class RangeIndex extends AbstractIndex { Boolean applyLimit = (Boolean) context.cacheGet(CompiledValue.CAN_APPLY_LIMIT_AT_INDEX); if (applyLimit != null && applyLimit) { limit = (Integer) context.cacheGet(CompiledValue.RESULT_LIMIT); + if (limit != -1 && limit < indexThresholdSize) { + limit = indexThresholdSize; + } } Boolean orderByClause = (Boolean) context.cacheGet(CompiledValue.CAN_APPLY_ORDER_BY_AT_INDEX); diff --git a/geode-cq/src/distributedTest/java/org/apache/geode/cache/query/dunit/QueryWithRangeIndexDUnitTest.java b/geode-cq/src/distributedTest/java/org/apache/geode/cache/query/dunit/QueryWithRangeIndexDUnitTest.java new file mode 100644 index 0000000..3ca054c --- /dev/null +++ b/geode-cq/src/distributedTest/java/org/apache/geode/cache/query/dunit/QueryWithRangeIndexDUnitTest.java @@ -0,0 +1,206 @@ +/* + * 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.geode.cache.query.dunit; + +import static org.apache.geode.cache.Region.SEPARATOR; +import static org.apache.geode.distributed.ConfigurationProperties.HTTP_SERVICE_PORT; +import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER; +import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER_PORT; +import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER_START; +import static org.apache.geode.distributed.ConfigurationProperties.LOCATORS; +import static org.apache.geode.internal.AvailablePortHelper.getRandomAvailableTCPPorts; +import static org.apache.geode.internal.lang.SystemPropertyHelper.GEMFIRE_PREFIX; +import static org.apache.geode.test.awaitility.GeodeAwaitility.await; +import static org.apache.geode.test.dunit.VM.getVM; +import static org.apache.geode.test.dunit.VM.getVMId; +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.File; +import java.io.Serializable; +import java.util.HashMap; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; + +import org.apache.geode.cache.Cache; +import org.apache.geode.cache.CacheFactory; +import org.apache.geode.cache.Region; +import org.apache.geode.cache.query.QueryService; +import org.apache.geode.cache.query.data.Portfolio; +import org.apache.geode.distributed.LocatorLauncher; +import org.apache.geode.distributed.ServerLauncher; +import org.apache.geode.distributed.internal.InternalLocator; +import org.apache.geode.test.dunit.VM; +import org.apache.geode.test.dunit.rules.DistributedRule; +import org.apache.geode.test.junit.rules.GfshCommandRule; +import org.apache.geode.test.junit.rules.serializable.SerializableTemporaryFolder; + +@SuppressWarnings("ALL") +public class QueryWithRangeIndexDUnitTest implements Serializable { + + @Rule + public transient GfshCommandRule gfsh = new GfshCommandRule(); + + @Rule + public DistributedRule distributedRule = new DistributedRule(); + + @Rule + public SerializableTemporaryFolder temporaryFolder = new SerializableTemporaryFolder(); + + private static final String locatorName = "locator"; + private static final String serverName = "server"; + + private File locatorDir; + private File serverDir; + + private int locatorPort; + private int locatorJmxPort; + private int serverPort; + + private String locators; + + private VM server; + + private static final String regionName = "exampleRegion"; + + @Before + public void setUp() throws Exception { + VM locator = getVM(0); + server = getVM(1); + + locatorDir = temporaryFolder.newFolder(locatorName); + serverDir = temporaryFolder.newFolder(serverName); + + int[] port = getRandomAvailableTCPPorts(3); + locatorPort = port[0]; + locatorJmxPort = port[1]; + serverPort = port[2]; + + locators = "localhost[" + locatorPort + "]"; + + locator.invoke(() -> startLocator(locatorDir, locatorPort, locatorJmxPort)); + + gfsh.connectAndVerify(locatorJmxPort, GfshCommandRule.PortType.jmxManager); + + server.invoke(() -> startServer(serverDir, serverPort, locators)); + } + + @Test + public void testQueryWithWildcardAndIndexOnAttributeFromHashMap() { + gfsh.executeAndAssertThat("create region --name=" + regionName + " --type=PARTITION") + .statusIsSuccess(); + + server.invoke(() -> { + Cache cache = CacheFactory.getAnyInstance(); + QueryService cacheQS = cache.getQueryService(); + cacheQS.createIndex("IdIndex", "value.positions['SUN']", + SEPARATOR + regionName + ".entrySet"); + Region<Integer, Portfolio> region = + cache.getRegion(regionName); + + for (int i = 1; i < 10001; i++) { + Portfolio p1 = new Portfolio(i, i); + p1.positions = new HashMap<>(); + p1.positions.put("IBM", "something"); + if (i == 1) { + p1.positions.put("SUN", "something"); + } else { + p1.positions.put("SUN", "some"); + } + region.put(i, p1); + } + }); + + String query = "query --query=\"<trace> select e.key, e.value from " + + SEPARATOR + regionName + ".entrySet e where e.value.positions['SUN'] like 'somethin%'\""; + + String cmdResult = String.valueOf(gfsh.executeAndAssertThat(query).getResultModel()); + assertThat(cmdResult).contains("\"Rows\":\"1\""); + assertThat(cmdResult).contains("indexesUsed(1):IdIndex(Results: 10000)"); + } + + @Test + public void testLimitIsAppliedOnlyOnQueryResults() { + gfsh.executeAndAssertThat("create region --name=" + regionName + " --type=PARTITION") + .statusIsSuccess(); + + server.invoke(() -> { + Cache cache = CacheFactory.getAnyInstance(); + QueryService cacheQS = cache.getQueryService(); + cacheQS.createIndex("IdIndex", "value.positions['SUN']", + SEPARATOR + regionName + ".entrySet"); + Region<Integer, Portfolio> region = + cache.getRegion(regionName); + + for (int i = 1; i < 10001; i++) { + Portfolio p1 = new Portfolio(i, i); + p1.positions = new HashMap<>(); + p1.positions.put("IBM", "something"); + if (i % 2 == 0) { + p1.positions.put("SUN", "something"); + } else { + p1.positions.put("SUN", "some"); + } + region.put(i, p1); + } + }); + + String query = "query --query=\"<trace> select e.key, e.value from " + + SEPARATOR + regionName + + ".entrySet e where e.value.positions['SUN'] like 'somethin%' limit 5\""; + + String cmdResult = String.valueOf(gfsh.executeAndAssertThat(query).getResultModel()); + assertThat(cmdResult).contains("\"Rows\":\"5\""); + assertThat(cmdResult).contains("indexesUsed(1):IdIndex(Results: 10000)"); + } + + private static void startLocator(File workingDirectory, int locatorPort, + int jmxPort) { + LocatorLauncher locatorLauncher = new LocatorLauncher.Builder() + .setMemberName(locatorName) + .setPort(locatorPort) + .setWorkingDirectory(workingDirectory.getAbsolutePath()) + .set(JMX_MANAGER, "true") + .set(JMX_MANAGER_PORT, String.valueOf(jmxPort)) + .set(JMX_MANAGER_START, "true") + .build(); + + locatorLauncher.start(); + + await().untilAsserted(() -> { + InternalLocator locator = (InternalLocator) locatorLauncher.getLocator(); + assertThat(locator.isSharedConfigurationRunning()) + .as("Locator shared configuration is running on locator" + getVMId()) + .isTrue(); + }); + } + + private static void startServer(File workingDirectory, int serverPort, + String locators) { + System.setProperty(GEMFIRE_PREFIX + "Query.INDEX_THRESHOLD_SIZE", "10000"); + ServerLauncher serverLauncher = new ServerLauncher.Builder() + .setDeletePidFileOnStop(Boolean.TRUE) + .setMemberName(serverName) + .setServerPort(serverPort) + .setWorkingDirectory(workingDirectory.getAbsolutePath()) + .set(HTTP_SERVICE_PORT, "0") + .set(LOCATORS, locators) + .build(); + + serverLauncher.start(); + } +}