/*
 * Copyright (c) 2003, 2004, 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.
 */
import sun.management.jmxremote.ConnectorBootstrap;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.FilenameFilter;
import java.io.IOException;

import java.util.Properties;
import java.util.Iterator;
import java.util.Set;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Enumeration;

import javax.management.remote.*;
import javax.management.*;

import sun.management.AgentConfigurationError;

import util.TestLogger;

/**
 * <p>This class implements unit test for RMI Bootstrap.
 * When called with no arguments main() looks in the directory indicated
 * by the "test.src" system property for files called management*ok.properties
 * or management*ko.properties. The *ok.properties files are assumed to be
 * valid Java M&M config files for which the bootstrap should succeed.
 * The *ko.properties files are assumed to be configurations for which the
 * bootstrap & connection test will fail.</p>
 *
 * <p>The rmi port number can be specified with the "rmi.port" system property.
 * If not, this test will use 12424</p>
 *
 * <p>When called with some argument, the main() will interprete its args to
 * be Java M&M configuration file names. The filenames are expected to end
 * with ok.properties or ko.properties - and are interpreted as above.</p>
 *
 * <p>Note that a limitation of the RMI registry (bug 4267864) prevent
 * this test from succeeding if more than 1 configuration is used.
 * As long as 4267864 isn't fix, this test must be called as many times
 * as needed but with a single argument (no arguments, or several arguments
 * will fail).</p>
 *
 * <p>Debug traces are logged in "sun.management.test"</p>
 **/
public class RmiBootstrapTest {

    static TestLogger log =
        new TestLogger("RmiBootstrapTest");

    /**
     * When launching several registries, we increment the port number
     * to avoid falling into "port number already in use" problems.
     **/
    static int testPort = 0;

    /**
     * Default values for RMI configuration properties.
     **/
    public static interface DefaultValues {
        public static final String PORT="0";
        public static final String CONFIG_FILE_NAME="management.properties";
        public static final String USE_SSL="true";
        public static final String USE_AUTHENTICATION="true";
        public static final String PASSWORD_FILE_NAME="jmxremote.password";
        public static final String ACCESS_FILE_NAME="jmxremote.access";
        public static final String KEYSTORE="keystore";
        public static final String KEYSTORE_PASSWD="password";
        public static final String TRUSTSTORE="truststore";
        public static final String TRUSTSTORE_PASSWD="trustword";
        public static final String SSL_NEED_CLIENT_AUTH="false";
    }

    /**
     * Names of RMI configuration properties.
     **/
    public static interface PropertyNames {
        public static final String PORT=
            "com.sun.management.jmxremote.port";
        public static final String CONFIG_FILE_NAME=
            "com.sun.management.config.file";
        public static final String USE_SSL=
            "com.sun.management.jmxremote.ssl";
        public static final String USE_AUTHENTICATION=
            "com.sun.management.jmxremote.authenticate";
        public static final String PASSWORD_FILE_NAME=
            "com.sun.management.jmxremote.password.file";
        public static final String ACCESS_FILE_NAME=
            "com.sun.management.jmxremote.access.file";
        public static final String INSTRUMENT_ALL=
            "com.sun.management.instrumentall";
        public static final String CREDENTIALS =
            "jmx.remote.credentials";
        public static final String KEYSTORE=
            "javax.net.ssl.keyStore";
        public static final String KEYSTORE_PASSWD=
            "javax.net.ssl.keyStorePassword";
        public static final String TRUSTSTORE=
            "javax.net.ssl.trustStore";
        public static final String TRUSTSTORE_PASSWD=
            "javax.net.ssl.trustStorePassword";
        public static final String SSL_ENABLED_CIPHER_SUITES =
            "com.sun.management.jmxremote.ssl.enabled.cipher.suites";
        public static final String SSL_ENABLED_PROTOCOLS =
            "com.sun.management.jmxremote.ssl.enabled.protocols";
        public static final String SSL_NEED_CLIENT_AUTH =
            "com.sun.management.jmxremote.ssl.need.client.auth";
    }

