/*
 * Copyright (c) 2003, 2012, 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
 * @build TestLibrary
 *     Apple AppleEvent AppleImpl
 *     Orange OrangeEcho OrangeEchoImpl OrangeImpl
 *     ApplicationServer
 *
 * @run main/othervm/policy=security.policy 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.createRegistryOnUnusedPort();
                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);
            }
        }
    }
}
