/*
* 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.junit.Assert.*;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import java.util.Properties;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.apache.geode.LogWriter;
import org.apache.geode.cache.Cache;
import org.apache.geode.cache.CacheExistsException;
import org.apache.geode.cache.CacheFactory;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.query.Index;
import org.apache.geode.cache.query.Query;
import org.apache.geode.cache.query.QueryService;
import org.apache.geode.cache.query.SelectResults;
import org.apache.geode.cache.query.data.Portfolio;
import org.apache.geode.cache.query.functional.StructSetOrResultsSet;
import org.apache.geode.cache.query.internal.QueryObserverAdapter;
import org.apache.geode.cache.query.internal.QueryObserverHolder;
import org.apache.geode.cache.query.internal.index.IndexManager;
import org.apache.geode.cache.query.internal.index.PartitionedIndex;
import org.apache.geode.cache30.CacheSerializableRunnable;
import org.apache.geode.distributed.internal.DistributionConfig;
import org.apache.geode.distributed.internal.InternalDistributedSystem;
import org.apache.geode.internal.FileUtil;
import org.apache.geode.internal.cache.GemFireCacheImpl;
import org.apache.geode.internal.cache.LocalRegion;
import org.apache.geode.internal.cache.PartitionedRegion;
import org.apache.geode.test.dunit.Assert;
import org.apache.geode.test.dunit.AsyncInvocation;
import org.apache.geode.test.dunit.DistributedTestUtils;
import org.apache.geode.test.dunit.Host;
import org.apache.geode.test.dunit.IgnoredException;
import org.apache.geode.test.dunit.Invoke;
import org.apache.geode.test.dunit.SerializableRunnable;
import org.apache.geode.test.dunit.ThreadUtils;
import org.apache.geode.test.dunit.VM;
import org.apache.geode.test.dunit.Wait;
import org.apache.geode.test.dunit.WaitCriterion;
import org.apache.geode.test.dunit.cache.internal.JUnit4CacheTestCase;
import org.apache.geode.test.junit.categories.DistributedTest;
import org.apache.geode.util.test.TestUtil;
@Category(DistributedTest.class)
public class QueryIndexUsingXMLDUnitTest extends JUnit4CacheTestCase {
static private final String WAIT_PROPERTY = "QueryIndexBuckets.maxWaitTime";
static private final int WAIT_DEFAULT = (60 * 1000);
public static final long MAX_TIME = Integer.getInteger(WAIT_PROPERTY, WAIT_DEFAULT).intValue();
final String name = "PartionedPortfolios";
final String repRegName = "Portfolios";
final String persistentRegName = "PersistentPrPortfolios";
final String nameWithRange = "PartitionedPortfoliosWithRange";
final String nameWithHash = "PartionedPortfoliosWithHash";
final String repRegNameWithRange = "PortfoliosWithRange";
final String repRegNameWithHash = "PortfoliosWithHash";
final String persistentRegNameWithRange = "PersistentPrPortfoliosWithRange";
final String persistentRegNameWithHash = "PersistentPrPortfoliosWithHash";
final String noIndexRepReg = "PortfoliosNoIndex";
final String statusIndex = "statusIndex";
final String idIndex = "idIndex";
String queryStr[][] = new String[][] {
{"Select * from /" + name + " where ID > 10",
"Select * from /" + repRegName + " where ID > 10",
"Select * from /" + persistentRegName + " where ID > 10",},
{"Select * from /" + name + " where ID = 5", "Select * from /" + repRegName + " where ID = 5",
"Select * from /" + persistentRegName + " where ID = 5",
"Select * from /" + nameWithHash + " where ID = 5",
"Select * from /" + repRegNameWithHash + " where ID = 5",
"Select * from /" + persistentRegNameWithHash + " where ID = 5"},
{"Select * from /" + name + " where status = 'active'",
"Select * from /" + repRegName + " where status = 'active'",
"Select * from /" + persistentRegName + " where status = 'active'",
"Select * from /" + nameWithHash + " where status = 'active'",
"Select * from /" + repRegNameWithHash + " where status = 'active'",
"Select * from /" + persistentRegNameWithHash + " where status = 'active'",},};
String queryStrNoIndex[] = new String[] {"Select * from /" + noIndexRepReg + " where ID > 10",
"Select * from /" + noIndexRepReg + " where ID = 5",
"Select * from /" + noIndexRepReg + " where status = 'active'",};
String queryStrValid = "Select * from /" + noIndexRepReg + " where ID > 10";
private String persistentOverFlowRegName = "PersistentOverflowPortfolios";
@Override
public final void postSetUp() throws Exception {
// Workaround for #52008
IgnoredException.addIgnoredException("Failed to create index");
}
@Override
public final void postTearDownCacheTestCase() throws Exception {
// avoid creating a new cache just to get the diskstore name
Invoke.invokeInEveryVM(resetTestHook());
disconnectFromDS();
FileUtil.delete(new File(GemFireCacheImpl.DEFAULT_DS_NAME).getAbsoluteFile());
}
/**
* Creates partitioned index from an xml description.
*/
@Test
public void testCreateIndexThroughXML() throws Exception {
Host host = Host.getHost(0);
VM vm0 = host.getVM(0);
VM vm1 = host.getVM(1);
final String fileName = "IndexCreation.xml";
org.apache.geode.test.dunit.LogWriterUtils.getLogWriter()
.info("Creating index using an xml file name : " + fileName);
AsyncInvocation asyInvk0 =
vm0.invokeAsync(createIndexThrougXML("vm0testCreateIndexThroughXML", name, fileName));
AsyncInvocation asyInvk1 =
vm1.invokeAsync(createIndexThrougXML("vm1testCreateIndexThroughXML", name, fileName));
ThreadUtils.join(asyInvk1, 30 * 1000);
if (asyInvk1.exceptionOccurred()) {
Assert.fail("asyInvk1 failed", asyInvk1.getException());
}
ThreadUtils.join(asyInvk0, 30 * 1000);
if (asyInvk0.exceptionOccurred()) {
Assert.fail("asyInvk0 failed", asyInvk0.getException());
}
// Check index for PR
vm0.invoke(prIndexCreationCheck(name, statusIndex, -1));
vm1.invoke(prIndexCreationCheck(name, statusIndex, -1));
vm0.invoke(prIndexCreationCheck(name, idIndex, -1));
vm1.invoke(prIndexCreationCheck(name, idIndex, -1));
vm0.invoke(prIndexCreationCheck(name, "secIndex", -1));
vm1.invoke(prIndexCreationCheck(name, "secIndex", -1));
// Check index for replicated
vm0.invoke(indexCreationCheck(repRegName, statusIndex));
vm1.invoke(indexCreationCheck(repRegName, statusIndex));
// Check index for persistent pr region
vm0.invoke(prIndexCreationCheck(persistentRegName, statusIndex, -1));
vm1.invoke(prIndexCreationCheck(persistentRegName, statusIndex, -1));
// check range index creation
vm0.invoke(prIndexCreationCheck(nameWithRange, statusIndex, -1));
vm1.invoke(prIndexCreationCheck(nameWithRange, statusIndex, -1));
vm0.invoke(prIndexCreationCheck(nameWithRange, idIndex, -1));
vm1.invoke(prIndexCreationCheck(nameWithRange, idIndex, -1));
vm0.invoke(indexCreationCheck(repRegNameWithRange, statusIndex));
vm1.invoke(indexCreationCheck(repRegNameWithRange, statusIndex));
vm0.invoke(prIndexCreationCheck(persistentRegNameWithRange, statusIndex, -1));
vm1.invoke(prIndexCreationCheck(persistentRegNameWithRange, statusIndex, -1));
// check hash index creation
vm0.invoke(prIndexCreationCheck(nameWithHash, statusIndex, -1));
vm1.invoke(prIndexCreationCheck(nameWithHash, statusIndex, -1));
vm0.invoke(prIndexCreationCheck(nameWithHash, idIndex, -1));
vm1.invoke(prIndexCreationCheck(nameWithHash, idIndex, -1));
vm0.invoke(indexCreationCheck(repRegNameWithHash, statusIndex));
vm1.invoke(indexCreationCheck(repRegNameWithHash, statusIndex));
vm0.invoke(prIndexCreationCheck(persistentRegNameWithHash, statusIndex, -1));
vm1.invoke(prIndexCreationCheck(persistentRegNameWithHash, statusIndex, -1));
vm0.invoke(close());
vm1.invoke(close());
}
/**
* Creates partitioned index from an xml description.
*/
@Test
public void testCreateIndexWhileDoingGII() throws Exception {
Host host = Host.getHost(0);
VM vm0 = host.getVM(0);
VM vm1 = host.getVM(1);
final String fileName = "IndexCreation.xml";
org.apache.geode.test.dunit.LogWriterUtils.getLogWriter()
.info("Creating index using an xml file name : " + fileName);
vm0.invoke(createIndexThrougXML("vm0testCreateIndexWhileDoingGII", name, fileName));
// LoadRegion
vm0.invoke(loadRegion(name));
vm0.invoke(loadRegion(nameWithHash));
vm0.invoke(loadRegion(nameWithRange));
vm0.invoke(prIndexCreationCheck(name, statusIndex, -1));
vm0.invoke(prIndexCreationCheck(nameWithHash, statusIndex, -1));
vm0.invoke(prIndexCreationCheck(nameWithRange, statusIndex, -1));
vm1.invoke(setTestHook());
vm1.invoke(createIndexThrougXML("vm1testCreateIndexWhileDoingGII", name, fileName));
vm0.invoke(prIndexCreationCheck(name, statusIndex, 50));
vm1.invoke(prIndexCreationCheck(name, statusIndex, 50));
vm0.invoke(prIndexCreationCheck(name, idIndex, 50));
vm1.invoke(prIndexCreationCheck(name, idIndex, 50));
vm0.invoke(prIndexCreationCheck(name, "secIndex", 50));
vm1.invoke(prIndexCreationCheck(name, "secIndex", 50));
// check range index creation
vm0.invoke(prIndexCreationCheck(nameWithRange, statusIndex, 50));
vm1.invoke(prIndexCreationCheck(nameWithRange, statusIndex, 50));
vm0.invoke(prIndexCreationCheck(nameWithRange, idIndex, 50));
vm1.invoke(prIndexCreationCheck(nameWithRange, idIndex, 50));
// check hash index creation
vm0.invoke(prIndexCreationCheck(nameWithHash, statusIndex, 50));
vm1.invoke(prIndexCreationCheck(nameWithHash, statusIndex, 50));
vm0.invoke(prIndexCreationCheck(nameWithHash, idIndex, 50));
vm1.invoke(prIndexCreationCheck(nameWithHash, idIndex, 50));
// Execute query and verify index usage
vm0.invoke(executeQuery(name));
vm1.invoke(executeQuery(name));
vm1.invoke(resetTestHook());
vm0.invoke(close());
vm1.invoke(close());
}
/**
* Creates partitioned index from an xml description.
*/
@Test
public void testReplicatedRegionCreateIndexWhileDoingGII() throws Exception {
Host host = Host.getHost(0);
VM vm0 = host.getVM(0);
VM vm1 = host.getVM(1);
final String fileName = "IndexCreation.xml";
org.apache.geode.test.dunit.LogWriterUtils.getLogWriter()
.info("Creating index using an xml file name : " + fileName);
vm0.invoke(
createIndexThrougXML("vm0testRRegionCreateIndexWhileDoingGII", repRegName, fileName));
// LoadRegion
vm0.invoke(loadRegion(repRegName));
vm0.invoke(loadRegion(repRegNameWithHash));
vm0.invoke(loadRegion(noIndexRepReg));
vm0.invoke(indexCreationCheck(repRegName, statusIndex));
vm0.invoke(indexCreationCheck(repRegNameWithHash, statusIndex));
vm1.invoke(setTestHook());
vm1.invoke(
createIndexThrougXML("vm1testRRegionCreateIndexWhileDoingGII", repRegName, fileName));
vm0.invoke(indexCreationCheck(repRegName, statusIndex));
vm1.invoke(indexCreationCheck(repRegName, statusIndex));
vm0.invoke(indexCreationCheck(repRegName, idIndex));
vm1.invoke(indexCreationCheck(repRegName, idIndex));
vm0.invoke(indexCreationCheck(repRegName, "secIndex"));
vm1.invoke(indexCreationCheck(repRegName, "secIndex"));
// check hash index creation
vm0.invoke(indexCreationCheck(repRegNameWithHash, statusIndex));
vm1.invoke(indexCreationCheck(repRegNameWithHash, statusIndex));
vm0.invoke(indexCreationCheck(repRegNameWithHash, idIndex));
vm1.invoke(indexCreationCheck(repRegNameWithHash, idIndex));
vm0.invoke(indexCreationCheck(repRegNameWithHash, "secIndex"));
vm1.invoke(indexCreationCheck(repRegNameWithHash, "secIndex"));
// Execute query and verify index usage
vm0.invoke(executeQuery(repRegName));
vm1.invoke(executeQuery(repRegName));
vm1.invoke(resetTestHook());
vm0.invoke(close());
vm1.invoke(close());
}
/**
* Creates persistent partitioned index from an xml description.
*/
@Test
public void testPersistentPRRegionCreateIndexWhileDoingGII() throws Exception {
Host host = Host.getHost(0);
VM vm0 = host.getVM(0);
VM vm1 = host.getVM(1);
final String fileName = "IndexCreation.xml";
org.apache.geode.test.dunit.LogWriterUtils.getLogWriter()
.info("Creating index using an xml file name : " + fileName);
vm0.invoke(createIndexThrougXML("vm0testPersistentPRRegion", persistentRegName, fileName));
// LoadRegion
vm0.invoke(loadRegion(this.persistentRegName));
vm0.invoke(loadRegion(noIndexRepReg));
vm0.invoke(loadRegion(persistentRegNameWithHash));
vm0.invoke(prIndexCreationCheck(persistentRegName, statusIndex, -1));
vm0.invoke(prIndexCreationCheck(persistentRegNameWithHash, statusIndex, -1));
vm1.invoke(setTestHook());
vm1.invoke(createIndexThrougXML("vm1testPersistentPRRegion", persistentRegName, fileName));
vm0.invoke(prIndexCreationCheck(persistentRegName, statusIndex, 50));
vm1.invoke(prIndexCreationCheck(persistentRegName, statusIndex, 50));
vm0.invoke(prIndexCreationCheck(persistentRegName, idIndex, 50));
vm1.invoke(prIndexCreationCheck(persistentRegName, idIndex, 50));
vm0.invoke(prIndexCreationCheck(persistentRegName, "secIndex", 50));
vm1.invoke(prIndexCreationCheck(persistentRegName, "secIndex", 50));
// check hash index creation
vm0.invoke(prIndexCreationCheck(persistentRegNameWithHash, statusIndex, 50));
vm1.invoke(prIndexCreationCheck(persistentRegNameWithHash, statusIndex, 50));
vm0.invoke(prIndexCreationCheck(persistentRegNameWithHash, idIndex, 50));
vm1.invoke(prIndexCreationCheck(persistentRegNameWithHash, idIndex, 50));
vm0.invoke(prIndexCreationCheck(persistentRegNameWithHash, "secIndex", 50));
vm1.invoke(prIndexCreationCheck(persistentRegNameWithHash, "secIndex", 50));
// Execute query and verify index usage
vm0.invoke(executeQuery(persistentRegName));
vm1.invoke(executeQuery(persistentRegName));
// close one vm cache
vm1.invoke(resetTestHook());
vm1.invoke(new SerializableRunnable() {
@Override
public void run() {
closeCache();
}
});
// restart
vm1.invoke(setTestHook());
vm1.invoke(createIndexThrougXML("vm1testPersistentPRRegion", persistentRegName, fileName));
vm1.invoke(prIndexCreationCheck(persistentRegName, statusIndex, 50));
vm1.invoke(resetTestHook());
vm0.invoke(close());
vm1.invoke(close());
}
/**
* Creates partitioned index from an xml description.
*/
@Test
public void testCreateIndexWhileDoingGIIWithEmptyPRRegion() throws Exception {
Host host = Host.getHost(0);
VM vm0 = host.getVM(0);
VM vm1 = host.getVM(1);
final String fileName = "IndexCreation.xml";
org.apache.geode.test.dunit.LogWriterUtils.getLogWriter()
.info("### in testCreateIndexWhileDoingGIIWithEmptyPRRegion.");
vm0.invoke(createIndexThrougXML("vm0testGIIWithEmptyPRRegion", name, fileName));
vm0.invoke(prIndexCreationCheck(name, statusIndex, -1));
vm0.invoke(prIndexCreationCheck(nameWithHash, statusIndex, -1));
vm1.invoke(setTestHook());
vm1.invoke(createIndexThrougXML("vm1testGIIWithEmptyPRRegion", name, fileName));
vm1.invoke(prIndexCreationCheck(name, statusIndex, -1));
vm1.invoke(prIndexCreationCheck(nameWithHash, statusIndex, -1));
// LoadRegion
vm0.invoke(loadRegion(name));
vm0.invoke(loadRegion(nameWithHash));
vm0.invoke(prIndexCreationCheck(name, statusIndex, 50));
vm1.invoke(prIndexCreationCheck(name, statusIndex, 50));
vm0.invoke(prIndexCreationCheck(nameWithHash, statusIndex, 50));
vm1.invoke(prIndexCreationCheck(nameWithHash, statusIndex, 50));
vm1.invoke(resetTestHook());
vm0.invoke(close());
vm1.invoke(close());
}
/**
* Creates partitioned index from an xml description.
*/
@Test
public void testCreateAsyncIndexWhileDoingGII() throws Exception {
Host host = Host.getHost(0);
VM vm0 = host.getVM(0);
VM vm1 = host.getVM(1);
final String fileName = "IndexCreation.xml";
org.apache.geode.test.dunit.LogWriterUtils.getLogWriter()
.info("Creating index using an xml file name : " + fileName);
AsyncInvocation asyInvk0 =
vm0.invokeAsync(createIndexThrougXML("vm0testAsyncIndexWhileDoingGII", name, fileName));
ThreadUtils.join(asyInvk0, 30 * 1000);
if (asyInvk0.exceptionOccurred()) {
Assert.fail("asyInvk0 failed", asyInvk0.getException());
}
// LoadRegion
asyInvk0 = vm0.invokeAsync(loadRegion(name));
vm1.invoke(setTestHook());
AsyncInvocation asyInvk1 =
vm1.invokeAsync(createIndexThrougXML("vm1testAsyncIndexWhileDoingGII", name, fileName));
vm0.invoke(prIndexCreationCheck(name, statusIndex, 50));
ThreadUtils.join(asyInvk1, 30 * 1000);
if (asyInvk1.exceptionOccurred()) {
Assert.fail("asyInvk1 failed", asyInvk1.getException());
}
vm1.invoke(prIndexCreationCheck(name, statusIndex, 50));
ThreadUtils.join(asyInvk0, 30 * 1000);
if (asyInvk0.exceptionOccurred()) {
Assert.fail("asyInvk0 failed", asyInvk0.getException());
}
vm1.invoke(resetTestHook());
vm0.invoke(close());
vm1.invoke(close());
}
/**
* Creates indexes and compares the results between index and non-index results.
*/
@Test
public void testCreateIndexWhileDoingGIIAndCompareQueryResults() throws Exception {
Host host = Host.getHost(0);
VM vm0 = host.getVM(0);
VM vm1 = host.getVM(1);
final String fileName = "IndexCreation.xml";
org.apache.geode.test.dunit.LogWriterUtils.getLogWriter()
.info("Creating index using an xml file name : " + fileName);
vm0.invoke(createIndexThrougXML("vm0testIndexCompareQResults", name, fileName));
// LoadRegion
vm0.invoke(loadRegion(name));
vm0.invoke(loadRegion(repRegName));
vm0.invoke(loadRegion(persistentRegName));
vm0.invoke(loadRegion(noIndexRepReg));
vm0.invoke(loadRegion(nameWithHash));
vm0.invoke(loadRegion(repRegNameWithHash));
vm0.invoke(loadRegion(persistentRegNameWithHash));
vm0.invoke(prIndexCreationCheck(name, statusIndex, -1));
vm1.invoke(setTestHook());
vm1.invoke(createIndexThrougXML("vm1testIndexCompareQResults", name, fileName));
vm0.invoke(prIndexCreationCheck(name, statusIndex, 50));
vm1.invoke(prIndexCreationCheck(name, statusIndex, 50));
vm0.invoke(prIndexCreationCheck(name, idIndex, 50));
vm1.invoke(prIndexCreationCheck(name, idIndex, 50));
vm0.invoke(prIndexCreationCheck(name, "secIndex", 50));
vm1.invoke(prIndexCreationCheck(name, "secIndex", 50));
vm0.invoke(prIndexCreationCheck(nameWithHash, statusIndex, 50));
vm1.invoke(prIndexCreationCheck(nameWithHash, statusIndex, 50));
vm0.invoke(prIndexCreationCheck(nameWithHash, idIndex, 50));
vm1.invoke(prIndexCreationCheck(nameWithHash, idIndex, 50));
vm0.invoke(prIndexCreationCheck(nameWithHash, "secIndex", 50));
vm1.invoke(prIndexCreationCheck(nameWithHash, "secIndex", 50));
vm0.invoke(prIndexCreationCheck(persistentRegName, "secIndex", 50));
vm0.invoke(indexCreationCheck(repRegName, "secIndex"));
vm0.invoke(prIndexCreationCheck(persistentRegNameWithHash, "secIndex", 50));
vm0.invoke(indexCreationCheck(repRegNameWithHash, "secIndex"));
vm1.invoke(prIndexCreationCheck(persistentRegName, "secIndex", 50));
vm1.invoke(indexCreationCheck(repRegName, "secIndex"));
vm1.invoke(prIndexCreationCheck(persistentRegNameWithHash, "secIndex", 50));
vm1.invoke(indexCreationCheck(repRegNameWithHash, "secIndex"));
// Execute query and verify index usage
vm0.invoke(executeQueryAndCompareResult(name, true));
vm1.invoke(executeQueryAndCompareResult(name, true));
vm1.invoke(resetTestHook());
vm0.invoke(close());
vm1.invoke(close());
}
/**
* Creates async partitioned index from an xml description.
*/
@Test
public void testCreateAsyncIndexWhileDoingGIIAndQuery() throws Exception {
Host host = Host.getHost(0);
VM vm0 = host.getVM(0);
VM vm1 = host.getVM(1);
final String fileName = "IndexCreation.xml";
org.apache.geode.test.dunit.LogWriterUtils.getLogWriter()
.info("Creating index using an xml file name : " + fileName);
AsyncInvocation asyInvk0 =
vm0.invokeAsync(createIndexThrougXML("vm0testCreateAsyncIndexGIIAndQuery", name, fileName));
ThreadUtils.join(asyInvk0, 30 * 1000);
if (asyInvk0.exceptionOccurred()) {
Assert.fail("asyInvk0 failed", asyInvk0.getException());
}
// LoadRegion
asyInvk0 = vm0.invokeAsync(loadRegion(name));
vm1.invoke(setTestHook());
AsyncInvocation asyInvk1 =
vm1.invokeAsync(createIndexThrougXML("vm1testCreateAsyncIndexGIIAndQuery", name, fileName));
ThreadUtils.join(asyInvk1, 30 * 1000);
if (asyInvk1.exceptionOccurred()) {
Assert.fail("asyInvk1 failed", asyInvk1.getException());
}
ThreadUtils.join(asyInvk0, 30 * 1000);
if (asyInvk0.exceptionOccurred()) {
Assert.fail("asyInvk0 failed", asyInvk0.getException());
}
vm0.invoke(prIndexCreationCheck(name, statusIndex, 50));
vm1.invoke(prIndexCreationCheck(name, statusIndex, 50));
// Execute query and verify index usage
vm0.invoke(executeQuery(name));
vm1.invoke(executeQuery(name));
vm1.invoke(resetTestHook());
vm0.invoke(close());
vm1.invoke(close());
}
/**
* Creates asynch indexes and compares the results between index and non-index results.
* <p>
* DISABLED. This test is disabled due to a high rate of failure. See ticket #52167
*/
@Ignore("TODO: test is disabled because of #52167")
@Test
public void testCreateAsyncIndexWhileDoingGIIAndCompareQueryResults() throws Exception {
Host host = Host.getHost(0);
VM vm0 = host.getVM(0);
VM vm1 = host.getVM(1);
final String fileName = "IndexCreation.xml";
org.apache.geode.test.dunit.LogWriterUtils.getLogWriter()
.info("Creating index using an xml file name : " + fileName);
vm0.invoke(createIndexThrougXML("vm0testAsyncIndexAndCompareQResults", name, fileName));
// LoadRegion
vm0.invoke(loadRegion(name));
vm0.invoke(loadRegion(repRegName));
vm0.invoke(loadRegion(persistentRegName));
vm0.invoke(loadRegion(noIndexRepReg));
// Start async update
vm0.invokeAsync(loadRegion(name, 500));
vm0.invokeAsync(loadRegion(repRegName, 500));
AsyncInvocation asyInvk0 = vm0.invokeAsync(loadRegion(persistentRegName, 500));
vm0.invokeAsync(loadRegion(noIndexRepReg, 500));
vm1.invoke(setTestHook());
vm1.invoke(createIndexThrougXML("vm1testAsyncIndexAndCompareQResults", name, fileName));
ThreadUtils.join(asyInvk0, 30 * 1000);
if (asyInvk0.exceptionOccurred()) {
Assert.fail("asyInvk0 failed", asyInvk0.getException());
}
vm1.invoke(prIndexCreationCheck(persistentRegName, "secIndex", 50));
vm1.invoke(indexCreationCheck(repRegName, "secIndex"));
// Execute query and verify index usage
vm0.invoke(executeQueryAndCompareResult(name, false));
vm1.invoke(executeQueryAndCompareResult(name, false));
vm1.invoke(resetTestHook());
vm0.invoke(close());
vm1.invoke(close());
}
@Test
public void testIndexCreationForReplicatedPersistentOverFlowRegionOnRestart() throws Exception {
Host host = Host.getHost(0);
VM vm0 = host.getVM(0);
VM vm1 = host.getVM(1);
final String fileName = "IndexCreation.xml";
org.apache.geode.test.dunit.LogWriterUtils.getLogWriter()
.info("Creating index using an xml file name : " + fileName);
// create index using xml
vm0.invoke(
createIndexThrougXML("vm0testIndexCreationForReplicatedPersistentOverFlowRegionOnRestart",
persistentOverFlowRegName, fileName));
// verify index creation
vm0.invoke(indexCreationCheck(persistentOverFlowRegName, statusIndex));
// LoadRegion
vm0.invoke(loadRegion(persistentOverFlowRegName));
// close cache without deleting diskstore
vm0.invoke(closeWithoutDeletingDiskStore());
// start cache by recovering data from diskstore
vm0.invoke(
createIndexThrougXML("vm0testIndexCreationForReplicatedPersistentOverFlowRegionOnRestart",
persistentOverFlowRegName, fileName));
// verify index creation on restart
vm0.invoke(indexCreationCheck(persistentOverFlowRegName, statusIndex));
// close cache and delete diskstore
vm0.invoke(close());
}
public CacheSerializableRunnable setTestHook() {
SerializableRunnable sr = new CacheSerializableRunnable("TestHook") {
public void run2() {
class IndexTestHook implements IndexManager.TestHook {
public boolean indexCreatedAsPartOfGII;
public void hook(int spot) throws RuntimeException {
GemFireCacheImpl.getInstance().getLogger()
.fine("In IndexTestHook.hook(). hook() argument value is : " + spot);
if (spot == 1) {
throw new RuntimeException("Index is not created as part of Region GII.");
}
}
};
IndexManager.testHook = new IndexTestHook();
}
};
return (CacheSerializableRunnable) sr;
}
public CacheSerializableRunnable resetTestHook() {
SerializableRunnable sr = new CacheSerializableRunnable("TestHook") {
public void run2() {
IndexManager.testHook = null;
}
};
return (CacheSerializableRunnable) sr;
}
public CacheSerializableRunnable createIndexThrougXML(final String vmid, final String regionName,
final String xmlFileName) {
SerializableRunnable sr = new CacheSerializableRunnable("RegionCreator") {
public void run2() {
try {
// closeCache();
File file = findFile(xmlFileName);
GemFireCacheImpl.testCacheXml = file;
// DistributedTestCase.diskStore = vmid;
getSystem();
Cache cache = getCache();
Region region = cache.getRegion(regionName);
if (region == null) {
fail("Region not found." + regionName);
}
} finally {
GemFireCacheImpl.testCacheXml = null;
// DistributedTestCase.diskStore = null;
}
}
};
return (CacheSerializableRunnable) sr;
}
public CacheSerializableRunnable prIndexCreationCheck(final String regionName,
final String indexName, final int bucketCount) {
CacheSerializableRunnable sr = new CacheSerializableRunnable(
"pr IndexCreationCheck" + regionName + " indexName :" + indexName) {
public void run2() {
// closeCache();
Cache cache = getCache();
LogWriter logger = cache.getLogger();
PartitionedRegion region = (PartitionedRegion) cache.getRegion(regionName);
Map indexMap = region.getIndex();
PartitionedIndex index = (PartitionedIndex) region.getIndex().get(indexName);
if (index == null) {
fail("Index " + indexName + " Not Found for region " + regionName);
}
logger.info("Current number of buckets indexed : " + ""
+ ((PartitionedIndex) index).getNumberOfIndexedBuckets());
if (bucketCount >= 0) {
waitForIndexedBuckets((PartitionedIndex) index, bucketCount);
}
if (!index.isPopulated()) {
fail("Index isPopulatedFlag is not set to true");
}
}
};
return sr;
}
public CacheSerializableRunnable indexCreationCheck(final String regionName,
final String indexName) {
CacheSerializableRunnable sr = new CacheSerializableRunnable(
"IndexCreationCheck region: " + regionName + " indexName :" + indexName) {
public void run2() {
// closeCache();
Cache cache = getCache();
LogWriter logger = cache.getLogger();
LocalRegion region = (LocalRegion) cache.getRegion(regionName);
Index index = region.getIndexManager().getIndex(indexName);
if (index == null) {
fail("Index " + indexName + " Not Found for region name:" + regionName);
}
}
};
return sr;
}
public boolean waitForIndexedBuckets(final PartitionedIndex index, final int bucketCount) {
WaitCriterion ev = new WaitCriterion() {
public boolean done() {
return (index.getNumberOfIndexedBuckets() >= bucketCount);
}
public String description() {
return "Number of Indexed Bucket is less than the expected number. " + bucketCount + ", "
+ index.getNumberOfIndexedBuckets();
}
};
Wait.waitForCriterion(ev, MAX_TIME, 200, true);
return true;
}
public CacheSerializableRunnable loadRegion(final String name) {
CacheSerializableRunnable sr = new CacheSerializableRunnable("load region on " + name) {
public void run2() {
Cache cache = getCache();
LogWriter logger = cache.getLogger();
Region region = cache.getRegion(name);
for (int i = 0; i < 100; i++) {
region.put("" + i, new Portfolio(i));
}
}
};
return sr;
}
public CacheSerializableRunnable loadRegion(final String name, final int size) {
CacheSerializableRunnable sr =
new CacheSerializableRunnable("LoadRegion: " + name + " size :" + size) {
public void run2() {
Cache cache = getCache();
LogWriter logger = cache.getLogger();
Region region = cache.getRegion(name);
for (int i = 0; i < size; i++) {
region.put("" + i, new Portfolio(i));
}
}
};
return sr;
}
public CacheSerializableRunnable executeQuery(final String rname) {
CacheSerializableRunnable sr = new CacheSerializableRunnable("execute query on " + rname) {
public void run2() {
QueryService qs = getCache().getQueryService();
QueryObserverImpl observer = new QueryObserverImpl();
QueryObserverHolder.setInstance(observer);
String queryStr = "Select * from /" + rname + " where ID > 10";
Query query = qs.newQuery(queryStr);
try {
query.execute();
} catch (Exception ex) {
fail("Failed to execute the query.");
}
if (!observer.isIndexesUsed) {
fail("Index not used for query. " + queryStr);
}
}
};
return sr;
}
public CacheSerializableRunnable executeQueryAndCompareResult(final String rname,
final boolean compareHash) {
CacheSerializableRunnable sr =
new CacheSerializableRunnable("execute query and compare results.") {
public void run2() {
QueryService qs = getCache().getQueryService();
StructSetOrResultsSet ssORrs = new StructSetOrResultsSet();
SelectResults[][] sr = new SelectResults[1][2];
String s[] = new String[2];
for (int j = 0; j < queryStr.length; j++) {
String[] queryArray = queryStr[j];
int numQueriesToCheck = compareHash ? queryArray.length : 3;
for (int i = 0; i < numQueriesToCheck; i++) {
QueryObserverImpl observer = new QueryObserverImpl();
QueryObserverHolder.setInstance(observer);
// Query using index.
s[0] = queryStr[j][i];
// Execute query with index.
Query query = qs.newQuery(s[0]);
try {
sr[0][0] = (SelectResults) query.execute();
} catch (Exception ex) {
fail("Failed to execute the query.");
}
if (!observer.isIndexesUsed) {
fail("Index not used for query. " + s[0]);
}
// Query using no index.
s[1] = queryStrNoIndex[j];
try {
query = qs.newQuery(s[1]);
sr[0][1] = (SelectResults) query.execute();
} catch (Exception ex) {
fail("Failed to execute the query on no index region.");
}
// compare.
org.apache.geode.test.dunit.LogWriterUtils.getLogWriter()
.info("Execute query : \n queryStr with index: " + s[0]
+ " \n queryStr without index: " + s[1]);
ssORrs.CompareQueryResultsWithoutAndWithIndexes(sr, 1, s);
}
}
}
};
return sr;
}
public CacheSerializableRunnable closeWithoutDeletingDiskStore() {
CacheSerializableRunnable sr = new CacheSerializableRunnable("close") {
public void run2() {
IndexManager.testHook = null;
// close the cache.
closeCache();
disconnectFromDS();
}
};
return sr;
}
public CacheSerializableRunnable close() {
CacheSerializableRunnable sr = new CacheSerializableRunnable("close") {
public void run2() {
IndexManager.testHook = null;
// Get the disk store name.
GemFireCacheImpl cache = (GemFireCacheImpl) getCache();
String diskStoreName = cache.getDefaultDiskStoreName();
// close the cache.
closeCache();
disconnectFromDS();
// remove the disk store.
File diskDir = new File(diskStoreName).getAbsoluteFile();
try {
org.apache.geode.internal.FileUtil.delete(diskDir);
} catch (Exception ex) {
fail("Failed to delete the disDir");
}
}
};
return sr;
}
protected File findFile(String fileName) {
String path = TestUtil.getResourcePath(getClass(), fileName);
return new File(path);
}
public final InternalDistributedSystem getSystem(String diskStoreId) {
new Exception("TEST DEBUG###" + diskStoreId).printStackTrace();
if (basicGetSystem() == null || !basicGetSystem().isConnected()) {
// Figure out our distributed system properties
Properties p =
DistributedTestUtils.getAllDistributedSystemProperties(getDistributedSystemProperties());
getSystem(p);
}
return basicGetSystem();
}
private Cache getCache(InternalDistributedSystem system) {
Cache cache = basicGetCache();
if (cache == null) {
try {
System.setProperty(
DistributionConfig.GEMFIRE_PREFIX + "DISABLE_DISCONNECT_DS_ON_CACHE_CLOSE", "true");
cache = CacheFactory.create(system);
} catch (CacheExistsException e) {
Assert.fail("the cache already exists", e);
} catch (RuntimeException ex) {
throw ex;
} catch (Exception ex) {
Assert.fail("Checked exception while initializing cache??", ex);
} finally {
System.clearProperty(
DistributionConfig.GEMFIRE_PREFIX + "DISABLE_DISCONNECT_DS_ON_CACHE_CLOSE");
}
}
return cache;
}
public static class QueryObserverImpl extends QueryObserverAdapter {
boolean isIndexesUsed = false;
ArrayList indexesUsed = new ArrayList();
@Override
public void beforeIndexLookup(Index index, int oper, Object key) {
indexesUsed.add(index.getName());
}
@Override
public void afterIndexLookup(Collection results) {
if (results != null) {
isIndexesUsed = true;
}
}
}
}