/*
 * Copyright 1999 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

/* @test
 * @bug 4183169
 * @summary Minor problem with the way ReliableLog handles IOExceptions.
 *
 * @author Laird Dornin; code borrowed from Ann Wollrath
 *
 * @library ../../../testlibrary
 * @build TestLibrary RMID JavaVM StreamPipe
 * @build TestSecurityManager
 * @build RegisteringActivatable
 * @build ShutdownGracefully
 * @build ShutdownGracefully_Stub
 * @run main/othervm/policy=security.policy/timeout=700 ShutdownGracefully
 */

import java.rmi.activation.*;
import java.rmi.*;
import java.util.Properties;

/**
 * The test creates an rmid with a special security manager.  After
 * rmid makes two registrations (which is greater than rmid's
 * snapshotInterval) the security manager stops allowing rmid to write
 * to update and snapshot log files in rmid's log directory.  The Test
 * registers an Activatable object twice with different group ids.
 * The second registration will cause rmid to have to write to a
 * LogFile (it causes a snapshot) and the security manager will not
 * allow the file write to happen.  The test makes sure that rmid
 * shuts down in a graceful manner without any explicit request to do
 * so.  The test will not exit for 400 seconds if rmid does not exit
 * (after that time, the test will fail).
 */
public class ShutdownGracefully
    extends Activatable implements Runnable, RegisteringActivatable
{
    private static RegisteringActivatable registering = null;

    private final static long SHUTDOWN_TIMEOUT = 400 * 1000;

    public static void main(String args[]) {

        RMID rmid = null;

        System.err.println("\nRegression test for bug/rfe 4183169\n");

        try {
            TestLibrary.suggestSecurityManager(
                "java.rmi.RMISecurityManager");

            // start an rmid.
            RMID.removeLog();
            rmid = RMID.createRMID();

            // rmid needs to run with a security manager that
            // simulates a log problem; rmid should also snapshot
            // quickly.
            rmid.addOptions(new String[] {
                "-Djava.security.manager=TestSecurityManager",
                "-Dsun.rmi.activation.snapshotInterval=1"});

            //      rmid.addArguments(new String[] {
            //          "-C-Djava.rmi.server.logCalls=true"});

            rmid.start();

            // Ensure that activation groups run with the correct
            // security manager.
            //
            Properties p = new Properties();
            p.put("java.security.policy",
                  TestParams.defaultGroupPolicy);
            p.put("java.security.manager",
                  "java.lang.SecurityManager");

            System.err.println("activation group will be created " +
                               "in a new VM");
            ActivationGroupDesc groupDesc =
                new ActivationGroupDesc(p, null);
            ActivationSystem system = ActivationGroup.getSystem();
            ActivationGroupID groupID = system.registerGroup(groupDesc);

            System.err.println("registering activatable");
            ActivationDesc desc = new ActivationDesc
                (groupID, "ShutdownGracefully", null, null);
            registering = (RegisteringActivatable)
                Activatable.register(desc);

            System.err.println("activate and deactivate object " +
                               "via method call");
            registering.shutdown();

            /*
             * the security manager rmid is running with will stop
             * rmid from writing to its log files; in 1.2.x this would
             * have caused rmid to have thrown a runtime exception and
             * continue running in an unstable state.  With the fix
             * for 4183169, rmid should shutdown gracefully instead.
             */

            /*
             * register another activatable with a new group id; rmid
             * should not recover from this...  I use two
             * registrations to more closely simulate the environment
             * in which the bug was found.  In java versions with out
             * the appropriate bug fix, rmid would hide a
             * NullPointerException in this circumstance.
             */
            p.put("dummyname", "dummyvalue");
            groupDesc = new ActivationGroupDesc(p, null);
            ActivationGroupID secondGroupID =
                system.registerGroup(groupDesc);
            desc = new ActivationDesc(secondGroupID,
                "ShutdownGracefully", null, null);

            try {
                registering = (RegisteringActivatable)
                    Activatable.register(desc);

                System.err.println("second activate and deactivate " +
                                   "object via method call");
            } catch (ActivationException e) {
                System.err.println("received exception from registration " +
                                   "call that should have failed...");
            }

            /*
             * no longer needed because the security manager
             * throws an exception during snapshot
             */
            /*
            try {
                registering.shutdown();

                System.err.println("received exception from remote " +
                                   "call that should have failed...");
            } catch (RemoteException e) {
            }
            */

        } catch (Exception e) {
            TestLibrary.bomb("\nfailure: unexpected exception ", e);
        } finally {
            try {
                Thread.sleep(4000);
            } catch (InterruptedException e) {
            }

            registering = null;

            // Need to make sure that rmid goes away by itself
            Process rmidProcess = rmid.getVM();
            if (rmidProcess != null) {
                try {
                    Runnable waitThread =
                        new ShutdownDetectThread(rmidProcess);

                    synchronized (waitThread) {
                        (new Thread(waitThread)).start();
                        waitThread.wait(SHUTDOWN_TIMEOUT);
                        System.err.println("rmid has shutdown");

                        if (!rmidDone) {
                            // ensure that this rmid does not infect
                            // other tests.
                            rmidProcess.destroy();
                            TestLibrary.bomb("rmid did not shutdown " +
                                             "gracefully in time");
                        }
                    }
                } catch (Exception e) {
                    TestLibrary.bomb("exception waiting for rmid " +
                                     "to shut down");
                }
            }
            // else rmid should be down
        }

        System.err.println
            ("\nsuccess: ShutdownGracefully test passed ");
    }

    private static boolean rmidDone = false;

    /**
     * class that waits for rmid to exit
     */
    private static class ShutdownDetectThread implements Runnable {
        private Process rmidProcess = null;

        ShutdownDetectThread(Process rmidProcess) {
            this.rmidProcess = rmidProcess;
        }
        public void run() {
            System.err.println("waiting for rmid to shutdown");

            try {
                rmidProcess.waitFor();
            } catch (InterruptedException e) {
                // should not happen
            }

            synchronized (this) {
                // notify parent thread when rmid has exited
                this.notify();
                rmidDone = true;
            }

            RMID.removeLog();
        }
    }

    /**
     * implementation of RegisteringActivatable
     */
    public ShutdownGracefully
        (ActivationID id, MarshalledObject mo) throws RemoteException
    {
        // register/export anonymously
        super(id, 0);
    }

    /**
     * Spawns a thread to deactivate the object.
     */
    public void shutdown() throws Exception {
        (new Thread(this, "ShutdownGracefully")).start();
    }

    /**
     * Thread to deactivate object. First attempts to make object
     * inactive (via the inactive method).  If that fails (the
     * object may still have pending/executing calls), then
     * unexport the object forcibly.
     */
    public void run() {
        try {
            Thread.sleep(50 * 1000);
        } catch (InterruptedException e) {
        }
        ActivationLibrary.deactivate(this, getID());
    }
}