    /**
     * A filter to find all filenames who match <prefix>*<suffix>.
     * Note that <prefix> and <suffix> can overlap.
     **/
    private static class ConfigFilenameFilter implements FilenameFilter {
        final String suffix;
        final String prefix;
        ConfigFilenameFilter(String prefix, String suffix) {
            this.suffix=suffix;
            this.prefix=prefix;
        }
        public boolean accept(File dir, String name) {
            return (name.startsWith(prefix) && name.endsWith(suffix));
        }
    }

    /**
     * Get all "management*ok.properties" files in the directory
     * indicated by the "test.src" management property.
     **/
    private static File[] findConfigurationFilesOk() {
        final String testSrc = System.getProperty("test.src");
        final File dir = new File(testSrc);
        final FilenameFilter filter =
            new ConfigFilenameFilter("management_test","ok.properties");
        return dir.listFiles(filter);
    }

    /**
     * Get all "management*ko.properties" files in the directory
     * indicated by the "test.src" management property.
     **/
    private static File[] findConfigurationFilesKo() {
        final String testSrc = System.getProperty("test.src");
        final File dir = new File(testSrc);
        final FilenameFilter filter =
            new ConfigFilenameFilter("management_test","ko.properties");
        return dir.listFiles(filter);
    }

    /**
     * List all MBeans and their attributes. Used to test communication
     * with the Java M&M MBean Server.
     * @return the number of queried MBeans.
     */
    public static int listMBeans(MBeanServerConnection server)
        throws IOException {
        return listMBeans(server,null,null);
    }

    /**
     * List all matching MBeans and their attributes.
     * Used to test communication with the Java M&M MBean Server.
     * @return the number of matching MBeans.
     */
    public static int listMBeans(MBeanServerConnection server,
                                  ObjectName pattern, QueryExp query)
        throws IOException {

        final Set names = server.queryNames(pattern,query);
        for (final Iterator i=names.iterator(); i.hasNext(); ) {
            ObjectName name = (ObjectName)i.next();
            log.trace("listMBeans","Got MBean: "+name);
            try {
                MBeanInfo info =
                    server.getMBeanInfo((ObjectName)name);
                MBeanAttributeInfo[] attrs = info.getAttributes();
                if (attrs == null) continue;
                for (int j=0; j<attrs.length; j++) {
                    if (attrs[j].isReadable()) {
                        try {
                            Object o =
                                server.getAttribute(name,attrs[j].getName());
                            if (log.isDebugOn())
                                log.debug("listMBeans","\t\t" +
                                          attrs[j].getName() +
                                          " = "+o);
                        } catch (Exception x) {
                            log.trace("listMBeans","JmxClient failed to get " +
                                      attrs[j].getName() + ": " + x);
                            final IOException io =
                                new IOException("JmxClient failed to get " +
                                                attrs[j].getName());
                            io.initCause(x);
                            throw io;
                        }
                    }
                }
            } catch (Exception x) {
               log.trace("listMBeans",
                         "JmxClient failed to get MBeanInfo: "  + x);
                final IOException io =
                    new IOException("JmxClient failed to get MBeanInfo: "+x);
                io.initCause(x);
                throw io;
            }
        }
        return names.size();
    }

    /**
     * Compute the full path name for a default file.
     * @param basename basename (with extension) of the default file.
     * @return ${JRE}/lib/management/${basename}
     **/
    private static String getDefaultFileName(String basename) {
        final String fileSeparator = File.separator;
        final StringBuffer defaultFileName =
            new StringBuffer(System.getProperty("java.home")).
            append(fileSeparator).append("lib").append(fileSeparator).
            append("management").append(fileSeparator).
            append(basename);
        return defaultFileName.toString();
    }

