Path: blob/master/test/jdk/sun/management/jmxremote/bootstrap/RmiBootstrapTest.java
41153 views
/*1* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/22import sun.management.jmxremote.ConnectorBootstrap;2324import java.io.File;25import java.io.FileInputStream;26import java.io.FilenameFilter;27import java.io.IOException;28import java.net.BindException;29import java.rmi.server.ExportException;3031import java.util.Properties;32import java.util.Iterator;33import java.util.Set;34import java.util.ArrayList;35import java.util.HashMap;36import java.util.Map;37import java.util.Enumeration;3839import javax.management.remote.*;40import javax.management.*;4142import jdk.internal.agent.AgentConfigurationError;4344import java.security.Security;4546/**47* <p>This class implements unit test for RMI Bootstrap.48* When called with no arguments main() looks in the directory indicated49* by the "test.src" system property for files called management*ok.properties50* or management*ko.properties. The *ok.properties files are assumed to be51* valid Java M&M config files for which the bootstrap should succeed.52* The *ko.properties files are assumed to be configurations for which the53* bootstrap & connection test will fail.</p>54*55* <p>The rmi port number can be specified with the "rmi.port" system property.56* If not, this test will use the first available port</p>57*58* <p>When called with some argument, the main() will interprete its args to59* be Java M&M configuration file names. The filenames are expected to end60* with ok.properties or ko.properties - and are interpreted as above.</p>61*62* <p>Note that a limitation of the RMI registry (bug 4267864) prevent63* this test from succeeding if more than 1 configuration is used.64* As long as 4267864 isn't fix, this test must be called as many times65* as needed but with a single argument (no arguments, or several arguments66* will fail).</p>67*68* <p>Debug traces are logged in "sun.management.test"</p>69**/70public class RmiBootstrapTest {71// the number of consecutive ports to test for availability72private static int MAX_GET_FREE_PORT_TRIES = 10;73static TestLogger log =74new TestLogger("RmiBootstrapTest");7576/**77* Default values for RMI configuration properties.78**/79public static interface DefaultValues {80public static final String PORT="0";81public static final String CONFIG_FILE_NAME="management.properties";82public static final String USE_SSL="true";83public static final String USE_AUTHENTICATION="true";84public static final String PASSWORD_FILE_NAME="jmxremote.password";85public static final String ACCESS_FILE_NAME="jmxremote.access";86public static final String KEYSTORE="keystore";87public static final String KEYSTORE_PASSWD="password";88public static final String TRUSTSTORE="truststore";89public static final String TRUSTSTORE_PASSWD="trustword";90public static final String SSL_NEED_CLIENT_AUTH="false";91}9293/**94* Names of RMI configuration properties.95**/96public static interface PropertyNames {97public static final String PORT=98"com.sun.management.jmxremote.port";99public static final String CONFIG_FILE_NAME=100"com.sun.management.config.file";101public static final String USE_SSL=102"com.sun.management.jmxremote.ssl";103public static final String USE_AUTHENTICATION=104"com.sun.management.jmxremote.authenticate";105public static final String PASSWORD_FILE_NAME=106"com.sun.management.jmxremote.password.file";107public static final String ACCESS_FILE_NAME=108"com.sun.management.jmxremote.access.file";109public static final String INSTRUMENT_ALL=110"com.sun.management.instrumentall";111public static final String CREDENTIALS =112"jmx.remote.credentials";113public static final String KEYSTORE=114"javax.net.ssl.keyStore";115public static final String KEYSTORE_PASSWD=116"javax.net.ssl.keyStorePassword";117public static final String TRUSTSTORE=118"javax.net.ssl.trustStore";119public static final String TRUSTSTORE_PASSWD=120"javax.net.ssl.trustStorePassword";121public static final String SSL_ENABLED_CIPHER_SUITES =122"com.sun.management.jmxremote.ssl.enabled.cipher.suites";123public static final String SSL_ENABLED_PROTOCOLS =124"com.sun.management.jmxremote.ssl.enabled.protocols";125public static final String SSL_NEED_CLIENT_AUTH =126"com.sun.management.jmxremote.ssl.need.client.auth";127public static final String SSL_CLIENT_ENABLED_CIPHER_SUITES =128"javax.rmi.ssl.client.enabledCipherSuites";129}130131/**132* A filter to find all filenames who match <prefix>*<suffix>.133* Note that <prefix> and <suffix> can overlap.134**/135private static class ConfigFilenameFilter implements FilenameFilter {136final String suffix;137final String prefix;138ConfigFilenameFilter(String prefix, String suffix) {139this.suffix=suffix;140this.prefix=prefix;141}142public boolean accept(File dir, String name) {143return (name.startsWith(prefix) && name.endsWith(suffix));144}145}146147/**148* Get all "management*ok.properties" files in the directory149* indicated by the "test.src" management property.150**/151private static File[] findConfigurationFilesOk() {152final String testSrc = System.getProperty("test.src");153final File dir = new File(testSrc);154final FilenameFilter filter =155new ConfigFilenameFilter("management_test","ok.properties");156return dir.listFiles(filter);157}158159/**160* Get all "management*ko.properties" files in the directory161* indicated by the "test.src" management property.162**/163private static File[] findConfigurationFilesKo() {164final String testSrc = System.getProperty("test.src");165final File dir = new File(testSrc);166final FilenameFilter filter =167new ConfigFilenameFilter("management_test","ko.properties");168return dir.listFiles(filter);169}170171/**172* List all MBeans and their attributes. Used to test communication173* with the Java M&M MBean Server.174* @return the number of queried MBeans.175*/176public static int listMBeans(MBeanServerConnection server)177throws IOException {178return listMBeans(server,null,null);179}180181/**182* List all matching MBeans and their attributes.183* Used to test communication with the Java M&M MBean Server.184* @return the number of matching MBeans.185*/186public static int listMBeans(MBeanServerConnection server,187ObjectName pattern, QueryExp query)188throws IOException {189190final Set names = server.queryNames(pattern,query);191for (final Iterator i=names.iterator(); i.hasNext(); ) {192ObjectName name = (ObjectName)i.next();193log.trace("listMBeans","Got MBean: "+name);194try {195MBeanInfo info =196server.getMBeanInfo((ObjectName)name);197MBeanAttributeInfo[] attrs = info.getAttributes();198if (attrs == null) continue;199for (int j=0; j<attrs.length; j++) {200if (attrs[j].isReadable()) {201try {202Object o =203server.getAttribute(name,attrs[j].getName());204if (log.isDebugOn())205log.debug("listMBeans","\t\t" +206attrs[j].getName() +207" = "+o);208} catch (Exception x) {209log.trace("listMBeans","JmxClient failed to get " +210attrs[j].getName() + ": " + x);211final IOException io =212new IOException("JmxClient failed to get " +213attrs[j].getName());214io.initCause(x);215throw io;216}217}218}219} catch (Exception x) {220log.trace("listMBeans",221"JmxClient failed to get MBeanInfo: " + x);222final IOException io =223new IOException("JmxClient failed to get MBeanInfo: "+x);224io.initCause(x);225throw io;226}227}228return names.size();229}230231/**232* Compute the full path name for a default file.233* @param basename basename (with extension) of the default file.234* @return ${JRE}/conf/management/${basename}235**/236private static String getDefaultFileName(String basename) {237final String fileSeparator = File.separator;238final StringBuffer defaultFileName =239new StringBuffer(System.getProperty("java.home")).240append(fileSeparator).append("conf").append(fileSeparator).241append("management").append(fileSeparator).242append(basename);243return defaultFileName.toString();244}245246/**247* Compute the full path name for a default file.248* @param basename basename (with extension) of the default file.249* @return ${JRE}/conf/management/${basename}250**/251private static String getDefaultStoreName(String basename) {252final String fileSeparator = File.separator;253final StringBuffer defaultFileName =254new StringBuffer(System.getProperty("test.src")).255append(fileSeparator).append("ssl").append(fileSeparator).256append(basename);257return defaultFileName.toString();258}259260261/**262* Parses the password file to read the credentials.263* Returns an ArrayList of arrays of 2 string:264* {<subject>, <password>}.265* If the password file does not exists, return an empty list.266* (File not found = empty file).267**/268private ArrayList readCredentials(String passwordFileName)269throws IOException {270final Properties pws = new Properties();271final ArrayList result = new ArrayList();272final File f = new File(passwordFileName);273if (!f.exists()) return result;274FileInputStream fin = new FileInputStream(passwordFileName);275try {pws.load(fin);}finally{fin.close();}276for (Enumeration en=pws.propertyNames();en.hasMoreElements();) {277final String[] cred = new String[2];278cred[0]=(String)en.nextElement();279cred[1]=pws.getProperty(cred[0]);280result.add(cred);281}282return result;283}284285286/**287* Connect with the given url, using all given credentials in turn.288* A null entry in the useCredentials arrays indicate a connection289* where no credentials are used.290* @param url JMXServiceURL of the server.291* @param useCredentials An array of credentials (a credential292* is a two String array, so this is an array of arrays293* of strings:294* useCredentials[i][0]=subject295* useCredentials[i][1]=password296* if useCredentials[i] == null means no credentials.297* @param expectConnectOk true if connection is expected to succeed298* Note: if expectConnectOk=false and the test fails to connect299* the number of failure is not incremented. Conversely,300* if expectConnectOk=false and the test does not fail to301* connect the number of failure is incremented.302* @param expectReadOk true if communication (listMBeans) is expected303* to succeed.304* Note: if expectReadOk=false and the test fails to read MBeans305* the number of failure is not incremented. Conversely,306* if expectReadOk=false and the test does not fail to307* read MBeans the number of failure is incremented.308* @return number of failure.309**/310public int connectAndRead(JMXServiceURL url,311Object[] useCredentials,312boolean expectConnectOk,313boolean expectReadOk)314throws IOException {315316int errorCount = 0;317318for (int i=0 ; i<useCredentials.length ; i++) {319final Map m = new HashMap();320final String[] credentials = (String[])useCredentials[i];321final String crinfo;322if (credentials != null) {323crinfo = "{"+credentials[0] + ", " + credentials[1] + "}";324m.put(PropertyNames.CREDENTIALS,credentials);325} else {326crinfo="no credentials";327}328log.trace("testCommunication","using credentials: " + crinfo);329330final JMXConnector c;331try {332c = JMXConnectorFactory.connect(url,m);333} catch (IOException x ) {334if (expectConnectOk) {335final String err = "Connection failed for " + crinfo +336": " + x;337System.out.println(err);338log.trace("testCommunication",err);339log.debug("testCommunication",x);340errorCount++;341continue;342} else {343System.out.println("Connection failed as expected for " +344crinfo + ": " + x);345continue;346}347} catch (RuntimeException x ) {348if (expectConnectOk) {349final String err = "Connection failed for " + crinfo +350": " + x;351System.out.println(err);352log.trace("testCommunication",err);353log.debug("testCommunication",x);354errorCount++;355continue;356} else {357System.out.println("Connection failed as expected for " +358crinfo + ": " + x);359continue;360}361}362try {363MBeanServerConnection conn =364c.getMBeanServerConnection();365if (log.isDebugOn()) {366log.debug("testCommunication","Connection is:" + conn);367log.debug("testCommunication","Server domain is: " +368conn.getDefaultDomain());369}370final ObjectName pattern =371new ObjectName("java.lang:type=Memory,*");372final int count = listMBeans(conn,pattern,null);373if (count == 0)374throw new Exception("Expected at least one matching "+375"MBean for "+pattern);376if (expectReadOk) {377System.out.println("Communication succeeded " +378"as expected for "+379crinfo + ": found " + count380+ ((count<2)?"MBean":"MBeans"));381} else {382final String err = "Expected failure didn't occur for " +383crinfo;384System.out.println(err);385errorCount++;386}387} catch (IOException x ) {388if (expectReadOk) {389final String err = "Communication failed with " + crinfo +390": " + x;391System.out.println(err);392log.trace("testCommunication",err);393log.debug("testCommunication",x);394errorCount++;395continue;396} else {397System.out.println("Communication failed as expected for "+398crinfo + ": " + x);399continue;400}401} catch (RuntimeException x ) {402if (expectReadOk) {403final String err = "Communication failed with " + crinfo +404": " + x;405System.out.println(err);406log.trace("testCommunication",err);407log.debug("testCommunication",x);408errorCount++;409continue;410} else {411System.out.println("Communication failed as expected for "+412crinfo + ": " + x);413}414} catch (Exception x) {415final String err = "Failed to read MBeans with " + crinfo +416": " + x;417System.out.println(err);418log.trace("testCommunication",err);419log.debug("testCommunication",x);420errorCount++;421continue;422} finally {423c.close();424}425}426return errorCount;427}428429430private void setSslProperties(String clientEnabledCipherSuites) {431final String defaultKeyStore =432getDefaultStoreName(DefaultValues.KEYSTORE);433final String defaultTrustStore =434getDefaultStoreName(DefaultValues.TRUSTSTORE);435436final String keyStore =437System.getProperty(PropertyNames.KEYSTORE, defaultKeyStore);438System.setProperty(PropertyNames.KEYSTORE,keyStore);439log.trace("setSslProperties",PropertyNames.KEYSTORE+"="+keyStore);440441final String password =442System.getProperty(PropertyNames.KEYSTORE_PASSWD,443DefaultValues.KEYSTORE_PASSWD);444System.setProperty(PropertyNames.KEYSTORE_PASSWD,password);445log.trace("setSslProperties",446PropertyNames.KEYSTORE_PASSWD+"="+password);447448final String trustStore =449System.getProperty(PropertyNames.TRUSTSTORE,450defaultTrustStore);451System.setProperty(PropertyNames.TRUSTSTORE,trustStore);452log.trace("setSslProperties",453PropertyNames.TRUSTSTORE+"="+trustStore);454455final String trustword =456System.getProperty(PropertyNames.TRUSTSTORE_PASSWD,457DefaultValues.TRUSTSTORE_PASSWD);458System.setProperty(PropertyNames.TRUSTSTORE_PASSWD,trustword);459log.trace("setSslProperties",460PropertyNames.TRUSTSTORE_PASSWD+"="+trustword);461462if (clientEnabledCipherSuites != null) {463System.setProperty("javax.rmi.ssl.client.enabledCipherSuites",464clientEnabledCipherSuites);465} else {466System.clearProperty("javax.rmi.ssl.client.enabledCipherSuites");467}468}469470private void checkSslConfiguration() {471try {472final String defaultConf =473getDefaultFileName(DefaultValues.CONFIG_FILE_NAME);474final String confname =475System.getProperty(PropertyNames.CONFIG_FILE_NAME,defaultConf);476477final Properties props = new Properties();478final File conf = new File(confname);479if (conf.exists()) {480FileInputStream fin = new FileInputStream(conf);481try {props.load(fin);} finally {fin.close();}482}483484// Do we use SSL?485final String useSslStr =486props.getProperty(PropertyNames.USE_SSL,487DefaultValues.USE_SSL);488final boolean useSsl =489Boolean.valueOf(useSslStr).booleanValue();490491log.debug("checkSslConfiguration",492PropertyNames.USE_SSL+"="+useSsl+493": setting SSL");494// Do we use SSL client authentication?495final String useSslClientAuthStr =496props.getProperty(PropertyNames.SSL_NEED_CLIENT_AUTH,497DefaultValues.SSL_NEED_CLIENT_AUTH);498final boolean useSslClientAuth =499Boolean.valueOf(useSslClientAuthStr).booleanValue();500501log.debug("checkSslConfiguration",502PropertyNames.SSL_NEED_CLIENT_AUTH+"="+useSslClientAuth);503504// Do we use customized SSL cipher suites?505final String sslCipherSuites =506props.getProperty(PropertyNames.SSL_ENABLED_CIPHER_SUITES);507508log.debug("checkSslConfiguration",509PropertyNames.SSL_ENABLED_CIPHER_SUITES + "=" +510sslCipherSuites);511512// Do we use customized SSL protocols?513final String sslProtocols =514props.getProperty(PropertyNames.SSL_ENABLED_PROTOCOLS);515516log.debug("checkSslConfiguration",517PropertyNames.SSL_ENABLED_PROTOCOLS + "=" +518sslProtocols);519520if (useSsl) {521setSslProperties(props.getProperty(522PropertyNames.SSL_CLIENT_ENABLED_CIPHER_SUITES));523}524} catch (Exception x) {525System.out.println("Failed to setup SSL configuration: " + x);526log.debug("checkSslConfiguration",x);527}528}529530/**531* Tests the server bootstraped at the given URL.532* Uses the system properties to determine which config file is used.533* Loads the config file to determine which password file is used.534* Loads the password file to find out wich credentials to use.535* Also checks that unregistered user/passwords are not allowed to536* connect when a password file is used.537*538* This method calls connectAndRead().539**/540public void testCommunication(JMXServiceURL url)541throws IOException {542543final String defaultConf =544getDefaultFileName(DefaultValues.CONFIG_FILE_NAME);545final String confname =546System.getProperty(PropertyNames.CONFIG_FILE_NAME,defaultConf);547548final Properties props = new Properties();549final File conf = new File(confname);550if (conf.exists()) {551FileInputStream fin = new FileInputStream(conf);552try {props.load(fin);} finally {fin.close();}553}554555// Do we use authentication?556final String useAuthenticationStr =557props.getProperty(PropertyNames.USE_AUTHENTICATION,558DefaultValues.USE_AUTHENTICATION);559final boolean useAuthentication =560Boolean.valueOf(useAuthenticationStr).booleanValue();561562// Get Password File563final String defaultPasswordFileName = Utils.convertPath(564getDefaultFileName(DefaultValues.PASSWORD_FILE_NAME));565final String passwordFileName = Utils.convertPath(566props.getProperty(PropertyNames.PASSWORD_FILE_NAME,567defaultPasswordFileName));568569// Get Access File570final String defaultAccessFileName = Utils.convertPath(571getDefaultFileName(DefaultValues.ACCESS_FILE_NAME));572final String accessFileName = Utils.convertPath(573props.getProperty(PropertyNames.ACCESS_FILE_NAME,574defaultAccessFileName));575576if (useAuthentication) {577System.out.println("PasswordFileName: " + passwordFileName);578System.out.println("accessFileName: " + accessFileName);579}580581final Object[] allCredentials;582final Object[] noCredentials = { null };583if (useAuthentication) {584final ArrayList l = readCredentials(passwordFileName);585if (l.size() == 0) allCredentials = null;586else allCredentials = l.toArray();587} else allCredentials = noCredentials;588589int errorCount = 0;590if (allCredentials!=null) {591// Tests that the registered user/passwords are allowed to592// connect & read593//594errorCount += connectAndRead(url,allCredentials,true,true);595} else {596// Tests that no one is allowed597// connect & read598//599final String[][] someCredentials = {600null,601{ "modify", "R&D" },602{ "measure", "QED" }603};604errorCount += connectAndRead(url,someCredentials,false,false);605}606607if (useAuthentication && allCredentials != noCredentials) {608// Tests that the registered user/passwords are not allowed to609// connect & read610//611final String[][] badCredentials = {612{ "bad.user", "R&D" },613{ "measure", "bad.password" }614};615errorCount += connectAndRead(url,badCredentials,false,false);616}617if (errorCount > 0) {618final String err = "Test " + confname + " failed with " +619errorCount + " error(s)";620log.debug("testCommunication",err);621throw new RuntimeException(err);622}623}624625626/**627* Test the configuration indicated by `file'.628* Sets the appropriate System properties for config file and629* port and then calls ConnectorBootstrap.initialize().630* eventually cleans up by calling ConnectorBootstrap.terminate().631* @return null if the test succeeds, an error message otherwise.632**/633private String testConfiguration(File file) throws IOException, InterruptedException {634635for (int i = 0; i < MAX_GET_FREE_PORT_TRIES; i++) {636try {637int port = jdk.test.lib.Utils.getFreePort();638final String path;639try {640path=(file==null)?null:file.getCanonicalPath();641} catch(IOException x) {642final String err = "Failed to test configuration " + file +643": " + x;644log.trace("testConfiguration",err);645log.debug("testConfiguration",x);646return err;647}648final String config = (path==null)?"Default config file":path;649650System.out.println("***");651System.out.println("*** Testing configuration (port=" + port + "): "652+ path);653System.out.println("***");654655System.setProperty("com.sun.management.jmxremote.port",656Integer.toString(port));657if (path != null)658System.setProperty("com.sun.management.config.file", path);659else660System.getProperties().remove("com.sun.management.config.file");661662log.trace("testConfiguration","com.sun.management.jmxremote.port="+port);663if (path != null && log.isDebugOn())664log.trace("testConfiguration",665"com.sun.management.config.file="+path);666667checkSslConfiguration();668669final JMXConnectorServer cs;670try {671cs = ConnectorBootstrap.initialize();672} catch (AgentConfigurationError x) {673if (x.getCause() instanceof ExportException) {674if (x.getCause().getCause() instanceof BindException) {675throw (BindException)x.getCause().getCause();676}677}678final String err = "Failed to initialize connector:" +679"\n\tcom.sun.management.jmxremote.port=" + port +680((path!=null)?"\n\tcom.sun.management.config.file="+path:681"\n\t"+config) +682"\n\tError is: " + x;683log.trace("testConfiguration",err);684log.debug("testConfiguration",x);685return err;686} catch (Exception x) {687log.debug("testConfiguration",x);688return x.toString();689}690691try {692JMXServiceURL url =693new JMXServiceURL("rmi",null,0,"/jndi/rmi://localhost:"+694port+"/jmxrmi");695696try {697testCommunication(url);698} catch (Exception x) {699final String err = "Failed to connect to agent {url="+url+700"}: " + x;701log.trace("testConfiguration",err);702log.debug("testConfiguration",x);703return err;704}705} catch (Exception x) {706final String err = "Failed to test configuration "+config+707": "+x;708log.trace("testConfiguration",err);709log.debug("testConfiguration",x);710return err;711} finally {712try {713cs.stop();714} catch (Exception x) {715final String err = "Failed to terminate: "+x;716log.trace("testConfiguration",err);717log.debug("testConfiguration",x);718}719}720System.out.println("Configuration " + config + " successfully tested");721return null;722} catch(BindException ex) {723}724}725System.err.println("Cannot find a free port after " + MAX_GET_FREE_PORT_TRIES + " tries");726return "Failed: cannot find a free port after " + MAX_GET_FREE_PORT_TRIES + " tries";727}728729/**730* Test a configuration file which should make the bootstrap fail.731* The test is assumed to have succeeded if the bootstrap fails.732* @return null if the test succeeds, an error message otherwise.733**/734private String testConfigurationKo(File conf) throws InterruptedException, IOException {735String errStr = null;736errStr = testConfiguration(conf);737if (errStr == null) {738return "Configuration " +739conf + " should have failed!";740}741System.out.println("Configuration " +742conf + " failed as expected");743log.debug("runko", "Error was: " + errStr);744return null;745}746747/**748* Test a configuration file. Determines whether the bootstrap749* should succeed or fail depending on the file name:750* *ok.properties: bootstrap should succeed.751* *ko.properties: bootstrap or connection should fail.752* @return null if the test succeeds, an error message otherwise.753**/754private String testConfigurationFile(String fileName) throws InterruptedException, IOException {755File file = new File(fileName);756757if (fileName.endsWith("ok.properties")) {758String errStr = null;759errStr = testConfiguration(file);760return errStr;761}762if (fileName.endsWith("ko.properties")) {763return testConfigurationKo(file);764}765return fileName +766": test file suffix must be one of [ko|ok].properties";767}768769/**770* Find all *ko.property files and test them.771* (see findConfigurationFilesKo() and testConfigurationKo())772* @throws RuntimeException if the test fails.773**/774public void runko() throws InterruptedException, IOException {775final File[] conf = findConfigurationFilesKo();776if ((conf == null)||(conf.length == 0))777throw new RuntimeException("No configuration found");778779String errStr;780for (int i=0;i<conf.length;i++) {781errStr = testConfigurationKo(conf[i]);782if (errStr != null) {783throw new RuntimeException(errStr);784}785}786787}788789/**790* Find all *ok.property files and test them.791* (see findConfigurationFilesOk() and testConfiguration())792* @throws RuntimeException if the test fails.793**/794public void runok() throws InterruptedException, IOException {795final File[] conf = findConfigurationFilesOk();796if ((conf == null)||(conf.length == 0))797throw new RuntimeException("No configuration found");798799String errStr = null;800for (int i=0;i<conf.length;i++) {801errStr = testConfiguration(conf[i]);802if (errStr != null) {803throw new RuntimeException(errStr);804}805}806807// FIXME: No jmxremote.password is not installed in JRE by default.808// - disable the following test case.809//810// Test default config811//812// errStr = testConfiguration(null,port+testPort++);813// if (errStr != null) {814// throw new RuntimeException(errStr);815// }816}817818/**819* Finds all configuration files (*ok.properties and *ko.properties)820* and tests them.821* (see runko() and runok()).822* @throws RuntimeException if the test fails.823**/824public void run() throws InterruptedException, IOException {825runok();826runko();827}828829/**830* Tests the specified configuration files.831* If args[] is not empty, each element in args[] is expected to be832* a filename ending either by ok.properties or ko.properties.833* Otherwise, the configuration files will be automatically determined834* by looking at all *.properties files located in the directory835* indicated by the System property "test.src".836* @throws RuntimeException if the test fails.837**/838public void run(String args[]) throws InterruptedException, IOException {839if (args.length == 0) {840run() ; return;841}842for (int i=0; i<args.length; i++) {843final String errStr =testConfigurationFile(args[i]);844if (errStr != null) {845throw new RuntimeException(errStr);846}847}848}849850/**851* Calls run(args[]).852* exit(1) if the test fails.853**/854public static void main(String args[]) throws Exception {855Security.setProperty("jdk.tls.disabledAlgorithms", "");856857try {858MAX_GET_FREE_PORT_TRIES = Integer.parseInt(System.getProperty("test.getfreeport.max.tries", "10"));859} catch (NumberFormatException ex) {860}861862RmiBootstrapTest manager = new RmiBootstrapTest();863try {864manager.run(args);865} catch (RuntimeException r) {866System.out.println("Test Failed: "+ r.getMessage());867System.exit(1);868} catch (Throwable t) {869System.out.println("Test Failed: "+ t);870t.printStackTrace();871System.exit(2);872}873System.out.println("**** Test RmiBootstrap Passed ****");874}875876}877878879