提交 9a758be4 编写于 作者: S shshahma

8199001: [TESTBUG] RMIConnectionFilterTest.java test fails in compilation

Reviewed-by: dfuchs, robm
上级 424ae0ef
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8159377
* @library /lib/testlibrary
* @summary Tests ObjectFilter on default agent
* @author Harsha Wardhana B
* @build jdk.testlibrary.* DefaultAgentFilterTest
* @run main/othervm/timeout=600 -XX:+UsePerfData DefaultAgentFilterTest
*/
import java.io.EOFException;
import java.io.File;
import java.io.IOException;
import java.io.InvalidClassException;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.net.BindException;
import java.rmi.UnmarshalException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import java.util.concurrent.TimeUnit;
import jdk.testlibrary.ProcessTools;
import jdk.testlibrary.Utils;
public class DefaultAgentFilterTest {
public static class MyTestObject implements Serializable {
String a;
int id;
}
public interface TestMBean {
public void op1(HashSet<Object> params);
public void op2(String s, HashSet<String> params);
public void op3(MyTestObject obj, String s, HashMap<String, String> param);
}
public static class Test implements TestMBean {
@Override
public void op1(HashSet<Object> params) {
System.out.println("Invoked op1");
}
@Override
public void op2(String s, HashSet<String> params) {
System.out.println("Invoked op2");
}
@Override
public void op3(MyTestObject obj, String s, HashMap<String, String> param) {
System.out.println("Invoked op3");
}
}
private static class TestAppRun implements AutoCloseable {
private Process p;
private final ProcessBuilder pb;
private final String name;
private final AtomicBoolean started = new AtomicBoolean(false);
public TestAppRun(ProcessBuilder pb, String name) {
this.pb = pb;
this.name = name;
}
public synchronized void start() throws Exception {
if (started.compareAndSet(false, true)) {
try {
AtomicBoolean error = new AtomicBoolean(false);
AtomicBoolean bindError = new AtomicBoolean(false);
p = ProcessTools.startProcess(
TEST_APP_NAME + "{" + name + "}",
pb,
(line) -> {
if (line.toLowerCase().contains("exception")
|| line.toLowerCase().contains("error")) {
error.set(true);
}
bindError.set(line.toLowerCase().contains("bindexception"));
return true;
}, 10, TimeUnit.SECONDS);
if (bindError.get()) {
throw new BindException("Process could not be started");
} else if (error.get()) {
throw new RuntimeException();
}
} catch (Exception ex) {
if (p != null) {
p.destroy();
p.waitFor();
}
throw ex;
}
}
}
public synchronized void stop()
throws IOException, InterruptedException {
if (started.compareAndSet(true, false)) {
p.getOutputStream().write(0);
p.getOutputStream().flush();
int ec = p.waitFor();
if (ec != 0) {
StringBuilder msg = new StringBuilder();
msg.append("Test application '").append(name);
msg.append("' failed with exit code: ");
msg.append(ec);
System.err.println(msg);
}
}
}
@Override
public void close() throws Exception {
stop();
}
}
private static final String TEST_APP_NAME = "TestApp";
private static void testDefaultAgent(String propertyFile) throws Exception {
int port = Utils.getFreePort();
String propFile = System.getProperty("test.src") + File.separator + propertyFile;
List<String> pbArgs = new ArrayList<>(Arrays.asList(
"-cp",
System.getProperty("test.class.path"),
"-XX:+UsePerfData"
));
String[] args = new String[]{
"-Dcom.sun.management.jmxremote.port=" + port,
"-Dcom.sun.management.jmxremote.authenticate=false",
"-Dcom.sun.management.jmxremote.ssl=false",
"-Dcom.sun.management.config.file=" + propFile
};
pbArgs.addAll(Arrays.asList(args));
pbArgs.add(TEST_APP_NAME);
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
pbArgs.toArray(new String[pbArgs.size()])
);
try (TestAppRun s = new TestAppRun(pb, DefaultAgentFilterTest.class.getSimpleName())) {
s.start();
JMXServiceURL url = testConnect(port);
testMBeanOperations(url);
}
}
private static JMXServiceURL testConnect(int port) throws Exception {
EOFException lastException = null;
JMXServiceURL url = null;
// factor adjusted timeout (5 seconds) for the RMI to become available
long timeout = System.currentTimeMillis() + Utils.adjustTimeout(5000);
do {
lastException = null;
try {
Registry registry = LocateRegistry.getRegistry(port);
String[] relist = registry.list();
for (int i = 0; i < relist.length; ++i) {
System.out.println("Got registry: " + relist[i]);
}
String jmxUrlStr = String.format(
"service:jmx:rmi:///jndi/rmi://localhost:%d/jmxrmi",
port);
url = new JMXServiceURL(jmxUrlStr);
try (JMXConnector c = JMXConnectorFactory.connect(url, null)) {
MBeanServerConnection conn = c.getMBeanServerConnection();
ObjectName name = new ObjectName("jtreg:type=Test");
conn.createMBean(Test.class.getName(), name);
}
} catch (Exception ex) {
if (ex instanceof EOFException) {
lastException = (EOFException) ex;
System.out.println("Error establishing RMI connection. Retrying in 500ms.");
Thread.sleep(500);
} else {
throw ex;
}
}
} while (lastException != null && System.currentTimeMillis() < timeout);
if (lastException != null) {
throw lastException;
}
return url;
}
public static void main(String[] args) throws Exception {
System.out.println("---" + DefaultAgentFilterTest.class.getName() + "-main: starting ...");
boolean retry = false;
do {
try {
// blacklist String
testDefaultAgent("mgmt1.properties");
System.out.println("----\tTest FAILED !!");
throw new RuntimeException("---" + DefaultAgentFilterTest.class.getName() + " - No exception reported");
} catch (Exception ex) {
if (ex instanceof InvocationTargetException) {
if (ex.getCause() instanceof BindException
|| ex.getCause() instanceof java.rmi.ConnectException) {
System.out.println("Failed to allocate ports. Retrying ...");
retry = true;
}
} else if (ex instanceof InvalidClassException) {
System.out.println("----\tTest PASSED !!");
} else if (ex instanceof UnmarshalException
&& ((UnmarshalException) ex).getCause() instanceof InvalidClassException) {
System.out.println("----\tTest PASSED !!");
} else {
System.out.println(ex);
System.out.println("----\tTest FAILED !!");
throw ex;
}
}
} while (retry);
retry = false;
do {
try {
// blacklist non-existent class
testDefaultAgent("mgmt2.properties");
System.out.println("----\tTest PASSED !!");
} catch (Exception ex) {
if (ex instanceof InvocationTargetException) {
if (ex.getCause() instanceof BindException
|| ex.getCause() instanceof java.rmi.ConnectException) {
System.out.println("Failed to allocate ports. Retrying ...");
retry = true;
}
} else {
System.out.println(ex);
System.out.println("----\tTest FAILED !!");
throw ex;
}
}
} while (retry);
System.out.println("---" + DefaultAgentFilterTest.class.getName() + "-main: finished ...");
}
private static void testMBeanOperations(JMXServiceURL serverUrl) throws Exception {
Map<String, Object> clientEnv = new HashMap<>(1);
ObjectName name = new ObjectName("jtreg:type=Test");
try (JMXConnector client = JMXConnectorFactory.connect(serverUrl, clientEnv)) {
MBeanServerConnection conn = client.getMBeanServerConnection();
HashSet<String> set = new HashSet<>();
set.add("test1");
set.add("test2");
String a = "A";
Object[] params1 = {set};
String[] sig1 = {HashSet.class.getName()};
conn.invoke(name, "op1", params1, sig1);
Object[] params2 = {a, set};
String[] sig2 = {String.class.getName(), HashSet.class.getName()};
conn.invoke(name, "op2", params2, sig2);
HashMap<String, String> map = new HashMap<>();
map.put("a", "A");
map.put("b", "B");
Object[] params3 = {new MyTestObject(), a, map};
String[] sig3 = {MyTestObject.class.getName(), String.class.getName(),
HashMap.class.getName()};
conn.invoke(name, "op3", params3, sig3);
}
}
}
class TestApp {
private static void doSomething() throws IOException {
int r = System.in.read();
System.out.println("read: " + r);
}
public static void main(String args[]) throws Exception {
System.out.println("main enter");
System.out.flush();
doSomething();
System.out.println("main exit");
}
}
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8159377
* @summary Tests ObjectInputFilter on RMIServer.newClient
* @author Harsha Wardhana B
* @run clean NewRMIClientFilterTest
* @run build NewRMIClientFilterTest
* @run main NewRMIClientFilterTest
*/
import java.io.InvalidClassException;
import java.io.Serializable;
import java.lang.management.ManagementFactory;
import java.util.HashMap;
import java.util.Map;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
import com.sun.jmx.remote.util.EnvHelp;
public class NewRMIClientFilterTest {
public static void main(String[] args) throws Exception {
System.out.println("---NewRMIClientFilterTest-main: starting ...");
String filter1 = java.lang.String.class.getName() + ";!*";
String filter2 = java.lang.String.class.getName() + ";" + MyCredentials.class.getName() + ";!*";
JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
JMXServiceURL serverUrl = null;
Map<String, Object> env = new HashMap<>(1);
JMXConnectorServer server = null;
System.out.println("\n---NewRMIClientFilterTest-main: testing types = null");
server = newServer(url, null);
serverUrl = server.getAddress();
doTest(serverUrl, null);
doTest(serverUrl, new String[]{"toto", "titi"});
doTest(serverUrl, new Object[]{new MyCredentials(), "toto"});
server.stop();
System.out.println("\n---NewRMIClientFilterTest-main: testing types = String[]");
env.put(EnvHelp.CREDENTIALS_FILTER_PATTERN,
filter1);
server = newServer(url, env);
serverUrl = server.getAddress();
doTest(serverUrl, null);
doTest(serverUrl, new String[]{"toto", "titi"});
try {
doTest(serverUrl, new MyCredentials());
throw new Error("Bad client is not refused!");
} catch (Exception e) {
isInvalidClassEx(e);
} finally {
server.stop();
}
System.out.println("\n---NewRMIClientFilterTest-main: testing user specific types = String, MyCredentials");
env.put(EnvHelp.CREDENTIALS_FILTER_PATTERN,
filter2);
server = newServer(url, env);
serverUrl = server.getAddress();
doTest(serverUrl, null);
doTest(serverUrl, new String[]{"toto", "titi"});
doTest(serverUrl, new MyCredentials[]{new MyCredentials(), (MyCredentials) null});
try {
doTest(serverUrl, new Object[]{"toto", new byte[3]});
throw new Error("Bad client is not refused!");
} catch (Exception e) {
isInvalidClassEx(e);
} finally {
server.stop();
}
System.out.println("---NewRMIClientFilterTest-main PASSED!!!");
}
private static void doTest(JMXServiceURL serverAddr, Object credentials) throws Exception {
System.out.println("---NewRMIClientFilterTest-test:\n\tserver address: "
+ serverAddr + "\n\tcredentials: " + credentials);
Map<String, Object> env = new HashMap<>(1);
env.put("jmx.remote.credentials", credentials);
JMXConnector client = null;
try {
client = JMXConnectorFactory.connect(serverAddr, env);
client.getMBeanServerConnection().getDefaultDomain();
} finally {
try {
client.close();
} catch (Exception e) {
}
}
System.out.println("---NewRMIClientFilterTest-test: PASSED!");
}
private static JMXConnectorServer newServer(JMXServiceURL url, Map<String, Object> env)
throws Exception {
JMXConnectorServer server = JMXConnectorServerFactory.newJMXConnectorServer(
url,
env,
ManagementFactory.getPlatformMBeanServer());
server.start();
return server;
}
private static class MyCredentials implements Serializable {
}
private static void isInvalidClassEx(Exception e) {
Throwable cause = e;
while (cause != null) {
if (cause instanceof InvalidClassException) {
System.out.println("---NewRMIClientFilterTest-InvalidClassException expected: " + cause);
return;
}
cause = cause.getCause();
}
e.printStackTrace();
throw new RuntimeException("Did not get expected InvalidClassException!");
}
}
# ################ Filter for ObjectInputStream #############################
com.sun.management.jmxremote.serial.filter.pattern=!DefaultAgentFilterTest$MyTestObject
# A filter, if configured, is used by java.io.ObjectInputStream during
# deserialization of parameters sent to the JMX default agent to validate the
# contents of the stream.
# A filter is configured as a sequence of patterns, each pattern is either
# matched against the name of a class in the stream or defines a limit.
# Patterns are separated by ";" (semicolon).
# Whitespace is significant and is considered part of the pattern.
#
# If a pattern includes a "=", it sets a limit.
# If a limit appears more than once the last value is used.
# Limits are checked before classes regardless of the order in the sequence of patterns.
# If any of the limits are exceeded, the filter status is REJECTED.
#
# maxdepth=value - the maximum depth of a graph
# maxrefs=value - the maximum number of internal references
# maxbytes=value - the maximum number of bytes in the input stream
# maxarray=value - the maximum array length allowed
#
# Other patterns, from left to right, match the class or package name as
# returned from Class.getName.
# If the class is an array type, the class or package to be matched is the element type.
# Arrays of any number of dimensions are treated the same as the element type.
# For example, a pattern of "!example.Foo", rejects creation of any instance or
# array of example.Foo.
#
# If the pattern starts with "!", the status is REJECTED if the remaining pattern
# is matched; otherwise the status is ALLOWED if the pattern matches.
# If the pattern ends with ".**" it matches any class in the package and all subpackages.
# If the pattern ends with ".*" it matches any class in the package.
# If the pattern ends with "*", it matches any class with the pattern as a prefix.
# If the pattern is equal to the class name, it matches.
# Otherwise, the status is UNDECIDED.
# ################ Filter for ObjectInputStream #############################
com.sun.management.jmxremote.serial.filter.pattern=!DefaultAgentFilterTest$ThisTypeIsNotUsed
# A filter, if configured, is used by java.io.ObjectInputStream during
# deserialization of parameters sent to the JMX default agent to validate the
# contents of the stream.
# A filter is configured as a sequence of patterns, each pattern is either
# matched against the name of a class in the stream or defines a limit.
# Patterns are separated by ";" (semicolon).
# Whitespace is significant and is considered part of the pattern.
#
# If a pattern includes a "=", it sets a limit.
# If a limit appears more than once the last value is used.
# Limits are checked before classes regardless of the order in the sequence of patterns.
# If any of the limits are exceeded, the filter status is REJECTED.
#
# maxdepth=value - the maximum depth of a graph
# maxrefs=value - the maximum number of internal references
# maxbytes=value - the maximum number of bytes in the input stream
# maxarray=value - the maximum array length allowed
#
# Other patterns, from left to right, match the class or package name as
# returned from Class.getName.
# If the class is an array type, the class or package to be matched is the element type.
# Arrays of any number of dimensions are treated the same as the element type.
# For example, a pattern of "!example.Foo", rejects creation of any instance or
# array of example.Foo.
#
# If the pattern starts with "!", the status is REJECTED if the remaining pattern
# is matched; otherwise the status is ALLOWED if the pattern matches.
# If the pattern ends with ".**" it matches any class in the package and all subpackages.
# If the pattern ends with ".*" it matches any class in the package.
# If the pattern ends with "*", it matches any class with the pattern as a prefix.
# If the pattern is equal to the class name, it matches.
# Otherwise, the status is UNDECIDED.
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册