package com.rackspacecloud.blueflood.utils;
import com.rackspacecloud.blueflood.io.DiscoveryIO;
import com.rackspacecloud.blueflood.io.DummyDiscoveryIO;
import com.rackspacecloud.blueflood.service.Configuration;
import com.rackspacecloud.blueflood.service.CoreConfig;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class ModuleLoaderTest {
@Before
public void setUp() {
Configuration.getInstance().clearProperty(CoreConfig.DISCOVERY_MODULES);
ModuleLoader.clearCache();
}
@After
public void tearDown() {
Configuration.getInstance().clearProperty(CoreConfig.DISCOVERY_MODULES);
ModuleLoader.clearCache();
}
@Test
public void singleClassYieldsThatClass() {
// given
Configuration.getInstance().setProperty(
CoreConfig.DISCOVERY_MODULES,
"com.rackspacecloud.blueflood.utils.DummyDiscoveryIO3");
// when
Object loadedModule = ModuleLoader.getInstance(DiscoveryIO.class, CoreConfig.DISCOVERY_MODULES);
// then
Assert.assertNotNull(loadedModule);
Assert.assertEquals(DummyDiscoveryIO3.class, loadedModule.getClass());
}
@Test
public void singleClassInDifferentPackageYieldsThatClass() {
// given
Configuration.getInstance().setProperty(
CoreConfig.DISCOVERY_MODULES,
"com.rackspacecloud.blueflood.io.DummyDiscoveryIO");
// when
Object loadedModule = ModuleLoader.getInstance(DiscoveryIO.class, CoreConfig.DISCOVERY_MODULES);
// then
Assert.assertNotNull(loadedModule);
Assert.assertEquals(DummyDiscoveryIO.class, loadedModule.getClass());
}
@Test
public void emptyStringYieldsNull() {
// given
Configuration.getInstance().setProperty(CoreConfig.DISCOVERY_MODULES, "");
// when
Object loadedModule = ModuleLoader.getInstance(DiscoveryIO.class, CoreConfig.DISCOVERY_MODULES);
// then
Assert.assertNull(loadedModule);
}
@Test(expected=RuntimeException.class)
public void multipleClassesCauseAnException() {
// given
Configuration.getInstance().setProperty(
CoreConfig.DISCOVERY_MODULES,
"com.rackspacecloud.blueflood.io.DummyDiscoveryIO,com.rackspacecloud.blueflood.io.DummyDiscoveryIO2");
// when
Object loadedModule = ModuleLoader.getInstance(DiscoveryIO.class, CoreConfig.DISCOVERY_MODULES);
// then
// an exception is thrown
}
@Test
public void nonExistentClassYieldsNull() {
// given
Configuration.getInstance().setProperty(
CoreConfig.DISCOVERY_MODULES,
"com.rackspacecloud.blueflood.NonExistentClass");
// when
Object loadedModule = ModuleLoader.getInstance(DiscoveryIO.class, CoreConfig.DISCOVERY_MODULES);
// then
Assert.assertNull(loadedModule);
}
@Test
public void callingTwiceYieldsTheSameObjectBothTimes() {
// given
Configuration.getInstance().setProperty(
CoreConfig.DISCOVERY_MODULES,
"com.rackspacecloud.blueflood.io.DummyDiscoveryIO");
Object loadedModule1 = ModuleLoader.getInstance(DiscoveryIO.class, CoreConfig.DISCOVERY_MODULES);
// precondition
Assert.assertNotNull(loadedModule1);
Assert.assertEquals(DummyDiscoveryIO.class, loadedModule1.getClass());
// when
Object loadedModule2 = ModuleLoader.getInstance(DiscoveryIO.class, CoreConfig.DISCOVERY_MODULES);
// then
Assert.assertNotNull(loadedModule2);
Assert.assertSame(loadedModule1, loadedModule2);
}
@Test
public void givingDifferentKeysButSameClassYieldsTwoSeparateObjects() {
// given
Configuration.getInstance().setProperty(
CoreConfig.DISCOVERY_MODULES,
"com.rackspacecloud.blueflood.io.DummyDiscoveryIO");
// when
Object loadedModule1 = ModuleLoader.getInstance(DiscoveryIO.class, CoreConfig.DISCOVERY_MODULES);
// then
Assert.assertNotNull(loadedModule1);
Assert.assertEquals(DummyDiscoveryIO.class, loadedModule1.getClass());
// then
Assert.assertEquals(DummyDiscoveryIO.class, loadedModule1.getClass());
}
@Test
public void callingTwiceWithSameKeyButDifferentClassesYieldsTheSameObjectBothTimes() {
// TODO: This functionality is extremely misleading. It's probably not
// what was originally intended, anyways. Basically, if we pass the
// same CoreConfig enum field a second time to getInstance after
// changing the configuration value for that key, ModuleLoader will
// still give us back the object that it loaded the first time. This is
// the case even if we specify completely incompatible classes each
// time, which could lead to runtime casting exceptions.
// given
Configuration.getInstance().setProperty(
CoreConfig.DISCOVERY_MODULES,
"com.rackspacecloud.blueflood.io.DummyDiscoveryIO");
Object loadedModule1 = ModuleLoader.getInstance(DiscoveryIO.class, CoreConfig.DISCOVERY_MODULES);
// precondition
Assert.assertNotNull(loadedModule1);
Assert.assertEquals(DummyDiscoveryIO.class, loadedModule1.getClass());
// when
Configuration.getInstance().setProperty(
CoreConfig.DISCOVERY_MODULES,
"com.rackspacecloud.blueflood.io.DummyDiscoveryIO2");
Object loadedModule2 = ModuleLoader.getInstance(DiscoveryIO.class, CoreConfig.DISCOVERY_MODULES);
// then
Assert.assertNotNull(loadedModule2);
Assert.assertSame(loadedModule1, loadedModule2);
}
@Test
public void specifyingAnInterfaceYieldsNull() {
// given
Configuration.getInstance().setProperty(
CoreConfig.DISCOVERY_MODULES,
"com.rackspacecloud.blueflood.io.DiscoveryIO");
// when
Object loadedModule = ModuleLoader.getInstance(DiscoveryIO.class, CoreConfig.DISCOVERY_MODULES);
// then
Assert.assertNull(loadedModule);
}
@Test
public void classWithNoParameterlessConstructorYieldsNull() {
// given
Configuration.getInstance().setProperty(
CoreConfig.DISCOVERY_MODULES,
"com.rackspacecloud.blueflood.io.DummyDiscoveryIO4");
// when
Object loadedModule = ModuleLoader.getInstance(DiscoveryIO.class, CoreConfig.DISCOVERY_MODULES);
// then
Assert.assertNull(loadedModule); // ClassLoader.loadClass will throw an InstantiationException
}
@Test
public void packagePrivateClassYieldsNull() {
// given
Configuration.getInstance().setProperty(
CoreConfig.DISCOVERY_MODULES,
"com.rackspacecloud.blueflood.io.DummyDiscoveryIO5");
// when
Object loadedModule = ModuleLoader.getInstance(DiscoveryIO.class, CoreConfig.DISCOVERY_MODULES);
// then
Assert.assertNull(loadedModule); // Class.newInstance will throw an IllegalAccessException
}
}