Package com.sun.jini.test.impl.outrigger.transaction

Source Code of com.sun.jini.test.impl.outrigger.transaction.PreparedTransactionTest

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.jini.test.impl.outrigger.transaction;

import java.util.logging.Level;

// Test harness specific classes
import com.sun.jini.qa.harness.TestException;
import com.sun.jini.qa.harness.QAConfig;

// All other imports
import net.jini.core.entry.*;
import net.jini.core.transaction.*;
import net.jini.core.transaction.server.*;
import com.sun.jini.constants.TxnConstants;
import com.sun.jini.test.share.TesterTransaction;
import com.sun.jini.test.share.TesterTransactionManager;


/**
* This tests to see if a prepared transaction that is hanging
* around after a crash behaves properly.
* <dl>
*
* <dt><code>-abort</code>
* <dd>Abort the transaction (default is to commit it).
*
* <dt><code>-wait</code>
* <dd>Wait -- set the transaction status, but let the particpant query
* for the state instead of sending it
*
* <dt><code>-active</code>
* <dd>Active -- don't send the prepare method -- go straight to
* <code>COMMITED</code> or <code>ABORTED</code>.  This implies
* <code>-abort</code>, since any active transaction is aborted
* by a crash.
*
* <dt><code>-throw_remote</code> <i>cnt</i>
* <dd>Throw <code>RemoteException</code> <i>cnt</i> times
* (implies <code>-wait</code>)
*
* </dl>
*
* @author Ken Arnold
*/
public abstract class PreparedTransactionTest extends TransactionTestBase
        implements TransactionConstants, com.sun.jini.constants.TimeConstants {

    /** Should we abort the transaction? */
    private boolean abort;

    /** Should we wait, letting the particpant query? */
    private boolean wait;

    /** Don't even send the prepared() message -- go straight from ACTIVE. */
    private boolean active;

    /**
     * Number of times that <code>getState</code> should throw
     * <code>RemoteException</code>.
     */
    private int throwRemote;

    /**
     * Sets up the testing environment.
     *
     * @param config Arguments from the runner for setup.
     */
    public void setup(QAConfig config) throws Exception {
        super.setup(config);
        this.parse();
    }

    /**
     * Parse non-generic option(s).
     */
    protected void parse() throws Exception {
        super.parse();
        abort = getConfig().getBooleanConfigVal("com.sun.jini.qa.outrigger."
                + "transaction.PreparedTransactionTest.abort", false);
        wait = getConfig().getBooleanConfigVal("com.sun.jini.qa.outrigger."
                + "transaction.PreparedTransactionTest.wait", false);
        active = getConfig().getBooleanConfigVal("com.sun.jini.qa.outrigger."
                + "transaction.PreparedTransactionTest.active", false);
        throwRemote = getConfig().getIntConfigVal("com.sun.jini.qa.outrigger."
                + "transaction.PreparedTransactionTest.throw_remote", 0);

        if (throwRemote > 0) {

            // implies -wait
            wait = true;
        }

        if (active) {

            // implies -abort
            abort = true;
        }
    }

    public void run() throws Exception {
        spaceOnlySetup();
        TesterTransactionManager mgr = new TesterTransactionManager();
        TesterTransaction tt = mgr.create();

        // an entry that should be there at the start
        SimpleEntry toTake = new SimpleEntry("toTake", 1, 13);
        writeEntry(null, toTake);
        logger.log(Level.INFO, "wrote entry " + toTake);

        // the entry written under the transaction
        SimpleEntry written = new SimpleEntry("tester", 17, 29);
        logger.log(Level.INFO, "wrote entry " + written);
        writeEntry(tt.transaction, written);
        tt.assertParticipants(1); // just to be sure
        Entry taken = space.take(toTake, tt.transaction, 0);
        assertEquals(taken, toTake, "reading 'toTake' entry");

        if (!active) {
            tt.sendPrepare(); // get the transaction prepared

            if (tt.localGetState() != PREPARED) {
                throw new TestException(
                        "state is "
                        + TxnConstants.getName(tt.localGetState())
                        + ", should be " + TxnConstants.getName(PREPARED));
            }
        }
        shutdown(0); // shut down the space

        /*
         * Only do this test if we're not active -- active txns should
         * be effectively aborted at this point, so they have no stage
         * that exists after a shutdown and before the transaction
         * completion
         */
        if (!active) {

            /*
             * try to see transacted stuff under a null transaction:
             * should fail
             */
            canSee(toTake, null, "txn not yet completed");
            canSee(written, null, "txn not yet completed");

            if (wait) {

                /*
                 * sleep long enough for the 15-second retries plus
                 * 5 for slop
                 */
                long sleepTime = (15 * SECONDS * (throwRemote + 1)
                        + 5 * SECONDS);
                tt.setState(abort ? ABORTED : COMMITTED);
                logger.log(Level.INFO, "transaction state set to "
                        + TxnConstants.getName(tt.localGetState())
                        + ", sleeping " + sleepTime);

                if (throwRemote > 0) {
                    tt.getStateFailCnt(throwRemote);
                }

                // give the participant a chance to ask
                Thread.sleep(sleepTime);
            } else {
                if (abort) {
                    tt.sendAbort();
                } else {
                    tt.sendCommit();
                }
            }
        }

        if (abort) {
            canSee(toTake, toTake, "txn aborted");
            canSee(written, null, "txn aborted");
        } else {
            canSee(toTake, null, "txn committed");
            canSee(written, written, "txn committed");
        }
    }

    private void canSee(Entry tmpl, Entry shouldMatch, String desc)
            throws Exception {
        Entry e = space.read(tmpl, null, 0);
        assertEquals(e, shouldMatch, desc);
    }
}
TOP

Related Classes of com.sun.jini.test.impl.outrigger.transaction.PreparedTransactionTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.