    /**
     * Compute the full path name for a default file.
     * @param basename basename (with extension) of the default file.
     * @return ${JRE}/lib/management/${basename}
     **/
    private static String getDefaultStoreName(String basename) {
        final String fileSeparator = File.separator;
        final StringBuffer defaultFileName =
            new StringBuffer(System.getProperty("test.src")).
            append(fileSeparator).append("ssl").append(fileSeparator).
            append(basename);
        return defaultFileName.toString();
    }


    /**
     * Parses the password file to read the credentials.
     * Returns an ArrayList of arrays of 2 string:
     * {<subject>, <password>}.
     * If the password file does not exists, return an empty list.
     * (File not found = empty file).
     **/
    private ArrayList readCredentials(String passwordFileName)
        throws IOException {
        final Properties pws = new Properties();
        final ArrayList  result = new ArrayList();
        final File f = new File(passwordFileName);
        if (!f.exists()) return result;
        FileInputStream fin = new FileInputStream(passwordFileName);
        try {pws.load(fin);}finally{fin.close();}
        for (Enumeration en=pws.propertyNames();en.hasMoreElements();) {
            final String[] cred = new String[2];
            cred[0]=(String)en.nextElement();
            cred[1]=pws.getProperty(cred[0]);
            result.add(cred);
        }
        return result;
    }


    /**
     * Connect with the given url, using all given credentials in turn.
     * A null entry in the useCredentials arrays indicate a connection
     * where no credentials are used.
     * @param url JMXServiceURL of the server.
     * @param useCredentials An array of credentials (a credential
     *        is a two String array, so this is an array of arrays
     *        of strings:
     *           useCredentials[i][0]=subject
     *           useCredentials[i][1]=password
     *        if useCredentials[i] == null means no credentials.
     * @param expectConnectOk true if connection is expected to succeed
     *    Note: if expectConnectOk=false and the test fails to connect
     *          the number of failure is not incremented. Conversely,
     *          if expectConnectOk=false and the test does not fail to
     *          connect the number of failure is incremented.
     * @param expectReadOk true if communication (listMBeans) is expected
     *        to succeed.
     *    Note: if expectReadOk=false and the test fails to read MBeans
     *          the number of failure is not incremented. Conversely,
     *          if expectReadOk=false and the test does not fail to
     *          read MBeans the number of failure is incremented.
     * @return number of failure.
     **/
    public int connectAndRead(JMXServiceURL url,
                              Object[] useCredentials,
                              boolean  expectConnectOk,
                              boolean  expectReadOk)
        throws IOException {

        int errorCount = 0;

        for (int i=0 ; i<useCredentials.length ; i++) {
            final Map m = new HashMap();
            final String[] credentials = (String[])useCredentials[i];
            final String   crinfo;
            if (credentials != null) {
                crinfo = "{"+credentials[0] + ", " + credentials[1] + "}";
                m.put(PropertyNames.CREDENTIALS,credentials);
            } else {
                crinfo="no credentials";
            }
            log.trace("testCommunication","using credentials: " + crinfo);

            final JMXConnector c;
            try {
                c = JMXConnectorFactory.connect(url,m);
            } catch (IOException x ) {
                if (expectConnectOk) {
                    final String err = "Connection failed for " + crinfo +
                        ": " + x;
                    System.out.println(err);
                    log.trace("testCommunication",err);
                    log.debug("testCommunication",x);
                    errorCount++;
                    continue;
                } else {
                    System.out.println("Connection failed as expected for " +
                                       crinfo + ": " + x);
                    continue;
                }
            } catch (RuntimeException x ) {
                if (expectConnectOk) {
                    final String err = "Connection failed for " + crinfo +
                        ": " + x;
                    System.out.println(err);
                    log.trace("testCommunication",err);
                    log.debug("testCommunication",x);
                    errorCount++;
                    continue;
                } else {
                    System.out.println("Connection failed as expected for " +
                                       crinfo + ": " + x);
                    continue;
                }
            }
            try {
                MBeanServerConnection conn =
                    c.getMBeanServerConnection();
                if (log.isDebugOn()) {
                    log.debug("testCommunication","Connection is:" + conn);
                    log.debug("testCommunication","Server domain is: " +
                              conn.getDefaultDomain());
                }
                final ObjectName pattern =
                    new ObjectName("java.lang:type=Memory,*");
                final int count = listMBeans(conn,pattern,null);
                if (count == 0)
                    throw new Exception("Expected at least one matching "+
                                        "MBean for "+pattern);
                if (expectReadOk) {
                    System.out.println("Communication succeeded " +
                                       "as expected for "+
                                       crinfo + ": found " + count
                                       + ((count<2)?"MBean":"MBeans"));
                } else {
                    final String err = "Expected failure didn't occur for " +
                        crinfo;
                    System.out.println(err);
                    errorCount++;
                }
            } catch (IOException x ) {
                if (expectReadOk) {
                    final String err = "Communication failed with " + crinfo +
                        ": " + x;
                    System.out.println(err);
                    log.trace("testCommunication",err);
                    log.debug("testCommunication",x);
                    errorCount++;
                    continue;
                } else {
                    System.out.println("Communication failed as expected for "+
                                       crinfo + ": " + x);
                    continue;
                }
            } catch (RuntimeException x ) {
                if (expectReadOk) {
                    final String err = "Communication failed with " + crinfo +
                        ": " + x;
                    System.out.println(err);
                    log.trace("testCommunication",err);
                    log.debug("testCommunication",x);
                    errorCount++;
                    continue;
                } else {
                    System.out.println("Communication failed as expected for "+
                                       crinfo + ": " + x);
                }
            } catch (Exception x) {
                final String err = "Failed to read MBeans with " + crinfo +
                    ": " + x;
                System.out.println(err);
                log.trace("testCommunication",err);
                log.debug("testCommunication",x);
                errorCount++;
                continue;
            } finally {
                c.close();
            }
        }
        return errorCount;
    }


