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

/* @test
 *
 * @summary The juicer is the classic RMI stress test.  The juicer makes
 * a large number of concurrent, long running, remote method invocations
 * between many threads which have exported remote objects.  These
 * threads use remote objects that carry on deep "two party"
 * recursion.  The juicer relies on Distributed Garbage Collection to
 * unexport these remote objects when no more references are held to them.
 * The two parties in the recursion are OrangeImpl and
 * OrangeEchoImpl.  OrangeImpl checks the base case of the recursion
 * so that the program will exit.
 *
 * When the AppleUserImpl.main() method is invoked, the class binds an
 * instance of itself in a registry.  A second server process,
 * an ApplicationServer, is started which looks up the recently
 * bound AppleUser object.  This server is either started up in
 * the same VM or can optionally be started in a separate VM on the
 * same host or on a different host. When this test is run on the
 * RMI profile, ApplicationServer must be started by AppleUserImpl
 * and the complete juicer runs in a single process.
 *
 * The second server process instructs the AppleUserImpl to "use" some apples.
 * AppleUserImpl creates a new thread for each apple.  These threads
 * initiate the two party recursion.
 *
 * Each recursive call nests to a depth determined by this
 * expression: (2 + Math.abs(random.nextInt() % (maxLevel + 1)),
 * where maxLevel is a command line parameter.  Thus each recursive
 * call nests a random number of levels between 2 and maxLevel.
 *
 * The test ends when an exception is encountered or the stop time
 * has been reached.
 *
 * @library ../../testlibrary
 * @modules java.rmi/sun.rmi.registry
 *          java.rmi/sun.rmi.server
 *          java.rmi/sun.rmi.transport
 *          java.rmi/sun.rmi.transport.tcp
 * @build TestLibrary
 *     Apple AppleEvent AppleImpl
 *     Orange OrangeEcho OrangeEchoImpl OrangeImpl
 *     ApplicationServer
 *
 * @run main/othervm AppleUserImpl -seconds 30
 *
 * @author Peter Jones, Nigel Daley
 */

import java.rmi.NoSuchObjectException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * The AppleUserImpl class implements the behavior of the remote
 * "apple user" objects exported by the server.  The application server
 * passes each of its remote "apple" objects to an apple user, and an
 * AppleUserThread is created for each apple.
 */
public class AppleUserImpl extends UnicastRemoteObject implements AppleUser {
    private static int registryPort = -1;
    private static final Logger logger =
        Logger.getLogger("reliability.appleuser");
    private static int threadNum = 0;
    private static long testDuration = 0;
    private static int maxLevel = 7;
    private static Exception status = null;
    private static boolean finished = false;
    private static boolean startTestNotified = false;
    private static final Random random = new Random();
    private static final Object lock = new Object();

    public AppleUserImpl() throws RemoteException {
    }

    /**
     * Allows the other server process to indicate that it is ready
     * to start "juicing".
     */
    public synchronized void startTest() throws RemoteException {
        startTestNotified = true;
        this.notifyAll();
    }

    /**
     * Allows the other server process to report an exception to this
     * process and thereby terminate the test.
     */
    public void reportException(Exception status) throws RemoteException {
        synchronized (lock) {
            this.status = status;
            lock.notifyAll();
        }
    }

    /**
     * "Use" supplied apple object.  Create an AppleUserThread to
     * stress it out.
     */
    public synchronized void useApple(Apple apple) throws RemoteException {
        String threadName = Thread.currentThread().getName();
        logger.log(Level.FINEST,
            threadName + ": AppleUserImpl.useApple(): BEGIN");

        AppleUserThread t =
            new AppleUserThread("AppleUserThread-" + (++threadNum), apple);
        t.start();

        logger.log(Level.FINEST,
            threadName + ": AppleUserImpl.useApple(): END");
    }

    /**
     * The AppleUserThread class repeatedly invokes calls on its associated
     * Apple object to stress the RMI system.
     */
    class AppleUserThread extends Thread {

