Make MBeanServer integration tests more robust
This commit overhauls several of the tests that interact with an MBeanServer with the goal of increasing the reliability of these tests. - MBeanClientInterceptorTests now uses JUnit "assumptions" instead of preemptively returning from test methods, thus allowing such methods to be properly marked as "ignored" instead of "passed". - MBeanClientInterceptorTests now uses JUnit's support for expected exceptions where appropriate. - MBeanClientInterceptorTests and RemoteMBeanClientInterceptorTests now use Spring's SocketUtils to find an available TCP port when starting an MBeanServer instead of aborting the tests when the default JMX port is not available. Issue: SPR-12601
This commit is contained in:
parent
08f3a79821
commit
7a6dfe3765
|
|
@ -35,14 +35,24 @@ import static org.junit.Assert.*;
|
||||||
/**
|
/**
|
||||||
* <strong>Note:</strong> certain tests throughout this hierarchy require the presence of
|
* <strong>Note:</strong> certain tests throughout this hierarchy require the presence of
|
||||||
* the {@code jmxremote_optional.jar} in your classpath. For this reason, these tests are
|
* the {@code jmxremote_optional.jar} in your classpath. For this reason, these tests are
|
||||||
* run only if {@link TestGroup#JMXMP} is enabled. If you wish to run these tests, follow
|
* run only if {@link TestGroup#JMXMP} is enabled.
|
||||||
* the instructions in the TestGroup class to enable JMXMP tests. If you run into the
|
*
|
||||||
* <em>"Unsupported protocol: jmxmp"</em> error, you will need to download the
|
* <p>If you wish to run these tests, follow the instructions in the TestGroup class to
|
||||||
* <a href="http://www.oracle.com/technetwork/java/javase/tech/download-jsp-141676.html">
|
* enable JMXMP tests (i.e., set the following Java system property:
|
||||||
* JMX Remote API 1.0.1_04 Reference Implementation</a> from Oracle and extract
|
* {@code -DtestGroups=jmxmp}).
|
||||||
|
*
|
||||||
|
* <p>If you run into the <em>"Unsupported protocol: jmxmp"</em> error, you will need to
|
||||||
|
* download the <a href="http://www.oracle.com/technetwork/java/javase/tech/download-jsp-141676.html">JMX
|
||||||
|
* Remote API 1.0.1_04 Reference Implementation</a> from Oracle and extract
|
||||||
* {@code jmxremote_optional.jar} into your classpath, for example in the {@code lib/ext}
|
* {@code jmxremote_optional.jar} into your classpath, for example in the {@code lib/ext}
|
||||||
* folder of your JVM.
|
* folder of your JVM.
|
||||||
* See also <a href="https://issuetracker.springsource.com/browse/EBR-349">EBR-349</a>.
|
*
|
||||||
|
* <p>See also:
|
||||||
|
* <ul>
|
||||||
|
* <li>
|
||||||
|
* <li><a href="https://jira.spring.io/browse/SPR-8093">SPR-8093</a></li>
|
||||||
|
* <li><a href="https://issuetracker.springsource.com/browse/EBR-349">EBR-349</a></li>
|
||||||
|
* </ul>
|
||||||
*
|
*
|
||||||
* @author Rob Harrop
|
* @author Rob Harrop
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2013 the original author or authors.
|
* Copyright 2002-2015 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
* use this file except in compliance with the License. You may obtain a copy of
|
* use this file except in compliance with the License. You may obtain a copy of
|
||||||
|
|
@ -22,6 +22,7 @@ import java.lang.reflect.Method;
|
||||||
import java.net.BindException;
|
import java.net.BindException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.management.Descriptor;
|
import javax.management.Descriptor;
|
||||||
import javax.management.MBeanServerConnection;
|
import javax.management.MBeanServerConnection;
|
||||||
import javax.management.remote.JMXConnectorServer;
|
import javax.management.remote.JMXConnectorServer;
|
||||||
|
|
@ -38,10 +39,15 @@ import org.springframework.jmx.export.MBeanExporter;
|
||||||
import org.springframework.jmx.export.assembler.AbstractReflectiveMBeanInfoAssembler;
|
import org.springframework.jmx.export.assembler.AbstractReflectiveMBeanInfoAssembler;
|
||||||
import org.springframework.tests.Assume;
|
import org.springframework.tests.Assume;
|
||||||
import org.springframework.tests.TestGroup;
|
import org.springframework.tests.TestGroup;
|
||||||
|
import org.springframework.util.SocketUtils;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
import static org.junit.Assume.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* To run the tests in the class, set the following Java system property:
|
||||||
|
* {@code -DtestGroups=jmxmp}.
|
||||||
|
*
|
||||||
* @author Rob Harrop
|
* @author Rob Harrop
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @author Sam Brannen
|
* @author Sam Brannen
|
||||||
|
|
@ -85,16 +91,14 @@ public class MBeanClientInterceptorTests extends AbstractMBeanServerTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testProxyClassIsDifferent() throws Exception {
|
public void testProxyClassIsDifferent() throws Exception {
|
||||||
if (!runTests)
|
assumeTrue(runTests);
|
||||||
return;
|
|
||||||
IJmxTestBean proxy = getProxy();
|
IJmxTestBean proxy = getProxy();
|
||||||
assertTrue("The proxy class should be different than the base class", (proxy.getClass() != IJmxTestBean.class));
|
assertTrue("The proxy class should be different than the base class", (proxy.getClass() != IJmxTestBean.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDifferentProxiesSameClass() throws Exception {
|
public void testDifferentProxiesSameClass() throws Exception {
|
||||||
if (!runTests)
|
assumeTrue(runTests);
|
||||||
return;
|
|
||||||
IJmxTestBean proxy1 = getProxy();
|
IJmxTestBean proxy1 = getProxy();
|
||||||
IJmxTestBean proxy2 = getProxy();
|
IJmxTestBean proxy2 = getProxy();
|
||||||
|
|
||||||
|
|
@ -104,8 +108,7 @@ public class MBeanClientInterceptorTests extends AbstractMBeanServerTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetAttributeValue() throws Exception {
|
public void testGetAttributeValue() throws Exception {
|
||||||
if (!runTests)
|
assumeTrue(runTests);
|
||||||
return;
|
|
||||||
IJmxTestBean proxy1 = getProxy();
|
IJmxTestBean proxy1 = getProxy();
|
||||||
int age = proxy1.getAge();
|
int age = proxy1.getAge();
|
||||||
assertEquals("The age should be 100", 100, age);
|
assertEquals("The age should be 100", 100, age);
|
||||||
|
|
@ -113,69 +116,43 @@ public class MBeanClientInterceptorTests extends AbstractMBeanServerTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSetAttributeValue() throws Exception {
|
public void testSetAttributeValue() throws Exception {
|
||||||
if (!runTests)
|
assumeTrue(runTests);
|
||||||
return;
|
|
||||||
IJmxTestBean proxy = getProxy();
|
IJmxTestBean proxy = getProxy();
|
||||||
proxy.setName("Rob Harrop");
|
proxy.setName("Rob Harrop");
|
||||||
assertEquals("The name of the bean should have been updated", "Rob Harrop", target.getName());
|
assertEquals("The name of the bean should have been updated", "Rob Harrop", target.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test(expected = IllegalArgumentException.class)
|
||||||
public void testSetAttributeValueWithRuntimeException() throws Exception {
|
public void testSetAttributeValueWithRuntimeException() throws Exception {
|
||||||
if (!runTests)
|
assumeTrue(runTests);
|
||||||
return;
|
|
||||||
IJmxTestBean proxy = getProxy();
|
IJmxTestBean proxy = getProxy();
|
||||||
try {
|
proxy.setName("Juergen");
|
||||||
proxy.setName("Juergen");
|
|
||||||
fail("Should have thrown IllegalArgumentException");
|
|
||||||
} catch (IllegalArgumentException ex) {
|
|
||||||
// expected
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test(expected = ClassNotFoundException.class)
|
||||||
public void testSetAttributeValueWithCheckedException() throws Exception {
|
public void testSetAttributeValueWithCheckedException() throws Exception {
|
||||||
if (!runTests)
|
assumeTrue(runTests);
|
||||||
return;
|
|
||||||
IJmxTestBean proxy = getProxy();
|
IJmxTestBean proxy = getProxy();
|
||||||
try {
|
proxy.setName("Juergen Class");
|
||||||
proxy.setName("Juergen Class");
|
|
||||||
fail("Should have thrown ClassNotFoundException");
|
|
||||||
} catch (ClassNotFoundException ex) {
|
|
||||||
// expected
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test(expected = IOException.class)
|
||||||
public void testSetAttributeValueWithIOException() throws Exception {
|
public void testSetAttributeValueWithIOException() throws Exception {
|
||||||
if (!runTests)
|
assumeTrue(runTests);
|
||||||
return;
|
|
||||||
IJmxTestBean proxy = getProxy();
|
IJmxTestBean proxy = getProxy();
|
||||||
try {
|
proxy.setName("Juergen IO");
|
||||||
proxy.setName("Juergen IO");
|
|
||||||
fail("Should have thrown IOException");
|
|
||||||
} catch (IOException ex) {
|
|
||||||
// expected
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test(expected = InvalidInvocationException.class)
|
||||||
public void testSetReadOnlyAttribute() throws Exception {
|
public void testSetReadOnlyAttribute() throws Exception {
|
||||||
if (!runTests)
|
assumeTrue(runTests);
|
||||||
return;
|
|
||||||
IJmxTestBean proxy = getProxy();
|
IJmxTestBean proxy = getProxy();
|
||||||
try {
|
proxy.setAge(900);
|
||||||
proxy.setAge(900);
|
|
||||||
fail("Should not be able to write to a read only attribute");
|
|
||||||
} catch (InvalidInvocationException ex) {
|
|
||||||
// success
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInvokeNoArgs() throws Exception {
|
public void testInvokeNoArgs() throws Exception {
|
||||||
if (!runTests)
|
assumeTrue(runTests);
|
||||||
return;
|
|
||||||
IJmxTestBean proxy = getProxy();
|
IJmxTestBean proxy = getProxy();
|
||||||
long result = proxy.myOperation();
|
long result = proxy.myOperation();
|
||||||
assertEquals("The operation should return 1", 1, result);
|
assertEquals("The operation should return 1", 1, result);
|
||||||
|
|
@ -183,34 +160,27 @@ public class MBeanClientInterceptorTests extends AbstractMBeanServerTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInvokeArgs() throws Exception {
|
public void testInvokeArgs() throws Exception {
|
||||||
if (!runTests)
|
assumeTrue(runTests);
|
||||||
return;
|
|
||||||
IJmxTestBean proxy = getProxy();
|
IJmxTestBean proxy = getProxy();
|
||||||
int result = proxy.add(1, 2);
|
int result = proxy.add(1, 2);
|
||||||
assertEquals("The operation should return 3", 3, result);
|
assertEquals("The operation should return 3", 3, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test(expected = InvalidInvocationException.class)
|
||||||
public void testInvokeUnexposedMethodWithException() throws Exception {
|
public void testInvokeUnexposedMethodWithException() throws Exception {
|
||||||
if (!runTests)
|
assumeTrue(runTests);
|
||||||
return;
|
|
||||||
IJmxTestBean bean = getProxy();
|
IJmxTestBean bean = getProxy();
|
||||||
try {
|
bean.dontExposeMe();
|
||||||
bean.dontExposeMe();
|
|
||||||
fail("Method dontExposeMe should throw an exception");
|
|
||||||
} catch (InvalidInvocationException desired) {
|
|
||||||
// success
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTestLazyConnectionToRemote() throws Exception {
|
public void testTestLazyConnectionToRemote() throws Exception {
|
||||||
if (!runTests)
|
assumeTrue(runTests);
|
||||||
return;
|
|
||||||
|
|
||||||
Assume.group(TestGroup.JMXMP);
|
Assume.group(TestGroup.JMXMP);
|
||||||
|
|
||||||
JMXServiceURL url = new JMXServiceURL("service:jmx:jmxmp://localhost:9876");
|
final int port = SocketUtils.findAvailableTcpPort();
|
||||||
|
|
||||||
|
JMXServiceURL url = new JMXServiceURL("service:jmx:jmxmp://localhost:" + port);
|
||||||
JMXConnectorServer connector = JMXConnectorServerFactory.newJMXConnectorServer(url, null, getServer());
|
JMXConnectorServer connector = JMXConnectorServerFactory.newJMXConnectorServer(url, null, getServer());
|
||||||
|
|
||||||
MBeanProxyFactoryBean factory = new MBeanProxyFactoryBean();
|
MBeanProxyFactoryBean factory = new MBeanProxyFactoryBean();
|
||||||
|
|
@ -227,9 +197,8 @@ public class MBeanClientInterceptorTests extends AbstractMBeanServerTests {
|
||||||
try {
|
try {
|
||||||
connector.start();
|
connector.start();
|
||||||
} catch (BindException ex) {
|
} catch (BindException ex) {
|
||||||
// couldn't bind to local port 9876 - let's skip the remainder of this test
|
System.out.println("Skipping remainder of JMX LazyConnectionToRemote test because binding to local port ["
|
||||||
System.out.println("Skipping JMX LazyConnectionToRemote test because binding to local port 9876 failed: "
|
+ port + "] failed: " + ex.getMessage());
|
||||||
+ ex.getMessage());
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2013 the original author or authors.
|
* Copyright 2002-2015 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
* use this file except in compliance with the License. You may obtain a copy of
|
* use this file except in compliance with the License. You may obtain a copy of
|
||||||
|
|
@ -18,6 +18,7 @@ package org.springframework.jmx.access;
|
||||||
|
|
||||||
import java.net.BindException;
|
import java.net.BindException;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
|
|
||||||
import javax.management.MBeanServerConnection;
|
import javax.management.MBeanServerConnection;
|
||||||
import javax.management.remote.JMXConnector;
|
import javax.management.remote.JMXConnector;
|
||||||
import javax.management.remote.JMXConnectorFactory;
|
import javax.management.remote.JMXConnectorFactory;
|
||||||
|
|
@ -27,14 +28,25 @@ import javax.management.remote.JMXServiceURL;
|
||||||
|
|
||||||
import org.springframework.tests.Assume;
|
import org.springframework.tests.Assume;
|
||||||
import org.springframework.tests.TestGroup;
|
import org.springframework.tests.TestGroup;
|
||||||
|
import org.springframework.util.SocketUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* To run the tests in the class, set the following Java system property:
|
||||||
|
* {@code -DtestGroups=jmxmp}.
|
||||||
|
*
|
||||||
* @author Rob Harrop
|
* @author Rob Harrop
|
||||||
* @author Chris Beams
|
* @author Chris Beams
|
||||||
|
* @author Sam Brannen
|
||||||
*/
|
*/
|
||||||
public class RemoteMBeanClientInterceptorTests extends MBeanClientInterceptorTests {
|
public class RemoteMBeanClientInterceptorTests extends MBeanClientInterceptorTests {
|
||||||
|
|
||||||
private static final String SERVICE_URL = "service:jmx:jmxmp://localhost:9876";
|
private static final int SERVICE_PORT;
|
||||||
|
private static final String SERVICE_URL;
|
||||||
|
|
||||||
|
static {
|
||||||
|
SERVICE_PORT = SocketUtils.findAvailableTcpPort();
|
||||||
|
SERVICE_URL = "service:jmx:jmxmp://localhost:" + SERVICE_PORT;
|
||||||
|
}
|
||||||
|
|
||||||
private JMXConnectorServer connectorServer;
|
private JMXConnectorServer connectorServer;
|
||||||
|
|
||||||
|
|
@ -50,7 +62,8 @@ public class RemoteMBeanClientInterceptorTests extends MBeanClientInterceptorTes
|
||||||
try {
|
try {
|
||||||
this.connectorServer.start();
|
this.connectorServer.start();
|
||||||
} catch (BindException ex) {
|
} catch (BindException ex) {
|
||||||
// skipping tests, server already running at this port
|
System.out.println("Skipping remote JMX tests because binding to local port ["
|
||||||
|
+ SERVICE_PORT + "] failed: " + ex.getMessage());
|
||||||
runTests = false;
|
runTests = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2013 the original author or authors.
|
* Copyright 2002-2015 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
* use this file except in compliance with the License. You may obtain a copy of
|
* use this file except in compliance with the License. You may obtain a copy of
|
||||||
|
|
@ -36,6 +36,9 @@ import org.springframework.tests.TestGroup;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* To run the tests in the class, set the following Java system property:
|
||||||
|
* {@code -DtestGroups=jmxmp}.
|
||||||
|
*
|
||||||
* @author Rob Harrop
|
* @author Rob Harrop
|
||||||
* @author Chris Beams
|
* @author Chris Beams
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2013 the original author or authors.
|
* Copyright 2002-2015 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -22,7 +22,6 @@ import javax.management.remote.JMXConnectorServer;
|
||||||
import javax.management.remote.JMXConnectorServerFactory;
|
import javax.management.remote.JMXConnectorServerFactory;
|
||||||
import javax.management.remote.JMXServiceURL;
|
import javax.management.remote.JMXServiceURL;
|
||||||
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.springframework.aop.support.AopUtils;
|
import org.springframework.aop.support.AopUtils;
|
||||||
|
|
@ -34,22 +33,22 @@ import org.springframework.util.SocketUtils;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* To run the tests in the class, set the following Java system property:
|
||||||
|
* {@code -DtestGroups=jmxmp}.
|
||||||
|
*
|
||||||
* @author Rob Harrop
|
* @author Rob Harrop
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
|
* @author Sam Brannen
|
||||||
*/
|
*/
|
||||||
public class MBeanServerConnectionFactoryBeanTests extends AbstractMBeanServerTests {
|
public class MBeanServerConnectionFactoryBeanTests extends AbstractMBeanServerTests {
|
||||||
|
|
||||||
|
private final String serviceUrl;
|
||||||
|
|
||||||
private String serviceUrl;
|
{
|
||||||
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void getUrl() {
|
|
||||||
int port = SocketUtils.findAvailableTcpPort(9800, 9900);
|
int port = SocketUtils.findAvailableTcpPort(9800, 9900);
|
||||||
this.serviceUrl = "service:jmx:jmxmp://localhost:" + port;
|
this.serviceUrl = "service:jmx:jmxmp://localhost:" + port;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private JMXServiceURL getJMXServiceUrl() throws MalformedURLException {
|
private JMXServiceURL getJMXServiceUrl() throws MalformedURLException {
|
||||||
return new JMXServiceURL(serviceUrl);
|
return new JMXServiceURL(serviceUrl);
|
||||||
}
|
}
|
||||||
|
|
@ -58,7 +57,6 @@ public class MBeanServerConnectionFactoryBeanTests extends AbstractMBeanServerTe
|
||||||
return JMXConnectorServerFactory.newJMXConnectorServer(getJMXServiceUrl(), null, getServer());
|
return JMXConnectorServerFactory.newJMXConnectorServer(getJMXServiceUrl(), null, getServer());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTestValidConnection() throws Exception {
|
public void testTestValidConnection() throws Exception {
|
||||||
Assume.group(TestGroup.JMXMP);
|
Assume.group(TestGroup.JMXMP);
|
||||||
|
|
@ -84,15 +82,10 @@ public class MBeanServerConnectionFactoryBeanTests extends AbstractMBeanServerTe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test(expected = IllegalArgumentException.class)
|
||||||
public void testWithNoServiceUrl() throws Exception {
|
public void testWithNoServiceUrl() throws Exception {
|
||||||
MBeanServerConnectionFactoryBean bean = new MBeanServerConnectionFactoryBean();
|
MBeanServerConnectionFactoryBean bean = new MBeanServerConnectionFactoryBean();
|
||||||
try {
|
bean.afterPropertiesSet();
|
||||||
bean.afterPropertiesSet();
|
|
||||||
fail("IllegalArgumentException should be raised when no service url is provided");
|
|
||||||
} catch (IllegalArgumentException ex) {
|
|
||||||
// expected
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue