/*
* 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.cq.dunit;
import org.junit.Ignore;
import org.junit.experimental.categories.Category;
import org.junit.Test;
import static org.junit.Assert.*;
import org.apache.geode.test.dunit.cache.internal.JUnit4CacheTestCase;
import org.apache.geode.test.dunit.internal.JUnit4DistributedTestCase;
import org.apache.geode.test.junit.categories.DistributedTest;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.junit.experimental.categories.Category;
import org.apache.geode.cache.CacheException;
import org.apache.geode.cache.query.CqAttributes;
import org.apache.geode.cache.query.CqAttributesFactory;
import org.apache.geode.cache.query.CqListener;
import org.apache.geode.cache.query.CqQuery;
import org.apache.geode.cache.query.QueryService;
import org.apache.geode.cache.query.internal.DefaultQueryService;
import org.apache.geode.cache.query.internal.cq.ServerCQImpl;
import org.apache.geode.cache.query.internal.cq.CqService;
import org.apache.geode.cache.query.internal.cq.CqServiceImpl;
import org.apache.geode.cache.query.internal.cq.InternalCqQuery;
import org.apache.geode.cache30.CacheSerializableRunnable;
import org.apache.geode.cache30.CacheTestCase;
import org.apache.geode.internal.AvailablePortHelper;
import org.apache.geode.test.dunit.Assert;
import org.apache.geode.test.dunit.Host;
import org.apache.geode.test.dunit.Invoke;
import org.apache.geode.test.dunit.LogWriterUtils;
import org.apache.geode.test.dunit.NetworkUtils;
import org.apache.geode.test.dunit.SerializableRunnable;
import org.apache.geode.test.dunit.VM;
import org.apache.geode.test.dunit.Wait;
/**
* This class tests the ContiunousQuery mechanism in GemFire. This includes the test with diffetent
* data activities.
*/
@Category(DistributedTest.class)
public class CqPerfUsingPoolDUnitTest extends JUnit4CacheTestCase {
protected CqQueryUsingPoolDUnitTest cqDUnitTest = new CqQueryUsingPoolDUnitTest(); // TODO: get
// rid of this!
public CqPerfUsingPoolDUnitTest() {
super();
}
@Override
public final void postSetUp() throws Exception {
// avoid IllegalStateException from HandShake by connecting all vms tor
// system before creating connection pools
getSystem();
Invoke.invokeInEveryVM(new SerializableRunnable("getSystem") {
public void run() {
getSystem();
}
});
}
/**
* Tests the cq performance.
*
* @throws Exception
*/
@Ignore("perf")
@Test
public void testCQPerf() throws Exception {
final Host host = Host.getHost(0);
VM server = host.getVM(0);
VM client = host.getVM(1);
cqDUnitTest.createServer(server);
final int port = server.invoke(() -> CqQueryUsingPoolDUnitTest.getCacheServerPort());
final String host0 = NetworkUtils.getServerHostName(server.getHost());
// Create client.
cqDUnitTest.createClient(client, port, host0);
final String cqName = "testCQPerf_0";
client.invoke(new CacheSerializableRunnable("Create CQ :" + cqName) {
public void run2() throws CacheException {
LogWriterUtils.getLogWriter().info("### Create CQ. ###" + cqName);
// Get CQ Service.
QueryService cqService = null;
try {
cqService = getCache().getQueryService();
} catch (Exception cqe) {
cqe.printStackTrace();
fail("Failed to getCQService.");
}
// Create CQ Attributes.
CqAttributesFactory cqf = new CqAttributesFactory();
CqListener[] cqListeners = {new CqTimeTestListener(LogWriterUtils.getLogWriter())};
((CqTimeTestListener) cqListeners[0]).cqName = cqName;
cqf.initCqListeners(cqListeners);
CqAttributes cqa = cqf.create();
// Create and Execute CQ.
try {
CqQuery cq1 = cqService.newCq(cqName, cqDUnitTest.cqs[0], cqa);
assertTrue("newCq() state mismatch", cq1.getState().isStopped());
cq1.execute();
} catch (Exception ex) {
LogWriterUtils.getLogWriter().info("CqService is :" + cqService);
ex.printStackTrace();
AssertionError err = new AssertionError("Failed to create CQ " + cqName + " . ");
err.initCause(ex);
throw err;
}
}
});
final int size = 50;
// Create values.
cqDUnitTest.createValuesWithTime(client, cqDUnitTest.regions[0], size);
Wait.pause(5000);
// Update values
cqDUnitTest.createValuesWithTime(client, cqDUnitTest.regions[0], size);
client.invoke(new CacheSerializableRunnable("Validate CQs") {
public void run2() throws CacheException {
LogWriterUtils.getLogWriter().info("### Validating CQ. ### " + cqName);
// Get CQ Service.
QueryService cqService = null;
try {
cqService = getCache().getQueryService();
} catch (Exception cqe) {
cqe.printStackTrace();
fail("Failed to getCqService.");
}
CqQuery cQuery = cqService.getCq(cqName);
if (cQuery == null) {
fail("Failed to get CqQuery for CQ : " + cqName);
}
// CqAttributes cqAttr = cQuery.getCqAttributes();
// CqListener cqListeners[] = cqAttr.getCqListeners();
// CqTimeTestListener listener = (CqTimeTestListener) cqListeners[0];
// Wait for all the create to arrive.
// for (int i=1; i <= size; i++) {
// listener.waitForCreated(cqDUnitTest.KEY+i);
// }
// Wait for all the update to arrive.
// for (int i=1; i <= size; i++) {
// listener.waitForUpdated(cqDUnitTest.KEY+i);
// }
// getLogWriter().info("### Time taken for Creation of " + size + " events is :" +
// listener.getTotalQueryCreateTime());
// getLogWriter().info("### Time taken for Update of " + size + " events is :" +
// listener.getTotalQueryUpdateTime());
}
});
Wait.pause(10 * 60 * 1000);
// Close.
cqDUnitTest.closeClient(client);
cqDUnitTest.closeServer(server);
}
/**
* Test for maintaining keys for update optimization.
*
* @throws Exception
*/
@Test
public void testKeyMaintenance() throws Exception {
final Host host = Host.getHost(0);
VM server = host.getVM(0);
VM client = host.getVM(1);
cqDUnitTest.createServer(server);
final int port = server.invoke(() -> CqQueryUsingPoolDUnitTest.getCacheServerPort());
final String host0 = NetworkUtils.getServerHostName(server.getHost());
// cqDUnitTest.createClient(client, port, host0);
String poolName = "testKeyMaintainance";
cqDUnitTest.createPool(client, poolName, host0, port);
// HashSet for caching purpose will be created for cqs.
final int cqSize = 2;
// Cq1
cqDUnitTest.createCQ(client, poolName, "testKeyMaintainance_0", cqDUnitTest.cqs[0]);
cqDUnitTest.executeCQ(client, "testKeyMaintainance_0", false, null);
// Cq2
cqDUnitTest.createCQ(client, poolName, "testKeyMaintainance_1", cqDUnitTest.cqs[10]);
cqDUnitTest.executeCQ(client, "testKeyMaintainance_1", false, null);
cqDUnitTest.createValues(server, cqDUnitTest.regions[0], 1);
cqDUnitTest.waitForCreated(client, "testKeyMaintainance_0", CqQueryUsingPoolDUnitTest.KEY + 1);
// Entry is made into the CQs cache hashset.
// testKeyMaintainance_0 with 1 entry and testKeyMaintainance_1 with 0
server.invoke(new CacheSerializableRunnable("LookForCachedEventKeys1") {
public void run2() throws CacheException {
CqService cqService = null;
try {
cqService = ((DefaultQueryService) getCache().getQueryService()).getCqService();
} catch (Exception ex) {
LogWriterUtils.getLogWriter().info("Failed to get the internal CqService.", ex);
Assert.fail("Failed to get the internal CqService.", ex);
}
Collection<? extends InternalCqQuery> cqs = cqService.getAllCqs();
for (InternalCqQuery cq : cqs) {
ServerCQImpl cqQuery = (ServerCQImpl) cq;
String serverCqName = (String) cqQuery.getServerCqName();
if (serverCqName.startsWith("testKeyMaintainance_0")) {
assertEquals("The number of keys cached for cq testKeyMaintainance_0 is wrong.", 1,
cqQuery.getCqResultKeysSize());
} else if (serverCqName.startsWith("testKeyMaintainance_1")) {
assertEquals("The number of keys cached for cq testKeyMaintainance_1 is wrong.", 0,
cqQuery.getCqResultKeysSize());
}
}
}
});
// Update 1.
cqDUnitTest.createValues(server, cqDUnitTest.regions[0], 10);
cqDUnitTest.waitForCreated(client, "testKeyMaintainance_0", CqQueryDUnitTest.KEY + 10);
// Entry/check is made into the CQs cache hashset.
// testKeyMaintainance_0 with 1 entry and testKeyMaintainance_1 with 1
server.invoke(new CacheSerializableRunnable("LookForCachedEventKeysAfterUpdate1") {
public void run2() throws CacheException {
CqService cqService = null;
try {
cqService = ((DefaultQueryService) getCache().getQueryService()).getCqService();
} catch (Exception ex) {
LogWriterUtils.getLogWriter().info("Failed to get the internal CqService.", ex);
Assert.fail("Failed to get the internal CqService.", ex);
}
Collection<? extends InternalCqQuery> cqs = cqService.getAllCqs();
for (InternalCqQuery cq : cqs) {
ServerCQImpl cqQuery = (ServerCQImpl) cq;
String serverCqName = (String) cqQuery.getServerCqName();
if (serverCqName.startsWith("testKeyMaintainance_0")) {
assertEquals("The number of keys cached for cq testKeyMaintainance_0 is wrong.", 10,
cqQuery.getCqResultKeysSize());
} else if (serverCqName.startsWith("testKeyMaintainance_1")) {
assertEquals("The number of keys cached for cq testKeyMaintainance_1 is wrong.", 5,
cqQuery.getCqResultKeysSize());
}
}
}
});
// Update.
cqDUnitTest.createValues(server, cqDUnitTest.regions[0], 12);
cqDUnitTest.waitForCreated(client, "testKeyMaintainance_0", CqQueryDUnitTest.KEY + 12);
// Entry/check is made into the CQs cache hashset.
// testKeyMaintainance_0 with 1 entry and testKeyMaintainance_1 with 1
server.invoke(new CacheSerializableRunnable("LookForCachedEventKeysAfterUpdate2") {
public void run2() throws CacheException {
CqService cqService = null;
try {
cqService = ((DefaultQueryService) getCache().getQueryService()).getCqService();
} catch (Exception ex) {
LogWriterUtils.getLogWriter().info("Failed to get the internal CqService.", ex);
Assert.fail("Failed to get the internal CqService.", ex);
}
Collection<? extends InternalCqQuery> cqs = cqService.getAllCqs();
for (InternalCqQuery cq : cqs) {
ServerCQImpl cqQuery = (ServerCQImpl) cq;
String serverCqName = (String) cqQuery.getServerCqName();
if (serverCqName.startsWith("testKeyMaintainance_0")) {
assertEquals("The number of keys cached for cq testKeyMaintainance_0 is wrong.", 12,
cqQuery.getCqResultKeysSize());
} else if (serverCqName.startsWith("testKeyMaintainance_1")) {
assertEquals("The number of keys cached for cq testKeyMaintainance_1 is wrong.", 6,
cqQuery.getCqResultKeysSize());
}
}
}
});
// Delete.
cqDUnitTest.deleteValues(server, cqDUnitTest.regions[0], 6);
cqDUnitTest.waitForDestroyed(client, "testKeyMaintainance_0", CqQueryDUnitTest.KEY + 6);
// Entry/check is made into the CQs cache hashset.
// testKeyMaintainance_0 with 1 entry and testKeyMaintainance_1 with 1
server.invoke(new CacheSerializableRunnable("LookForCachedEventKeysAfterUpdate2") {
public void run2() throws CacheException {
CqService cqService = null;
try {
cqService = ((DefaultQueryService) getCache().getQueryService()).getCqService();
} catch (Exception ex) {
LogWriterUtils.getLogWriter().info("Failed to get the internal CqService.", ex);
Assert.fail("Failed to get the internal CqService.", ex);
}
Collection<? extends InternalCqQuery> cqs = cqService.getAllCqs();
for (InternalCqQuery cq : cqs) {
ServerCQImpl cqQuery = (ServerCQImpl) cq;
String serverCqName = (String) cqQuery.getServerCqName();
if (serverCqName.startsWith("testKeyMaintainance_0")) {
assertEquals("The number of keys cached for cq testKeyMaintainance_0 is wrong.", 6,
cqQuery.getCqResultKeysSize());
} else if (serverCqName.startsWith("testKeyMaintainance_1")) {
assertEquals("The number of keys cached for cq testKeyMaintainance_1 is wrong.", 3,
cqQuery.getCqResultKeysSize());
}
}
}
});
// This should still needs to process the events so that Results are uptodate.
cqDUnitTest.stopCQ(client, "testKeyMaintainance_1");
cqDUnitTest.createValues(server, cqDUnitTest.regions[0], 12);
server.invoke(new CacheSerializableRunnable("LookForCachedEventKeysAfterUpdate2") {
public void run2() throws CacheException {
CqService cqService = null;
try {
cqService = ((DefaultQueryService) getCache().getQueryService()).getCqService();
} catch (Exception ex) {
LogWriterUtils.getLogWriter().info("Failed to get the internal CqService.", ex);
Assert.fail("Failed to get the internal CqService.", ex);
}
Collection<? extends InternalCqQuery> cqs = cqService.getAllCqs();
for (InternalCqQuery cq : cqs) {
ServerCQImpl cqQuery = (ServerCQImpl) cq;
String serverCqName = (String) cqQuery.getServerCqName();
if (serverCqName.startsWith("testKeyMaintainance_0")) {
assertEquals("The number of keys cached for cq testKeyMaintainance_0 is wrong.", 12,
cqQuery.getCqResultKeysSize());
} else if (serverCqName.startsWith("testKeyMaintainance_1")) {
assertEquals("The number of keys cached for cq testKeyMaintainance_1 is wrong.", 6,
cqQuery.getCqResultKeysSize());
}
}
}
});
// This should re-start the caching for this CQ.
cqDUnitTest.executeCQ(client, "testKeyMaintainance_1", false, null);
// This will remove the caching for this CQ.
cqDUnitTest.closeCQ(client, "testKeyMaintainance_1");
server.invoke(new CacheSerializableRunnable("LookForCachedEventKeysAfterUpdate2") {
public void run2() throws CacheException {
CqService cqService = null;
try {
cqService = ((DefaultQueryService) getCache().getQueryService()).getCqService();
} catch (Exception ex) {
LogWriterUtils.getLogWriter().info("Failed to get the internal CqService.", ex);
Assert.fail("Failed to get the internal CqService.", ex);
}
Collection<? extends InternalCqQuery> cqs = cqService.getAllCqs();
for (InternalCqQuery cq : cqs) {
ServerCQImpl cqQuery = (ServerCQImpl) cq;
String serverCqName = (String) cqQuery.getServerCqName();
if (serverCqName.startsWith("testKeyMaintainance_0")) {
assertEquals("The number of keys cached for cq testKeyMaintainance_0 is wrong.", 12,
cqQuery.getCqResultKeysSize());
} else if (serverCqName.startsWith("testKeyMaintainance_1")) {
fail("The key maintainance should not be present for this CQ.");
}
}
}
});
// Close.
cqDUnitTest.closeClient(client);
cqDUnitTest.closeServer(server);
}
/**
* Test for common CQs. To test the changes relating to, executing CQ only once for all similar
* CQs.
*
* @throws Exception
*/
@Test
public void testMatchingCqs() throws Exception {
final Host host = Host.getHost(0);
VM server = host.getVM(0);
VM client = host.getVM(1);
cqDUnitTest.createServer(server);
final int port = server.invoke(() -> CqQueryUsingPoolDUnitTest.getCacheServerPort()); // TODO:
// move
// static
// methods
// from
// other
// dunit
// into
// util
// class
final String host0 = NetworkUtils.getServerHostName(server.getHost());
// cqDUnitTest.createClient(client, port, host0);
String poolName = "testMatchingCqs";
cqDUnitTest.createPool(client, poolName, host0, port);
// Create and Execute same kind of CQs.
for (int i = 0; i < 4; i++) {
cqDUnitTest.createCQ(client, poolName, "testMatchingCqs_" + i, cqDUnitTest.cqs[0]);
cqDUnitTest.executeCQ(client, "testMatchingCqs_" + i, false, null);
}
validateMatchingCqs(server, 1, cqDUnitTest.cqs[0], 4);
int size = 1;
// Create.
cqDUnitTest.createValues(server, cqDUnitTest.regions[0], size);
cqDUnitTest.waitForCreated(client, "testMatchingCqs_0", CqQueryUsingPoolDUnitTest.KEY + size);
// Close one of the CQ.
cqDUnitTest.closeCQ(client, "testMatchingCqs_0");
validateMatchingCqs(server, 1, cqDUnitTest.cqs[0], 3);
// Update.
cqDUnitTest.createValues(server, cqDUnitTest.regions[0], size);
cqDUnitTest.waitForUpdated(client, "testMatchingCqs_3", CqQueryUsingPoolDUnitTest.KEY + size);
cqDUnitTest.waitForUpdated(client, "testMatchingCqs_1", CqQueryUsingPoolDUnitTest.KEY + size);
// Stop one of the CQ.
cqDUnitTest.stopCQ(client, "testMatchingCqs_1");
validateMatchingCqs(server, 1, cqDUnitTest.cqs[0], 2);
// Update - 2.
cqDUnitTest.clearCQListenerEvents(client, "testMatchingCqs_3");
cqDUnitTest.createValues(server, cqDUnitTest.regions[0], size);
cqDUnitTest.waitForUpdated(client, "testMatchingCqs_3", CqQueryUsingPoolDUnitTest.KEY + size);
// stopped CQ should not receive 2nd/previous updates.
cqDUnitTest.validateCQ(client, "testMatchingCqs_1",
/* resultSize: */ CqQueryUsingPoolDUnitTest.noTest, /* creates: */ size,
/* updates: once */ size, /* deletes; */ 0, /* queryInserts: */ size,
/* queryUpdates: */ size, /* queryDeletes: */ 0, /* totalEvents: */ size * 2);
// Execute the stopped CQ.
cqDUnitTest.executeCQ(client, "testMatchingCqs_1", false, null);
// Update - 3.
cqDUnitTest.clearCQListenerEvents(client, "testMatchingCqs_3");
cqDUnitTest.createValues(server, cqDUnitTest.regions[0], size);
cqDUnitTest.waitForUpdated(client, "testMatchingCqs_3", CqQueryUsingPoolDUnitTest.KEY + size);
cqDUnitTest.validateCQ(client, "testMatchingCqs_1",
/* resultSize: */ CqQueryUsingPoolDUnitTest.noTest, /* creates: */ size,
/* updates: 2 */ size * 2, /* deletes; */ 0, /* queryInserts: */ size,
/* queryUpdates: */ size * 2, /* queryDeletes: */ 0, /* totalEvents: */ size * 3);
// Create different kind of CQs.
cqDUnitTest.createCQ(client, poolName, "testMatchingCqs_4", cqDUnitTest.cqs[1]);
cqDUnitTest.executeCQ(client, "testMatchingCqs_4", false, null);
cqDUnitTest.createCQ(client, poolName, "testMatchingCqs_5", cqDUnitTest.cqs[1]);
cqDUnitTest.executeCQ(client, "testMatchingCqs_5", false, null);
cqDUnitTest.createCQ(client, poolName, "testMatchingCqs_6", cqDUnitTest.cqs[2]);
cqDUnitTest.executeCQ(client, "testMatchingCqs_6", false, null);
validateMatchingCqs(server, 3, cqDUnitTest.cqs[1], 2);
cqDUnitTest.closeCQ(client, "testMatchingCqs_6");
validateMatchingCqs(server, 2, cqDUnitTest.cqs[1], 2);
cqDUnitTest.closeCQ(client, "testMatchingCqs_5");
cqDUnitTest.closeCQ(client, "testMatchingCqs_4");
cqDUnitTest.closeCQ(client, "testMatchingCqs_3");
cqDUnitTest.closeCQ(client, "testMatchingCqs_2");
cqDUnitTest.closeCQ(client, "testMatchingCqs_1");
validateMatchingCqs(server, 0, null, 0);
// update 4
cqDUnitTest.createValues(server, cqDUnitTest.regions[0], size);
// Close.
cqDUnitTest.closeClient(client);
cqDUnitTest.closeServer(server);
}
/**
* Test for common CQs. To test the changes relating to, executing CQ only once for all similar
* CQs.
*
* @throws Exception
*/
@Test
public void testMatchingCQWithMultipleClients() throws Exception {
final Host host = Host.getHost(0);
VM server = host.getVM(0);
VM client1 = host.getVM(1);
VM client2 = host.getVM(2);
VM client3 = host.getVM(3);
VM clients[] = new VM[] {client1, client2, client3};
cqDUnitTest.createServer(server);
final int port = server.invoke(() -> CqQueryUsingPoolDUnitTest.getCacheServerPort());
final String host0 = NetworkUtils.getServerHostName(server.getHost());
String poolName = "testMatchingCQWithMultipleClients";
for (int clientIndex = 0; clientIndex < 3; clientIndex++) {
String cPoolName = "testMatchingCQWithMultipleClients" + clientIndex;
cqDUnitTest.createPool(clients[clientIndex], cPoolName, host0, port);
// cqDUnitTest.createClient(clients[clientIndex], port, host0);
// Create and Execute same kind of CQs.
for (int i = 0; i < 4; i++) {
cqDUnitTest.createCQ(clients[clientIndex], cPoolName,
"testMatchingCQWithMultipleClients_" + i, cqDUnitTest.cqs[0]);
cqDUnitTest.executeCQ(clients[clientIndex], "testMatchingCQWithMultipleClients_" + i, false,
null);
}
}
validateMatchingCqs(server, 1, cqDUnitTest.cqs[0], clients.length * 4);
int size = 1;
// Create.
cqDUnitTest.createValues(server, cqDUnitTest.regions[0], size);
for (int clientIndex = 0; clientIndex < 3; clientIndex++) {
cqDUnitTest.waitForCreated(clients[clientIndex], "testMatchingCQWithMultipleClients_0",
CqQueryUsingPoolDUnitTest.KEY + size);
cqDUnitTest.waitForCreated(clients[clientIndex], "testMatchingCQWithMultipleClients_3",
CqQueryUsingPoolDUnitTest.KEY + size);
}
// Close one of the CQ.
cqDUnitTest.closeCQ(client1, "testMatchingCQWithMultipleClients_0");
validateMatchingCqs(server, 1, cqDUnitTest.cqs[0], (clients.length * 4) - 1);
// Update.
cqDUnitTest.createValues(server, cqDUnitTest.regions[0], size);
for (int clientIndex = 0; clientIndex < 3; clientIndex++) {
cqDUnitTest.waitForUpdated(clients[clientIndex], "testMatchingCQWithMultipleClients_3",
CqQueryUsingPoolDUnitTest.KEY + size);
}
// Stop one of the CQ.
cqDUnitTest.stopCQ(client2, "testMatchingCQWithMultipleClients_1");
validateMatchingCqs(server, 1, cqDUnitTest.cqs[0], (clients.length * 4) - 2);
// Update - 2.
for (int clientIndex = 0; clientIndex < 3; clientIndex++) {
cqDUnitTest.clearCQListenerEvents(clients[clientIndex],
"testMatchingCQWithMultipleClients_3");
}
cqDUnitTest.createValues(server, cqDUnitTest.regions[0], size);
for (int clientIndex = 0; clientIndex < 3; clientIndex++) {
cqDUnitTest.waitForUpdated(clients[clientIndex], "testMatchingCQWithMultipleClients_3",
CqQueryUsingPoolDUnitTest.KEY + size);
}
// stopped CQ should not receive 2nd/previous updates.
cqDUnitTest.validateCQ(client2, "testMatchingCQWithMultipleClients_1",
/* resultSize: */ CqQueryUsingPoolDUnitTest.noTest, /* creates: */ size,
/* updates: once */ size, /* deletes; */ 0, /* queryInserts: */ size,
/* queryUpdates: */ size, /* queryDeletes: */ 0, /* totalEvents: */ size * 2);
// Execute the stopped CQ.
cqDUnitTest.executeCQ(client2, "testMatchingCQWithMultipleClients_1", false, null);
// Update - 3.
for (int clientIndex = 0; clientIndex < 3; clientIndex++) {
cqDUnitTest.clearCQListenerEvents(clients[clientIndex],
"testMatchingCQWithMultipleClients_3");
}
validateMatchingCqs(server, 1, cqDUnitTest.cqs[0], (clients.length * 4) - 1);
cqDUnitTest.createValues(server, cqDUnitTest.regions[0], size);
for (int clientIndex = 0; clientIndex < 3; clientIndex++) {
cqDUnitTest.waitForUpdated(clients[clientIndex], "testMatchingCQWithMultipleClients_3",
CqQueryUsingPoolDUnitTest.KEY + size);
}
cqDUnitTest.validateCQ(client2, "testMatchingCQWithMultipleClients_1",
/* resultSize: */ CqQueryUsingPoolDUnitTest.noTest, /* creates: */ size,
/* updates: 2 */ size * 2, /* deletes; */ 0, /* queryInserts: */ size,
/* queryUpdates: */ size * 2, /* queryDeletes: */ 0, /* totalEvents: */ size * 3);
// Create different kind of CQs.
for (int clientIndex = 0; clientIndex < 3; clientIndex++) {
String cPoolName = poolName + clientIndex;
cqDUnitTest.createCQ(clients[clientIndex], cPoolName, "testMatchingCQWithMultipleClients_4",
cqDUnitTest.cqs[1]);
cqDUnitTest.executeCQ(clients[clientIndex], "testMatchingCQWithMultipleClients_4", false,
null);
cqDUnitTest.createCQ(clients[clientIndex], cPoolName, "testMatchingCQWithMultipleClients_5",
cqDUnitTest.cqs[1]);
cqDUnitTest.executeCQ(clients[clientIndex], "testMatchingCQWithMultipleClients_5", false,
null);
cqDUnitTest.createCQ(clients[clientIndex], cPoolName, "testMatchingCQWithMultipleClients_6",
cqDUnitTest.cqs[2]);
cqDUnitTest.executeCQ(clients[clientIndex], "testMatchingCQWithMultipleClients_6", false,
null);
}
validateMatchingCqs(server, 3, cqDUnitTest.cqs[1], 2 * clients.length);
for (int clientIndex = 0; clientIndex < 3; clientIndex++) {
cqDUnitTest.closeCQ(clients[clientIndex], "testMatchingCQWithMultipleClients_6");
}
validateMatchingCqs(server, 2, cqDUnitTest.cqs[1], 2 * clients.length);
// update 4
cqDUnitTest.createValues(server, cqDUnitTest.regions[0], size);
// Close.
cqDUnitTest.closeClient(client3);
validateMatchingCqs(server, 2, cqDUnitTest.cqs[1], 2 * (clients.length - 1));
for (int clientIndex = 0; clientIndex < 2; clientIndex++) {
cqDUnitTest.closeCQ(clients[clientIndex], "testMatchingCQWithMultipleClients_5");
cqDUnitTest.closeCQ(clients[clientIndex], "testMatchingCQWithMultipleClients_4");
cqDUnitTest.closeCQ(clients[clientIndex], "testMatchingCQWithMultipleClients_3");
cqDUnitTest.closeCQ(clients[clientIndex], "testMatchingCQWithMultipleClients_2");
cqDUnitTest.closeCQ(clients[clientIndex], "testMatchingCQWithMultipleClients_1");
if (clientIndex != 0) {
cqDUnitTest.closeCQ(clients[clientIndex], "testMatchingCQWithMultipleClients_0");
}
}
validateMatchingCqs(server, 0, null, 0);
cqDUnitTest.closeClient(client2);
cqDUnitTest.closeClient(client1);
cqDUnitTest.closeServer(server);
}
/**
* Test for CQ Fail over.
*
* @throws Exception
*/
@Test
public void testMatchingCQsWithMultipleServers() throws Exception {
final Host host = Host.getHost(0);
VM server1 = host.getVM(0);
VM server2 = host.getVM(1);
VM client1 = host.getVM(2);
VM client2 = host.getVM(3);
cqDUnitTest.createServer(server1);
VM clients[] = new VM[] {client1, client2};
final int port1 = server1.invoke(() -> CqQueryUsingPoolDUnitTest.getCacheServerPort());
final String host0 = NetworkUtils.getServerHostName(server1.getHost());
// Create client.
// Create client with redundancyLevel -1
final int[] ports = AvailablePortHelper.getRandomAvailableTCPPorts(1);
String poolName1 = "testClientWithFeederAndCQ1";
String poolName2 = "testClientWithFeederAndCQ2";
cqDUnitTest.createPool(client1, poolName1, new String[] {host0, host0},
new int[] {port1, ports[0]});
cqDUnitTest.createPool(client2, poolName2, new String[] {host0, host0},
new int[] {port1, ports[0]});
// cqDUnitTest.createClient(client1, new int[] {port1, ports[0]}, host0, "-1");
// cqDUnitTest.createClient(client2, new int[] {port1, ports[0]}, host0, "-1");
int numCQs = 3;
for (int i = 0; i < numCQs; i++) {
cqDUnitTest.createCQ(client1, poolName1, "testMatchingCQsWithMultipleServers_" + i,
cqDUnitTest.cqs[i]);
cqDUnitTest.executeCQ(client1, "testMatchingCQsWithMultipleServers_" + i, false, null);
cqDUnitTest.createCQ(client2, poolName2, "testMatchingCQsWithMultipleServers_" + i,
cqDUnitTest.cqs[i]);
cqDUnitTest.executeCQ(client2, "testMatchingCQsWithMultipleServers_" + i, false, null);
}
validateMatchingCqs(server1, numCQs, cqDUnitTest.cqs[0], 1 * clients.length);
validateMatchingCqs(server1, numCQs, cqDUnitTest.cqs[1], 1 * clients.length);
Wait.pause(1 * 1000);
// CREATE.
cqDUnitTest.createValues(server1, cqDUnitTest.regions[0], 10);
cqDUnitTest.createValues(server1, cqDUnitTest.regions[1], 10);
for (int i = 1; i <= 10; i++) {
cqDUnitTest.waitForCreated(client1, "testMatchingCQsWithMultipleServers_0",
CqQueryUsingPoolDUnitTest.KEY + i);
}
Wait.pause(1 * 1000);
cqDUnitTest.createServer(server2, ports[0]);
final int port2 = server2.invoke(() -> CqQueryUsingPoolDUnitTest.getCacheServerPort());
System.out
.println("### Port on which server1 running : " + port1 + " Server2 running : " + port2);
Wait.pause(3 * 1000);
// UPDATE - 1.
for (int k = 0; k < numCQs; k++) {
cqDUnitTest.clearCQListenerEvents(client1, "testMatchingCQsWithMultipleServers_" + k);
cqDUnitTest.clearCQListenerEvents(client2, "testMatchingCQsWithMultipleServers_" + k);
}
cqDUnitTest.createValues(server1, cqDUnitTest.regions[0], 10);
cqDUnitTest.createValues(server1, cqDUnitTest.regions[1], 10);
// Wait for updates on regions[0]
for (int i = 1; i <= 10; i++) {
cqDUnitTest.waitForUpdated(client1, "testMatchingCQsWithMultipleServers_0",
CqQueryDUnitTest.KEY + i);
cqDUnitTest.waitForUpdated(client2, "testMatchingCQsWithMultipleServers_0",
CqQueryDUnitTest.KEY + i);
}
// Wait for updates on regions[1] - Waiting for last key is good enough.
cqDUnitTest.waitForUpdated(client1, "testMatchingCQsWithMultipleServers_2",
CqQueryDUnitTest.KEY + 4);
cqDUnitTest.waitForUpdated(client2, "testMatchingCQsWithMultipleServers_2",
CqQueryDUnitTest.KEY + 4);
int[] resultsCnt = new int[] {10, 1, 2};
for (int i = 0; i < numCQs; i++) {
cqDUnitTest.validateCQ(client1, "testMatchingCQsWithMultipleServers_" + i,
CqQueryUsingPoolDUnitTest.noTest, resultsCnt[i], resultsCnt[i],
CqQueryUsingPoolDUnitTest.noTest);
cqDUnitTest.validateCQ(client2, "testMatchingCQsWithMultipleServers_" + i,
CqQueryUsingPoolDUnitTest.noTest, resultsCnt[i], resultsCnt[i],
CqQueryUsingPoolDUnitTest.noTest);
}
// Close server1.
cqDUnitTest.closeServer(server1);
// Fail over should happen.
Wait.pause(5 * 1000);
validateMatchingCqs(server2, numCQs, cqDUnitTest.cqs[0], 1 * clients.length);
for (int i = 0; i < numCQs; i++) {
cqDUnitTest.validateCQ(client1, "testMatchingCQsWithMultipleServers_" + i,
CqQueryUsingPoolDUnitTest.noTest, resultsCnt[i], resultsCnt[i],
CqQueryUsingPoolDUnitTest.noTest);
cqDUnitTest.validateCQ(client2, "testMatchingCQsWithMultipleServers_" + i,
CqQueryUsingPoolDUnitTest.noTest, resultsCnt[i], resultsCnt[i],
CqQueryUsingPoolDUnitTest.noTest);
}
// UPDATE - 2
for (int k = 0; k < numCQs; k++) {
cqDUnitTest.clearCQListenerEvents(client1, "testMatchingCQsWithMultipleServers_" + k);
cqDUnitTest.clearCQListenerEvents(client2, "testMatchingCQsWithMultipleServers_" + k);
}
cqDUnitTest.createValues(server2, cqDUnitTest.regions[0], 10);
cqDUnitTest.createValues(server2, cqDUnitTest.regions[1], 10);
// Wait for cq1. on region[0]
for (int i = 1; i <= resultsCnt[0]; i++) {
cqDUnitTest.waitForUpdated(client1, "testMatchingCQsWithMultipleServers_0",
CqQueryUsingPoolDUnitTest.KEY + i);
cqDUnitTest.waitForUpdated(client2, "testMatchingCQsWithMultipleServers_0",
CqQueryUsingPoolDUnitTest.KEY + i);
}
// Wait for cq3. on region[1]
{
cqDUnitTest.waitForUpdated(client1, "testMatchingCQsWithMultipleServers_2",
CqQueryUsingPoolDUnitTest.KEY + "4");
cqDUnitTest.waitForUpdated(client2, "testMatchingCQsWithMultipleServers_2",
CqQueryUsingPoolDUnitTest.KEY + "4");
}
for (int i = 0; i < numCQs; i++) {
cqDUnitTest.validateCQ(client1, "testMatchingCQsWithMultipleServers_" + i,
CqQueryUsingPoolDUnitTest.noTest, resultsCnt[i], resultsCnt[i] * 2,
CqQueryUsingPoolDUnitTest.noTest);
cqDUnitTest.validateCQ(client2, "testMatchingCQsWithMultipleServers_" + i,
CqQueryUsingPoolDUnitTest.noTest, resultsCnt[i], resultsCnt[i] * 2,
CqQueryUsingPoolDUnitTest.noTest);
}
// Close.
cqDUnitTest.closeClient(client1);
validateMatchingCqs(server2, numCQs, cqDUnitTest.cqs[0], 1 * (clients.length - 1));
cqDUnitTest.closeClient(client2);
cqDUnitTest.closeServer(server2);
}
/**
* Performance test for Matching CQ optimization changes.
*
* @throws Exception
*/
@Ignore("perf")
@Test
public void testPerformanceForMatchingCQs() throws Exception {
final Host host = Host.getHost(0);
VM server1 = host.getVM(0);
VM server2 = host.getVM(1);
VM client1 = host.getVM(2);
VM client2 = host.getVM(3);
cqDUnitTest.createServer(server1);
cqDUnitTest.createServer(server2);
// VM clients[] = new VM[]{client1, client2};
final int port1 = server1.invoke(() -> CqQueryUsingPoolDUnitTest.getCacheServerPort());
final int port2 = server2.invoke(() -> CqQueryUsingPoolDUnitTest.getCacheServerPort());
final String host0 = NetworkUtils.getServerHostName(server1.getHost());
// Create client.
// final int[] ports = AvailablePortHelper.getRandomAvailableTCPPorts(1);
// Client1 connects to server1.
cqDUnitTest.createClient(client1, new int[] {port1}, host0, "-1", null);
// Client2 connects to server2.
cqDUnitTest.createClient(client2, new int[] {port2}, host0, "-1", null);
// Client1 registers matching CQs on server1.
boolean uniqueQueries = false;
String[] matchingCqs = this.generateCqQueries(uniqueQueries);
for (int i = 0; i < matchingCqs.length; i++) {
cqDUnitTest.createCQ(client1, "testPerformanceForMatchingCQs_" + i, matchingCqs[i]);
cqDUnitTest.executeCQ(client1, "testPerformanceForMatchingCQs_" + i, false, null);
}
// Client2 registers non-matching CQs on server2.
uniqueQueries = true;
matchingCqs = this.generateCqQueries(uniqueQueries);
for (int i = 0; i < matchingCqs.length; i++) {
cqDUnitTest.createCQ(client2, "testPerformanceForMatchingCQs_" + i, matchingCqs[i]);
cqDUnitTest.executeCQ(client2, "testPerformanceForMatchingCQs_" + i, false, null);
}
Wait.pause(1 * 1000);
// CREATE.
int size = 1000;
cqDUnitTest.createValues(server1, cqDUnitTest.regions[0], size);
cqDUnitTest.createValues(server2, cqDUnitTest.regions[1], size);
// Update couple of times;
for (int j = 0; j < 5; j++) {
cqDUnitTest.createValues(server1, cqDUnitTest.regions[0], size - 1);
cqDUnitTest.createValues(server2, cqDUnitTest.regions[1], size - 1);
}
for (int j = 0; j < 4; j++) {
cqDUnitTest.createValues(server2, cqDUnitTest.regions[0], size - 1);
cqDUnitTest.createValues(server1, cqDUnitTest.regions[1], size - 1);
}
// Update the last key.
cqDUnitTest.createValues(server2, cqDUnitTest.regions[0], size);
cqDUnitTest.createValues(server1, cqDUnitTest.regions[1], size);
for (int k = 1; k <= size; k++) {
cqDUnitTest.waitForUpdated(client1, "testPerformanceForMatchingCQs_0",
CqQueryUsingPoolDUnitTest.KEY + k);
}
Wait.pause(1 * 1000);
printCqQueryExecutionTime(server1);
printCqQueryExecutionTime(server2);
// Close.
cqDUnitTest.closeClient(client1);
cqDUnitTest.closeClient(client2);
cqDUnitTest.closeServer(server2);
cqDUnitTest.closeServer(server1);
}
public void validateMatchingCqs(VM server, final int mapSize, final String query,
final int numCqSize) {
server.invoke(new CacheSerializableRunnable("validateMatchingCqs") {
public void run2() throws CacheException {
CqServiceImpl cqService = null;
try {
cqService =
(CqServiceImpl) ((DefaultQueryService) getCache().getQueryService()).getCqService();
} catch (Exception ex) {
LogWriterUtils.getLogWriter().info("Failed to get the internal CqService.", ex);
Assert.fail("Failed to get the internal CqService.", ex);
}
Map matchedCqMap = cqService.getMatchingCqMap();
assertEquals("The number of matched cq is not as expected.", mapSize, matchedCqMap.size());
if (query != null) {
if (!matchedCqMap.containsKey(query)) {
fail("Query not found in the matched cq map. Query:" + query);
}
Collection cqs = (Collection) matchedCqMap.get(query);
assertEquals("Number of matched cqs are not equal to the expected matched cqs", numCqSize,
cqs.size());
}
}
});
}
public void printCqQueryExecutionTime(VM server) {
server.invoke(new CacheSerializableRunnable("printCqQueryExecutionTime") {
public void run2() throws CacheException {
CqServiceImpl cqService = null;
try {
cqService =
(CqServiceImpl) ((DefaultQueryService) getCache().getQueryService()).getCqService();
} catch (Exception ex) {
LogWriterUtils.getLogWriter().info("Failed to get the internal CqService.", ex);
Assert.fail("Failed to get the internal CqService.", ex);
}
long timeTaken = cqService.getCqServiceVsdStats().getCqQueryExecutionTime();
LogWriterUtils.getLogWriter().info("Total Time taken to Execute CQ Query :" + timeTaken);
System.out.println("Total Time taken to Execute CQ Query :" + timeTaken);
}
});
}
public String[] generateCqQueries(boolean uniqueQueries) {
ArrayList initQueries = new ArrayList();
// From Portfolio object.
String[] names = {"aaa", "bbb", "ccc", "ddd"};
int nameIndex = 0;
// Construct few unique Queries.
for (int i = 0; i < 3; i++) {
for (int cnt = 0; cnt < 5; cnt++) {
String query = cqDUnitTest.cqs[i];
if (cnt > 0) {
nameIndex = (cnt % names.length);
query += " or p.names[" + nameIndex + "] = '" + names[nameIndex] + cnt + "'";
}
initQueries.add(query);
}
}
int numMatchedQueries = 10;
ArrayList cqQueries = new ArrayList();
Iterator iter = initQueries.iterator();
while (iter.hasNext()) {
String query = (String) iter.next();
for (int cnt = 0; cnt < numMatchedQueries; cnt++) {
if (uniqueQueries) {
// Append blank string, so that query string is different but the
// Query constraint remains same.
query += " ";
}
cqQueries.add(query);
}
}
String[] queries = new String[cqQueries.size()];
cqQueries.toArray(queries);
return queries;
}
}