    private void setSslProperties() {
        final String defaultKeyStore =
            getDefaultStoreName(DefaultValues.KEYSTORE);
        final String defaultTrustStore =
            getDefaultStoreName(DefaultValues.TRUSTSTORE);

        final String keyStore =
            System.getProperty(PropertyNames.KEYSTORE, defaultKeyStore);
        System.setProperty(PropertyNames.KEYSTORE,keyStore);
        log.trace("setSslProperties",PropertyNames.KEYSTORE+"="+keyStore);

        final String password =
            System.getProperty(PropertyNames.KEYSTORE_PASSWD,
                               DefaultValues.KEYSTORE_PASSWD);
        System.setProperty(PropertyNames.KEYSTORE_PASSWD,password);
        log.trace("setSslProperties",
                  PropertyNames.KEYSTORE_PASSWD+"="+password);

        final String trustStore =
            System.getProperty(PropertyNames.TRUSTSTORE,
                               defaultTrustStore);
        System.setProperty(PropertyNames.TRUSTSTORE,trustStore);
        log.trace("setSslProperties",
                  PropertyNames.TRUSTSTORE+"="+trustStore);

        final String trustword =
            System.getProperty(PropertyNames.TRUSTSTORE_PASSWD,
                               DefaultValues.TRUSTSTORE_PASSWD);
        System.setProperty(PropertyNames.TRUSTSTORE_PASSWD,trustword);
        log.trace("setSslProperties",
                  PropertyNames.TRUSTSTORE_PASSWD+"="+trustword);
    }

