package org.infinispan.client.hotrod.event;
import static org.infinispan.server.hotrod.test.HotRodTestingUtil.hotRodCacheConfiguration;
import static org.infinispan.test.TestingUtil.extractField;
import static org.infinispan.test.fwk.TestCacheManagerFactory.createCacheManager;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.net.ServerSocket;
import org.infinispan.client.hotrod.RemoteCache;
import org.infinispan.client.hotrod.RemoteCacheManager;
import org.infinispan.client.hotrod.configuration.ConfigurationBuilder;
import org.infinispan.client.hotrod.test.HotRodClientTestingUtil;
import org.infinispan.commons.util.Util;
import org.infinispan.manager.EmbeddedCacheManager;
import org.infinispan.server.hotrod.HotRodServer;
import org.infinispan.server.hotrod.test.HotRodTestingUtil;
import org.infinispan.test.AbstractInfinispanTest;
import org.infinispan.test.TestingUtil;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
/**
* Test to verify that the listener threads are stopped.
*
* @author gustavonalle
* @since 7.2
*/
@Test(groups = "functional", testName = "client.hotrod.event.ListenerCacheManagerStopTest")
public class ListenerCacheManagerStopTest extends AbstractInfinispanTest {
HotRodServer hotRodServer;
RemoteCacheManager remoteCacheManager;
RemoteCache<Integer, String> cache;
EmbeddedCacheManager cacheManager;
@BeforeMethod
public void setup() throws IOException {
Integer port = getRandomFreePort();
cacheManager = createCacheManager(hotRodCacheConfiguration());
hotRodServer = HotRodTestingUtil.startHotRodServer(cacheManager, port);
remoteCacheManager = new RemoteCacheManager(
new ConfigurationBuilder()
.addServer()
.port(port)
.host(HotRodTestingUtil.host())
.connectionTimeout(3000)
.socketTimeout(3000)
.build()
);
cache = remoteCacheManager.getCache();
}
@AfterMethod
public void tearDown() {
HotRodClientTestingUtil.killServers(hotRodServer);
HotRodClientTestingUtil.killRemoteCacheManager(remoteCacheManager);
TestingUtil.killCacheManagers(cacheManager);
}
@Test
public void testThreadsAreStopped() throws Exception {
final EventLogListener listener = new EventLogListener<>(remoteCacheManager.getCache());
cache.addClientListener(listener);
final String listenerId = findListenerId(listener);
assertListenerThreadRunning(listenerId);
remoteCacheManager.stop();
hotRodServer.stop();
assertListenerThreadNotRunning(listenerId);
}
private String findListenerId(Object listener) {
ClientListenerNotifier clientNotifier = extractField(remoteCacheManager, "listenerNotifier");
return Util.toHexString(clientNotifier.findListenerId(listener), 8);
}
private void assertListenerThreadRunning(final String listenerId) {
eventually(new Condition() {
@Override
public boolean isSatisfied() throws Exception {
return isListenerThreadRunning(listenerId);
}
});
}
private void assertListenerThreadNotRunning(final String listenerId) {
eventually(new Condition() {
@Override
public boolean isSatisfied() throws Exception {
return !isListenerThreadRunning(listenerId);
}
});
}
private boolean isListenerThreadRunning(String listenerId) {
ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(false, false);
for (ThreadInfo threadInfo : threadInfos) {
if ((threadInfo.getThreadState().equals(Thread.State.RUNNABLE) ||
threadInfo.getThreadState().equals(Thread.State.BLOCKED)) &&
threadInfo.getThreadName().contains(listenerId)) {
return true;
}
}
return false;
}
private Integer getRandomFreePort() throws IOException {
try (ServerSocket socket = new ServerSocket(0)) {
return socket.getLocalPort();
}
}
}