/*
 * Copyright (c) 1998, 2024, 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.
 */

/**
 *
 *
 * @author Adrian Colley
 * @author Laird Dornin
 * @author Peter Jones
 * @author Ann Wollrath
 *
 * The rmi library directory contains a set of simple utiltity classes
 * for use in rmi regression tests.
 *
 * NOTE: The JavaTest group has recommended that regression tests do
 * not make use of packages.
 */

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.net.MalformedURLException;
import java.net.ServerSocket;
import java.net.URL;
import java.rmi.NoSuchObjectException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.RemoteRef;
import java.rmi.server.UnicastRemoteObject;
import java.util.Enumeration;
import java.util.Properties;

import sun.rmi.registry.RegistryImpl;
import sun.rmi.server.UnicastServerRef;
import sun.rmi.transport.Endpoint;
import sun.rmi.transport.LiveRef;
import sun.rmi.transport.tcp.TCPEndpoint;

/**
 * Class of utility/library methods (i.e. procedures) that assist with
 * the writing and maintainance of rmi regression tests.
 */
public class TestLibrary {
    /**
     *                       IMPORTANT!
     *
     * RMI tests are run concurrently and port conflicts result when a single
     * port number is used by multiple tests.  When needing a port, use
     * getUnusedRandomPort() wherever possible.  If getUnusedRandomPort() cannot
     * be used, reserve and specify a port to use for your test here.   This
     * will ensure there are no port conflicts amongst the RMI tests.  The
     * port numbers specified here may also be specified in the respective
     * tests.  Do not change the reserved port numbers here without also
     * changing the port numbers in the respective tests.
     *
     * When needing an instance of the RMIRegistry, use
     * createRegistryOnUnusedPort wherever possible to prevent port conflicts.
     *
     * Reserved port range: FIXED_PORT_MIN to FIXED_PORT_MAX (inclusive) for
     * tests which cannot use a random port.  If new fixed ports are added below
     * FIXED_PORT_MIN or above FIXED_PORT_MAX, then adjust
     * FIXED_PORT_MIN/MAX appropriately.
     */
    public final static int FIXED_PORT_MIN = 60001;
    public final static int FIXED_PORT_MAX = 60010;
    public final static int INHERITEDCHANNELNOTSERVERSOCKET_ACTIVATION_PORT = 60003;
    public final static int INHERITEDCHANNELNOTSERVERSOCKET_REGISTRY_PORT = 60004;
    public final static int READTEST_REGISTRY_PORT = 60005;
    private final static int MAX_SERVER_SOCKET_TRIES = 2*(FIXED_PORT_MAX-FIXED_PORT_MIN+1);

    static void mesg(Object mesg) {
        System.err.println("TEST_LIBRARY: " + mesg.toString());
    }

    /**
     * Routines that enable rmi tests to fail in a uniformly
     * informative fashion.
     */
    public static void bomb(String message, Exception e) {
        String testFailed = "TEST FAILED: ";

        if ((message == null) && (e == null)) {
            testFailed += " No relevant information";
        } else if (e == null) {
            testFailed += message;
        }

        System.err.println(testFailed);
        if (e != null) {
            System.err.println("Test failed with: " +
                               e.getMessage());
            e.printStackTrace(System.err);
        }
        throw new TestFailedException(testFailed, e);
    }
    public static void bomb(String message) {
        bomb(message, null);
    }
    public static void bomb(Exception e) {
        bomb(null, e);
    }

    /**
     * Helper method to determine if registry has started
     *
     * @param port The port number to check
     * @param msTimeout The amount of milliseconds to spend checking
     */

    public static boolean checkIfRegistryRunning(int port, int msTimeout) {
        final long POLLTIME_MS = 100L;
        long stopTime = computeDeadline(System.currentTimeMillis(), msTimeout);
        do {
            try {
                Registry r = LocateRegistry.getRegistry(port);
                String[] s = r.list();
                // no exception. We're now happy that registry is running
                return true;
            } catch (RemoteException e) {
                // problem - not ready ? Try again
                try {
                    Thread.sleep(POLLTIME_MS);
                } catch (InterruptedException ie) {
                    // not expected
                }
            }
        } while (System.currentTimeMillis() < stopTime);
        return false;
    }

    public static String getProperty(final String property,
                                     final String defaultVal) {
        try {
            return java.security.AccessController.doPrivileged(
                new java.security.PrivilegedAction<String>() {
                    public String run() {
                        return System.getProperty(property, defaultVal);
                    }
                });
        } catch (Exception ex) {
            bomb("Exception getting property " + property, ex);
            throw new AssertionError("this should be unreachable");
        }
    }

    public static double getTimeoutFactor() {
        String prop = getProperty("test.timeout.factor", "1.0");
        double timeoutFactor = 1.0;

        try {
            timeoutFactor = Double.parseDouble(prop);
        } catch (NumberFormatException ignore) { }

        return timeoutFactor;
    }

    /**
     * Computes a deadline from a timestamp and a timeout value.
     * Maximum timeout (before multipliers are applied) is one hour.
     */
    public static long computeDeadline(long timestamp, long timeout) {
        if (timeout < 0L) {
            throw new IllegalArgumentException("timeout " + timeout + "ms out of range");
        }

        return timestamp + (long)(timeout * getTimeoutFactor());
    }

    /**
     * Property mutators
     */
    public static void setBoolean(String property, boolean value) {
        setProperty(property, (new Boolean(value)).toString());
    }
    public static void setInteger(String property, int value) {
        setProperty(property, Integer.toString(value));
    }
    public static void setProperty(String property, String value) {
        final String prop = property;
        final String val = value;
        java.security.AccessController.doPrivileged(
            new java.security.PrivilegedAction<Void>() {
                public Void run() {
                    System.setProperty(prop, val);
                    return null;
                }
        });
    }

    /**
     * Routines to print out a test's properties environment.
     */
    public static void printEnvironment() {
        printEnvironment(System.err);
    }
    public static void printEnvironment(PrintStream out) {
        out.println("-------------------Test environment----------" +
                    "---------");

        for(Enumeration<?> keys = System.getProperties().keys();
            keys.hasMoreElements();) {

            String property = (String) keys.nextElement();
            out.println(property + " = " + getProperty(property, null));
        }
        out.println("---------------------------------------------" +
                    "---------");
    }

    /**
     * Routine that "works-around" a limitation in jtreg.
     * Currently it is not possible for a test to specify that the
     * test harness should build a given source file and install the
     * resulting class in a location that is not accessible from the
     * test's classpath.  This method enables a test to move a
     * compiled test class file from the test's class directory into a
     * given "codebase" directory.  As a result the test can only
     * access the class file for <code>className</code>if the test loads
     * it from a classloader (e.g. RMIClassLoader).
     *
     * Tests that use this routine must have the following permissions
     * granted to them:
     *
     *   getProperty user.dir
     *   getProperty etc.
     */
    public static URL installClassInCodebase(String className,
                                             String codebase)
        throws MalformedURLException
    {
        return installClassInCodebase(className, codebase, true);
    }

    public static URL installClassInCodebase(String className,
                                             String codebase,
                                             boolean delete)
        throws MalformedURLException
    {
        /*
         * NOTES/LIMITATIONS: The class must not be in a named package,
         * and the codebase must be a relative path (it's created relative
         * to the working directory).
         */
        String classFileName = className + ".class";

        /*
         * Specify the file to contain the class definition.  Make sure
         * that the codebase directory exists (underneath the working
         * directory).
         */
        File dstDir = (new File(getProperty("user.dir", "."), codebase));

        if (!dstDir.exists()) {
            if (!dstDir.mkdir()) {
                throw new RuntimeException(
                    "could not create codebase directory");
            }
        }
        File dstFile = new File(dstDir, classFileName);

        /*
         * Obtain the URL for the codebase.
         */
        URL codebaseURL = dstDir.toURI().toURL();

        /*
         * Specify where we will copy the class definition from, if
         * necessary.  After the test is built, the class file can be
         * found in the "test.classes" directory.
         */
        File srcDir = new File(getProperty("test.classes", "."));
        File srcFile = new File(srcDir, classFileName);

        mesg(srcFile);
        mesg(dstFile);

        /*
         * If the class definition is not already located at the codebase,
         * copy it there from the test build area.
         */
        if (!dstFile.exists()) {
            if (!srcFile.exists()) {
                throw new RuntimeException(
                    "could not find class file to install in codebase " +
                    "(try rebuilding the test): " + srcFile);
            }

            try {
                copyFile(srcFile, dstFile);
            } catch (IOException e) {
                throw new RuntimeException(
                    "could not install class file in codebase");
            }

            mesg("Installed class \"" + className +
                "\" in codebase " + codebaseURL);
        }

        /*
         * After the class definition is successfully installed at the
         * codebase, delete it from the test's CLASSPATH, so that it will
         * not be found there first before the codebase is searched.
         */
        if (srcFile.exists()) {
            if (delete && !srcFile.delete()) {
                throw new RuntimeException(
                    "could not delete duplicate class file in CLASSPATH");
            }
        }

        return codebaseURL;
    }

    public static void copyFile(File srcFile, File dstFile)
        throws IOException
    {
        FileInputStream src = new FileInputStream(srcFile);
        FileOutputStream dst = new FileOutputStream(dstFile);

        byte[] buf = new byte[32768];
        while (true) {
            int count = src.read(buf);
            if (count < 0) {
                break;
            }
            dst.write(buf, 0, count);
        }

        dst.close();
        src.close();
    }

    /** routine to unexport an object */
    public static void unexport(Remote obj) {
        if (obj != null) {
            try {
                mesg("unexporting object...");
                UnicastRemoteObject.unexportObject(obj, true);
            } catch (NoSuchObjectException munch) {
            } catch (Exception e) {
                e.getMessage();
                e.printStackTrace();
            }
        }
    }

