FailureInducerpublic class FailureInducer extends Object This class defines API's for the test harness to induce
recovery by setting crash points (in the case of TM crashes)
and wait points (in the case of RM crashes).
In order to induce TM crashes, the test harness sets the failure points
by calling setCrashPoint(), after transaction.begin() from each thread.
Thus, multiple threads involving different transactions can
set different points of failure, which will cause the TM to wait
at the failure points, until crash() method is invoked.
Note: Only those transactions calling setCrashPoint() will be affected.
The crash() method needs to be invoked from a seperate
thread. The TM would increment TestRecovery.waitCount field to
indicate the total number of failure points reached.
When the waitCount reaches the expected value
(obtained through getWaitCount()), the test harness shall call crash().
In order to test RM recovery, the
test harness sets the failure points by calling setWaitPoint(),
after transaction.begin() from each thread. The TM waits at predefined
failure points for the stipulated time duration, during which the RM is
expected to crash; after which the TM will proceed with regular
completion (a human is expected to crash the RM manually during the
wait duration). As in the TM recovery case, the waitCount will be
incremented to indicate the total number of failure points reached.
If the RM does not crash during the stipulated time
duration, the TM will proceed with normal completion for the specific
transaction. It does not matter if the RM
comes back alive, since the TM would anyway retry completion.
Note: Only those transactions calling setWaitPoint() will be affected. |
Fields Summary |
---|
public static final Integer | ACTIVE | public static final Integer | PREPARING | public static final Integer | PREPARED | public static final Integer | COMPLETING | public static final Integer | COMPLETED | private static boolean | failureInducerIsActive | private static boolean | crash | private static int | waitPeriod | private static int | waitCount | private static Hashtable | crashList | private static Hashtable | waitList | private static Hashtable | waitTime | private static ResourceBundle | messages | static Logger | _logger |
Methods Summary |
---|
public static void | activateFailureInducer()This activates the FailureInducer. An application needs to activate
the failure inducer first, before setting the fail or wait points.
// static initializer
failureInducerIsActive = true;
| public static void | crash()Forces the TM to crash.
crash = true;
| public static void | deactivateFailureInducer()This deactivates the FailureInducer. An application deactivate the
failure inducer, to temporarily stop failure inducement. The fail
or wait points are not forgotten during the dormant state.
failureInducerIsActive = false;
| private static java.lang.String | getMessage(java.lang.String key)
return getMessage(key, null);
| private static java.lang.String | getMessage(java.lang.String key, java.lang.Object[] inserts)
if (messages == null || key == null) {
return null;
}
String msg = messages.getString(key);
if (msg == null) {
return null;
}
if (inserts == null) {
return msg;
} else {
return MessageFormat.format(msg, inserts);
}
| public static int | getWaitCount()
return waitCount;
| private static void | incrementWaitCount()Increments the wait count (called only by TM).
waitCount++;
| public static boolean | isFailureInducerActive()
return failureInducerIsActive;
| public static void | setCrashPoint(java.lang.Integer crashPoint)Setting a crash point will cause the TM to wait at the
failure point, until crash() is called.
// sanity check
if (crashPoint == null) {
_logger.log(Level.SEVERE,"jts.invalid_crash_point");
return;
}
Coordinator coord = Utility.getCoordinator(Utility.getControl());
JCoordinator jcoord = JCoordinatorHelper.narrow(coord);
if (jcoord != null) {
GlobalTID gtid = new GlobalTID(jcoord.getGlobalTID());
crashList.put(gtid, crashPoint);
}
| public static void | setWaitPoint(java.lang.Integer waitPoint, int waitDuration)Setting a wait point will cause the TM to wait at the
failure point, for the stipulated wait duration.
// sanity check
if (waitPoint == null) {
_logger.log(Level.SEVERE,"jts.invalid_wait_point");
return;
}
Coordinator coord = Utility.getCoordinator(Utility.getControl());
JCoordinator jcoord = JCoordinatorHelper.narrow(coord);
if (jcoord != null) {
GlobalTID gtid = new GlobalTID(jcoord.getGlobalTID());
waitList.put(gtid, waitPoint);
waitTime.put(gtid, new Integer(waitDuration));
}
| public static void | waitForFailure(com.sun.jts.CosTransactions.GlobalTID gtid, java.lang.Integer failPoint)This method is called by the coordinator at every valid
failure point. If the crash point or the wait point set for
the current transaction matches the current failure point,
an appropriate action (crash or wait) is taken.
Note: Crash action takes precedence over wait actions for the
same failure point.
// sanity check
if (gtid == null)
return;
Integer crashPoint = (Integer) crashList.get(gtid);
Integer waitPoint = (Integer) waitList.get(gtid);
// no crash point or wait point has been set for the transaction
if (crashPoint == null && waitPoint == null) {
return;
}
_logger.log(Level.WARNING,"jts.failpoint",failPoint);
// increment wait count and wait for the crash flag to be set
if (crashPoint != null && crashPoint.equals(failPoint)) {
incrementWaitCount();
while (crash == false) {
try {
Thread.sleep(3000);
} catch (Exception e) {}
}
System.exit(0);
}
// wait for the wait duration and continue
if (waitPoint != null && waitPoint.equals(failPoint)) {
Integer waitDuration = (Integer) waitTime.get(gtid);
// wait duration has not be set or is invalid
if (waitDuration == null || waitDuration.intValue() < 0)
return;
// wait for the stipulated duration
try {
Thread.sleep(waitDuration.intValue() * 1000);
} catch (Exception e) {}
}
|
|