package org.marketcetera.module;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Pattern;
import javax.management.JMX;
import org.junit.Test;
import org.marketcetera.util.log.SLF4JLoggerProxy;
import org.marketcetera.util.misc.ClassVersion;
/* $License$ */
/**
* Tests integration of module configuration provider
* with module manager.
*
* @author anshul@marketcetera.com
*/
@ClassVersion("$Id: ConfigurationProviderTest.java 16154 2012-07-14 16:34:05Z colin $")
public class ConfigurationProviderTest extends ConfigurationProviderTestBase {
/**
* Verifies the behavior without configuration provider.
*
* @throws Exception if there unexpected errors.
*/
@Test
public void noProvider() throws Exception {
// Create a module manager without provider
// and verify that module factory and instances
// get empty values
mManager = new ModuleManager();
mManager.init();
verifyEmptyValues();
}
/**
* Verifies the behavior when the configuration provider has
* no default values for module factory / instances.
*
* @throws Exception if there unexpected errors.
*/
@Test
public void providerNoValues() throws Exception {
// Create a module manager with provider that has no values
// and verify that module factory and instances
// get default values
mManager = new ModuleManager();
MockConfigurationProvider provider = new MockConfigurationProvider();
mManager.setConfigurationProvider(provider);
mManager.init();
verifyEmptyValues();
assertEquals(25, provider.getFetches());
}
/**
* Tests the behavior where default values are provider for various
* data types.
*
* @throws Exception if there unexpected errors.
*/
@Test
public void providerWithValues() throws Exception {
// Create a module manager with provider that has values
// and verify that module factory and instances
// get supplied values
mManager = new ModuleManager();
MockConfigurationProvider provider = new MockConfigurationProvider();
String maxLimit = "5434543.8934";
provider.addValue(ConfigurationProviderTestFactory.PROVIDER_URN,
"MaxLimit", maxLimit);
ModuleURN instanceURN = new ModuleURN(ConfigurationProviderTestFactory.PROVIDER_URN,
"values");
provider.addValue(instanceURN,"Boolean","true");
provider.addValue(instanceURN,"Byte","13");
provider.addValue(instanceURN,"Character","m");
provider.addValue(instanceURN,"Decimal","123456789.123456789");
provider.addValue(instanceURN,"Double","2345.8789");
provider.addValue(instanceURN,"FactoryAnnotation","anno");
provider.addValue(instanceURN,"File","/my/file");
provider.addValue(instanceURN,"Float","123.123");
provider.addValue(instanceURN,"Int","123456");
provider.addValue(instanceURN,"Integer","123456789");
provider.addValue(instanceURN,"Long","123456789");
provider.addValue(instanceURN,"PrimByte","124");
provider.addValue(instanceURN,"PrimCharacter","c");
provider.addValue(instanceURN,"PrimDouble","123456.123456");
provider.addValue(instanceURN,"PrimFloat","321.321");
provider.addValue(instanceURN,"PrimInt","654321");
provider.addValue(instanceURN,"PrimLong","987654321");
provider.addValue(instanceURN,"PrimShort","321");
provider.addValue(instanceURN,"Short","123");
provider.addValue(instanceURN,"String","theory");
provider.addValue(instanceURN,"URL","http://blah.com");
provider.addValue(instanceURN,"PrimBoolean","true");
mManager.setConfigurationProvider(provider);
mManager.init();
ConfigurationProviderFactoryMXBean factory = JMX.newMXBeanProxy(
getMBeanServer(),
ConfigurationProviderTestFactory.PROVIDER_URN.toObjectName(),
ConfigurationProviderFactoryMXBean.class);
assertEquals(new BigDecimal("5434543.8934"),factory.getMaxLimit());
assertEquals(new BigInteger("0"),factory.getInstances());
//Create a module and verify all its values are empty
mManager.createModule(ConfigurationProviderTestFactory.PROVIDER_URN,
instanceURN);
JMXTestModuleMXBean module = JMX.newMXBeanProxy(getMBeanServer(),
instanceURN.toObjectName(), JMXTestModuleMXBean.class);
assertEquals(true,module.getBoolean());
assertEquals(new Byte((byte) 13), module.getByte());
assertEquals(new Character('m'), module.getCharacter());
assertEquals(new BigDecimal("123456789.123456789"),module.getDecimal());
assertEquals(new Double("2345.8789"),module.getDouble());
assertEquals("anno",module.getFactoryAnnotation());
assertEquals("/my/file", module.getFile());
assertEquals(new Float("123.123"), module.getFloat());
assertEquals(new Integer(123456), module.getInt());
assertEquals(new BigInteger("123456789"), module.getInteger());
assertEquals(new Long("123456789"),module.getLong());
assertEquals(true,module.isPrimBoolean());
assertEquals(124,module.getPrimByte());
assertEquals('c', module.getPrimCharacter());
assertEquals(123456.123456, module.getPrimDouble(),0.0);
assertEquals(321.321f, module.getPrimFloat(),0.0);
assertEquals(654321, module.getPrimInt());
assertEquals(987654321l, module.getPrimLong());
assertEquals(321,module.getPrimShort());
assertEquals(new Short((short) 123), module.getShort());
assertEquals("theory", module.getString());
assertEquals("http://blah.com", module.getURL());
assertEquals(25, provider.getFetches());
}
/**
* Verifies that the provider is refreshed when the module manager
* is refreshed.
*
* @throws Exception if there unexpected errors.
*/
@Test
public void providerRefresh() throws Exception {
mManager = new ModuleManager();
MockConfigurationProvider provider = new MockConfigurationProvider();
mManager.setConfigurationProvider(provider);
mManager.init();
assertFalse(provider.isRefreshInvoked());
mManager.refresh();
assertTrue(provider.isRefreshInvoked());
}
/**
* Verifies the behavior when errors are encountered converting the
* default values from string to the factory bean attribute's data type
* when doing a {@link ModuleManager#init()}.
*
* @throws Exception if there unexpected errors.
*/
@Test
public void valueConversionFailureFactoryInit() throws Exception {
mManager = new ModuleManager();
MockConfigurationProvider provider = new MockConfigurationProvider();
String maxLimit = "ksdfikjor9390ue93";
provider.addValue(ConfigurationProviderTestFactory.PROVIDER_URN,
"MaxLimit", maxLimit);
mManager.setConfigurationProvider(provider);
new ExpectedFailure<BeanAttributeSetException>(
Messages.UNABLE_SET_ATTRIBUTE,
"MaxLimit", maxLimit,
ConfigurationProviderTestFactory.PROVIDER_URN.toObjectName()){
protected void run() throws Exception {
mManager.init();
}
};
}
/**
* Verifies the behavior when errors are encountered converting the
* default values from string to the factory bean attribute's data type
* when doing a {@link ModuleManager#refresh()}. Also, verifies that
* the class can be loaded after the error is fixed.
*
* @throws Exception if there unexpected errors.
*/
@Test
public void valueConversionFailureFactoryRefresh() throws Exception {
//Use the test loader to not load the factory during init, but load
//it during refresh.
ModuleTestClassLoader loader = new ModuleTestClassLoader(
LifecycleTest.class.getClassLoader());
mManager = new ModuleManager(loader);
MockConfigurationProvider provider = new MockConfigurationProvider();
String maxLimit = "ksdfikjor9390ue93";
provider.addValue(ConfigurationProviderTestFactory.PROVIDER_URN,
"MaxLimit", maxLimit);
mManager.setConfigurationProvider(provider);
loader.setFilterResources(Pattern.compile(".*test.*"));
loader.setFailClasses(Pattern.compile(".*ConfigurationProviderTestFactory.*"));
mManager.init();
//verify that the provider is not loaded
List<ModuleURN> providers = mManager.getProviders();
assertFalse(providers.toString(), providers.contains(
ConfigurationProviderTestFactory.PROVIDER_URN));
//now set the provider class to get loaded.
loader.setFailClasses(null);
loader.setFilterResources(null);
new ExpectedFailure<BeanAttributeSetException>(
Messages.UNABLE_SET_ATTRIBUTE,
"MaxLimit", maxLimit,
ConfigurationProviderTestFactory.PROVIDER_URN.toObjectName()){
protected void run() throws Exception {
mManager.refresh();
}
};
//verify that the provider is not loaded
providers = mManager.getProviders();
assertFalse(providers.toString(), providers.contains(
ConfigurationProviderTestFactory.PROVIDER_URN));
//now fix the error and retry refresh, it should pass
maxLimit = "3437930";
provider.addValue(ConfigurationProviderTestFactory.PROVIDER_URN,
"MaxLimit", maxLimit);
mManager.refresh();
providers = mManager.getProviders();
assertTrue(providers.toString(), providers.contains(
ConfigurationProviderTestFactory.PROVIDER_URN));
//verify that the attribute has the expected value
ConfigurationProviderFactoryMXBean factory = JMX.newMXBeanProxy(
getMBeanServer(),
ConfigurationProviderTestFactory.PROVIDER_URN.toObjectName(),
ConfigurationProviderFactoryMXBean.class);
assertEquals(new BigDecimal("3437930"),factory.getMaxLimit());
}
/**
* Verifies the behavior when errors are encountered converting the
* default values from string to the instance bean attribute's data type.
* And that the instance can be successfully instantiated after the error
* is fixed.
*
* @throws Exception if there were errors
*/
@Test
public void valueConversionFailureInstance() throws Exception {
mManager = new ModuleManager();
MockConfigurationProvider provider = new MockConfigurationProvider();
mManager.setConfigurationProvider(provider);
mManager.init();
//Setup one of the instance properties to fail on conversion.
final ModuleURN instanceURN = new ModuleURN(
ConfigurationProviderTestFactory.PROVIDER_URN, "values");
String value = "234afjklj45r34";
provider.addValue(instanceURN,"Int",value);
new ExpectedFailure<BeanAttributeSetException>(
Messages.UNABLE_SET_ATTRIBUTE,
"Int", value,
instanceURN.toObjectName()){
protected void run() throws Exception {
mManager.createModule(instanceURN.parent(), instanceURN);
}
};
//fix the error
value = "2343";
provider.addValue(instanceURN,"Int",value);
//verify that the instance can be created
assertEquals(instanceURN, mManager.createModule(instanceURN.parent(),
instanceURN));
//verify the attribute has the expected value
JMXTestModuleMXBean module = JMX.newMXBeanProxy(getMBeanServer(),
instanceURN.toObjectName(), JMXTestModuleMXBean.class);
assertEquals(new Integer(2343), module.getInt());
}
/**
* A mock configuration provider for unit testing.
*/
public static class MockConfigurationProvider
implements ModuleConfigurationProvider {
public String getDefaultFor(ModuleURN inURN, String inAttribute) {
SLF4JLoggerProxy.debug(this, "{} {}:", inURN, inAttribute);
mFetches++;
return mValues.get(new Tuple(inURN, inAttribute));
}
public void refresh() throws ModuleException {
mRefreshInvoked = true;
}
public int getFetches() {
return mFetches;
}
public boolean isRefreshInvoked() {
return mRefreshInvoked;
}
public void addValue(ModuleURN inURN, String inName, String inValue) {
mValues.put(new Tuple(inURN, inName), inValue);
}
private boolean mRefreshInvoked = false;
private int mFetches = 0;
private HashMap<Tuple,String> mValues = new HashMap<Tuple, String>();
}
/**
* A class to keep track of attribute names for module
* factory / instances.
*/
private static class Tuple {
private Tuple(ModuleURN inURN, String inName) {
mURN = inURN;
mName = inName;
}
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Tuple tuple = (Tuple) o;
return mName.equals(tuple.mName) && mURN.equals(tuple.mURN);
}
public int hashCode() {
int result;
result = mURN.hashCode();
result = 31 * result + mName.hashCode();
return result;
}
private ModuleURN mURN;
private String mName;
}
}