package org.infinispan.persistence.factory;
import static org.testng.Assert.assertEquals;
import java.net.URL;
import java.net.URLClassLoader;
import org.infinispan.commons.CacheException;
import org.infinispan.commons.configuration.attributes.AttributeSet;
import org.infinispan.configuration.cache.StoreConfiguration;
import org.infinispan.persistence.dummy.DummyInMemoryStoreConfiguration;
import org.testng.annotations.Test;
@Test(groups = "unit", testName = "persistence.CacheStoreFactoryRegistryTest")
public class CacheStoreFactoryRegistryTest {
public void testIfNewlyAddedFactoryIsInvokedFirst() {
// given
final Object instanceReturnedByTheFactory = new Object();
StoreConfiguration doesNotMatter = null;
CacheStoreFactoryRegistry registry = new CacheStoreFactoryRegistry();
registry.addCacheStoreFactory(new CacheStoreFactory() {
@Override
public <T> T createInstance(StoreConfiguration storeConfiguration) {
return (T) instanceReturnedByTheFactory;
}
@Override
public StoreConfiguration processConfiguration(StoreConfiguration storeConfiguration) {
return null;
}
});
// when
Object instance = registry.createInstance(doesNotMatter);
// then
assertEquals(instance, instanceReturnedByTheFactory);
}
public void testIfInstanceFromDifferentClassLoaderIsReturned() throws Exception {
// given
final Object instanceReturnedByTheFactory = loadWithCustomClassLoader(this.getClass().getName());
StoreConfiguration doesNotMatter = null;
CacheStoreFactoryRegistry registry = new CacheStoreFactoryRegistry();
registry.addCacheStoreFactory(new CacheStoreFactory() {
@Override
public <T> T createInstance(StoreConfiguration storeConfiguration) {
return (T) instanceReturnedByTheFactory;
}
@Override
public StoreConfiguration processConfiguration(StoreConfiguration storeConfiguration) {
return null;
}
});
// when
Object instance = registry.createInstance(doesNotMatter);
// then
assertEquals(instance, instanceReturnedByTheFactory);
}
@Test(expectedExceptions = CacheException.class, expectedExceptionsMessageRegExp = "ISPN000\\d{3}: Unable to instantiate loader/writer instance for StoreConfiguration class .*.DummyInMemoryStoreConfiguration")
public void testIfACacheExceptionIfThrownWhenNoInstanceIfFound() throws Exception {
// given
StoreConfiguration configuration = createDummyConfiguration();
CacheStoreFactoryRegistry registry = new CacheStoreFactoryRegistry();
// when
registry.clearFactories();
registry.createInstance(configuration);
}
@Test
public void testProcessingConfigurationWithoutCustomFactories () throws Exception {
// given
StoreConfiguration configuration = createDummyConfiguration();
CacheStoreFactoryRegistry registry = new CacheStoreFactoryRegistry();
//when
StoreConfiguration processedConfiguration = registry.processStoreConfiguration(configuration);
//than
assertEquals(configuration, processedConfiguration);
}
@Test
public void testCustomFactoryProcessesConfigurationFirst() throws Exception {
// given
final StoreConfiguration configuration = createDummyConfiguration();
final StoreConfiguration enhancedConfiguration = createDummyConfiguration();
CacheStoreFactoryRegistry registry = new CacheStoreFactoryRegistry();
registry.addCacheStoreFactory(new CacheStoreFactory() {
@Override
public <T> T createInstance(StoreConfiguration storeConfiguration) {
throw new AssertionError("Should not be called");
}
@Override
public StoreConfiguration processConfiguration(StoreConfiguration storeConfiguration) {
return enhancedConfiguration;
}
});
// when
StoreConfiguration returnedConfiguration = registry.processStoreConfiguration(configuration);
// then
assertEquals(enhancedConfiguration, returnedConfiguration);
}
private DummyInMemoryStoreConfiguration createDummyConfiguration() {
AttributeSet protectedAttributesSet = DummyInMemoryStoreConfiguration.attributeDefinitionSet().protect();
return new DummyInMemoryStoreConfiguration(protectedAttributesSet, null, null);
}
private Object loadWithCustomClassLoader(String className) throws Exception {
URL thisClass = this.getClass().getResource(this.getClass().getSimpleName() + ".class");
ClassLoader customClassLoader = new URLClassLoader(new URL[] {thisClass});
Class<?> customInstanceFromDifferentClassLoader = customClassLoader.loadClass(className);
return customInstanceFromDifferentClassLoader.newInstance();
}
}