package org.cyclopsgroup.jmxterm.cmd; import static org.junit.Assert.assertEquals; import java.io.IOException; import java.io.StringWriter; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import javax.management.JMException; import javax.management.MBeanAttributeInfo; import javax.management.MBeanInfo; import javax.management.MBeanServerConnection; import javax.management.ObjectName; import javax.management.openmbean.CompositeDataSupport; import javax.management.openmbean.CompositeType; import javax.management.openmbean.OpenDataException; import javax.management.openmbean.SimpleType; import org.apache.commons.lang.RandomStringUtils; import org.apache.commons.lang.SystemUtils; import org.cyclopsgroup.jmxterm.MockSession; import org.jmock.Expectations; import org.jmock.Mockery; import org.jmock.lib.legacy.ClassImposteriser; import org.junit.Before; import org.junit.Test; /** * Test case of {@link GetCommand} * * @author <a href="mailto:jiaqi.guo@gmail.com">Jiaqi Guo</a> */ public class GetCommandTest { private GetCommand command; private Mockery context; private StringWriter output; private void getAttributeAndVerify( final String domain, String bean, final String attribute, final String expectedBean, final Object expectedValue, final boolean singleLine, final String delimiter) { command.setDomain( domain ); command.setBean( bean ); command.setAttributes( Arrays.asList( attribute ) ); command.setSimpleFormat( true ); command.setSingleLine( singleLine ); command.setDelimiter( delimiter ); final String[] attributePath = attribute.split("\\."); final MBeanServerConnection con = context.mock( MBeanServerConnection.class ); final MBeanInfo beanInfo = context.mock( MBeanInfo.class ); final MBeanAttributeInfo attributeInfo = context.mock( MBeanAttributeInfo.class ); try { context.checking( new Expectations() { { one( con ).getDomains(); will( returnValue( new String[] { domain, RandomStringUtils.randomAlphabetic( 5 ) } ) ); allowing( con ).getMBeanInfo( new ObjectName( expectedBean ) ); will( returnValue( beanInfo ) ); one( beanInfo ).getAttributes(); will( returnValue( new MBeanAttributeInfo[] { attributeInfo } ) ); allowing( attributeInfo ).getName(); will( returnValue( attributePath[0] ) ); allowing( attributeInfo ).isReadable(); will( returnValue( true ) ); one( con ).getAttribute( new ObjectName( expectedBean ), attributePath[0] ); will( returnValue( expectedValue ) ); } } ); command.setSession( new MockSession( output, con ) ); command.execute(); context.assertIsSatisfied(); Object nestedExpectedValue = expectedValue; if ( expectedValue instanceof CompositeDataSupport ) { nestedExpectedValue = ((CompositeDataSupport)expectedValue).get(attributePath[1]); } assertEquals( nestedExpectedValue.toString() + delimiter + (singleLine ? "" : SystemUtils.LINE_SEPARATOR), output.toString() ); } catch ( JMException e ) { throw new RuntimeException( "Test failed for unexpected JMException", e ); } catch ( IOException e ) { throw new RuntimeException( "Test failed for unexpected IOException", e ); } } /** * Set up class to test */ @Before public void setUp() { command = new GetCommand(); context = new Mockery(); context.setImposteriser( ClassImposteriser.INSTANCE ); output = new StringWriter(); } /** * Test normal execution */ @Test public void testExecuteNormally() { getAttributeAndVerify( "a", "type=x", "a", "a:type=x", "bingo", false, "" ); } /** * Verify non string type is formatted into string */ @Test public void testExecuteWithNonStringType() { getAttributeAndVerify( "a", "type=x", "a", "a:type=x", new Integer( 10 ), false, "" ); } @Test public void testExecuteWithSlashInDomainName() { getAttributeAndVerify( "a/b", "type=c", "a", "a/b:type=c", "bingo", false, "" ); } /** * Verify attribute name with dash, underline and dot is acceptable * @throws OpenDataException */ @Test public void testExecuteWithStrangeAttributeName() throws OpenDataException { final Map<String, Object> entries = new HashMap<String, Object>(); entries.put("d", "bingo"); final CompositeType compositeType = context.mock(CompositeType.class); context.checking( new Expectations() { { one( compositeType ).keySet(); will( returnValue( entries.keySet() ) ); one ( compositeType ).getType( "d" ); will( returnValue( SimpleType.STRING ) ); } } ); Object expectedValue = new CompositeDataSupport(compositeType, entries); getAttributeAndVerify( "a", "type=x", "a_b-c.d", "a:type=x", expectedValue, false, "" ); } /** * Verify unusual bean name and domain name is acceptable */ @Test public void testExecuteWithUnusualDomainAndBeanName() { getAttributeAndVerify( "a-a", "a.b-c_d=x-y.z", "a", "a-a:a.b-c_d=x-y.z", "bingo", false, "" ); } /** * Verify that delimiters are working */ @Test public void testExecuteWithDelimiters() { getAttributeAndVerify( "a", "type=x", "a", "a:type=x", "bingo", false, "," ); } /** * Verify that single line output is working */ @Test public void testExecuteForSingleLineOutput() { getAttributeAndVerify( "a", "type=x", "a", "a:type=x", "bingo", true, "" ); } }