    /**
     * Creates an RMI {@link Registry} on a random, un-reserved port.
     *
     * @return an RMI Registry, using a random port.
     * @throws RemoteException if there was a problem creating a Registry.
     */
    public static Registry createRegistryOnUnusedPort() throws RemoteException {
        return LocateRegistry.createRegistry(getUnusedRandomPort());
    }

    /**
     * Creates an RMI {@link Registry} on an ephemeral port.
     *
     * @return an RMI Registry
     * @throws RemoteException if there was a problem creating a Registry.
     */
    public static Registry createRegistryOnEphemeralPort() throws RemoteException {
        return LocateRegistry.createRegistry(0);
    }

    /**
     * Returns the port number the RMI {@link Registry} is running on.
     *
     * @param registry the registry to find the port of.
     * @return the port number the registry is using.
     * @throws RuntimeException if there was a problem getting the port number.
     */
    public static int getRegistryPort(Registry registry) {
        int port = -1;

        try {
            RemoteRef remoteRef = ((RegistryImpl)registry).getRef();
            LiveRef liveRef = ((UnicastServerRef)remoteRef).getLiveRef();
            Endpoint endpoint = liveRef.getChannel().getEndpoint();
            TCPEndpoint tcpEndpoint = (TCPEndpoint) endpoint;
            port = tcpEndpoint.getPort();
        } catch (Exception ex) {
            throw new RuntimeException("Error getting registry port.", ex);
        }

        return port;
    }

    /**
     * Returns an unused random port number which is not a reserved port.  Will
     * try up to 10 times to get a random port before giving up and throwing a
     * RuntimeException.
     *
     * @return an unused random port number.
     * @throws RuntimeException if there was a problem getting a port.
     */
    public static int getUnusedRandomPort() {
        int numTries = 0;
        IOException ex = null;

        while (numTries++ < MAX_SERVER_SOCKET_TRIES) {
            int unusedRandomPort = -1;
            ex = null; //reset

            try (ServerSocket ss = new ServerSocket(0)) {
                unusedRandomPort = ss.getLocalPort();
            } catch (IOException e) {
                ex = e;
                // temporarily print stack trace here until we find out why
                // tests are failing.
                System.err.println("TestLibrary.getUnusedRandomPort() caught "
                        + "exception on iteration " + numTries
                        + (numTries==MAX_SERVER_SOCKET_TRIES ? " (the final try)."
                        : "."));
                ex.printStackTrace();
            }

            if (unusedRandomPort >= 0) {
                if (isReservedPort(unusedRandomPort)) {
                    System.out.println("INFO: On try # " + numTries
                        + (numTries==MAX_SERVER_SOCKET_TRIES ? ", the final try, ": ",")
                        + " ServerSocket(0) returned the reserved port "
                        + unusedRandomPort
                        + " in TestLibrary.getUnusedRandomPort() ");
                } else {
                    return unusedRandomPort;
                }
            }
        }

        // If we're here, then either an exception was thrown or the port is
        // a reserved port.
        if (ex==null) {
            throw new RuntimeException("Error getting unused random port. The"
                    +" last port returned by ServerSocket(0) was a reserved port");
        } else {
            throw new RuntimeException("Error getting unused random port.", ex);
        }
    }

    /**
     * Determines if a port is one of the reserved port numbers.
     *
     * @param port the port to test.
     * @return {@code true} if the port is a reserved port, otherwise
     *         {@code false}.
     */
    public static boolean isReservedPort(int port) {
        return ((port >= FIXED_PORT_MIN) && (port <= FIXED_PORT_MAX) ||
                (port == 1099));
    }

    /**
     * Method to capture the stack trace of an exception and return it
     * as a string.
     */
    public String stackTraceToString(Exception e) {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        PrintStream ps = new PrintStream(bos);

        e.printStackTrace(ps);
        return bos.toString();
    }

    /** extra properties */
    private static Properties props;

    /**
     * Returns extra test properties. Looks for the file "../../test.props"
     * and reads it in as a Properties file. Assuming the working directory
     * is "<path>/JTwork/scratch", this will find "<path>/test.props".
     */
    private static synchronized Properties getExtraProperties() {
        if (props != null) {
            return props;
        }
        props = new Properties();
        File f = new File(".." + File.separator + ".." + File.separator +
                          "test.props");
        if (!f.exists()) {
            return props;
        }
        try {
            FileInputStream in = new FileInputStream(f);
            try {
                props.load(in);
            } finally {
                in.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("extra property setup failed", e);
        }
        return props;
    }

    /**
     * Returns an extra test property. Looks for the file "../../test.props"
     * and reads it in as a Properties file. Assuming the working directory
     * is "<path>/JTwork/scratch", this will find "<path>/test.props".
     * If the property isn't found, defaultVal is returned.
     */
    public static String getExtraProperty(String property, String defaultVal) {
        return getExtraProperties().getProperty(property, defaultVal);
    }
}
