/*
* (c) Rob Gordon 2005
*/
package org.oddjob.jobs.job;
import java.beans.PropertyVetoException;
import java.io.File;
import junit.framework.TestCase;
import org.apache.log4j.Logger;
import org.oddjob.FailedToStopException;
import org.oddjob.Iconic;
import org.oddjob.Oddjob;
import org.oddjob.OddjobComponentResolver;
import org.oddjob.OddjobLookup;
import org.oddjob.Resetable;
import org.oddjob.Stateful;
import org.oddjob.Stoppable;
import org.oddjob.arooa.ArooaParseException;
import org.oddjob.arooa.convert.ArooaConversionException;
import org.oddjob.arooa.life.ComponentProxyResolver;
import org.oddjob.arooa.parsing.DragPoint;
import org.oddjob.arooa.parsing.DragTransaction;
import org.oddjob.arooa.reflect.ArooaPropertyException;
import org.oddjob.arooa.registry.ChangeHow;
import org.oddjob.arooa.standard.StandardArooaSession;
import org.oddjob.arooa.xml.XMLConfiguration;
import org.oddjob.images.IconHelper;
import org.oddjob.jobs.WaitJob;
import org.oddjob.jobs.structural.SequentialJob;
import org.oddjob.state.IsAnyState;
import org.oddjob.state.JobState;
import org.oddjob.state.ParentState;
import org.oddjob.state.ServiceState;
import org.oddjob.state.StateEvent;
import org.oddjob.state.StateHandler;
import org.oddjob.state.StateListener;
import org.oddjob.tools.IconSteps;
import org.oddjob.tools.OddjobTestHelper;
import org.oddjob.tools.StateSteps;
import org.oddjob.util.OddjobLockedException;
/**
*
*/
public class RunJobTest extends TestCase {
private static final Logger logger = Logger.getLogger(RunJobTest.class);
@Override
protected void setUp() throws Exception {
super.setUp();
logger.info("------------------------ " + getName() +
" ---------------------------");
}
public static class OurRunnable implements Runnable {
int ran;
public void run() {
++ran;
}
public int getRan() {
return ran;
}
}
public void testCanRunAnyGivenRunnable() {
StandardArooaSession session = new StandardArooaSession() {
@Override
public ComponentProxyResolver getComponentProxyResolver() {
return new OddjobComponentResolver();
}
};
OurRunnable r = new OurRunnable();
RunJob test = new RunJob();
test.setShowJob(true);
test.setArooaSession(session);
test.setJob(r);
test.run();
assertEquals(ParentState.COMPLETE,
test.lastStateEvent().getState());
assertEquals(1, r.ran);
test.hardReset();
assertEquals(ParentState.READY,
test.lastStateEvent().getState());
test.run();
assertEquals(ParentState.COMPLETE,
test.lastStateEvent().getState());
assertEquals(2, r.ran);
Object[] children = OddjobTestHelper.getChildren(test);
assertEquals(1, children.length);
Object proxy = children[0];
assertEquals(JobState.COMPLETE,
((Stateful) proxy).lastStateEvent().getState());
((Resetable) proxy).hardReset();
assertEquals(JobState.READY,
((Stateful) proxy).lastStateEvent().getState());
((Runnable) proxy).run();
assertEquals(JobState.COMPLETE,
((Stateful) proxy).lastStateEvent().getState());
assertEquals(3, r.ran);
}
public void testInOddjob() throws Exception {
String xml =
"<oddjob>" +
" <job>" +
" <sequential>" +
" <jobs>" +
" <bean id='r' class='" + OurRunnable.class.getName() + "'/>" +
" <run id='j' job='${r}' />" +
" </jobs>" +
" </sequential>" +
" </job>" +
"</oddjob>";
Oddjob oddjob = new Oddjob();
oddjob.setConfiguration(new XMLConfiguration("XML", xml));
oddjob.run();
OddjobLookup lookup = new OddjobLookup(oddjob);
assertEquals(1, lookup.lookup("r.ran"));
RunJob test = lookup.lookup("j", RunJob.class);
test.hardReset();
test.run();
assertEquals(1, lookup.lookup("r.ran"));
oddjob.destroy();
}
public void testDestroyAfterRunning() throws InterruptedException, ArooaPropertyException, ArooaConversionException, ArooaParseException, FailedToStopException {
String xml =
"<oddjob>" +
" <job>" +
" <sequential>" +
" <jobs>" +
" <folder>" +
" <jobs>" +
" <wait id='w'/>" +
" </jobs>" +
" </folder>" +
" <run id='r' job='${w}' />" +
" </jobs>" +
" </sequential>" +
" </job>" +
"</oddjob>";
Oddjob oddjob = new Oddjob();
oddjob.setConfiguration(new XMLConfiguration("XML", xml));
oddjob.load();
OddjobLookup lookup = new OddjobLookup(oddjob);
Iconic wait = lookup.lookup("w", Iconic.class);
IconSteps icons = new IconSteps(wait);
icons.startCheck("ready", "executing", "sleeping");
Thread t = new Thread(oddjob);
t.start();
icons.checkWait();
((Stoppable) wait).stop();
t.join();
assertEquals(ParentState.COMPLETE,
oddjob.lastStateEvent().getState());
logger.info("*** Cutting.");
DragPoint dp = oddjob.provideConfigurationSession(
).dragPointFor(lookup.lookup("w"));
DragTransaction trn = dp.beginChange(ChangeHow.FRESH);
dp.cut();
trn.commit();
assertEquals(ParentState.COMPLETE,
oddjob.lastStateEvent().getState());
logger.info("Destroying Oddjob.");
oddjob.destroy();
}
private class MyStateful implements Stateful, Runnable {
StateHandler<ServiceState> states = new StateHandler<ServiceState>(
this, ServiceState.STARTABLE);
void fireJobState(final ServiceState state) {
try {
states.tryToWhen(new IsAnyState(), new Runnable() {
@Override
public void run() {
states.setState(state);
states.fireEvent();
}
});
}
catch (OddjobLockedException e) {
fail(e.getMessage());
}
}
@Override
public void addStateListener(StateListener listener) {
states.addStateListener(listener);
}
@Override
public void removeStateListener(StateListener listener) {
states.removeStateListener(listener);
}
@Override
public StateEvent lastStateEvent() {
throw new RuntimeException("Unexpected");
}
@Override
public void run() {
fireJobState(ServiceState.STARTING);
}
}
public void testDestroyedWhileActive() throws InterruptedException {
StandardArooaSession session = new StandardArooaSession() {
@Override
public ComponentProxyResolver getComponentProxyResolver() {
return new OddjobComponentResolver();
}
};
MyStateful job = new MyStateful();
RunJob test = new RunJob();
test.setArooaSession(session);
test.setJob(job);
IconSteps icons = new IconSteps(test);
icons.startCheck(IconHelper.READY, IconHelper.EXECUTING,
IconHelper.ACTIVE);
StateSteps states = new StateSteps(test);
states.startCheck(ParentState.READY, ParentState.EXECUTING,
ParentState.ACTIVE);
test.run();
icons.checkNow();
states.checkNow();
states.startCheck(ParentState.ACTIVE, ParentState.EXCEPTION);
job.fireJobState(ServiceState.DESTROYED);
states.checkNow();
}
private class MyStateful2 extends MyStateful {
@Override
public void run() {
fireJobState(ServiceState.STARTING);
fireJobState(ServiceState.DESTROYED);
}
}
public void testDestroyedWhileExecuting() throws InterruptedException {
MyStateful2 job = new MyStateful2();
RunJob test = new RunJob();
test.setJob(job);
StateSteps states = new StateSteps(test);
states.startCheck(ParentState.READY, ParentState.EXECUTING,
ParentState.EXCEPTION);
test.run();
states.checkNow();
}
public void testRunRemoteJob()
throws ArooaPropertyException, ArooaConversionException,
InterruptedException, FailedToStopException, PropertyVetoException {
File file = new File(getClass().getResource(
"RunRemoteJob.xml").getFile());
Oddjob oddjob = new Oddjob();
oddjob.setFile(file);
oddjob.load();
OddjobLookup lookup = new OddjobLookup(oddjob);
Iconic test = lookup.lookup("r", Iconic.class);
Stateful wait = lookup.lookup("w", Stateful.class);
IconSteps testIcons = new IconSteps(test);
testIcons.startCheck("ready", "executing", "active");
StateSteps oddjobStates = new StateSteps(oddjob);
oddjobStates.startCheck(ParentState.READY, ParentState.EXECUTING,
ParentState.ACTIVE);
StateSteps waitStates = new StateSteps(wait);
waitStates.startCheck(JobState.READY, JobState.EXECUTING);
Thread t = new Thread(oddjob);
t.start();
// OddjobExplorer explorer = new OddjobExplorer();
// explorer.setOddjob(oddjob);
// explorer.run();
waitStates.checkWait();
testIcons.checkWait();
oddjobStates.checkWait();
oddjobStates.startCheck(ParentState.ACTIVE, ParentState.STARTED);
logger.info("*** Stopping Wait *** ");
((Stoppable) wait).stop();
t.join(5000);
oddjobStates.checkWait();
oddjobStates.startCheck(ParentState.STARTED, ParentState.COMPLETE);
logger.info("*** Stopping Oddjob *** ");
oddjob.stop();
oddjobStates.checkNow();
assertEquals(ParentState.COMPLETE,
oddjob.lastStateEvent().getState());
logger.info("*** Destroying *** ");
oddjob.destroy();
}
public void testStopStopsRunningJobAndResetDoesnt() throws ArooaPropertyException, ArooaConversionException, InterruptedException, FailedToStopException {
String xml =
"<oddjob>" +
" <job>" +
" <sequential>" +
" <jobs>" +
" <folder>" +
" <jobs>" +
" <sequential id='s'>" +
" <jobs>" +
" <wait id='w1'/>" +
" <wait id='w2'/>" +
" </jobs>" +
" </sequential>" +
" </jobs>" +
" </folder>" +
" <run id='r' job='${s}' />" +
" </jobs>" +
" </sequential>" +
" </job>" +
"</oddjob>";
Oddjob oddjob = new Oddjob();
oddjob.setConfiguration(new XMLConfiguration("XML", xml));
oddjob.load();
OddjobLookup lookup = new OddjobLookup(oddjob);
// wait1
WaitJob wait1 = lookup.lookup("w1", WaitJob.class);
IconSteps icons1 = new IconSteps(wait1);
icons1.startCheck("ready", "executing", "sleeping");
Thread t = new Thread(oddjob);
t.start();
icons1.checkWait();
icons1.startCheck("sleeping", "stopping", "complete");
RunJob test = lookup.lookup("r", RunJob.class);
test.stop();
t.join(5000);
icons1.checkNow();
assertEquals(ParentState.READY,
oddjob.lastStateEvent().getState());
// run again.
// wait2
WaitJob wait2 = lookup.lookup("w2", WaitJob.class);
IconSteps icons2 = new IconSteps(wait2);
icons2.startCheck("ready", "executing", "sleeping");
t = new Thread(test);
t.start();
icons2.checkWait();
icons2.startCheck("sleeping", "stopping", "complete");
wait2.stop();
t.join(5000);
icons2.checkNow();
assertEquals(ParentState.COMPLETE,
test.lastStateEvent().getState());
// reset
test.hardReset();
assertEquals(ParentState.READY,
test.lastStateEvent().getState());
SequentialJob sequential = lookup.lookup("s", SequentialJob.class);
assertEquals(ParentState.COMPLETE,
sequential.lastStateEvent().getState());
logger.info("Destroying Oddjob.");
oddjob.destroy();
}
public void testResetPropertyResetsTargetJob() throws ArooaPropertyException, ArooaConversionException, InterruptedException, FailedToStopException {
String xml =
"<oddjob>" +
" <job>" +
" <sequential>" +
" <jobs>" +
" <folder>" +
" <jobs>" +
" <echo id='e'>I've been run</echo>" +
" </jobs>" +
" </folder>" +
" <run id='r' job='${e}' reset='HARD'/>" +
" </jobs>" +
" </sequential>" +
" </job>" +
"</oddjob>";
Oddjob oddjob = new Oddjob();
oddjob.setConfiguration(new XMLConfiguration("XML", xml));
oddjob.load();
OddjobLookup lookup = new OddjobLookup(oddjob);
Stateful echo = lookup.lookup("e", Stateful.class);
StateSteps echoStates = new StateSteps(echo);
echoStates.startCheck(JobState.READY, JobState.EXECUTING,
JobState.COMPLETE);
Thread t = new Thread(oddjob);
t.start();
t.join(5000);
echoStates.checkNow();
RunJob test = lookup.lookup("r", RunJob.class);
assertEquals(ParentState.COMPLETE,
((Stateful) test).lastStateEvent().getState());
assertEquals(ParentState.COMPLETE,
oddjob.lastStateEvent().getState());
// run again.
((Resetable) test).hardReset();
echoStates.startCheck(JobState.COMPLETE, JobState.READY, JobState.EXECUTING,
JobState.COMPLETE);
t = new Thread(test);
t.start();
t.join(5000);
echoStates.checkNow();
assertEquals(ParentState.COMPLETE,
test.lastStateEvent().getState());
oddjob.destroy();
}
}