PageRenderTime 45ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/atlassian-plugins-core/src/test/java/com/atlassian/plugin/jmx/TestAbstractJmxBridge.java

https://bitbucket.org/purewind/atlassian-plugins
Java | 279 lines | 205 code | 60 blank | 14 comment | 0 complexity | f6c4e0a0d359f02a1512c7ca5315e19f MD5 | raw file
  1. package com.atlassian.plugin.jmx;
  2. import org.hamcrest.Matchers;
  3. import org.junit.Before;
  4. import org.junit.Rule;
  5. import org.junit.Test;
  6. import org.junit.rules.ExpectedException;
  7. import javax.management.InstanceNotFoundException;
  8. import javax.management.MBeanServer;
  9. import javax.management.ObjectName;
  10. import javax.management.RuntimeMBeanException;
  11. import java.lang.management.ManagementFactory;
  12. import java.util.concurrent.atomic.AtomicInteger;
  13. import static org.hamcrest.MatcherAssert.assertThat;
  14. import static org.hamcrest.Matchers.containsString;
  15. import static org.hamcrest.Matchers.instanceOf;
  16. import static org.hamcrest.Matchers.is;
  17. public class TestAbstractJmxBridge {
  18. private static final boolean NONDEFAULT_BOOLEAN = true;
  19. private static final char NONDEFAULT_CHAR = 'A';
  20. private static final byte NONDEFAULT_BYTE = 1;
  21. private static final short NONDEFAULT_SHORT = 2;
  22. private static final int NONDEFAULT_INT = 3;
  23. private static final long NONDEFAULT_LONG = 4;
  24. private static final float NONDEFAULT_FLOAT = 5;
  25. private static final double NONDEFAULT_DOUBLE = 6;
  26. private static final String NONDEFAULT_STRING = "B";
  27. @Rule
  28. public ExpectedException expectedException = ExpectedException.none();
  29. @SuppressWarnings("UnusedDeclaration")
  30. public interface SampleMXBean {
  31. boolean getBoolean();
  32. char getChar();
  33. byte getByte();
  34. short getShort();
  35. int getInt();
  36. long getLong();
  37. float getFloat();
  38. double getDouble();
  39. String getString();
  40. void operation();
  41. String concat(String left, String right);
  42. }
  43. /**
  44. * Test class for abstract {@link AbstractJmxBridge}.
  45. * <p/>
  46. * As well as a test class, this serves as an example for the idiomatic usage {@link AbstractJmxBridge}.
  47. */
  48. private static class SampleJmxBridge extends AbstractJmxBridge<SampleMXBean> implements SampleMXBean {
  49. /**
  50. * Counter for uniqueifying jmx object names.
  51. */
  52. private static final AtomicInteger nextJmxInstance = new AtomicInteger();
  53. private int operationCount;
  54. public SampleJmxBridge() {
  55. super(JmxUtil.objectName(nextJmxInstance, "Sample"), SampleMXBean.class);
  56. }
  57. @Override
  58. protected SampleMXBean getMXBean() {
  59. return this;
  60. }
  61. public int getOperationCount() {
  62. return operationCount;
  63. }
  64. @Override
  65. public boolean getBoolean() {
  66. return NONDEFAULT_BOOLEAN;
  67. }
  68. @Override
  69. public char getChar() {
  70. return NONDEFAULT_CHAR;
  71. }
  72. @Override
  73. public byte getByte() {
  74. return NONDEFAULT_BYTE;
  75. }
  76. @Override
  77. public short getShort() {
  78. return NONDEFAULT_SHORT;
  79. }
  80. @Override
  81. public int getInt() {
  82. return NONDEFAULT_INT;
  83. }
  84. @Override
  85. public long getLong() {
  86. return NONDEFAULT_LONG;
  87. }
  88. @Override
  89. public float getFloat() {
  90. return NONDEFAULT_FLOAT;
  91. }
  92. @Override
  93. public double getDouble() {
  94. return NONDEFAULT_DOUBLE;
  95. }
  96. @Override
  97. public String getString() {
  98. return NONDEFAULT_STRING;
  99. }
  100. @Override
  101. public void operation() {
  102. ++operationCount;
  103. }
  104. @Override
  105. public String concat(final String left, final String right) {
  106. return left + right;
  107. }
  108. }
  109. private SampleJmxBridge sampleJmxBridge;
  110. private MBeanServer platformMBeanServer;
  111. @Before
  112. public void setUp() throws Exception {
  113. sampleJmxBridge = new SampleJmxBridge();
  114. platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
  115. }
  116. @Test
  117. public void getObjectNameMentionsType() {
  118. final ObjectName objectName = sampleJmxBridge.getObjectName();
  119. assertThat(objectName.toString(), containsString("Sample"));
  120. }
  121. @Test
  122. public void notExposedToJmxBeforeRegister() throws Exception {
  123. final ObjectName objectName = sampleJmxBridge.getObjectName();
  124. expectedException.expect(InstanceNotFoundException.class);
  125. expectedException.expectMessage(objectName.toString());
  126. platformMBeanServer.invoke(objectName, "operation", new Object[0], new String[0]);
  127. }
  128. @Test
  129. public void registerExposesToJmx() throws Exception {
  130. final ObjectName objectName = sampleJmxBridge.getObjectName();
  131. sampleJmxBridge.register();
  132. final int before = sampleJmxBridge.getOperationCount();
  133. platformMBeanServer.invoke(objectName, "operation", new Object[0], new String[0]);
  134. assertThat(sampleJmxBridge.getOperationCount(), is(before + 1));
  135. }
  136. @Test
  137. public void primitiveTypesAreReturnedBoxed() throws Exception {
  138. // Originally the proxy had some special case code around primitives, so i'm leaving these tests here as they not costly
  139. final ObjectName objectName = sampleJmxBridge.getObjectName();
  140. sampleJmxBridge.register();
  141. final Object aBoolean = platformMBeanServer.getAttribute(objectName, "Boolean");
  142. assertThat(aBoolean, instanceOf(Boolean.class));
  143. assertThat((Boolean) aBoolean, is(NONDEFAULT_BOOLEAN));
  144. final Object aChar = platformMBeanServer.getAttribute(objectName, "Char");
  145. assertThat(aChar, instanceOf(Character.class));
  146. assertThat((Character) aChar, is(NONDEFAULT_CHAR));
  147. final Object aByte = platformMBeanServer.getAttribute(objectName, "Byte");
  148. assertThat(aByte, instanceOf(Byte.class));
  149. assertThat((Byte) aByte, is(NONDEFAULT_BYTE));
  150. final Object aShort = platformMBeanServer.getAttribute(objectName, "Short");
  151. assertThat(aShort, instanceOf(Short.class));
  152. assertThat((Short) aShort, is(NONDEFAULT_SHORT));
  153. final Object anInt = platformMBeanServer.getAttribute(objectName, "Int");
  154. assertThat(anInt, instanceOf(Integer.class));
  155. assertThat((Integer) anInt, is(NONDEFAULT_INT));
  156. final Object aLong = platformMBeanServer.getAttribute(objectName, "Long");
  157. assertThat(aLong, instanceOf(Long.class));
  158. assertThat((Long) aLong, is(NONDEFAULT_LONG));
  159. final Object aFloat = platformMBeanServer.getAttribute(objectName, "Float");
  160. assertThat(aFloat, instanceOf(Float.class));
  161. assertThat((Float) aFloat, is(NONDEFAULT_FLOAT));
  162. final Object aDouble = platformMBeanServer.getAttribute(objectName, "Double");
  163. assertThat(aDouble, instanceOf(Double.class));
  164. assertThat((Double) aDouble, is(NONDEFAULT_DOUBLE));
  165. final Object aString = platformMBeanServer.getAttribute(objectName, "String");
  166. assertThat(aString, instanceOf(String.class));
  167. assertThat((String) aString, is(NONDEFAULT_STRING));
  168. }
  169. @Test
  170. public void parametersArePassedCorrectly() throws Exception {
  171. final ObjectName objectName = sampleJmxBridge.getObjectName();
  172. sampleJmxBridge.register();
  173. final Object[] params = {"left", "right"};
  174. final String[] signature = new String[]{String.class.getName(), String.class.getName()};
  175. final Object result = platformMBeanServer.invoke(objectName, "concat", params, signature);
  176. assertThat(result, instanceOf(String.class));
  177. assertThat((String) result, is("leftright"));
  178. }
  179. @Test
  180. public void notExposedToJmxAfterUnregister() throws Exception {
  181. final ObjectName objectName = sampleJmxBridge.getObjectName();
  182. sampleJmxBridge.register();
  183. sampleJmxBridge.unregister();
  184. expectedException.expect(InstanceNotFoundException.class);
  185. expectedException.expectMessage(objectName.toString());
  186. platformMBeanServer.invoke(objectName, "operation", new Object[0], new String[0]);
  187. }
  188. @Test
  189. public void throwsIllegalStateExceptionIfReferenceIsCleared() throws Exception {
  190. // This is as close to testing the garbage collection can be easily managed
  191. final ObjectName objectName = sampleJmxBridge.getObjectName();
  192. // registerInternal is just register but exposing state we can use to fake garbage collection.
  193. final AbstractJmxBridge.WeakMXBeanInvocationHandler<SampleMXBean> invocationHandler = sampleJmxBridge.registerInternal();
  194. // Quick check that registerInternal works as expected to validate the test
  195. final Object aString = platformMBeanServer.getAttribute(objectName, "String");
  196. assertThat(aString, instanceOf(String.class));
  197. assertThat((String) aString, is(NONDEFAULT_STRING));
  198. invocationHandler.getImplementationReference().clear();
  199. expectedException.expect(RuntimeMBeanException.class);
  200. expectedException.expectCause(Matchers.<Throwable>instanceOf(IllegalStateException.class));
  201. expectedException.expectMessage(objectName.toString());
  202. platformMBeanServer.invoke(objectName, "operation", new Object[0], new String[0]);
  203. }
  204. @Test
  205. public void usageAfterReferenceClearsCausesUnregister() throws Exception {
  206. final ObjectName objectName = sampleJmxBridge.getObjectName();
  207. final AbstractJmxBridge.WeakMXBeanInvocationHandler<SampleMXBean> invocationHandler = sampleJmxBridge.registerInternal();
  208. invocationHandler.getImplementationReference().clear();
  209. try {
  210. platformMBeanServer.invoke(objectName, "operation", new Object[0], new String[0]);
  211. } catch (RuntimeMBeanException ermb) {
  212. // Expected
  213. }
  214. // Note that this is the same exception shape as use before registration
  215. expectedException.expect(InstanceNotFoundException.class);
  216. expectedException.expectMessage(objectName.toString());
  217. platformMBeanServer.invoke(objectName, "operation", new Object[0], new String[0]);
  218. }
  219. }