Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/sun/management/jmxremote/bootstrap/RmiBootstrapTest.java
38867 views
/*1* Copyright (c) 2003, 2015, 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.net.ServerSocket;30import java.rmi.server.ExportException;3132import java.util.Properties;33import java.util.Iterator;34import java.util.Set;35import java.util.ArrayList;36import java.util.HashMap;37import java.util.Map;38import java.util.Enumeration;3940import javax.management.remote.*;41import javax.management.*;4243import sun.management.AgentConfigurationError;4445import java.security.Security;4647import util.TestLogger;4849/**50* <p>This class implements unit test for RMI Bootstrap.51* When called with no arguments main() looks in the directory indicated52* by the "test.src" system property for files called management*ok.properties53* or management*ko.properties. The *ok.properties files are assumed to be54* valid Java M&M config files for which the bootstrap should succeed.55* The *ko.properties files are assumed to be configurations for which the56* bootstrap & connection test will fail.</p>57*58* <p>The rmi port number can be specified with the "rmi.port" system property.59* If not, this test will use the first available port</p>60*61* <p>When called with some argument, the main() will interprete its args to62* be Java M&M configuration file names. The filenames are expected to end63* with ok.properties or ko.properties - and are interpreted as above.</p>64*65* <p>Note that a limitation of the RMI registry (bug 4267864) prevent66* this test from succeeding if more than 1 configuration is used.67* As long as 4267864 isn't fix, this test must be called as many times68* as needed but with a single argument (no arguments, or several arguments69* will fail).</p>70*71* <p>Debug traces are logged in "sun.management.test"</p>72**/73public class RmiBootstrapTest {74// the number of consecutive ports to test for availability75private static final int PORT_TEST_LEN = 800;76static TestLogger log =77new TestLogger("RmiBootstrapTest");7879/**80* When launching several registries, we increment the port number81* to avoid falling into "port number already in use" problems.82**/83static int testPort = 0;84static int basePort = 0;8586/**87* Default values for RMI configuration properties.88**/89public static interface DefaultValues {90public static final String PORT="0";91public static final String CONFIG_FILE_NAME="management.properties";92public static final String USE_SSL="true";93public static final String USE_AUTHENTICATION="true";94public static final String PASSWORD_FILE_NAME="jmxremote.password";95public static final String ACCESS_FILE_NAME="jmxremote.access";96public static final String KEYSTORE="keystore";97public static final String KEYSTORE_PASSWD="password";98public static final String TRUSTSTORE="truststore";99public static final String TRUSTSTORE_PASSWD="trustword";100public static final String SSL_NEED_CLIENT_AUTH="false";101}102103/**104* Names of RMI configuration properties.105**/106public static interface PropertyNames {107public static final String PORT=108"com.sun.management.jmxremote.port";109public static final String CONFIG_FILE_NAME=110"com.sun.management.config.file";111public static final String USE_SSL=112"com.sun.management.jmxremote.ssl";113public static final String USE_AUTHENTICATION=114"com.sun.management.jmxremote.authenticate";115public static final String PASSWORD_FILE_NAME=116"com.sun.management.jmxremote.password.file";117public static final String ACCESS_FILE_NAME=118"com.sun.management.jmxremote.access.file";119public static final String INSTRUMENT_ALL=120"com.sun.management.instrumentall";121public static final String CREDENTIALS =122"jmx.remote.credentials";123public static final String KEYSTORE=124"javax.net.ssl.keyStore";125public static final String KEYSTORE_PASSWD=126"javax.net.ssl.keyStorePassword";127public static final String TRUSTSTORE=128"javax.net.ssl.trustStore";129public static final String TRUSTSTORE_PASSWD=130"javax.net.ssl.trustStorePassword";131public static final String SSL_ENABLED_CIPHER_SUITES =132"com.sun.management.jmxremote.ssl.enabled.cipher.suites";133public static final String SSL_ENABLED_PROTOCOLS =134"com.sun.management.jmxremote.ssl.enabled.protocols";135public static final String SSL_NEED_CLIENT_AUTH =136"com.sun.management.jmxremote.ssl.need.client.auth";137public static final String SSL_CLIENT_ENABLED_CIPHER_SUITES =138"javax.rmi.ssl.client.enabledCipherSuites";139}140141/**142* A filter to find all filenames who match <prefix>*<suffix>.143* Note that <prefix> and <suffix> can overlap.144**/145private static class ConfigFilenameFilter implements FilenameFilter {146final String suffix;147final String prefix;148ConfigFilenameFilter(String prefix, String suffix) {149this.suffix=suffix;150this.prefix=prefix;151}152public boolean accept(File dir, String name) {153return (name.startsWith(prefix) && name.endsWith(suffix));154}155}156157/**158* Get all "management*ok.properties" files in the directory159* indicated by the "test.src" management property.160**/161private static File[] findConfigurationFilesOk() {162final String testSrc = System.getProperty("test.src");163final File dir = new File(testSrc);164final FilenameFilter filter =165new ConfigFilenameFilter("management_test","ok.properties");166return dir.listFiles(filter);167}168169/**170* Get all "management*ko.properties" files in the directory171* indicated by the "test.src" management property.172**/173private static File[] findConfigurationFilesKo() {174final String testSrc = System.getProperty("test.src");175final File dir = new File(testSrc);176final FilenameFilter filter =177new ConfigFilenameFilter("management_test","ko.properties");178return dir.listFiles(filter);179}180181/**182* List all MBeans and their attributes. Used to test communication183* with the Java M&M MBean Server.184* @return the number of queried MBeans.185*/186public static int listMBeans(MBeanServerConnection server)187throws IOException {188return listMBeans(server,null,null);189}190191/**192* List all matching MBeans and their attributes.193* Used to test communication with the Java M&M MBean Server.194* @return the number of matching MBeans.195*/196public static int listMBeans(MBeanServerConnection server,197ObjectName pattern, QueryExp query)198throws IOException {199200final Set names = server.queryNames(pattern,query);201for (final Iterator i=names.iterator(); i.hasNext(); ) {202ObjectName name = (ObjectName)i.next();203log.trace("listMBeans","Got MBean: "+name);204try {205MBeanInfo info =206server.getMBeanInfo((ObjectName)name);207MBeanAttributeInfo[] attrs = info.getAttributes();208if (attrs == null) continue;209for (int j=0; j<attrs.length; j++) {210if (attrs[j].isReadable()) {211try {212Object o =213server.getAttribute(name,attrs[j].getName());214if (log.isDebugOn())215log.debug("listMBeans","\t\t" +216attrs[j].getName() +217" = "+o);218} catch (Exception x) {219log.trace("listMBeans","JmxClient failed to get " +220attrs[j].getName() + ": " + x);221final IOException io =222new IOException("JmxClient failed to get " +223attrs[j].getName());224io.initCause(x);225throw io;226}227}228}229} catch (Exception x) {230log.trace("listMBeans",231"JmxClient failed to get MBeanInfo: " + x);232final IOException io =233new IOException("JmxClient failed to get MBeanInfo: "+x);234io.initCause(x);235throw io;236}237}238return names.size();239}240241/**242* Compute the full path name for a default file.243* @param basename basename (with extension) of the default file.244* @return ${JRE}/lib/management/${basename}245**/246private static String getDefaultFileName(String basename) {247final String fileSeparator = File.separator;248final StringBuffer defaultFileName =249new StringBuffer(System.getProperty("java.home")).250append(fileSeparator).append("lib").append(fileSeparator).251append("management").append(fileSeparator).252append(basename);253return defaultFileName.toString();254}255256/**257* Compute the full path name for a default file.258* @param basename basename (with extension) of the default file.259* @return ${JRE}/lib/management/${basename}260**/261private static String getDefaultStoreName(String basename) {262final String fileSeparator = File.separator;263final StringBuffer defaultFileName =264new StringBuffer(System.getProperty("test.src")).265append(fileSeparator).append("ssl").append(fileSeparator).266append(basename);267return defaultFileName.toString();268}269270271/**272* Parses the password file to read the credentials.273* Returns an ArrayList of arrays of 2 string:274* {<subject>, <password>}.275* If the password file does not exists, return an empty list.276* (File not found = empty file).277**/278private ArrayList readCredentials(String passwordFileName)279throws IOException {280final Properties pws = new Properties();281final ArrayList result = new ArrayList();282final File f = new File(passwordFileName);283if (!f.exists()) return result;284FileInputStream fin = new FileInputStream(passwordFileName);285try {pws.load(fin);}finally{fin.close();}286for (Enumeration en=pws.propertyNames();en.hasMoreElements();) {287final String[] cred = new String[2];288cred[0]=(String)en.nextElement();289cred[1]=pws.getProperty(cred[0]);290result.add(cred);291}292return result;293}294295296/**297* Connect with the given url, using all given credentials in turn.298* A null entry in the useCredentials arrays indicate a connection299* where no credentials are used.300* @param url JMXServiceURL of the server.301* @param useCredentials An array of credentials (a credential302* is a two String array, so this is an array of arrays303* of strings:304* useCredentials[i][0]=subject305* useCredentials[i][1]=password306* if useCredentials[i] == null means no credentials.307* @param expectConnectOk true if connection is expected to succeed308* Note: if expectConnectOk=false and the test fails to connect309* the number of failure is not incremented. Conversely,310* if expectConnectOk=false and the test does not fail to311* connect the number of failure is incremented.312* @param expectReadOk true if communication (listMBeans) is expected313* to succeed.314* Note: if expectReadOk=false and the test fails to read MBeans315* the number of failure is not incremented. Conversely,316* if expectReadOk=false and the test does not fail to317* read MBeans the number of failure is incremented.318* @return number of failure.319**/320public int connectAndRead(JMXServiceURL url,321Object[] useCredentials,322boolean expectConnectOk,323boolean expectReadOk)324throws IOException {325326int errorCount = 0;327328for (int i=0 ; i<useCredentials.length ; i++) {329final Map m = new HashMap();330final String[] credentials = (String[])useCredentials[i];331final String crinfo;332if (credentials != null) {333crinfo = "{"+credentials[0] + ", " + credentials[1] + "}";334m.put(PropertyNames.CREDENTIALS,credentials);335} else {336crinfo="no credentials";337}338log.trace("testCommunication","using credentials: " + crinfo);339340final JMXConnector c;341try {342c = JMXConnectorFactory.connect(url,m);343} catch (IOException x ) {344if (expectConnectOk) {345final String err = "Connection failed for " + crinfo +346": " + x;347System.out.println(err);348log.trace("testCommunication",err);349log.debug("testCommunication",x);350errorCount++;351continue;352} else {353System.out.println("Connection failed as expected for " +354crinfo + ": " + x);355continue;356}357} catch (RuntimeException x ) {358if (expectConnectOk) {359final String err = "Connection failed for " + crinfo +360": " + x;361System.out.println(err);362log.trace("testCommunication",err);363log.debug("testCommunication",x);364errorCount++;365continue;366} else {367System.out.println("Connection failed as expected for " +368crinfo + ": " + x);369continue;370}371}372try {373MBeanServerConnection conn =374c.getMBeanServerConnection();375if (log.isDebugOn()) {376log.debug("testCommunication","Connection is:" + conn);377log.debug("testCommunication","Server domain is: " +378conn.getDefaultDomain());379}380final ObjectName pattern =381new ObjectName("java.lang:type=Memory,*");382final int count = listMBeans(conn,pattern,null);383if (count == 0)384throw new Exception("Expected at least one matching "+385"MBean for "+pattern);386if (expectReadOk) {387System.out.println("Communication succeeded " +388"as expected for "+389crinfo + ": found " + count390+ ((count<2)?"MBean":"MBeans"));391} else {392final String err = "Expected failure didn't occur for " +393crinfo;394System.out.println(err);395errorCount++;396}397} catch (IOException x ) {398if (expectReadOk) {399final String err = "Communication failed with " + crinfo +400": " + x;401System.out.println(err);402log.trace("testCommunication",err);403log.debug("testCommunication",x);404errorCount++;405continue;406} else {407System.out.println("Communication failed as expected for "+408crinfo + ": " + x);409continue;410}411} catch (RuntimeException x ) {412if (expectReadOk) {413final String err = "Communication failed with " + crinfo +414": " + x;415System.out.println(err);416log.trace("testCommunication",err);417log.debug("testCommunication",x);418errorCount++;419continue;420} else {421System.out.println("Communication failed as expected for "+422crinfo + ": " + x);423}424} catch (Exception x) {425final String err = "Failed to read MBeans with " + crinfo +426": " + x;427System.out.println(err);428log.trace("testCommunication",err);429log.debug("testCommunication",x);430errorCount++;431continue;432} finally {433c.close();434}435}436return errorCount;437}438439440private void setSslProperties(String clientEnabledCipherSuites) {441final String defaultKeyStore =442getDefaultStoreName(DefaultValues.KEYSTORE);443final String defaultTrustStore =444getDefaultStoreName(DefaultValues.TRUSTSTORE);445446final String keyStore =447System.getProperty(PropertyNames.KEYSTORE, defaultKeyStore);448System.setProperty(PropertyNames.KEYSTORE,keyStore);449log.trace("setSslProperties",PropertyNames.KEYSTORE+"="+keyStore);450451final String password =452System.getProperty(PropertyNames.KEYSTORE_PASSWD,453DefaultValues.KEYSTORE_PASSWD);454System.setProperty(PropertyNames.KEYSTORE_PASSWD,password);455log.trace("setSslProperties",456PropertyNames.KEYSTORE_PASSWD+"="+password);457458final String trustStore =459System.getProperty(PropertyNames.TRUSTSTORE,460defaultTrustStore);461System.setProperty(PropertyNames.TRUSTSTORE,trustStore);462log.trace("setSslProperties",463PropertyNames.TRUSTSTORE+"="+trustStore);464465final String trustword =466System.getProperty(PropertyNames.TRUSTSTORE_PASSWD,467DefaultValues.TRUSTSTORE_PASSWD);468System.setProperty(PropertyNames.TRUSTSTORE_PASSWD,trustword);469log.trace("setSslProperties",470PropertyNames.TRUSTSTORE_PASSWD+"="+trustword);471472if (clientEnabledCipherSuites != null) {473System.setProperty("javax.rmi.ssl.client.enabledCipherSuites",474clientEnabledCipherSuites);475} else {476System.clearProperty("javax.rmi.ssl.client.enabledCipherSuites");477}478}479480private void checkSslConfiguration() {481try {482final String defaultConf =483getDefaultFileName(DefaultValues.CONFIG_FILE_NAME);484final String confname =485System.getProperty(PropertyNames.CONFIG_FILE_NAME,defaultConf);486487final Properties props = new Properties();488final File conf = new File(confname);489if (conf.exists()) {490FileInputStream fin = new FileInputStream(conf);491try {props.load(fin);} finally {fin.close();}492}493494// Do we use SSL?495final String useSslStr =496props.getProperty(PropertyNames.USE_SSL,497DefaultValues.USE_SSL);498final boolean useSsl =499Boolean.valueOf(useSslStr).booleanValue();500501log.debug("checkSslConfiguration",502PropertyNames.USE_SSL+"="+useSsl+503": setting SSL");504// Do we use SSL client authentication?505final String useSslClientAuthStr =506props.getProperty(PropertyNames.SSL_NEED_CLIENT_AUTH,507DefaultValues.SSL_NEED_CLIENT_AUTH);508final boolean useSslClientAuth =509Boolean.valueOf(useSslClientAuthStr).booleanValue();510511log.debug("checkSslConfiguration",512PropertyNames.SSL_NEED_CLIENT_AUTH+"="+useSslClientAuth);513514// Do we use customized SSL cipher suites?515final String sslCipherSuites =516props.getProperty(PropertyNames.SSL_ENABLED_CIPHER_SUITES);517518log.debug("checkSslConfiguration",519PropertyNames.SSL_ENABLED_CIPHER_SUITES + "=" +520sslCipherSuites);521522// Do we use customized SSL protocols?523final String sslProtocols =524props.getProperty(PropertyNames.SSL_ENABLED_PROTOCOLS);525526log.debug("checkSslConfiguration",527PropertyNames.SSL_ENABLED_PROTOCOLS + "=" +528sslProtocols);529530if (useSsl) {531setSslProperties(props.getProperty(532PropertyNames.SSL_CLIENT_ENABLED_CIPHER_SUITES));533}534} catch (Exception x) {535System.out.println("Failed to setup SSL configuration: " + x);536log.debug("checkSslConfiguration",x);537}538}539540/**541* Tests the server bootstraped at the given URL.542* Uses the system properties to determine which config file is used.543* Loads the config file to determine which password file is used.544* Loads the password file to find out wich credentials to use.545* Also checks that unregistered user/passwords are not allowed to546* connect when a password file is used.547*548* This method calls connectAndRead().549**/550public void testCommunication(JMXServiceURL url)551throws IOException {552553final String defaultConf =554getDefaultFileName(DefaultValues.CONFIG_FILE_NAME);555final String confname =556System.getProperty(PropertyNames.CONFIG_FILE_NAME,defaultConf);557558final Properties props = new Properties();559final File conf = new File(confname);560if (conf.exists()) {561FileInputStream fin = new FileInputStream(conf);562try {props.load(fin);} finally {fin.close();}563}564565// Do we use authentication?566final String useAuthenticationStr =567props.getProperty(PropertyNames.USE_AUTHENTICATION,568DefaultValues.USE_AUTHENTICATION);569final boolean useAuthentication =570Boolean.valueOf(useAuthenticationStr).booleanValue();571572// Get Password File573final String defaultPasswordFileName = Utils.convertPath(574getDefaultFileName(DefaultValues.PASSWORD_FILE_NAME));575final String passwordFileName = Utils.convertPath(576props.getProperty(PropertyNames.PASSWORD_FILE_NAME,577defaultPasswordFileName));578579// Get Access File580final String defaultAccessFileName = Utils.convertPath(581getDefaultFileName(DefaultValues.ACCESS_FILE_NAME));582final String accessFileName = Utils.convertPath(583props.getProperty(PropertyNames.ACCESS_FILE_NAME,584defaultAccessFileName));585586if (useAuthentication) {587System.out.println("PasswordFileName: " + passwordFileName);588System.out.println("accessFileName: " + accessFileName);589}590591final Object[] allCredentials;592final Object[] noCredentials = { null };593if (useAuthentication) {594final ArrayList l = readCredentials(passwordFileName);595if (l.size() == 0) allCredentials = null;596else allCredentials = l.toArray();597} else allCredentials = noCredentials;598599int errorCount = 0;600if (allCredentials!=null) {601// Tests that the registered user/passwords are allowed to602// connect & read603//604errorCount += connectAndRead(url,allCredentials,true,true);605} else {606// Tests that no one is allowed607// connect & read608//609final String[][] someCredentials = {610null,611{ "modify", "R&D" },612{ "measure", "QED" }613};614errorCount += connectAndRead(url,someCredentials,false,false);615}616617if (useAuthentication && allCredentials != noCredentials) {618// Tests that the registered user/passwords are not allowed to619// connect & read620//621final String[][] badCredentials = {622{ "bad.user", "R&D" },623{ "measure", "bad.password" }624};625errorCount += connectAndRead(url,badCredentials,false,false);626}627if (errorCount > 0) {628final String err = "Test " + confname + " failed with " +629errorCount + " error(s)";630log.debug("testCommunication",err);631throw new RuntimeException(err);632}633}634635636/**637* Test the configuration indicated by `file'.638* Sets the appropriate System properties for config file and639* port and then calls ConnectorBootstrap.initialize().640* eventually cleans up by calling ConnectorBootstrap.terminate().641* @return null if the test succeeds, an error message otherwise.642**/643private String testConfiguration(File file,int port) throws BindException {644645final String path;646try {647path=(file==null)?null:file.getCanonicalPath();648} catch(IOException x) {649final String err = "Failed to test configuration " + file +650": " + x;651log.trace("testConfiguration",err);652log.debug("testConfiguration",x);653return err;654}655final String config = (path==null)?"Default config file":path;656657System.out.println("***");658System.out.println("*** Testing configuration (port=" + port + "): "659+ path);660System.out.println("***");661662System.setProperty("com.sun.management.jmxremote.port",663Integer.toString(port));664if (path != null)665System.setProperty("com.sun.management.config.file", path);666else667System.getProperties().remove("com.sun.management.config.file");668669log.trace("testConfiguration","com.sun.management.jmxremote.port="+port);670if (path != null && log.isDebugOn())671log.trace("testConfiguration",672"com.sun.management.config.file="+path);673674checkSslConfiguration();675676final JMXConnectorServer cs;677try {678cs = ConnectorBootstrap.initialize();679} catch (AgentConfigurationError x) {680if (x.getCause() instanceof ExportException) {681if (x.getCause().getCause() instanceof BindException) {682throw (BindException)x.getCause().getCause();683}684}685final String err = "Failed to initialize connector:" +686"\n\tcom.sun.management.jmxremote.port=" + port +687((path!=null)?"\n\tcom.sun.management.config.file="+path:688"\n\t"+config) +689"\n\tError is: " + x;690log.trace("testConfiguration",err);691log.debug("testConfiguration",x);692return err;693} catch (Exception x) {694log.debug("testConfiguration",x);695return x.toString();696}697698try {699JMXServiceURL url =700new JMXServiceURL("rmi",null,0,"/jndi/rmi://localhost:"+701port+"/jmxrmi");702703try {704testCommunication(url);705} catch (Exception x) {706final String err = "Failed to connect to agent {url="+url+707"}: " + x;708log.trace("testConfiguration",err);709log.debug("testConfiguration",x);710return err;711}712} catch (Exception x) {713final String err = "Failed to test configuration "+config+714": "+x;715log.trace("testConfiguration",err);716log.debug("testConfiguration",x);717return err;718} finally {719try {720cs.stop();721} catch (Exception x) {722final String err = "Failed to terminate: "+x;723log.trace("testConfiguration",err);724log.debug("testConfiguration",x);725}726}727System.out.println("Configuration " + config + " successfully tested");728return null;729}730731/**732* Test a configuration file which should make the bootstrap fail.733* The test is assumed to have succeeded if the bootstrap fails.734* @return null if the test succeeds, an error message otherwise.735**/736private String testConfigurationKo(File conf,int port) {737String errStr = null;738for (int i = 0; i < PORT_TEST_LEN; i++) {739try {740errStr = testConfiguration(conf,port+testPort++);741break;742} catch (BindException e) {743// port conflict; try another port744}745}746if (errStr == null) {747return "Configuration " +748conf + " should have failed!";749}750System.out.println("Configuration " +751conf + " failed as expected");752log.debug("runko","Error was: " + errStr);753return null;754}755756/**757* Test a configuration file. Determines whether the bootstrap758* should succeed or fail depending on the file name:759* *ok.properties: bootstrap should succeed.760* *ko.properties: bootstrap or connection should fail.761* @return null if the test succeeds, an error message otherwise.762**/763private String testConfigurationFile(String fileName) {764File file = new File(fileName);765final String portStr = System.getProperty("rmi.port",null);766final int port = portStr != null ?767Integer.parseInt(portStr) : basePort;768769if (fileName.endsWith("ok.properties")) {770String errStr = null;771for (int i = 0; i < PORT_TEST_LEN; i++) {772try {773errStr = testConfiguration(file,port+testPort++);774return errStr;775} catch (BindException e) {776// port conflict; try another port777}778}779return "Can not locate available port";780}781if (fileName.endsWith("ko.properties")) {782return testConfigurationKo(file,port+testPort++);783}784return fileName +785": test file suffix must be one of [ko|ok].properties";786}787788/**789* Find all *ko.property files and test them.790* (see findConfigurationFilesKo() and testConfigurationKo())791* @throws RuntimeException if the test fails.792**/793public void runko() {794final String portStr = System.getProperty("rmi.port",null);795final int port = portStr != null ?796Integer.parseInt(portStr) : basePort;797final File[] conf = findConfigurationFilesKo();798if ((conf == null)||(conf.length == 0))799throw new RuntimeException("No configuration found");800801String errStr;802for (int i=0;i<conf.length;i++) {803errStr = testConfigurationKo(conf[i],port+testPort++);804if (errStr != null) {805throw new RuntimeException(errStr);806}807}808809}810811/**812* Find all *ok.property files and test them.813* (see findConfigurationFilesOk() and testConfiguration())814* @throws RuntimeException if the test fails.815**/816public void runok() {817final String portStr = System.getProperty("rmi.port",null);818final int port = portStr != null ?819Integer.parseInt(portStr) : basePort;820final File[] conf = findConfigurationFilesOk();821if ((conf == null)||(conf.length == 0))822throw new RuntimeException("No configuration found");823824String errStr = null;825for (int i=0;i<conf.length;i++) {826for (int j = 0; j < PORT_TEST_LEN; j++) {827try {828errStr = testConfiguration(conf[i],port+testPort++);829break;830} catch (BindException e) {831// port conflict; try another port832}833}834if (errStr != null) {835throw new RuntimeException(errStr);836}837}838839// FIXME: No jmxremote.password is not installed in JRE by default.840// - disable the following test case.841//842// Test default config843//844// errStr = testConfiguration(null,port+testPort++);845// if (errStr != null) {846// throw new RuntimeException(errStr);847// }848}849850/**851* Finds all configuration files (*ok.properties and *ko.properties)852* and tests them.853* (see runko() and runok()).854* @throws RuntimeException if the test fails.855**/856public void run() {857runok();858runko();859}860861/**862* Tests the specified configuration files.863* If args[] is not empty, each element in args[] is expected to be864* a filename ending either by ok.properties or ko.properties.865* Otherwise, the configuration files will be automatically determined866* by looking at all *.properties files located in the directory867* indicated by the System property "test.src".868* @throws RuntimeException if the test fails.869**/870public void run(String args[]) {871if (args.length == 0) {872run() ; return;873}874for (int i=0; i<args.length; i++) {875final String errStr =testConfigurationFile(args[i]);876if (errStr != null) {877throw new RuntimeException(errStr);878}879}880}881882/**883* Calls run(args[]).884* exit(1) if the test fails.885**/886public static void main(String args[]) throws Exception {887Security.setProperty("jdk.tls.disabledAlgorithms", "");888889setupBasePort();890RmiBootstrapTest manager = new RmiBootstrapTest();891try {892manager.run(args);893} catch (RuntimeException r) {894System.out.println("Test Failed: "+ r.getMessage());895System.exit(1);896} catch (Throwable t) {897System.out.println("Test Failed: "+ t);898t.printStackTrace();899System.exit(2);900}901System.out.println("**** Test RmiBootstrap Passed ****");902}903904private static void setupBasePort() throws IOException {905try (ServerSocket s = new ServerSocket(0)) {906basePort = s.getLocalPort() + 1;907}908}909}910911912