/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.portal.kernel.resiliency.mpi;
import com.liferay.portal.kernel.messaging.config.AbstractMessagingConfigurator;
import com.liferay.portal.kernel.messaging.config.MessagingConfigurator;
import com.liferay.portal.kernel.messaging.config.MessagingConfiguratorRegistry;
import com.liferay.portal.kernel.nio.intraband.DatagramReceiveHandler;
import com.liferay.portal.kernel.nio.intraband.Intraband;
import com.liferay.portal.kernel.nio.intraband.SystemDataType;
import com.liferay.portal.kernel.nio.intraband.blocking.ExecutorIntraband;
import com.liferay.portal.kernel.nio.intraband.nonblocking.SelectorIntraband;
import com.liferay.portal.kernel.nio.intraband.rpc.BootstrapRPCDatagramReceiveHandler;
import com.liferay.portal.kernel.nio.intraband.test.MockIntraband;
import com.liferay.portal.kernel.nio.intraband.welder.socket.SocketWelder;
import com.liferay.portal.kernel.resiliency.spi.MockSPI;
import com.liferay.portal.kernel.resiliency.spi.MockSPIProvider;
import com.liferay.portal.kernel.resiliency.spi.SPI;
import com.liferay.portal.kernel.resiliency.spi.SPIConfiguration;
import com.liferay.portal.kernel.resiliency.spi.SPIRegistryUtil;
import com.liferay.portal.kernel.resiliency.spi.provider.SPIProvider;
import com.liferay.portal.kernel.test.CaptureHandler;
import com.liferay.portal.kernel.test.JDKLoggerTestUtil;
import com.liferay.portal.kernel.test.ReflectionTestUtil;
import com.liferay.portal.kernel.test.rule.AggregateTestRule;
import com.liferay.portal.kernel.test.rule.CodeCoverageAssertor;
import com.liferay.portal.kernel.test.rule.NewEnv;
import com.liferay.portal.kernel.util.Props;
import com.liferay.portal.kernel.util.PropsKeys;
import com.liferay.portal.kernel.util.PropsUtil;
import com.liferay.portal.kernel.util.PropsUtilAdvice;
import com.liferay.portal.kernel.util.ProxyUtil;
import com.liferay.portal.resiliency.spi.SPIRegistryImpl;
import com.liferay.portal.test.rule.AdviseWith;
import com.liferay.portal.test.rule.AspectJNewEnvTestRule;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.rmi.NoSuchObjectException;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
/**
* @author Shuyang Zhou
*/
@NewEnv(type = NewEnv.Type.CLASSLOADER)
public class MPIHelperUtilTest {
@ClassRule
@Rule
public static final AggregateTestRule aggregateTestRule =
new AggregateTestRule(
CodeCoverageAssertor.INSTANCE, AspectJNewEnvTestRule.INSTANCE);
@Before
public void setUp() {
PropsUtilAdvice.setProps(
PropsKeys.INTRABAND_IMPL, ExecutorIntraband.class.getName());
PropsUtilAdvice.setProps(PropsKeys.INTRABAND_TIMEOUT_DEFAULT, "10000");
PropsUtilAdvice.setProps(
PropsKeys.INTRABAND_WELDER_IMPL, SocketWelder.class.getName());
SPIRegistryUtil spiRegistryUtil = new SPIRegistryUtil();
spiRegistryUtil.setSPIRegistry(
new SPIRegistryImpl() {
@Override
public void registerSPI(SPI spi) {
}
@Override
public void unregisterSPI(SPI spi) {
}
});
}
@After
public void tearDown() {
try (CaptureHandler captureHandler =
JDKLoggerTestUtil.configureJDKLogger(
MPIHelperUtil.class.getName(), Level.OFF)) {
MPIHelperUtil.shutdown();
}
catch (Throwable t) {
}
}
@AdviseWith(adviceClasses = {PropsUtilAdvice.class})
@Test
public void testClassInitializationFailed() {
System.setProperty(PropsKeys.INTRABAND_IMPL, "NoSuchClass");
try {
MPIHelperUtil.getMPI();
Assert.fail();
}
catch (ExceptionInInitializerError eiie) {
Throwable throwable = eiie.getCause();
Assert.assertSame(RuntimeException.class, throwable.getClass());
Assert.assertEquals(
"Unable to instantiate NoSuchClass", throwable.getMessage());
}
finally {
System.clearProperty(PropsKeys.INTRABAND_IMPL);
}
}
@AdviseWith(adviceClasses = {PropsUtilAdvice.class})
@Test
public void testClassInitializationOnMPI() throws Exception {
PropsUtil.setProps(
(Props)ProxyUtil.newProxyInstance(
MPIHelperUtilTest.class.getClassLoader(),
new Class<?>[] {Props.class},
new InvocationHandler() {
@Override
public Object invoke(
Object proxy, Method method, Object[] args) {
throw new UnsupportedOperationException();
}
}));
MPI mpiImpl = _getMPIImpl();
Assert.assertNotNull(mpiImpl);
Assert.assertTrue(mpiImpl.isAlive());
MPI mpi = MPIHelperUtil.getMPI();
Assert.assertSame(mpi, UnicastRemoteObject.toStub(mpiImpl));
Assert.assertTrue(mpi.isAlive());
Intraband intraband = MPIHelperUtil.getIntraband();
Assert.assertSame(ExecutorIntraband.class, intraband.getClass());
DatagramReceiveHandler[] datagramReceiveHandlers =
intraband.getDatagramReceiveHandlers();
Assert.assertSame(
BootstrapRPCDatagramReceiveHandler.class,
datagramReceiveHandlers[SystemDataType.RPC.getValue()].getClass());
}
@AdviseWith(adviceClasses = {PropsUtilAdvice.class})
@Test
public void testClassInitializationOnSPI() throws Exception {
System.setProperty(
PropsKeys.INTRABAND_IMPL, SelectorIntraband.class.getName());
System.setProperty(PropsKeys.INTRABAND_TIMEOUT_DEFAULT, "10000");
System.setProperty(
PropsKeys.INTRABAND_WELDER_IMPL, SocketWelder.class.getName());
MPI mpiImpl = _getMPIImpl();
Assert.assertNotNull(mpiImpl);
Assert.assertTrue(mpiImpl.isAlive());
MPI mpi = MPIHelperUtil.getMPI();
Assert.assertSame(mpi, UnicastRemoteObject.toStub(mpiImpl));
Assert.assertTrue(mpi.isAlive());
Intraband intraband = MPIHelperUtil.getIntraband();
Assert.assertSame(SelectorIntraband.class, intraband.getClass());
DatagramReceiveHandler[] datagramReceiveHandlers =
intraband.getDatagramReceiveHandlers();
Assert.assertSame(
BootstrapRPCDatagramReceiveHandler.class,
datagramReceiveHandlers[SystemDataType.RPC.getValue()].getClass());
}
@NewEnv(type = NewEnv.Type.NONE)
@Test
public void testConstructor() {
new MPIHelperUtil();
}
@AdviseWith(adviceClasses = {PropsUtilAdvice.class})
@Test
public void testShutdownFailWithLog() throws NoSuchObjectException {
UnicastRemoteObject.unexportObject(_getMPIImpl(), true);
final IOException ioException = new IOException();
ReflectionTestUtil.setFieldValue(
MPIHelperUtil.class, "_intraband",
new MockIntraband() {
@Override
public void close() throws IOException {
throw ioException;
}
});
try (CaptureHandler captureHandler =
JDKLoggerTestUtil.configureJDKLogger(
MPIHelperUtil.class.getName(), Level.WARNING)) {
MPIHelperUtil.shutdown();
List<LogRecord> logRecords = captureHandler.getLogRecords();
Assert.assertEquals(logRecords.toString(), 2, logRecords.size());
LogRecord logRecord = logRecords.get(0);
logRecord = logRecords.get(0);
Assert.assertEquals(
"Unable to unexport " + _getMPIImpl(), logRecord.getMessage());
Throwable throwable = logRecord.getThrown();
Assert.assertSame(
NoSuchObjectException.class, throwable.getClass());
logRecord = logRecords.get(1);
Assert.assertEquals(
"Unable to close intraband", logRecord.getMessage());
Assert.assertSame(ioException, logRecord.getThrown());
}
}
@AdviseWith(adviceClasses = {PropsUtilAdvice.class})
@Test
public void testShutdownFailWithoutLog() throws NoSuchObjectException {
UnicastRemoteObject.unexportObject(_getMPIImpl(), true);
final IOException ioException = new IOException();
ReflectionTestUtil.setFieldValue(
MPIHelperUtil.class, "_intraband",
new MockIntraband() {
@Override
public void close() throws IOException {
throw ioException;
}
});
try (CaptureHandler captureHandler =
JDKLoggerTestUtil.configureJDKLogger(
MPIHelperUtil.class.getName(), Level.OFF)) {
MPIHelperUtil.shutdown();
List<LogRecord> logRecords = captureHandler.getLogRecords();
Assert.assertTrue(logRecords.isEmpty());
}
}
@AdviseWith(adviceClasses = {PropsUtilAdvice.class})
@Test
public void testShutdownSuccess() {
try (CaptureHandler captureHandler =
JDKLoggerTestUtil.configureJDKLogger(
MPIHelperUtil.class.getName(), Level.ALL)) {
MPIHelperUtil.shutdown();
List<LogRecord> logRecords = captureHandler.getLogRecords();
Assert.assertTrue(logRecords.isEmpty());
}
}
@AdviseWith(adviceClasses = {PropsUtilAdvice.class})
@Test
public void testSPIProviderRegistration() throws RemoteException {
// Register SPI provider, null name
MockSPIProvider mockSPIProvider1 = new MockSPIProvider(null);
try {
MPIHelperUtil.registerSPIProvider(mockSPIProvider1);
Assert.fail();
}
catch (NullPointerException npe) {
}
try (CaptureHandler captureHandler =
JDKLoggerTestUtil.configureJDKLogger(
MPIHelperUtil.class.getName(), Level.INFO)) {
// Register SPI provider, with log
List<LogRecord> logRecords = captureHandler.getLogRecords();
String name1 = "spiProvider1";
mockSPIProvider1 = new MockSPIProvider(name1);
Assert.assertTrue(
MPIHelperUtil.registerSPIProvider(mockSPIProvider1));
Assert.assertEquals(logRecords.toString(), 1, logRecords.size());
LogRecord logRecord1 = logRecords.get(0);
Assert.assertEquals(
"Registered SPI provider " + mockSPIProvider1,
logRecord1.getMessage());
// Register SPI provider, without log
logRecords = captureHandler.resetLogLevel(Level.OFF);
String name2 = "spiProvider2";
MockSPIProvider mockSPIProvider2 = new MockSPIProvider(name2);
Assert.assertTrue(
MPIHelperUtil.registerSPIProvider(mockSPIProvider2));
Assert.assertTrue(logRecords.isEmpty());
// Register SPI provider, duplicate name, with log
logRecords = captureHandler.resetLogLevel(Level.WARNING);
MockSPIProvider mockSPIProvider3 = new MockSPIProvider(name1);
Assert.assertFalse(
MPIHelperUtil.registerSPIProvider(mockSPIProvider3));
Assert.assertEquals(logRecords.toString(), 1, logRecords.size());
logRecord1 = logRecords.get(0);
Assert.assertEquals(
"Not registering SPI provider " + mockSPIProvider3 +
" because it duplicates " + mockSPIProvider1,
logRecord1.getMessage());
// Register SPI provider, duplicate name, without log
logRecords = captureHandler.resetLogLevel(Level.OFF);
mockSPIProvider3 = new MockSPIProvider(name1);
Assert.assertFalse(
MPIHelperUtil.registerSPIProvider(mockSPIProvider3));
Assert.assertTrue(logRecords.isEmpty());
// Get SPI provider
String name3 = "spiProvider3";
Assert.assertSame(
mockSPIProvider1, MPIHelperUtil.getSPIProvider(name1));
Assert.assertSame(
mockSPIProvider2, MPIHelperUtil.getSPIProvider(name2));
Assert.assertNull(MPIHelperUtil.getSPIProvider(name3));
List<SPIProvider> spiProviders = MPIHelperUtil.getSPIProviders();
Assert.assertEquals(
spiProviders.toString(), 2, spiProviders.size());
Assert.assertTrue(spiProviders.contains(mockSPIProvider1));
Assert.assertTrue(spiProviders.contains(mockSPIProvider2));
// Unregister SPI provider, null name
mockSPIProvider3 = new MockSPIProvider(null);
try {
MPIHelperUtil.unregisterSPIProvider(mockSPIProvider3);
Assert.fail();
}
catch (NullPointerException npe) {
}
// Unregister SPI provider, nonexistent name, with log
logRecords = captureHandler.resetLogLevel(Level.WARNING);
mockSPIProvider3 = new MockSPIProvider(name3);
Assert.assertFalse(
MPIHelperUtil.unregisterSPIProvider(mockSPIProvider3));
Assert.assertEquals(logRecords.toString(), 1, logRecords.size());
logRecord1 = logRecords.get(0);
Assert.assertEquals(
"Not unregistering unregistered SPI provider " +
mockSPIProvider3,
logRecord1.getMessage());
// Unregister SPI provider, nonexistent name, without log
logRecords = captureHandler.resetLogLevel(Level.OFF);
mockSPIProvider3 = new MockSPIProvider(name3);
Assert.assertFalse(
MPIHelperUtil.unregisterSPIProvider(mockSPIProvider3));
Assert.assertTrue(logRecords.isEmpty());
// Unregister SPI provider, mismatch instance, with log
logRecords = captureHandler.resetLogLevel(Level.INFO);
Assert.assertFalse(
MPIHelperUtil.unregisterSPIProvider(
new MockSPIProvider(name2)));
Assert.assertEquals(logRecords.toString(), 1, logRecords.size());
logRecord1 = logRecords.get(0);
Assert.assertEquals(
"Not unregistering unregistered SPI provider " + name2,
logRecord1.getMessage());
// Unregister SPI provider, mismatch instance, without log
logRecords = captureHandler.resetLogLevel(Level.OFF);
Assert.assertFalse(
MPIHelperUtil.unregisterSPIProvider(
new MockSPIProvider(name2)));
Assert.assertTrue(logRecords.isEmpty());
// Unregister SPI provider, concurrent remove failure, with log
logRecords = captureHandler.resetLogLevel(Level.INFO);
ConcurrentMap<String, Object> oldSPIProviderContainers =
ReflectionTestUtil.getFieldValue(
MPIHelperUtil.class, "_spiProviderContainers");
try {
ReflectionTestUtil.setFieldValue(
MPIHelperUtil.class, "_spiProviderContainers",
new ConcurrentHashMap<String, Object>(
oldSPIProviderContainers) {
@Override
public boolean remove(Object key, Object value) {
return false;
}
});
Assert.assertFalse(
MPIHelperUtil.unregisterSPIProvider(mockSPIProvider2));
}
finally {
ReflectionTestUtil.setFieldValue(
MPIHelperUtil.class, "_spiProviderContainers",
oldSPIProviderContainers);
}
Assert.assertEquals(logRecords.toString(), 1, logRecords.size());
logRecord1 = logRecords.get(0);
Assert.assertEquals(
"Not unregistering unregistered SPI provider " + name2,
logRecord1.getMessage());
// Unregister SPI provider, concurrent remove failure, without log
logRecords = captureHandler.resetLogLevel(Level.OFF);
oldSPIProviderContainers = ReflectionTestUtil.getFieldValue(
MPIHelperUtil.class, "_spiProviderContainers");
try {
ReflectionTestUtil.setFieldValue(
MPIHelperUtil.class, "_spiProviderContainers",
new ConcurrentHashMap<String, Object>(
oldSPIProviderContainers) {
@Override
public boolean remove(Object key, Object value) {
return false;
}
});
Assert.assertFalse(
MPIHelperUtil.unregisterSPIProvider(mockSPIProvider2));
}
finally {
ReflectionTestUtil.setFieldValue(
MPIHelperUtil.class, "_spiProviderContainers",
oldSPIProviderContainers);
}
Assert.assertTrue(logRecords.isEmpty());
// Unregister SPI provider, with no SPI, with log
logRecords = captureHandler.resetLogLevel(Level.INFO);
Assert.assertTrue(
MPIHelperUtil.unregisterSPIProvider(mockSPIProvider2));
Assert.assertEquals(logRecords.toString(), 1, logRecords.size());
logRecord1 = logRecords.get(0);
Assert.assertEquals(
"Unregistered SPI provider " + mockSPIProvider2,
logRecord1.getMessage());
// Unregister SPI provider, with no SPI, without log
logRecords = captureHandler.resetLogLevel(Level.OFF);
Assert.assertTrue(
MPIHelperUtil.unregisterSPIProvider(mockSPIProvider1));
Assert.assertTrue(logRecords.isEmpty());
// Unregister SPI provider, with SPI, fail on stop, with log
logRecords = captureHandler.resetLogLevel(Level.SEVERE);
mockSPIProvider1 = new MockSPIProvider(name1);
Assert.assertTrue(
MPIHelperUtil.registerSPIProvider(mockSPIProvider1));
mockSPIProvider2 = new MockSPIProvider(name2);
Assert.assertTrue(
MPIHelperUtil.registerSPIProvider(mockSPIProvider2));
MockSPI mockSPI1 = new MockSPI();
mockSPI1.failOnStop = true;
mockSPI1.spiProviderName = name1;
MPIHelperUtilTestUtil.directResigterSPI("spi1", mockSPI1);
MockSPI mockSPI2 = new MockSPI();
mockSPI2.failOnStop = true;
mockSPI2.spiProviderName = name2;
MPIHelperUtilTestUtil.directResigterSPI("spi2", mockSPI2);
Assert.assertTrue(
MPIHelperUtil.unregisterSPIProvider(mockSPIProvider1));
Assert.assertFalse(mockSPI1.destroyed);
Assert.assertFalse(mockSPI1.stopped);
Assert.assertFalse(mockSPI2.destroyed);
Assert.assertFalse(mockSPI2.stopped);
Assert.assertEquals(logRecords.toString(), 1, logRecords.size());
logRecord1 = logRecords.get(0);
Assert.assertEquals(
"Unable to unregister SPI " + mockSPI1 +
" while unregistering SPI provider " + mockSPIProvider1,
logRecord1.getMessage());
Throwable throwable = logRecord1.getThrown();
Assert.assertSame(RemoteException.class, throwable.getClass());
// Unregister SPI provider, with SPI, fail on destroy, without log
logRecords = captureHandler.resetLogLevel(Level.OFF);
mockSPI1.failOnDestroy = true;
mockSPI1.failOnStop = false;
mockSPI2.failOnDestroy = true;
mockSPI2.failOnStop = false;
Assert.assertTrue(
MPIHelperUtil.unregisterSPIProvider(mockSPIProvider2));
Assert.assertFalse(mockSPI1.destroyed);
Assert.assertFalse(mockSPI1.stopped);
Assert.assertFalse(mockSPI2.destroyed);
Assert.assertTrue(mockSPI2.stopped);
Assert.assertTrue(logRecords.isEmpty());
// Unregister SPI provider, with SPI, fail on catch, without log
logRecords = captureHandler.resetLogLevel(Level.OFF);
mockSPIProvider1 = new MockSPIProvider(name1);
Assert.assertTrue(
MPIHelperUtil.registerSPIProvider(mockSPIProvider1));
final RuntimeException runtimeException = new RuntimeException();
mockSPI1 = new MockSPI() {
@Override
public String toString() {
throw runtimeException;
}
};
mockSPI1.failOnDestroy = true;
mockSPI1.failOnStop = false;
mockSPI1.spiProviderName = name1;
MPIHelperUtilTestUtil.directResigterSPI(name1, mockSPI1);
try {
MPIHelperUtil.unregisterSPIProvider(mockSPIProvider1);
Assert.fail();
}
catch (RuntimeException re) {
Assert.assertSame(runtimeException, re);
}
Assert.assertTrue(logRecords.isEmpty());
// Unregister SPI provider, with SPI, success, with log
mockSPIProvider1 = new MockSPIProvider(name1);
Assert.assertTrue(
MPIHelperUtil.registerSPIProvider(mockSPIProvider1));
mockSPIProvider2 = new MockSPIProvider(name2);
Assert.assertTrue(
MPIHelperUtil.registerSPIProvider(mockSPIProvider2));
mockSPI1 = new MockSPI();
mockSPI1.failOnDestroy = false;
mockSPI1.spiProviderName = name1;
MPIHelperUtilTestUtil.directResigterSPI("spi1", mockSPI1);
mockSPI2 = new MockSPI();
mockSPI2.failOnDestroy = false;
mockSPI2.spiProviderName = name2;
MPIHelperUtilTestUtil.directResigterSPI("spi2", mockSPI2);
logRecords = captureHandler.resetLogLevel(Level.INFO);
Assert.assertTrue(
MPIHelperUtil.unregisterSPIProvider(mockSPIProvider1));
Assert.assertTrue(mockSPI1.destroyed);
Assert.assertTrue(mockSPI1.stopped);
Assert.assertFalse(mockSPI2.destroyed);
Assert.assertFalse(mockSPI2.stopped);
Assert.assertEquals(logRecords.toString(), 2, logRecords.size());
logRecord1 = logRecords.get(0);
Assert.assertEquals(
"Unregistered SPI " + mockSPI1 +
" while unregistering SPI provider " + mockSPIProvider1,
logRecord1.getMessage());
LogRecord logRecord2 = logRecords.get(1);
Assert.assertEquals(
"Unregistered SPI provider " + mockSPIProvider1,
logRecord2.getMessage());
// Unregister SPI provider, with SPI, success, without log
logRecords = captureHandler.resetLogLevel(Level.OFF);
Assert.assertTrue(
MPIHelperUtil.unregisterSPIProvider(mockSPIProvider2));
Assert.assertTrue(mockSPI1.destroyed);
Assert.assertTrue(mockSPI1.stopped);
Assert.assertTrue(mockSPI2.destroyed);
Assert.assertTrue(mockSPI2.stopped);
Assert.assertTrue(logRecords.isEmpty());
}
}
@AdviseWith(adviceClasses = {PropsUtilAdvice.class})
@Test
public void testSPIRegistration() {
try (CaptureHandler captureHandler =
JDKLoggerTestUtil.configureJDKLogger(
MPIHelperUtil.class.getName(), Level.WARNING)) {
// Mismatch MPI, with log
List<LogRecord> logRecords = captureHandler.getLogRecords();
MockSPI mockSPI1 = new MockSPI();
mockSPI1.mpi = new MockMPI();
Assert.assertFalse(MPIHelperUtil.registerSPI(mockSPI1));
LogRecord logRecord = logRecords.get(0);
Assert.assertEquals(
"Not registering SPI " + mockSPI1 + " with foreign MPI " +
mockSPI1.mpi + " versus " + MPIHelperUtil.getMPI(),
logRecord.getMessage());
// Mismatch MPI, without log
logRecords = captureHandler.resetLogLevel(Level.OFF);
Assert.assertFalse(MPIHelperUtil.registerSPI(mockSPI1));
Assert.assertTrue(logRecords.isEmpty());
// Null SPI provider name
mockSPI1 = new MockSPI();
mockSPI1.mpi = MPIHelperUtil.getMPI();
mockSPI1.spiProviderName = null;
try {
MPIHelperUtil.registerSPI(mockSPI1);
Assert.fail();
}
catch (NullPointerException npe) {
}
// No such SPI provider, with log
logRecords = captureHandler.resetLogLevel(Level.WARNING);
mockSPI1 = new MockSPI();
mockSPI1.mpi = MPIHelperUtil.getMPI();
mockSPI1.spiProviderName = "name1";
Assert.assertFalse(MPIHelperUtil.registerSPI(mockSPI1));
Assert.assertEquals(logRecords.toString(), 1, logRecords.size());
logRecord = logRecords.get(0);
Assert.assertEquals(
"Not registering SPI " + mockSPI1 +
" with unknown SPI provider " + mockSPI1.spiProviderName,
logRecord.getMessage());
// No such SPI provider, without log
logRecords = captureHandler.resetLogLevel(Level.OFF);
mockSPI1 = new MockSPI();
mockSPI1.mpi = MPIHelperUtil.getMPI();
mockSPI1.spiProviderName = "name1";
Assert.assertFalse(MPIHelperUtil.registerSPI(mockSPI1));
Assert.assertTrue(logRecords.isEmpty());
// Successful register, with log
String name = "name1";
MockSPIProvider mockSPIProvider = new MockSPIProvider(name);
Assert.assertTrue(
MPIHelperUtil.registerSPIProvider(mockSPIProvider));
mockSPI1 = new MockSPI();
mockSPI1.mpi = MPIHelperUtil.getMPI();
mockSPI1.spiConfiguration = new SPIConfiguration(
"testId1", "", 8081, "", new String[0],
new String[] {"servletContextName1"}, null);
mockSPI1.spiProviderName = name;
logRecords = captureHandler.resetLogLevel(Level.INFO);
Assert.assertTrue(MPIHelperUtil.registerSPI(mockSPI1));
Assert.assertEquals(logRecords.toString(), 1, logRecords.size());
logRecord = logRecords.get(0);
Assert.assertEquals(
"Registered SPI " + mockSPI1, logRecord.getMessage());
// Successful register, without log
logRecords = captureHandler.resetLogLevel(Level.OFF);
MessagingConfigurator messagingConfigurator =
new AbstractMessagingConfigurator() {
@Override
public void connect() {
}
@Override
public void disconnect() {
}
@Override
protected ClassLoader getOperatingClassloader() {
return null;
}
};
MessagingConfiguratorRegistry.registerMessagingConfigurator(
"servletContextName2", messagingConfigurator);
MockSPI mockSPI2 = new MockSPI();
mockSPI2.mpi = MPIHelperUtil.getMPI();
mockSPI2.spiConfiguration = new SPIConfiguration(
"testId2", "", 8082, "", new String[0],
new String[] {"servletContextName2"}, null);
mockSPI2.spiProviderName = name;
Assert.assertTrue(MPIHelperUtil.registerSPI(mockSPI2));
Assert.assertTrue(logRecords.isEmpty());
// Duplicate register, with log
logRecords = captureHandler.resetLogLevel(Level.WARNING);
Assert.assertFalse(MPIHelperUtil.registerSPI(mockSPI1));
Assert.assertEquals(logRecords.toString(), 1, logRecords.size());
logRecord = logRecords.get(0);
Assert.assertEquals(
"Not registering SPI " + mockSPI1 + " because it duplicates " +
mockSPI1,
logRecord.getMessage());
// Duplicate register, without log
logRecords = captureHandler.resetLogLevel(Level.OFF);
Assert.assertFalse(MPIHelperUtil.registerSPI(mockSPI2));
Assert.assertTrue(logRecords.isEmpty());
// Bad SPI impl
mockSPI1 = new MockSPI();
mockSPI1.failOnGetConfiguration = true;
mockSPI1.mpi = MPIHelperUtil.getMPI();
mockSPI1.spiProviderName = name;
try {
MPIHelperUtil.registerSPI(mockSPI1);
Assert.fail();
}
catch (RuntimeException re) {
Throwable throwable = re.getCause();
Assert.assertSame(RemoteException.class, throwable.getClass());
}
// Get SPI, no such SPI provider
Assert.assertNull(MPIHelperUtil.getSPI("name2", "testId1"));
// Get SPI, exists
Assert.assertNotNull(MPIHelperUtil.getSPI(name, "testId1"));
// Get SPI, does not exist
Assert.assertNull(MPIHelperUtil.getSPI(name, "testId3"));
// Get SPIs
logRecords = captureHandler.resetLogLevel(Level.SEVERE);
mockSPI2.failOnIsAlive = true;
List<SPI> spis = MPIHelperUtil.getSPIs();
Assert.assertEquals(spis.toString(), 1, spis.size());
mockSPI1 = (MockSPI)spis.get(0);
Assert.assertEquals(name, mockSPI1.spiProviderName);
Assert.assertEquals(logRecords.toString(), 1, logRecords.size());
logRecord = logRecords.get(0);
Throwable throwable = logRecord.getThrown();
Assert.assertSame(RemoteException.class, throwable.getClass());
// Get SPIs by SPI provider, exists
mockSPI2 = new MockSPI();
mockSPI2.mpi = MPIHelperUtil.getMPI();
mockSPI2.spiConfiguration = new SPIConfiguration(
"testId2", "", 8082, "", new String[0], new String[0], null);
mockSPI2.spiProviderName = name;
Assert.assertTrue(MPIHelperUtil.registerSPI(mockSPI2));
mockSPI2.failOnIsAlive = true;
spis = MPIHelperUtil.getSPIs(name);
Assert.assertEquals(spis.toString(), 1, spis.size());
mockSPI1 = (MockSPI)spis.get(0);
Assert.assertEquals(name, mockSPI1.spiProviderName);
// Get SPIs by SPI provider, does not exist
spis = MPIHelperUtil.getSPIs("name2");
Assert.assertTrue(spis.isEmpty());
// Unregister thread local shortcut, with log
mockSPI1 = new MockSPI();
mockSPI1.spiConfiguration = new SPIConfiguration(
null, null, 0, null, null, new String[0], null);
ThreadLocal<SPI> unregisteringSPIThreadLocal =
ReflectionTestUtil.getFieldValue(
MPIHelperUtil.class, "_unregisteringSPIThreadLocal");
unregisteringSPIThreadLocal.set(mockSPI1);
try {
Assert.assertTrue(MPIHelperUtil.unregisterSPI(mockSPI1));
}
finally {
unregisteringSPIThreadLocal.remove();
}
// Unregister MPI mismatch, with log
logRecords = captureHandler.resetLogLevel(Level.WARNING);
mockSPI1 = new MockSPI();
mockSPI1.mpi = new MockMPI();
Assert.assertFalse(MPIHelperUtil.unregisterSPI(mockSPI1));
Assert.assertEquals(logRecords.toString(), 1, logRecords.size());
logRecord = logRecords.get(0);
Assert.assertEquals(
"Not unregistering SPI " + mockSPI1 + " with foreign MPI " +
mockSPI1.mpi + " versus " + MPIHelperUtil.getMPI(),
logRecord.getMessage());
// Unregister MPI mismatch, without log
logRecords = captureHandler.resetLogLevel(Level.OFF);
Assert.assertFalse(MPIHelperUtil.unregisterSPI(mockSPI1));
Assert.assertTrue(logRecords.isEmpty());
// Unregister no such SPI provider, with log
logRecords = captureHandler.resetLogLevel(Level.WARNING);
mockSPI1 = new MockSPI();
mockSPI1.mpi = MPIHelperUtil.getMPI();
mockSPI1.spiProviderName = "name2";
Assert.assertFalse(MPIHelperUtil.unregisterSPI(mockSPI1));
Assert.assertEquals(logRecords.toString(), 1, logRecords.size());
logRecord = logRecords.get(0);
Assert.assertEquals(
"Not unregistering SPI " + mockSPI1 +
" with unknown SPI provider " + mockSPI1.spiProviderName,
logRecord.getMessage());
// Unregister no such SPI provider, without log
logRecords = captureHandler.resetLogLevel(Level.OFF);
mockSPI1 = new MockSPI();
mockSPI1.mpi = MPIHelperUtil.getMPI();
mockSPI1.spiProviderName = "name2";
Assert.assertFalse(MPIHelperUtil.unregisterSPI(mockSPI1));
Assert.assertTrue(logRecords.isEmpty());
// Unregister no such SPI, with log
logRecords = captureHandler.resetLogLevel(Level.WARNING);
mockSPI1 = new MockSPI();
mockSPI1.mpi = MPIHelperUtil.getMPI();
mockSPI1.spiConfiguration = new SPIConfiguration(
"testId3", "", 8083, "", new String[0], new String[0], null);
mockSPI1.spiProviderName = name;
Assert.assertFalse(MPIHelperUtil.unregisterSPI(mockSPI1));
Assert.assertEquals(logRecords.toString(), 1, logRecords.size());
logRecord = logRecords.get(0);
Assert.assertEquals(
"Not unregistering unregistered SPI " + mockSPI1,
logRecord.getMessage());
// Unregister no such SPI, without log
logRecords = captureHandler.resetLogLevel(Level.OFF);
mockSPI1 = new MockSPI();
mockSPI1.mpi = MPIHelperUtil.getMPI();
mockSPI1.spiConfiguration = new SPIConfiguration(
"testId3", "", 8083, "", new String[0], new String[0], null);
mockSPI1.spiProviderName = name;
Assert.assertFalse(MPIHelperUtil.unregisterSPI(mockSPI1));
Assert.assertTrue(logRecords.isEmpty());
// Unregister success, with log
mockSPI1 = (MockSPI)MPIHelperUtil.getSPI(name, "testId1");
logRecords = captureHandler.resetLogLevel(Level.INFO);
Assert.assertTrue(MPIHelperUtil.unregisterSPI(mockSPI1));
Assert.assertEquals(logRecords.toString(), 1, logRecords.size());
logRecord = logRecords.get(0);
Assert.assertEquals(
"Unregistered SPI " + mockSPI1, logRecord.getMessage());
// Unregister success, without log
Assert.assertTrue(MPIHelperUtil.registerSPI(mockSPI1));
logRecords = captureHandler.resetLogLevel(Level.OFF);
Assert.assertTrue(MPIHelperUtil.unregisterSPI(mockSPI1));
Assert.assertTrue(logRecords.isEmpty());
// Unregister fail on getting configuration
mockSPI1.failOnGetConfiguration = true;
try {
MPIHelperUtil.unregisterSPI(mockSPI1);
Assert.fail();
}
catch (RuntimeException re) {
throwable = re.getCause();
Assert.assertSame(RemoteException.class, throwable.getClass());
}
}
}
private static MPI _getMPIImpl() {
MPI mpiImpl = ReflectionTestUtil.getFieldValue(
MPIHelperUtil.class, "_mpiImpl");
Assert.assertNotNull(mpiImpl);
return mpiImpl;
}
private static class MockMPI implements MPI {
@Override
public boolean isAlive() {
return true;
}
}
}