    private void checkSslConfiguration() {
        try {
            final String defaultConf =
                getDefaultFileName(DefaultValues.CONFIG_FILE_NAME);
            final String confname =
                System.getProperty(PropertyNames.CONFIG_FILE_NAME,defaultConf);

            final Properties props = new Properties();
            final File conf = new File(confname);
            if (conf.exists()) {
                FileInputStream fin = new FileInputStream(conf);
                try {props.load(fin);} finally {fin.close();}
            }

            // Do we use SSL?
            final String  useSslStr =
                props.getProperty(PropertyNames.USE_SSL,
                                  DefaultValues.USE_SSL);
            final boolean useSsl =
                Boolean.valueOf(useSslStr).booleanValue();

            log.debug("checkSslConfiguration",
                      PropertyNames.USE_SSL+"="+useSsl+
                      ": setting SSL");
            // Do we use SSL client authentication?
            final String  useSslClientAuthStr =
                props.getProperty(PropertyNames.SSL_NEED_CLIENT_AUTH,
                                  DefaultValues.SSL_NEED_CLIENT_AUTH);
            final boolean useSslClientAuth =
                Boolean.valueOf(useSslClientAuthStr).booleanValue();

            log.debug("checkSslConfiguration",
                      PropertyNames.SSL_NEED_CLIENT_AUTH+"="+useSslClientAuth);

            // Do we use customized SSL cipher suites?
            final String sslCipherSuites =
                props.getProperty(PropertyNames.SSL_ENABLED_CIPHER_SUITES);

            log.debug("checkSslConfiguration",
                      PropertyNames.SSL_ENABLED_CIPHER_SUITES + "=" +
                      sslCipherSuites);

            // Do we use customized SSL protocols?
            final String sslProtocols =
                props.getProperty(PropertyNames.SSL_ENABLED_PROTOCOLS);

            log.debug("checkSslConfiguration",
                      PropertyNames.SSL_ENABLED_PROTOCOLS + "=" +
                      sslProtocols);

            if (useSsl) setSslProperties();
        } catch (Exception x) {
            System.out.println("Failed to setup SSL configuration: " + x);
            log.debug("checkSslConfiguration",x);
        }
    }

    /**
     * Tests the server bootstraped at the given URL.
     * Uses the system properties to determine which config file is used.
     * Loads the config file to determine which password file is used.
     * Loads the password file to find out wich credentials to use.
     * Also checks that unregistered user/passwords are not allowed to
     * connect when a password file is used.
     *
     * This method calls connectAndRead().
     **/
    public void testCommunication(JMXServiceURL url)
        throws IOException {

        final String defaultConf =
            getDefaultFileName(DefaultValues.CONFIG_FILE_NAME);
        final String confname =
            System.getProperty(PropertyNames.CONFIG_FILE_NAME,defaultConf);

        final Properties props = new Properties();
        final File conf = new File(confname);
        if (conf.exists()) {
            FileInputStream fin = new FileInputStream(conf);
            try {props.load(fin);} finally {fin.close();}
        }

        // Do we use authentication?
        final String  useAuthenticationStr =
            props.getProperty(PropertyNames.USE_AUTHENTICATION,
                              DefaultValues.USE_AUTHENTICATION);
        final boolean useAuthentication =
            Boolean.valueOf(useAuthenticationStr).booleanValue();

        // Get Password File
        final String defaultPasswordFileName = Utils.convertPath(
            getDefaultFileName(DefaultValues.PASSWORD_FILE_NAME));
        final String passwordFileName = Utils.convertPath(
            props.getProperty(PropertyNames.PASSWORD_FILE_NAME,
                              defaultPasswordFileName));

        // Get Access File
        final String defaultAccessFileName = Utils.convertPath(
            getDefaultFileName(DefaultValues.ACCESS_FILE_NAME));
        final String accessFileName = Utils.convertPath(
            props.getProperty(PropertyNames.ACCESS_FILE_NAME,
                              defaultAccessFileName));

        if (useAuthentication) {
            System.out.println("PasswordFileName: " + passwordFileName);
            System.out.println("accessFileName: " + accessFileName);
        }

        final Object[] allCredentials;
        final Object[] noCredentials = { null };
        if (useAuthentication) {
            final ArrayList l = readCredentials(passwordFileName);
            if (l.size() == 0) allCredentials = null;
            else allCredentials = l.toArray();
        } else allCredentials = noCredentials;

        int errorCount = 0;
        if (allCredentials!=null) {
            // Tests that the registered user/passwords are allowed to
            // connect & read
            //
            errorCount += connectAndRead(url,allCredentials,true,true);
        } else {
            // Tests that no one is allowed
            // connect & read
            //
            final String[][] someCredentials = {
                null,
                { "modify", "R&D" },
                { "measure", "QED" }
            };
            errorCount += connectAndRead(url,someCredentials,false,false);
        }

        if (useAuthentication && allCredentials != noCredentials) {
            // Tests that the registered user/passwords are not allowed to
            // connect & read
            //
            final String[][] badCredentials = {
                { "bad.user", "R&D" },
                { "measure", "bad.password" }
            };
            errorCount += connectAndRead(url,badCredentials,false,false);
        }
        if (errorCount > 0) {
            final String err = "Test " + confname + " failed with " +
                errorCount + " error(s)";
            log.debug("testCommunication",err);
            throw new RuntimeException(err);
        }
    }


