Make MBeanServer tests more robust
This commit refactors several tests to use SocketUtils to find an available port, compose a custom JMX service URL using that port, and start an MBeanServer for the particular test using that port. This commit also makes other changes to MBeanServer related tests in an effort to make them more robust when executed concurrently. Closes gh-23699
This commit is contained in:
parent
57b4b74e7d
commit
74b7b550f6
|
|
@ -24,15 +24,16 @@ import javax.management.ObjectName;
|
|||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.api.extension.LifecycleMethodExecutionExceptionHandler;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
import org.junit.jupiter.api.extension.TestExecutionExceptionHandler;
|
||||
import org.opentest4j.TestAbortedException;
|
||||
|
||||
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.jmx.AbstractMBeanServerTests.BindExceptionHandler;
|
||||
import org.springframework.jmx.export.MBeanExporter;
|
||||
import org.springframework.util.MBeanTestUtils;
|
||||
|
||||
|
|
@ -57,11 +58,9 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||
* @author Chris Beams
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@ExtendWith(BindExceptionHandler.class)
|
||||
public abstract class AbstractMBeanServerTests {
|
||||
|
||||
@RegisterExtension
|
||||
BindExceptionHandler bindExceptionHandler = new BindExceptionHandler();
|
||||
|
||||
protected MBeanServer server;
|
||||
|
||||
|
||||
|
|
@ -77,14 +76,6 @@ public abstract class AbstractMBeanServerTests {
|
|||
}
|
||||
}
|
||||
|
||||
protected ConfigurableApplicationContext loadContext(String configLocation) {
|
||||
GenericApplicationContext ctx = new GenericApplicationContext();
|
||||
new XmlBeanDefinitionReader(ctx).loadBeanDefinitions(configLocation);
|
||||
ctx.getDefaultListableBeanFactory().registerSingleton("server", this.server);
|
||||
ctx.refresh();
|
||||
return ctx;
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void tearDown() throws Exception {
|
||||
releaseServer();
|
||||
|
|
@ -92,17 +83,32 @@ public abstract class AbstractMBeanServerTests {
|
|||
}
|
||||
|
||||
private void releaseServer() throws Exception {
|
||||
MBeanServerFactory.releaseMBeanServer(getServer());
|
||||
try {
|
||||
MBeanServerFactory.releaseMBeanServer(getServer());
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
if (!ex.getMessage().contains("not in list")) {
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
MBeanTestUtils.resetMBeanServers();
|
||||
}
|
||||
|
||||
protected void onTearDown() throws Exception {
|
||||
protected final ConfigurableApplicationContext loadContext(String configLocation) {
|
||||
GenericApplicationContext ctx = new GenericApplicationContext();
|
||||
new XmlBeanDefinitionReader(ctx).loadBeanDefinitions(configLocation);
|
||||
ctx.getDefaultListableBeanFactory().registerSingleton("server", getServer());
|
||||
ctx.refresh();
|
||||
return ctx;
|
||||
}
|
||||
|
||||
protected void onSetUp() throws Exception {
|
||||
}
|
||||
|
||||
public MBeanServer getServer() {
|
||||
protected void onTearDown() throws Exception {
|
||||
}
|
||||
|
||||
protected final MBeanServer getServer() {
|
||||
return this.server;
|
||||
}
|
||||
|
||||
|
|
@ -123,7 +129,7 @@ public abstract class AbstractMBeanServerTests {
|
|||
}
|
||||
|
||||
|
||||
private static class BindExceptionHandler implements TestExecutionExceptionHandler, LifecycleMethodExecutionExceptionHandler {
|
||||
static class BindExceptionHandler implements TestExecutionExceptionHandler, LifecycleMethodExecutionExceptionHandler {
|
||||
|
||||
@Override
|
||||
public void handleTestExecutionException(ExtensionContext context, Throwable throwable) throws Throwable {
|
||||
|
|
|
|||
|
|
@ -17,6 +17,9 @@
|
|||
package org.springframework.jmx.access;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.MemoryMXBean;
|
||||
import java.lang.management.ThreadMXBean;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.BindException;
|
||||
import java.util.HashMap;
|
||||
|
|
@ -30,6 +33,7 @@ import javax.management.remote.JMXServiceURL;
|
|||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.jmx.AbstractMBeanServerTests;
|
||||
import org.springframework.jmx.IJmxTestBean;
|
||||
import org.springframework.jmx.JmxException;
|
||||
|
|
@ -50,7 +54,7 @@ import static org.junit.jupiter.api.Assumptions.assumeTrue;
|
|||
* @author Sam Brannen
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class MBeanClientInterceptorTests extends AbstractMBeanServerTests {
|
||||
class MBeanClientInterceptorTests extends AbstractMBeanServerTests {
|
||||
|
||||
protected static final String OBJECT_NAME = "spring:test=proxy";
|
||||
|
||||
|
|
@ -87,14 +91,14 @@ public class MBeanClientInterceptorTests extends AbstractMBeanServerTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testProxyClassIsDifferent() throws Exception {
|
||||
void testProxyClassIsDifferent() throws Exception {
|
||||
assumeTrue(runTests);
|
||||
IJmxTestBean proxy = getProxy();
|
||||
assertThat((proxy.getClass() != IJmxTestBean.class)).as("The proxy class should be different than the base class").isTrue();
|
||||
assertThat(proxy.getClass()).as("The proxy class should be different than the base class").isNotSameAs(IJmxTestBean.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDifferentProxiesSameClass() throws Exception {
|
||||
void testDifferentProxiesSameClass() throws Exception {
|
||||
assumeTrue(runTests);
|
||||
IJmxTestBean proxy1 = getProxy();
|
||||
IJmxTestBean proxy2 = getProxy();
|
||||
|
|
@ -104,7 +108,7 @@ public class MBeanClientInterceptorTests extends AbstractMBeanServerTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testGetAttributeValue() throws Exception {
|
||||
void testGetAttributeValue() throws Exception {
|
||||
assumeTrue(runTests);
|
||||
IJmxTestBean proxy1 = getProxy();
|
||||
int age = proxy1.getAge();
|
||||
|
|
@ -112,7 +116,7 @@ public class MBeanClientInterceptorTests extends AbstractMBeanServerTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testSetAttributeValue() throws Exception {
|
||||
void testSetAttributeValue() throws Exception {
|
||||
assumeTrue(runTests);
|
||||
IJmxTestBean proxy = getProxy();
|
||||
proxy.setName("Rob Harrop");
|
||||
|
|
@ -120,7 +124,7 @@ public class MBeanClientInterceptorTests extends AbstractMBeanServerTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testSetAttributeValueWithRuntimeException() throws Exception {
|
||||
void testSetAttributeValueWithRuntimeException() throws Exception {
|
||||
assumeTrue(runTests);
|
||||
IJmxTestBean proxy = getProxy();
|
||||
assertThatIllegalArgumentException().isThrownBy(() ->
|
||||
|
|
@ -128,7 +132,7 @@ public class MBeanClientInterceptorTests extends AbstractMBeanServerTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testSetAttributeValueWithCheckedException() throws Exception {
|
||||
void testSetAttributeValueWithCheckedException() throws Exception {
|
||||
assumeTrue(runTests);
|
||||
IJmxTestBean proxy = getProxy();
|
||||
assertThatExceptionOfType(ClassNotFoundException.class).isThrownBy(() ->
|
||||
|
|
@ -136,7 +140,7 @@ public class MBeanClientInterceptorTests extends AbstractMBeanServerTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testSetAttributeValueWithIOException() throws Exception {
|
||||
void testSetAttributeValueWithIOException() throws Exception {
|
||||
assumeTrue(runTests);
|
||||
IJmxTestBean proxy = getProxy();
|
||||
assertThatIOException().isThrownBy(() ->
|
||||
|
|
@ -144,7 +148,7 @@ public class MBeanClientInterceptorTests extends AbstractMBeanServerTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testSetReadOnlyAttribute() throws Exception {
|
||||
void testSetReadOnlyAttribute() throws Exception {
|
||||
assumeTrue(runTests);
|
||||
IJmxTestBean proxy = getProxy();
|
||||
assertThatExceptionOfType(InvalidInvocationException.class).isThrownBy(() ->
|
||||
|
|
@ -152,7 +156,7 @@ public class MBeanClientInterceptorTests extends AbstractMBeanServerTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testInvokeNoArgs() throws Exception {
|
||||
void testInvokeNoArgs() throws Exception {
|
||||
assumeTrue(runTests);
|
||||
IJmxTestBean proxy = getProxy();
|
||||
long result = proxy.myOperation();
|
||||
|
|
@ -160,7 +164,7 @@ public class MBeanClientInterceptorTests extends AbstractMBeanServerTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testInvokeArgs() throws Exception {
|
||||
void testInvokeArgs() throws Exception {
|
||||
assumeTrue(runTests);
|
||||
IJmxTestBean proxy = getProxy();
|
||||
int result = proxy.add(1, 2);
|
||||
|
|
@ -168,7 +172,7 @@ public class MBeanClientInterceptorTests extends AbstractMBeanServerTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testInvokeUnexposedMethodWithException() throws Exception {
|
||||
void testInvokeUnexposedMethodWithException() throws Exception {
|
||||
assumeTrue(runTests);
|
||||
IJmxTestBean bean = getProxy();
|
||||
assertThatExceptionOfType(InvalidInvocationException.class).isThrownBy(() ->
|
||||
|
|
@ -176,7 +180,7 @@ public class MBeanClientInterceptorTests extends AbstractMBeanServerTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testTestLazyConnectionToRemote() throws Exception {
|
||||
void testTestLazyConnectionToRemote() throws Exception {
|
||||
assumeTrue(runTests);
|
||||
|
||||
final int port = SocketUtils.findAvailableTcpPort();
|
||||
|
|
@ -219,28 +223,15 @@ public class MBeanClientInterceptorTests extends AbstractMBeanServerTests {
|
|||
catch (JmxException ex) {
|
||||
// expected
|
||||
}
|
||||
|
||||
connector = JMXConnectorServerFactory.newJMXConnectorServer(url, null, getServer());
|
||||
connector.start();
|
||||
|
||||
// should now be able to access data via the lazy proxy
|
||||
try {
|
||||
assertThat(bean.getName()).isEqualTo("Rob Harrop");
|
||||
assertThat(bean.getAge()).isEqualTo(100);
|
||||
}
|
||||
finally {
|
||||
connector.stop();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
public void testMXBeanAttributeAccess() throws Exception {
|
||||
MBeanClientInterceptor interceptor = new MBeanClientInterceptor();
|
||||
interceptor.setServer(ManagementFactory.getPlatformMBeanServer());
|
||||
interceptor.setObjectName("java.lang:type=Memory");
|
||||
interceptor.setManagementInterface(MemoryMXBean.class);
|
||||
MemoryMXBean proxy = ProxyFactory.getProxy(MemoryMXBean.class, interceptor);
|
||||
assertTrue(proxy.getHeapMemoryUsage().getMax() > 0);
|
||||
assertThat(proxy.getHeapMemoryUsage().getMax()).isGreaterThan(0);
|
||||
}
|
||||
|
||||
public void testMXBeanOperationAccess() throws Exception {
|
||||
|
|
@ -248,17 +239,9 @@ public class MBeanClientInterceptorTests extends AbstractMBeanServerTests {
|
|||
interceptor.setServer(ManagementFactory.getPlatformMBeanServer());
|
||||
interceptor.setObjectName("java.lang:type=Threading");
|
||||
ThreadMXBean proxy = ProxyFactory.getProxy(ThreadMXBean.class, interceptor);
|
||||
assertTrue(proxy.getThreadInfo(Thread.currentThread().getId()).getStackTrace() != null);
|
||||
assertThat(proxy.getThreadInfo(Thread.currentThread().getId()).getStackTrace()).isNotNull();
|
||||
}
|
||||
|
||||
public void testMXBeanAttributeListAccess() throws Exception {
|
||||
MBeanClientInterceptor interceptor = new MBeanClientInterceptor();
|
||||
interceptor.setServer(ManagementFactory.getPlatformMBeanServer());
|
||||
interceptor.setObjectName("com.sun.management:type=HotSpotDiagnostic");
|
||||
HotSpotDiagnosticMXBean proxy = ProxyFactory.getProxy(HotSpotDiagnosticMXBean.class, interceptor);
|
||||
assertFalse(proxy.getDiagnosticOptions().isEmpty());
|
||||
}
|
||||
*/
|
||||
|
||||
private static class ProxyTestAssembler extends AbstractReflectiveMBeanInfoAssembler {
|
||||
|
||||
|
|
|
|||
|
|
@ -35,16 +35,11 @@ import org.springframework.util.SocketUtils;
|
|||
* @author Chris Beams
|
||||
* @author Sam Brannen
|
||||
*/
|
||||
public class RemoteMBeanClientInterceptorTests extends MBeanClientInterceptorTests {
|
||||
class RemoteMBeanClientInterceptorTests extends MBeanClientInterceptorTests {
|
||||
|
||||
private static final int SERVICE_PORT;
|
||||
private final int servicePort = SocketUtils.findAvailableTcpPort();
|
||||
|
||||
private static final String SERVICE_URL;
|
||||
|
||||
static {
|
||||
SERVICE_PORT = SocketUtils.findAvailableTcpPort();
|
||||
SERVICE_URL = "service:jmx:jmxmp://localhost:" + SERVICE_PORT;
|
||||
}
|
||||
private final String serviceUrl = "service:jmx:jmxmp://localhost:" + servicePort;
|
||||
|
||||
|
||||
private JMXConnectorServer connectorServer;
|
||||
|
|
@ -61,13 +56,13 @@ public class RemoteMBeanClientInterceptorTests extends MBeanClientInterceptorTes
|
|||
}
|
||||
catch (BindException ex) {
|
||||
System.out.println("Skipping remote JMX tests because binding to local port ["
|
||||
+ SERVICE_PORT + "] failed: " + ex.getMessage());
|
||||
+ this.servicePort + "] failed: " + ex.getMessage());
|
||||
runTests = false;
|
||||
}
|
||||
}
|
||||
|
||||
private JMXServiceURL getServiceUrl() throws MalformedURLException {
|
||||
return new JMXServiceURL(SERVICE_URL);
|
||||
return new JMXServiceURL(this.serviceUrl);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||
/**
|
||||
* @author Rob Harrop
|
||||
*/
|
||||
public class CustomEditorConfigurerTests extends AbstractJmxTests {
|
||||
class CustomEditorConfigurerTests extends AbstractJmxTests {
|
||||
|
||||
private final SimpleDateFormat df = new SimpleDateFormat("yyyy/MM/dd");
|
||||
|
||||
|
|
@ -41,33 +41,30 @@ public class CustomEditorConfigurerTests extends AbstractJmxTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testDatesInJmx() throws Exception {
|
||||
// System.out.println(getServer().getClass().getName());
|
||||
void datesInApplicationContext() throws Exception {
|
||||
DateRange dr = getContext().getBean("dateRange", DateRange.class);
|
||||
|
||||
assertThat(dr.getStartDate()).as("startDate").isEqualTo(getStartDate());
|
||||
assertThat(dr.getEndDate()).as("endDate").isEqualTo(getEndDate());
|
||||
}
|
||||
|
||||
@Test
|
||||
void datesInJmx() throws Exception {
|
||||
ObjectName oname = new ObjectName("bean:name=dateRange");
|
||||
|
||||
Date startJmx = (Date) getServer().getAttribute(oname, "StartDate");
|
||||
Date endJmx = (Date) getServer().getAttribute(oname, "EndDate");
|
||||
|
||||
assertThat(startJmx).as("startDate ").isEqualTo(getStartDate());
|
||||
assertThat(endJmx).as("endDate ").isEqualTo(getEndDate());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDates() throws Exception {
|
||||
DateRange dr = (DateRange) getContext().getBean("dateRange");
|
||||
|
||||
assertThat(dr.getStartDate()).as("startDate ").isEqualTo(getStartDate());
|
||||
assertThat(dr.getEndDate()).as("endDate ").isEqualTo(getEndDate());
|
||||
assertThat(startJmx).as("startDate").isEqualTo(getStartDate());
|
||||
assertThat(endJmx).as("endDate").isEqualTo(getEndDate());
|
||||
}
|
||||
|
||||
private Date getStartDate() throws ParseException {
|
||||
Date start = df.parse("2004/10/12");
|
||||
return start;
|
||||
return df.parse("2004/10/12");
|
||||
}
|
||||
|
||||
private Date getEndDate() throws ParseException {
|
||||
Date end = df.parse("2004/11/13");
|
||||
return end;
|
||||
return df.parse("2004/11/13");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,10 +37,10 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
|||
* @author Rob Harrop
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
public class MBeanExporterOperationsTests extends AbstractMBeanServerTests {
|
||||
class MBeanExporterOperationsTests extends AbstractMBeanServerTests {
|
||||
|
||||
@Test
|
||||
public void testRegisterManagedResourceWithUserSuppliedObjectName() throws Exception {
|
||||
void testRegisterManagedResourceWithUserSuppliedObjectName() throws Exception {
|
||||
ObjectName objectName = ObjectNameManager.getInstance("spring:name=Foo");
|
||||
|
||||
JmxTestBean bean = new JmxTestBean();
|
||||
|
|
@ -55,7 +55,7 @@ public class MBeanExporterOperationsTests extends AbstractMBeanServerTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testRegisterExistingMBeanWithUserSuppliedObjectName() throws Exception {
|
||||
void testRegisterExistingMBeanWithUserSuppliedObjectName() throws Exception {
|
||||
ObjectName objectName = ObjectNameManager.getInstance("spring:name=Foo");
|
||||
ModelMBeanInfo info = new ModelMBeanInfoSupport("myClass", "myDescription", null, null, null, null);
|
||||
RequiredModelMBean bean = new RequiredModelMBean(info);
|
||||
|
|
@ -69,7 +69,7 @@ public class MBeanExporterOperationsTests extends AbstractMBeanServerTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testRegisterManagedResourceWithGeneratedObjectName() throws Exception {
|
||||
void testRegisterManagedResourceWithGeneratedObjectName() throws Exception {
|
||||
final ObjectName objectNameTemplate = ObjectNameManager.getInstance("spring:type=Test");
|
||||
|
||||
MBeanExporter exporter = new MBeanExporter();
|
||||
|
|
@ -95,7 +95,7 @@ public class MBeanExporterOperationsTests extends AbstractMBeanServerTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testRegisterManagedResourceWithGeneratedObjectNameWithoutUniqueness() throws Exception {
|
||||
void testRegisterManagedResourceWithGeneratedObjectNameWithoutUniqueness() throws Exception {
|
||||
final ObjectName objectNameTemplate = ObjectNameManager.getInstance("spring:type=Test");
|
||||
|
||||
MBeanExporter exporter = new MBeanExporter();
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||
* @author Rob Harrop
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class PropertyPlaceholderConfigurerTests extends AbstractJmxTests {
|
||||
class PropertyPlaceholderConfigurerTests extends AbstractJmxTests {
|
||||
|
||||
@Override
|
||||
protected String getApplicationContextPath() {
|
||||
|
|
@ -37,15 +37,15 @@ public class PropertyPlaceholderConfigurerTests extends AbstractJmxTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testPropertiesReplaced() {
|
||||
IJmxTestBean bean = (IJmxTestBean) getContext().getBean("testBean");
|
||||
void propertiesReplacedInApplicationContext() {
|
||||
IJmxTestBean bean = getContext().getBean("testBean", IJmxTestBean.class);
|
||||
|
||||
assertThat(bean.getName()).as("Name is incorrect").isEqualTo("Rob Harrop");
|
||||
assertThat(bean.getAge()).as("Age is incorrect").isEqualTo(100);
|
||||
assertThat(bean.getName()).as("Name").isEqualTo("Rob Harrop");
|
||||
assertThat(bean.getAge()).as("Age").isEqualTo(100);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPropertiesCorrectInJmx() throws Exception {
|
||||
void propertiesCorrectInJmx() throws Exception {
|
||||
ObjectName oname = new ObjectName("bean:name=proxyTestBean1");
|
||||
Object name = getServer().getAttribute(oname, "Name");
|
||||
Integer age = (Integer) getServer().getAttribute(oname, "Age");
|
||||
|
|
|
|||
|
|
@ -31,23 +31,29 @@ import javax.management.remote.JMXServiceURL;
|
|||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.jmx.AbstractMBeanServerTests;
|
||||
import org.springframework.util.SocketUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link ConnectorServerFactoryBean}.
|
||||
*
|
||||
* @author Rob Harrop
|
||||
* @author Chris Beams
|
||||
* @author Sam Brannen
|
||||
*/
|
||||
public class ConnectorServerFactoryBeanTests extends AbstractMBeanServerTests {
|
||||
class ConnectorServerFactoryBeanTests extends AbstractMBeanServerTests {
|
||||
|
||||
private static final String OBJECT_NAME = "spring:type=connector,name=test";
|
||||
|
||||
private final String serviceUrl = "service:jmx:jmxmp://localhost:" + SocketUtils.findAvailableTcpPort();
|
||||
|
||||
|
||||
@Test
|
||||
public void startupWithLocatedServer() throws Exception {
|
||||
void startupWithLocatedServer() throws Exception {
|
||||
ConnectorServerFactoryBean bean = new ConnectorServerFactoryBean();
|
||||
bean.setServiceUrl(this.serviceUrl);
|
||||
bean.afterPropertiesSet();
|
||||
|
||||
try {
|
||||
|
|
@ -59,12 +65,9 @@ public class ConnectorServerFactoryBeanTests extends AbstractMBeanServerTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void startupWithSuppliedServer() throws Exception {
|
||||
//Added a brief snooze here - seems to fix occasional
|
||||
//java.net.BindException: Address already in use errors
|
||||
Thread.sleep(1);
|
||||
|
||||
void startupWithSuppliedServer() throws Exception {
|
||||
ConnectorServerFactoryBean bean = new ConnectorServerFactoryBean();
|
||||
bean.setServiceUrl(this.serviceUrl);
|
||||
bean.setServer(getServer());
|
||||
bean.afterPropertiesSet();
|
||||
|
||||
|
|
@ -77,11 +80,9 @@ public class ConnectorServerFactoryBeanTests extends AbstractMBeanServerTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void registerWithMBeanServer() throws Exception {
|
||||
//Added a brief snooze here - seems to fix occasional
|
||||
//java.net.BindException: Address already in use errors
|
||||
Thread.sleep(1);
|
||||
void registerWithMBeanServer() throws Exception {
|
||||
ConnectorServerFactoryBean bean = new ConnectorServerFactoryBean();
|
||||
bean.setServiceUrl(this.serviceUrl);
|
||||
bean.setObjectName(OBJECT_NAME);
|
||||
bean.afterPropertiesSet();
|
||||
|
||||
|
|
@ -96,8 +97,9 @@ public class ConnectorServerFactoryBeanTests extends AbstractMBeanServerTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void noRegisterWithMBeanServer() throws Exception {
|
||||
void noRegisterWithMBeanServer() throws Exception {
|
||||
ConnectorServerFactoryBean bean = new ConnectorServerFactoryBean();
|
||||
bean.setServiceUrl(this.serviceUrl);
|
||||
bean.afterPropertiesSet();
|
||||
try {
|
||||
// Try to get the connector bean.
|
||||
|
|
@ -111,7 +113,7 @@ public class ConnectorServerFactoryBeanTests extends AbstractMBeanServerTests {
|
|||
|
||||
private void checkServerConnection(MBeanServer hostedServer) throws IOException, MalformedURLException {
|
||||
// Try to connect using client.
|
||||
JMXServiceURL serviceURL = new JMXServiceURL(ConnectorServerFactoryBean.DEFAULT_SERVICE_URL);
|
||||
JMXServiceURL serviceURL = new JMXServiceURL(this.serviceUrl);
|
||||
JMXConnector connector = JMXConnectorFactory.connect(serviceURL);
|
||||
|
||||
assertThat(connector).as("Client Connector should not be null").isNotNull();
|
||||
|
|
|
|||
|
|
@ -37,48 +37,62 @@ import org.springframework.util.ObjectUtils;
|
|||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link JmxUtils}.
|
||||
*
|
||||
* @author Rob Harrop
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
public class JmxUtilsTests {
|
||||
class JmxUtilsTests {
|
||||
|
||||
@Test
|
||||
public void testIsMBeanWithDynamicMBean() throws Exception {
|
||||
void isMBean() {
|
||||
// Correctly returns true for a class
|
||||
assertThat(JmxUtils.isMBean(JmxClass.class)).isTrue();
|
||||
|
||||
// Correctly returns false since JmxUtils won't navigate to the extended interface
|
||||
assertThat(JmxUtils.isMBean(SpecializedJmxInterface.class)).isFalse();
|
||||
|
||||
// Incorrectly returns true since it doesn't detect that this is an interface
|
||||
assertThat(JmxUtils.isMBean(JmxInterface.class)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void isMBeanWithDynamicMBean() throws Exception {
|
||||
DynamicMBean mbean = new TestDynamicMBean();
|
||||
assertThat(JmxUtils.isMBean(mbean.getClass())).as("Dynamic MBean not detected correctly").isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsMBeanWithStandardMBeanWrapper() throws Exception {
|
||||
void isMBeanWithStandardMBeanWrapper() throws Exception {
|
||||
StandardMBean mbean = new StandardMBean(new JmxTestBean(), IJmxTestBean.class);
|
||||
assertThat(JmxUtils.isMBean(mbean.getClass())).as("Standard MBean not detected correctly").isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsMBeanWithStandardMBeanInherited() throws Exception {
|
||||
void isMBeanWithStandardMBeanInherited() throws Exception {
|
||||
StandardMBean mbean = new StandardMBeanImpl();
|
||||
assertThat(JmxUtils.isMBean(mbean.getClass())).as("Standard MBean not detected correctly").isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotAnMBean() throws Exception {
|
||||
void notAnMBean() throws Exception {
|
||||
assertThat(JmxUtils.isMBean(Object.class)).as("Object incorrectly identified as an MBean").isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleMBean() throws Exception {
|
||||
void simpleMBean() throws Exception {
|
||||
Foo foo = new Foo();
|
||||
assertThat(JmxUtils.isMBean(foo.getClass())).as("Simple MBean not detected correctly").isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleMXBean() throws Exception {
|
||||
void simpleMXBean() throws Exception {
|
||||
FooX foo = new FooX();
|
||||
assertThat(JmxUtils.isMBean(foo.getClass())).as("Simple MXBean not detected correctly").isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleMBeanThroughInheritance() throws Exception {
|
||||
void simpleMBeanThroughInheritance() throws Exception {
|
||||
Bar bar = new Bar();
|
||||
Abc abc = new Abc();
|
||||
assertThat(JmxUtils.isMBean(bar.getClass())).as("Simple MBean (through inheritance) not detected correctly").isTrue();
|
||||
|
|
@ -86,21 +100,21 @@ public class JmxUtilsTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testGetAttributeNameWithStrictCasing() {
|
||||
void getAttributeNameWithStrictCasing() {
|
||||
PropertyDescriptor pd = new BeanWrapperImpl(AttributeTestBean.class).getPropertyDescriptor("name");
|
||||
String attributeName = JmxUtils.getAttributeName(pd, true);
|
||||
assertThat(attributeName).as("Incorrect casing on attribute name").isEqualTo("Name");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAttributeNameWithoutStrictCasing() {
|
||||
void getAttributeNameWithoutStrictCasing() {
|
||||
PropertyDescriptor pd = new BeanWrapperImpl(AttributeTestBean.class).getPropertyDescriptor("name");
|
||||
String attributeName = JmxUtils.getAttributeName(pd, false);
|
||||
assertThat(attributeName).as("Incorrect casing on attribute name").isEqualTo("name");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAppendIdentityToObjectName() throws MalformedObjectNameException {
|
||||
void appendIdentityToObjectName() throws MalformedObjectNameException {
|
||||
ObjectName objectName = ObjectNameManager.getInstance("spring:type=Test");
|
||||
Object managedResource = new Object();
|
||||
ObjectName uniqueName = JmxUtils.appendIdentityToObjectName(objectName, managedResource);
|
||||
|
|
@ -113,7 +127,7 @@ public class JmxUtilsTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testLocatePlatformMBeanServer() {
|
||||
void locatePlatformMBeanServer() {
|
||||
MBeanServer server = null;
|
||||
try {
|
||||
server = JmxUtils.locateMBeanServer();
|
||||
|
|
@ -125,18 +139,6 @@ public class JmxUtilsTests {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsMBean() {
|
||||
// Correctly returns true for a class
|
||||
assertThat(JmxUtils.isMBean(JmxClass.class)).isTrue();
|
||||
|
||||
// Correctly returns false since JmxUtils won't navigate to the extended interface
|
||||
assertThat(JmxUtils.isMBean(SpecializedJmxInterface.class)).isFalse();
|
||||
|
||||
// Incorrectly returns true since it doesn't detect that this is an interface
|
||||
assertThat(JmxUtils.isMBean(JmxInterface.class)).isFalse();
|
||||
}
|
||||
|
||||
|
||||
public static class AttributeTestBean {
|
||||
|
||||
|
|
|
|||
|
|
@ -16,8 +16,6 @@
|
|||
|
||||
package org.springframework.jmx.support;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
|
||||
import javax.management.MBeanServerConnection;
|
||||
import javax.management.remote.JMXConnectorServer;
|
||||
import javax.management.remote.JMXConnectorServerFactory;
|
||||
|
|
@ -33,31 +31,32 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link MBeanServerConnectionFactoryBean}.
|
||||
*
|
||||
* @author Rob Harrop
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
*/
|
||||
public class MBeanServerConnectionFactoryBeanTests extends AbstractMBeanServerTests {
|
||||
class MBeanServerConnectionFactoryBeanTests extends AbstractMBeanServerTests {
|
||||
|
||||
private final String serviceUrl = "service:jmx:jmxmp://localhost:" + SocketUtils.findAvailableTcpPort(9800, 9900);
|
||||
private final String serviceUrl = "service:jmx:jmxmp://localhost:" + SocketUtils.findAvailableTcpPort();
|
||||
|
||||
|
||||
private JMXServiceURL getJMXServiceUrl() throws MalformedURLException {
|
||||
return new JMXServiceURL(serviceUrl);
|
||||
}
|
||||
|
||||
private JMXConnectorServer getConnectorServer() throws Exception {
|
||||
return JMXConnectorServerFactory.newJMXConnectorServer(getJMXServiceUrl(), null, getServer());
|
||||
@Test
|
||||
void noServiceUrl() throws Exception {
|
||||
MBeanServerConnectionFactoryBean bean = new MBeanServerConnectionFactoryBean();
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(bean::afterPropertiesSet)
|
||||
.withMessage("Property 'serviceUrl' is required");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTestValidConnection() throws Exception {
|
||||
JMXConnectorServer connectorServer = getConnectorServer();
|
||||
connectorServer.start();
|
||||
void validConnection() throws Exception {
|
||||
JMXConnectorServer connectorServer = startConnectorServer();
|
||||
|
||||
try {
|
||||
MBeanServerConnectionFactoryBean bean = new MBeanServerConnectionFactoryBean();
|
||||
bean.setServiceUrl(serviceUrl);
|
||||
bean.setServiceUrl(this.serviceUrl);
|
||||
bean.afterPropertiesSet();
|
||||
|
||||
try {
|
||||
|
|
@ -77,16 +76,9 @@ public class MBeanServerConnectionFactoryBeanTests extends AbstractMBeanServerTe
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testWithNoServiceUrl() throws Exception {
|
||||
void lazyConnection() throws Exception {
|
||||
MBeanServerConnectionFactoryBean bean = new MBeanServerConnectionFactoryBean();
|
||||
assertThatIllegalArgumentException().isThrownBy(
|
||||
bean::afterPropertiesSet);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTestWithLazyConnection() throws Exception {
|
||||
MBeanServerConnectionFactoryBean bean = new MBeanServerConnectionFactoryBean();
|
||||
bean.setServiceUrl(serviceUrl);
|
||||
bean.setServiceUrl(this.serviceUrl);
|
||||
bean.setConnectOnStartup(false);
|
||||
bean.afterPropertiesSet();
|
||||
|
||||
|
|
@ -95,8 +87,7 @@ public class MBeanServerConnectionFactoryBeanTests extends AbstractMBeanServerTe
|
|||
|
||||
JMXConnectorServer connector = null;
|
||||
try {
|
||||
connector = getConnectorServer();
|
||||
connector.start();
|
||||
connector = startConnectorServer();
|
||||
assertThat(connection.getMBeanCount()).as("Incorrect MBean count").isEqualTo(getServer().getMBeanCount());
|
||||
}
|
||||
finally {
|
||||
|
|
@ -108,9 +99,9 @@ public class MBeanServerConnectionFactoryBeanTests extends AbstractMBeanServerTe
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testWithLazyConnectionAndNoAccess() throws Exception {
|
||||
void lazyConnectionAndNoAccess() throws Exception {
|
||||
MBeanServerConnectionFactoryBean bean = new MBeanServerConnectionFactoryBean();
|
||||
bean.setServiceUrl(serviceUrl);
|
||||
bean.setServiceUrl(this.serviceUrl);
|
||||
bean.setConnectOnStartup(false);
|
||||
bean.afterPropertiesSet();
|
||||
|
||||
|
|
@ -119,4 +110,11 @@ public class MBeanServerConnectionFactoryBeanTests extends AbstractMBeanServerTe
|
|||
bean.destroy();
|
||||
}
|
||||
|
||||
private JMXConnectorServer startConnectorServer() throws Exception {
|
||||
JMXServiceURL jmxServiceUrl = new JMXServiceURL(this.serviceUrl);
|
||||
JMXConnectorServer connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(jmxServiceUrl, null, getServer());
|
||||
connectorServer.start();
|
||||
return connectorServer;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,26 +31,23 @@ import org.springframework.util.MBeanTestUtils;
|
|||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link MBeanServerFactoryBean}.
|
||||
*
|
||||
* @author Rob Harrop
|
||||
* @author Juergen Hoeller
|
||||
* @author Phillip Webb
|
||||
* @author Sam Brannen
|
||||
*/
|
||||
public class MBeanServerFactoryBeanTests {
|
||||
|
||||
class MBeanServerFactoryBeanTests {
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() throws Exception {
|
||||
MBeanTestUtils.resetMBeanServers();
|
||||
}
|
||||
|
||||
|
||||
@AfterEach
|
||||
public void tearDown() throws Exception {
|
||||
void resetMBeanServers() throws Exception {
|
||||
MBeanTestUtils.resetMBeanServers();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getObject() throws Exception {
|
||||
void defaultValues() throws Exception {
|
||||
MBeanServerFactoryBean bean = new MBeanServerFactoryBean();
|
||||
bean.afterPropertiesSet();
|
||||
try {
|
||||
|
|
@ -63,7 +60,7 @@ public class MBeanServerFactoryBeanTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void defaultDomain() throws Exception {
|
||||
void defaultDomain() throws Exception {
|
||||
MBeanServerFactoryBean bean = new MBeanServerFactoryBean();
|
||||
bean.setDefaultDomain("foo");
|
||||
bean.afterPropertiesSet();
|
||||
|
|
@ -77,7 +74,7 @@ public class MBeanServerFactoryBeanTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void withLocateExistingAndExistingServer() {
|
||||
void locateExistingServerIfPossibleWithExistingServer() {
|
||||
MBeanServer server = MBeanServerFactory.createMBeanServer();
|
||||
try {
|
||||
MBeanServerFactoryBean bean = new MBeanServerFactoryBean();
|
||||
|
|
@ -97,7 +94,7 @@ public class MBeanServerFactoryBeanTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void withLocateExistingAndFallbackToPlatformServer() {
|
||||
void locateExistingServerIfPossibleWithFallbackToPlatformServer() {
|
||||
MBeanServerFactoryBean bean = new MBeanServerFactoryBean();
|
||||
bean.setLocateExistingServerIfPossible(true);
|
||||
bean.afterPropertiesSet();
|
||||
|
|
@ -110,7 +107,7 @@ public class MBeanServerFactoryBeanTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void withEmptyAgentIdAndFallbackToPlatformServer() {
|
||||
void withEmptyAgentIdAndFallbackToPlatformServer() {
|
||||
MBeanServerFactoryBean bean = new MBeanServerFactoryBean();
|
||||
bean.setAgentId("");
|
||||
bean.afterPropertiesSet();
|
||||
|
|
@ -123,16 +120,16 @@ public class MBeanServerFactoryBeanTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void createMBeanServer() throws Exception {
|
||||
testCreation(true, "The server should be available in the list");
|
||||
void createMBeanServer() throws Exception {
|
||||
assertCreation(true, "The server should be available in the list");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void newMBeanServer() throws Exception {
|
||||
testCreation(false, "The server should not be available in the list");
|
||||
void newMBeanServer() throws Exception {
|
||||
assertCreation(false, "The server should not be available in the list");
|
||||
}
|
||||
|
||||
private void testCreation(boolean referenceShouldExist, String failMsg) throws Exception {
|
||||
private void assertCreation(boolean referenceShouldExist, String failMsg) throws Exception {
|
||||
MBeanServerFactoryBean bean = new MBeanServerFactoryBean();
|
||||
bean.setRegisterWithFactory(referenceShouldExist);
|
||||
bean.afterPropertiesSet();
|
||||
|
|
@ -147,12 +144,7 @@ public class MBeanServerFactoryBeanTests {
|
|||
}
|
||||
|
||||
private boolean hasInstance(List<MBeanServer> servers, MBeanServer server) {
|
||||
for (MBeanServer candidate : servers) {
|
||||
if (candidate == server) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return servers.stream().anyMatch(current -> current == server);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -31,13 +31,21 @@ public class MBeanTestUtils {
|
|||
|
||||
/**
|
||||
* Resets MBeanServerFactory and ManagementFactory to a known consistent state.
|
||||
* This involves releasing all currently registered MBeanServers and resetting
|
||||
* <p>This involves releasing all currently registered MBeanServers and resetting
|
||||
* the platformMBeanServer to null.
|
||||
*/
|
||||
public static void resetMBeanServers() throws Exception {
|
||||
public static synchronized void resetMBeanServers() throws Exception {
|
||||
for (MBeanServer server : MBeanServerFactory.findMBeanServer(null)) {
|
||||
MBeanServerFactory.releaseMBeanServer(server);
|
||||
try {
|
||||
MBeanServerFactory.releaseMBeanServer(server);
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
if (!ex.getMessage().contains("not in list")) {
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Field field = ManagementFactory.class.getDeclaredField("platformMBeanServer");
|
||||
field.setAccessible(true);
|
||||
field.set(null, null);
|
||||
|
|
|
|||
|
|
@ -5,22 +5,22 @@
|
|||
|
||||
<bean id="customEditorConfigurer" class="org.springframework.beans.factory.config.CustomEditorConfigurer">
|
||||
<property name="propertyEditorRegistrars">
|
||||
<bean class="org.springframework.jmx.export.CustomDateEditorRegistrar"/>
|
||||
<bean class="org.springframework.jmx.export.CustomDateEditorRegistrar" />
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="dateRange" class="org.springframework.jmx.export.DateRange">
|
||||
<property name="startDate" value="2004/10/12"/>
|
||||
<property name="endDate" value="2004/11/13"/>
|
||||
<property name="startDate" value="2004/10/12" />
|
||||
<property name="endDate" value="2004/11/13" />
|
||||
</bean>
|
||||
|
||||
<bean class="org.springframework.jmx.export.MBeanExporter">
|
||||
<property name="beans">
|
||||
<map>
|
||||
<entry key="bean:name=dateRange" value-ref="dateRange"/>
|
||||
<entry key="bean:name=dateRange" value-ref="dateRange" />
|
||||
</map>
|
||||
</property>
|
||||
<property name="server" ref="server"/>
|
||||
</bean>
|
||||
<property name="server" ref="server" />
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
|
|
|
|||
Loading…
Reference in New Issue