/*
* (c) Rob Gordon 2005
*/
package org.oddjob.state;
import java.util.concurrent.TimeUnit;
import junit.framework.TestCase;
import org.apache.log4j.Logger;
import org.oddjob.FailedToStopException;
import org.oddjob.Oddjob;
import org.oddjob.OddjobLookup;
import org.oddjob.Resetable;
import org.oddjob.Stateful;
import org.oddjob.arooa.convert.ArooaConversionException;
import org.oddjob.arooa.reflect.ArooaPropertyException;
import org.oddjob.arooa.xml.XMLConfiguration;
import org.oddjob.framework.SimpleJob;
import org.oddjob.schedules.schedules.CountSchedule;
import org.oddjob.schedules.schedules.IntervalSchedule;
import org.oddjob.scheduling.DefaultExecutors;
import org.oddjob.scheduling.Timer;
import org.oddjob.state.FlagState;
import org.oddjob.state.JobState;
import org.oddjob.tools.StateSteps;
/**
*
*/
public class JoinJobTest extends TestCase {
private static final Logger logger = Logger.getLogger(JoinJobTest.class);
static final long TIMEOUT = 15_000L;
@Override
protected void setUp() throws Exception {
super.setUp();
logger.info("---------------- " + getName() + " -----------------");
}
private static class OurJob extends SimpleJob {
int ran;
@Override
protected int execute() throws Throwable {
++ran;
return 0;
}
}
// an empty sequence must be ready. This is to agree with oddjob
// which must also be ready when reset and empty.
// this is really a bug in StatefulChildHelper. An empty sequence should
// be ready until run and then be complete. I think.
public void testEmpty() {
JoinJob test = new JoinJob();
test.setTimeout(TIMEOUT);
assertEquals(ParentState.READY, test.lastStateEvent().getState());
test.run();
assertEquals(ParentState.READY, test.lastStateEvent().getState());
}
public void testSimpleRunnable() throws FailedToStopException, InterruptedException {
OurJob job1 = new OurJob();
JoinJob test = new JoinJob();
test.setTimeout(TIMEOUT);
test.setJob(job1);
assertEquals(ParentState.READY, test.lastStateEvent().getState());
StateSteps testState = new StateSteps(test);
testState.startCheck(ParentState.READY,
ParentState.EXECUTING, ParentState.COMPLETE);
test.run();
testState.checkNow();
assertEquals(JobState.COMPLETE, job1.lastStateEvent().getState());
assertEquals(1, job1.ran);
((Resetable) job1).hardReset();
assertEquals(ParentState.READY, test.lastStateEvent().getState());
assertEquals(JobState.READY, job1.lastStateEvent().getState());
testState.startCheck(ParentState.READY,
ParentState.EXECUTING, ParentState.COMPLETE);
test.run();
testState.checkNow();
assertEquals(2, job1.ran);
}
public void testNotComplete() throws FailedToStopException {
FlagState job1 = new FlagState();
job1.setState(JobState.INCOMPLETE);
JoinJob test = new JoinJob();
test.setTimeout(TIMEOUT);
test.setJob(job1);
assertEquals(ParentState.READY, test.lastStateEvent().getState());
test.run();
assertEquals(ParentState.INCOMPLETE, test.lastStateEvent().getState());
job1.setState(JobState.COMPLETE);
job1.hardReset();
job1.run();
assertEquals(ParentState.COMPLETE, test.lastStateEvent().getState());
assertEquals(JobState.COMPLETE, job1.lastStateEvent().getState());
}
public void testAsynchronous() throws FailedToStopException, InterruptedException {
DefaultExecutors executors = new DefaultExecutors();
FlagState job1 = new FlagState();
job1.setState(JobState.COMPLETE);
Timer timer = new Timer();
CountSchedule count = new CountSchedule(1);
IntervalSchedule interval = new IntervalSchedule(500);
count.setRefinement(interval);
timer.setSchedule(count);
timer.setJob(job1);
timer.setScheduleExecutorService(executors.getScheduledExecutor());
JoinJob test = new JoinJob();
test.setTimeout(TIMEOUT);
test.setJob(timer);
StateSteps testStates = new StateSteps(test);
testStates.startCheck(ParentState.READY,
ParentState.EXECUTING, ParentState.COMPLETE);
test.run();
testStates.checkNow();
assertEquals(JobState.COMPLETE, job1.lastStateEvent().getState());
assertEquals(ParentState.COMPLETE, test.lastStateEvent().getState());
executors.stop();
}
public void testAsynchronousStop() throws FailedToStopException, InterruptedException {
DefaultExecutors executors = new DefaultExecutors();
FlagState job1 = new FlagState();
job1.setState(JobState.COMPLETE);
Timer timer = new Timer();
CountSchedule count = new CountSchedule(1);
IntervalSchedule interval = new IntervalSchedule(1000000L);
count.setRefinement(interval);
timer.setSchedule(count);
timer.setJob(job1);
timer.setScheduleExecutorService(executors.getScheduledExecutor());
final JoinJob test = new JoinJob();
test.setTimeout(TIMEOUT);
test.setJob(timer);
StateSteps testStates = new StateSteps(test);
testStates.startCheck(ParentState.READY,
ParentState.EXECUTING, ParentState.COMPLETE);
executors.getScheduledExecutor().schedule(new Runnable() {
@Override
public void run() {
try {
test.stop();
} catch (FailedToStopException e) {
throw new RuntimeException(e);
}
}
}, 500, TimeUnit.MILLISECONDS);
test.run();
testStates.checkNow();
assertEquals(JobState.COMPLETE, job1.lastStateEvent().getState());
assertEquals(ParentState.COMPLETE, test.lastStateEvent().getState());
executors.stop();
}
public void testDestroyed() throws FailedToStopException {
FlagState job1 = new FlagState();
job1.setState(JobState.COMPLETE);
JoinJob test = new JoinJob();
test.setTimeout(TIMEOUT);
test.setJob(job1);
assertEquals(ParentState.READY, test.lastStateEvent().getState());
test.run();
assertEquals(ParentState.COMPLETE, test.lastStateEvent().getState());
StateSteps testStates = new StateSteps(test);
testStates.startCheck(ParentState.COMPLETE,
ParentState.DESTROYED);
test.destroy();
testStates.checkNow();
}
public void testInOddjob() throws InterruptedException, ArooaPropertyException, ArooaConversionException {
Oddjob oddjob = new Oddjob();
oddjob.setConfiguration(new XMLConfiguration(
"org/oddjob/state/JoinExample.xml",
getClass().getClassLoader()));
oddjob.load();
assertEquals(ParentState.READY, oddjob.lastStateEvent().getState());
OddjobLookup lookup = new OddjobLookup(oddjob);
Stateful test = lookup.lookup("our-join", Stateful.class);
StateSteps state = new StateSteps(test);
Thread t = new Thread(oddjob);
state.startCheck(ParentState.READY, ParentState.EXECUTING);
logger.info("** starting first run");
t.start();
state.checkWait();
assertEquals(ParentState.EXECUTING,
oddjob.lastStateEvent().getState());
Stateful lastJob = lookup.lookup("last-job", Stateful.class);
assertEquals(JobState.READY,
lastJob.lastStateEvent().getState());
Object applesFlag = lookup.lookup("apples");
Object orangesFlag = lookup.lookup("oranges");
((Runnable) applesFlag).run();
((Runnable) orangesFlag).run();
t.join(TIMEOUT);
logger.info("** first run done.");
assertEquals(ParentState.COMPLETE,
oddjob.lastStateEvent().getState());
assertEquals(JobState.COMPLETE,
lastJob.lastStateEvent().getState());
logger.info("** resetting");
((Resetable) test).hardReset();
((Resetable) lastJob).hardReset();
Thread t2 = new Thread(oddjob);
state.startCheck(ParentState.READY, ParentState.EXECUTING);
logger.info("** starting second run");
t2.start();
state.checkWait();
assertEquals(JobState.READY,
lastJob.lastStateEvent().getState());
((Resetable) applesFlag).hardReset();
((Resetable) orangesFlag).hardReset();
((Runnable) applesFlag).run();
((Runnable) orangesFlag).run();
t2.join(TIMEOUT);
logger.info("** second run done.");
assertEquals(JobState.COMPLETE,
lastJob.lastStateEvent().getState());
}
}