    /**
     * Test the configuration indicated by `file'.
     * Sets the appropriate System properties for config file and
     * port and then calls ConnectorBootstrap.initialize().
     * eventually cleans up by calling ConnectorBootstrap.terminate().
     * @return null if the test succeeds, an error message otherwise.
     **/
    private String testConfiguration(File file,int port) {

        final String path;
        try {
            path=(file==null)?null:file.getCanonicalPath();
        } catch(IOException x) {
            final String err = "Failed to test configuration " + file +
                ": " + x;
            log.trace("testConfiguration",err);
            log.debug("testConfiguration",x);
            return err;
        }
        final String config = (path==null)?"Default config file":path;

        System.out.println("***");
        System.out.println("*** Testing configuration (port=" + port + "): "
                           + path);
        System.out.println("***");

        System.setProperty("com.sun.management.jmxremote.port",
                           Integer.toString(port));
        if (path != null)
            System.setProperty("com.sun.management.config.file", path);
        else
            System.getProperties().remove("com.sun.management.config.file");

        log.trace("testConfiguration","com.sun.management.jmxremote.port="+port);
        if (path != null && log.isDebugOn())
            log.trace("testConfiguration",
                      "com.sun.management.config.file="+path);

        checkSslConfiguration();

        final JMXConnectorServer cs;
        try {
            cs = ConnectorBootstrap.initialize();
        } catch (AgentConfigurationError x) {
            final String err = "Failed to initialize connector:" +
                "\n\tcom.sun.management.jmxremote.port=" + port +
                ((path!=null)?"\n\tcom.sun.management.config.file="+path:
                 "\n\t"+config) +
                "\n\tError is: " + x;
            log.trace("testConfiguration",err);
            log.debug("testConfiguration",x);
            return err;
        } catch (Exception x) {
            log.debug("testConfiguration",x);
            return x.toString();
        }

        try {
            JMXServiceURL url =
                new JMXServiceURL("rmi",null,0,"/jndi/rmi://localhost:"+
                                  port+"/jmxrmi");

            try {
                testCommunication(url);
            } catch (Exception x) {
                final String err = "Failed to connect to agent {url="+url+
                    "}: " + x;
                log.trace("testConfiguration",err);
                log.debug("testConfiguration",x);
                return err;
            }
        } catch (Exception x) {
            final String err = "Failed to test configuration "+config+
                ": "+x;
            log.trace("testConfiguration",err);
            log.debug("testConfiguration",x);
            return err;
        } finally {
            try {
                cs.stop();
            } catch (Exception x) {
                final String err = "Failed to terminate: "+x;
                log.trace("testConfiguration",err);
                log.debug("testConfiguration",x);
            }
        }
        System.out.println("Configuration " + config + " successfully tested");
        return null;
    }

    /**
     * Test a configuration file which should make the bootstrap fail.
     * The test is assumed to have succeeded if the bootstrap fails.
     * @return null if the test succeeds, an error message otherwise.
     **/
    private String testConfigurationKo(File conf,int port) {
        final String errStr = testConfiguration(conf,port+testPort++);
        if (errStr == null) {
            return "Configuration " +
                conf + " should have failed!";
        }
        System.out.println("Configuration " +
                           conf + " failed as expected");
        log.debug("runko","Error was: " + errStr);
        return null;
    }

