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(); } }