        final Apple apple;

        public AppleUserThread(String name, Apple apple) {
            super(name);
            this.apple = apple;
        }

        public void run() {
            int orangeNum = 0;
            long stopTime = System.currentTimeMillis() + testDuration;
            Logger logger = Logger.getLogger("reliability.appleuserthread");

            try {
                do { // loop until stopTime is reached

                    /*
                     * Notify apple with some apple events.  This tests
                     * serialization of arrays.
                     */
                    int numEvents = Math.abs(random.nextInt() % 5);
                    AppleEvent[] events = new AppleEvent[numEvents];
                    for (int i = 0; i < events.length; i++) {
                        events[i] = new AppleEvent(orangeNum % 3);
                    }
                    apple.notify(events);

                    /*
                     * Request a new orange object be created in
                     * the application server.
                     */
                    Orange orange = apple.newOrange(
                        "Orange(" + getName() + ")-" + (++orangeNum));

                    /*
                     * Create a large message of random ints to pass to orange.
                     */
                    int msgLength = 1000 + Math.abs(random.nextInt() % 3000);
                    int[] message = new int[msgLength];
                    for (int i = 0; i < message.length; i++) {
                        message[i] = random.nextInt();
                    }

                    /*
                     * Invoke recursive call on the orange.  Base case
                     * of recursion inverts messgage.
                     */
                    OrangeEchoImpl echo = new OrangeEchoImpl(
                        "OrangeEcho(" + getName() + ")-" + orangeNum);
                    int[] response = orange.recurse(echo, message,
                        2 + Math.abs(random.nextInt() % (maxLevel + 1)));

                    /*
                     * Verify message was properly inverted and not corrupted
                     * through all the recursive method invocations.
                     */
                    if (response.length != message.length) {
                        throw new RuntimeException(
                            "ERROR: CORRUPTED RESPONSE: " +
                            "wrong length of returned array " + "(should be " +
                            message.length + ", is " + response.length + ")");
                    }
                    for (int i = 0; i < message.length; i++) {
                        if (~message[i] != response[i]) {
                            throw new RuntimeException(
                                "ERROR: CORRUPTED RESPONSE: " +
                                "at element " + i + "/" + message.length +
                                " of returned array (should be " +
                                Integer.toHexString(~message[i]) + ", is " +
                                Integer.toHexString(response[i]) + ")");
                        }
                    }

                    try {
                        Thread.sleep(Math.abs(random.nextInt() % 10) * 1000);
                    } catch (InterruptedException e) {
                    }

                } while (System.currentTimeMillis() < stopTime);

            } catch (Exception e) {
                status = e;
            }
            finished = true;
            synchronized (lock) {
                lock.notifyAll();
            }
        }
    }

    private static void usage() {
        System.err.println("Usage: AppleUserImpl [-hours <hours> | " +
                                                 "-seconds <seconds>]");
        System.err.println("                     [-maxLevel <maxLevel>]");
        System.err.println("                     [-othervm]");
        System.err.println("                     [-exit]");
        System.err.println("  hours    The number of hours to run the juicer.");
        System.err.println("           The default is 0 hours.");
        System.err.println("  seconds  The number of seconds to run the juicer.");
        System.err.println("           The default is 0 seconds.");
        System.err.println("  maxLevel The maximum number of levels to ");
        System.err.println("           recurse on each call.");
        System.err.println("           The default is 7 levels.");
        System.err.println("  othervm  If present, the VM will wait for the");
        System.err.println("           ApplicationServer to start in");
        System.err.println("           another process.");
        System.err.println("           The default is to run everything in");
        System.err.println("           a single VM.");
        System.err.println("  exit     If present, the VM will call");
        System.err.println("           System.exit() when main() finishes.");
        System.err.println("           The default is to not call");
        System.err.println("           System.exit().");
        System.err.println();
    }