    /**
     * Test a configuration file. Determines whether the bootstrap
     * should succeed or fail depending on the file name:
     *     *ok.properties: bootstrap should succeed.
     *     *ko.properties: bootstrap or connection should fail.
     * @return null if the test succeeds, an error message otherwise.
     **/
    private String testConfigurationFile(String fileName) {
        File file = new File(fileName);
        final String portStr = System.getProperty("rmi.port","12424");
        final int port       = Integer.parseInt(portStr);

        if (fileName.endsWith("ok.properties")) {
            return testConfiguration(file,port+testPort++);
        }
        if (fileName.endsWith("ko.properties")) {
            return testConfigurationKo(file,port+testPort++);
        }
        return fileName +
            ": test file suffix must be one of [ko|ok].properties";
    }

    /**
     * Find all *ko.property files and test them.
     * (see findConfigurationFilesKo() and testConfigurationKo())
     * @throws RuntimeException if the test fails.
     **/
    public void runko() {
        final String portStr = System.getProperty("rmi.port","12424");
        final int port       = Integer.parseInt(portStr);
        final File[] conf = findConfigurationFilesKo();
        if ((conf == null)||(conf.length == 0))
            throw new RuntimeException("No configuration found");

        String errStr;
        for (int i=0;i<conf.length;i++) {
            errStr = testConfigurationKo(conf[i],port+testPort++);
            if (errStr != null) {
                throw new RuntimeException(errStr);
            }
        }

    }

    /**
     * Find all *ok.property files and test them.
     * (see findConfigurationFilesOk() and testConfiguration())
     * @throws RuntimeException if the test fails.
     **/
    public void runok() {
        final String portStr = System.getProperty("rmi.port","12424");
        final int port       = Integer.parseInt(portStr);
        final File[] conf = findConfigurationFilesOk();
        if ((conf == null)||(conf.length == 0))
            throw new RuntimeException("No configuration found");

        String errStr;
        for (int i=0;i<conf.length;i++) {
            errStr = testConfiguration(conf[i],port+testPort++);
            if (errStr != null) {
                throw new RuntimeException(errStr);
            }
        }

        // FIXME: No jmxremote.password is not installed in JRE by default.
        // - disable the following test case.
        //
        // Test default config
        //
        // errStr = testConfiguration(null,port+testPort++);
        // if (errStr != null) {
        //    throw new RuntimeException(errStr);
        // }
    }

    /**
     * Finds all configuration files (*ok.properties and *ko.properties)
     * and tests them.
     * (see runko() and runok()).
     * @throws RuntimeException if the test fails.
     **/
    public void run() {
        runok();
        runko();
    }

    /**
     * Tests the specified configuration files.
     * If args[] is not empty, each element in args[] is expected to be
     * a filename ending either by ok.properties or ko.properties.
     * Otherwise, the configuration files will be automatically determined
     * by looking at all *.properties files located in the directory
     * indicated by the System property "test.src".
     * @throws RuntimeException if the test fails.
     **/
    public void run(String args[]) {
        if (args.length == 0) {
            run() ; return;
        }
        for (int i=0; i<args.length; i++) {
            final String errStr =testConfigurationFile(args[i]);
            if (errStr != null) {
                throw new RuntimeException(errStr);
            }
        }
    }

    /**
     * Calls run(args[]).
     * exit(1) if the test fails.
     **/
    public static void main(String args[]) {
        RmiBootstrapTest manager = new RmiBootstrapTest();
        try {
            manager.run(args);
        } catch (RuntimeException r) {
            System.out.println("Test Failed: "+ r.getMessage());
            System.exit(1);
        } catch (Throwable t) {
            System.out.println("Test Failed: "+ t);
            t.printStackTrace();
            System.exit(2);
        }
        System.out.println("**** Test  RmiBootstrap Passed ****");
    }

}
