/** * Copyright (C) 2009-2013 FoundationDB, LLC * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.foundationdb.server.service.jmx; import static org.junit.Assert.assertEquals; import java.util.HashSet; import java.util.Set; import javax.management.MalformedObjectNameException; import javax.management.ObjectName; import org.junit.Test; public final class JmxRegistryServiceImplTest { private interface TestMXBean { public int getInt(); } private interface NotMXBeanInterface { public int getInt(); } private interface SubInterface extends TestMXBean { } private static class GoodService implements TestMXBean, JmxManageable { private final String name; private GoodService(String name) { this.name = name; } @Override public int getInt() { return 2; } @Override public JmxObjectInfo getJmxObjectInfo() { return new JmxObjectInfo(name, this, TestMXBean.class); } } private static class MockedJmxRegistry extends JmxRegistryServiceImpl { final MBeanServerProxy.MockMBeanServer mock = MBeanServerProxy.getMock(); @Override protected MBeanServerProxy.MockMBeanServer getMBeanServer() { return mock; } } @Test(expected=JmxRegistrationException.class) public void managedClassNotAnInterface() { class MyMXBean implements JmxManageable { public int getInt() { return 1; } @Override public JmxObjectInfo getJmxObjectInfo() { return new JmxObjectInfo("Test", this, MyMXBean.class); } } MockedJmxRegistry service = new MockedJmxRegistry(); final MyMXBean probe = new MyMXBean(); service.validate(probe.getJmxObjectInfo()); } @Test(expected=JmxRegistrationException.class) public void managedInterfaceNotWellNamed() { class MyMXBean implements JmxManageable, NotMXBeanInterface { public int getInt() { return 1; } @Override public JmxObjectInfo getJmxObjectInfo() { return new JmxObjectInfo("Test", this, MyMXBean.class); } } final MyMXBean probe = new MyMXBean(); MockedJmxRegistry service = new MockedJmxRegistry(); service.validate(probe.getJmxObjectInfo()); } @Test public void managedInterfaceGood() { class MyMXBean implements JmxManageable, TestMXBean { public int getInt() { return 1; } @Override public JmxObjectInfo getJmxObjectInfo() { return new JmxObjectInfo("Test", this, MyMXBean.class); } } final MyMXBean probe = new MyMXBean(); MockedJmxRegistry service = new MockedJmxRegistry(); service.validate(probe.getJmxObjectInfo()); } @Test public void managedSubInterfaceGood() { class MyMXBean implements JmxManageable, SubInterface { public int getInt() { return 1; } @Override public JmxObjectInfo getJmxObjectInfo() { return new JmxObjectInfo("Test", this, MyMXBean.class); } } final MyMXBean probe = new MyMXBean(); MockedJmxRegistry service = new MockedJmxRegistry(); service.validate(probe.getJmxObjectInfo()); } @Test public void registerThenStart() { MockedJmxRegistry service = new MockedJmxRegistry(); assertRegisteredServices(service); service.register(new GoodService("Alpha")); assertRegisteredServices(service); service.start(); assertRegisteredServices(service, "com.foundationdb:type=Alpha"); service.stop(); assertRegisteredServices(service); } @Test public void registerAfterStarting() { MockedJmxRegistry service = new MockedJmxRegistry(); assertRegisteredServices(service); service.start(); service.register(new GoodService("Alpha")); assertRegisteredServices(service, "com.foundationdb:type=Alpha"); service.stop(); assertRegisteredServices(service); } @Test public void registerThenRestart() { MockedJmxRegistry service = new MockedJmxRegistry(); assertRegisteredServices(service); service.register(new GoodService("Alpha")); assertRegisteredServices(service); service.start(); assertRegisteredServices(service, "com.foundationdb:type=Alpha"); service.stop(); assertRegisteredServices(service); service.start(); assertRegisteredServices(service, "com.foundationdb:type=Alpha"); } @Test public void registerInterfaceTwice() { final MockedJmxRegistry service; try { service = new MockedJmxRegistry(); assertRegisteredServices(service); service.register(new GoodService("Alpha")); } catch (Throwable t) { throw new RuntimeException(t); } service.register(new GoodService("Beta")); service.start(); assertRegisteredServices(service, "com.foundationdb:type=Alpha", "com.foundationdb:type=Beta"); } @Test(expected=JmxRegistrationException.class) public void registerNameTwice() { final MockedJmxRegistry service; try { service = new MockedJmxRegistry(); assertRegisteredServices(service); service.register(new GoodService("Alpha")); } catch (Throwable t) { throw new RuntimeException(t); } service.register(new GoodService("Alpha")); } private void assertRegisteredServices(MockedJmxRegistry registry, String... actuals) { assertRegisteredServices(registry.getMBeanServer().getRegisteredObjectNames(), actuals); } private void assertRegisteredServices(Set<ObjectName> actual, String... expecteds) { Set<ObjectName> expectedSet = new HashSet<>(); for (String expected : expecteds) { try { expectedSet.add(new ObjectName(expected)); } catch (MalformedObjectNameException e) { throw new RuntimeException(e); } } assertEquals("registered services", expectedSet, actual); } }