    /**
     * Entry point for the "juicer" server process.  Create and export
     * an apple user implementation in an rmiregistry running on localhost.
     */
    public static void main(String[] args) {
        String durationString = null;
        boolean othervm = false;
        boolean exit = false;
        try {
            // parse command line args
            for (int i = 0; i < args.length ; i++ ) {
                String arg = args[i];
                if (arg.equals("-hours")) {
                    if (durationString != null) {
                        usage();
                    }
                    i++;
                    int hours = Integer.parseInt(args[i]);
                    durationString = hours + " hours";
                    testDuration = hours * 60 * 60 * 1000;
                } else if (arg.equals("-seconds")) {
                    if (durationString != null) {
                        usage();
                    }
                    i++;
                    long seconds = Long.parseLong(args[i]);
                    durationString = seconds + " seconds";
                    testDuration = seconds * 1000;
                } else if (arg.equals("-maxLevel")) {
                    i++;
                    maxLevel = Integer.parseInt(args[i]);
                } else if (arg.equals("-othervm")) {
                    othervm = true;
                } else if (arg.equals("-exit")) {
                    exit = true;
                } else {
                    usage();
                }
            }
            if (durationString == null) {
                durationString = testDuration + " milliseconds";
            }
        } catch (Throwable t) {
            usage();
            throw new RuntimeException("TEST FAILED: Bad argument");
        }

        AppleUserImpl user = null;
        long startTime = 0;
        Thread server = null;
        int exitValue = 0;
        try {
            user = new AppleUserImpl();

            synchronized (user) {
                // create new registry and bind new AppleUserImpl in registry
                Registry registry = TestLibrary.createRegistryOnEphemeralPort();
                registryPort = TestLibrary.getRegistryPort(registry);
                LocateRegistry.getRegistry(registryPort).rebind("AppleUser",
                                                                 user);

                // start the other server if applicable
                if (othervm) {
                    // the other server must be running in a separate process
                    logger.log(Level.INFO, "Application server must be " +
                        "started in separate process");
                } else {
                    Class app = Class.forName("ApplicationServer");
                    java.lang.reflect.Constructor appConstructor =
                            app.getDeclaredConstructor(new Class[] {Integer.TYPE});
                    server = new Thread((Runnable) appConstructor.newInstance(registryPort));
                    logger.log(Level.INFO, "Starting application server " +
                        "in same process");
                    server.start();
                }

                // wait for other server to call startTest method
                logger.log(Level.INFO, "Waiting for application server " +
                    "process to start");
                while (!startTestNotified) {
                   user.wait();
                }
            }

            startTime = System.currentTimeMillis();
            logger.log(Level.INFO, "Test starting");

            // wait for exception to be reported or first thread to complete
            logger.log(Level.INFO, "Waiting " + durationString + " for " +
                "test to complete or exception to be thrown");

            synchronized (lock) {
                while (status == null && !finished) {
                    lock.wait();
                }
            }

            if (status != null) {
                throw new RuntimeException("TEST FAILED: "
                    + "juicer server reported an exception", status);
            } else {
                logger.log(Level.INFO, "TEST PASSED");
            }
        } catch (Exception e) {
            logger.log(Level.INFO, "TEST FAILED");
            exitValue = 1;
            if (exit) {
                e.printStackTrace();
            }
            throw new RuntimeException("TEST FAILED: "
                    + "unexpected exception", e);
        } finally {
            long actualDuration = System.currentTimeMillis() - startTime;
            logger.log(Level.INFO, "Test finished");
            try {
                UnicastRemoteObject.unexportObject(user, true);
            } catch (NoSuchObjectException ignore) {
            }
            logger.log(Level.INFO, "Test duration was " +
                (actualDuration/1000) + " seconds " +
                "(" + (actualDuration/3600000) + " hours)");
            System.gc(); System.gc();
            if (exit) {
                System.exit(exitValue);
            }
        }
    }
}
