/*
* (c) Rob Gordon 2005
*/
package org.oddjob.state;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import junit.framework.TestCase;
import org.apache.log4j.Logger;
import org.oddjob.FailedToStopException;
import org.oddjob.Oddjob;
import org.oddjob.OddjobComponentResolver;
import org.oddjob.Resetable;
import org.oddjob.Stateful;
import org.oddjob.Stoppable;
import org.oddjob.arooa.standard.StandardArooaSession;
import org.oddjob.arooa.xml.XMLConfiguration;
import org.oddjob.framework.Service;
import org.oddjob.framework.SimpleJob;
import org.oddjob.framework.StopWait;
import org.oddjob.jobs.WaitJob;
import org.oddjob.jobs.structural.JobFolder;
import org.oddjob.scheduling.DefaultExecutors;
import org.oddjob.tools.ConsoleCapture;
import org.oddjob.tools.OddjobTestHelper;
import org.oddjob.tools.StateSteps;
/**
*
*/
public class CascadeJobTest extends TestCase {
private static final Logger logger = Logger.getLogger(CascadeJobTest.class);
@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() throws InterruptedException {
DefaultExecutors executors = new DefaultExecutors();
CascadeJob test = new CascadeJob();
test.setExecutorService(executors.getPoolExecutor());
StateSteps steps = new StateSteps(test);
steps.startCheck(ParentState.READY,
ParentState.EXECUTING,
ParentState.READY);
test.run();
steps.checkWait();
executors.stop();
}
public void testSimpleRunnables() throws FailedToStopException, InterruptedException {
DefaultExecutors executors = new DefaultExecutors();
OurJob job1 = new OurJob();
OurJob job2 = new OurJob();
OurJob job3 = new OurJob();
CascadeJob test = new CascadeJob();
test.setExecutorService(executors.getPoolExecutor());
test.setJobs(0, job1);
test.setJobs(1, job2);
test.setJobs(2, job3);
StateSteps testState = new StateSteps(test);
testState.startCheck(ParentState.READY,
ParentState.EXECUTING, ParentState.ACTIVE, ParentState.COMPLETE);
test.run();
testState.checkWait();
assertEquals(JobState.COMPLETE, job1.lastStateEvent().getState());
assertEquals(JobState.COMPLETE, job2.lastStateEvent().getState());
assertEquals(JobState.COMPLETE, job3.lastStateEvent().getState());
assertEquals(1, job1.ran);
assertEquals(1, job2.ran);
assertEquals(1, job3.ran);
((Resetable) job2).hardReset();
assertEquals(ParentState.READY, test.lastStateEvent().getState());
assertEquals(JobState.COMPLETE, job1.lastStateEvent().getState());
assertEquals(JobState.READY, job2.lastStateEvent().getState());
assertEquals(JobState.COMPLETE, job3.lastStateEvent().getState());
test.hardReset();
assertEquals(ParentState.READY, test.lastStateEvent().getState());
assertEquals(JobState.READY, job1.lastStateEvent().getState());
assertEquals(JobState.READY, job2.lastStateEvent().getState());
assertEquals(JobState.READY, job3.lastStateEvent().getState());
testState.startCheck(ParentState.READY, ParentState.EXECUTING,
ParentState.ACTIVE, ParentState.COMPLETE);
test.run();
testState.checkWait();
assertEquals(2, job1.ran);
assertEquals(2, job2.ran);
assertEquals(2, job3.ran);
executors.stop();
}
public void testNotComplete() throws FailedToStopException, InterruptedException {
DefaultExecutors executors = new DefaultExecutors();
FlagState job1 = new FlagState();
job1.setState(JobState.INCOMPLETE);
FlagState job2 = new FlagState();
job2.setState(JobState.INCOMPLETE);
CascadeJob test = new CascadeJob();
test.setExecutorService(executors.getPoolExecutor());
test.setJobs(0, job1);
test.setJobs(1, job2);
assertEquals(ParentState.READY, test.lastStateEvent().getState());
StateSteps testStates = new StateSteps(test);
testStates.startCheck(ParentState.READY, ParentState.EXECUTING,
ParentState.ACTIVE, ParentState.INCOMPLETE);
test.run();
testStates.checkWait();
assertEquals(JobState.INCOMPLETE, job1.lastStateEvent().getState());
assertEquals(JobState.READY, job2.lastStateEvent().getState());
job1.setState(JobState.COMPLETE);
testStates.startCheck(ParentState.INCOMPLETE, ParentState.READY,
ParentState.EXECUTING, ParentState.ACTIVE,
ParentState.INCOMPLETE);
test.softReset();
test.run();
testStates.checkWait();
assertEquals(JobState.COMPLETE, job1.lastStateEvent().getState());
assertEquals(JobState.INCOMPLETE, job2.lastStateEvent().getState());
executors.stop();
}
public void testException() throws FailedToStopException, InterruptedException {
DefaultExecutors executors = new DefaultExecutors();
FlagState job1 = new FlagState();
job1.setState(JobState.COMPLETE);
FlagState job2 = new FlagState();
job2.setState(JobState.EXCEPTION);
CascadeJob test = new CascadeJob();
test.setExecutorService(executors.getPoolExecutor());
test.setJobs(0, job1);
test.setJobs(1, job2);
assertEquals(ParentState.READY, test.lastStateEvent().getState());
StateSteps job2Check = new StateSteps(job2);
job2Check.startCheck(JobState.READY,
JobState.EXECUTING, JobState.EXCEPTION);
test.run();
job2Check.checkWait();
new StopWait(test).run();
assertEquals(JobState.COMPLETE, job1.lastStateEvent().getState());
assertEquals(JobState.EXCEPTION, job2.lastStateEvent().getState());
assertEquals(ParentState.EXCEPTION, test.lastStateEvent().getState());
job2Check.startCheck(JobState.EXCEPTION, JobState.READY,
JobState.EXECUTING, JobState.COMPLETE);
job2.setState(JobState.COMPLETE);
job2.softReset();
job2.run();
job2Check.checkWait();
assertEquals(JobState.COMPLETE, job1.lastStateEvent().getState());
assertEquals(JobState.COMPLETE, job2.lastStateEvent().getState());
executors.stop();
}
private static class OurService implements Service {
@Override
public void start() throws Exception {
}
@Override
public void stop() throws FailedToStopException {
}
}
public void testServiceAndException() throws FailedToStopException, InterruptedException {
DefaultExecutors executors = new DefaultExecutors();
Stateful service1 = (Stateful) new OddjobComponentResolver().resolve(
new OurService(), new StandardArooaSession());
FlagState job2 = new FlagState();
job2.setState(JobState.EXCEPTION);
CascadeJob test = new CascadeJob();
test.setExecutorService(executors.getPoolExecutor());
test.setJobs(0, service1);
test.setJobs(1, job2);
assertEquals(ParentState.READY, test.lastStateEvent().getState());
StateSteps service1States = new StateSteps(service1);
service1States.startCheck(ServiceState.STARTABLE,
ServiceState.STARTING, ServiceState.STARTED);
StateSteps job2States = new StateSteps(job2);
job2States.startCheck(JobState.READY,
JobState.EXECUTING, JobState.EXCEPTION);
test.run();
service1States.checkWait();
assertEquals(JobState.READY, job2.lastStateEvent().getState());
((Stoppable) service1).stop();
job2States.checkWait();
new StopWait(test).run();
assertEquals(ServiceState.STOPPED, service1.lastStateEvent().getState());
assertEquals(JobState.EXCEPTION, job2.lastStateEvent().getState());
assertEquals(ParentState.EXCEPTION, test.lastStateEvent().getState());
job2States.startCheck(JobState.EXCEPTION, JobState.READY,
JobState.EXECUTING, JobState.COMPLETE);
job2.setState(JobState.COMPLETE);
job2.softReset();
job2.run();
job2States.checkWait();
assertEquals(ServiceState.STOPPED, service1.lastStateEvent().getState());
assertEquals(JobState.COMPLETE, job2.lastStateEvent().getState());
executors.stop();
}
public void testDestroyed() throws FailedToStopException, InterruptedException {
DefaultExecutors executors = new DefaultExecutors();
FlagState job1 = new FlagState();
job1.setState(JobState.COMPLETE);
CascadeJob test = new CascadeJob();
test.setExecutorService(executors.getPoolExecutor());
test.setJobs(0, job1);
assertEquals(ParentState.READY, test.lastStateEvent().getState());
StateSteps state = new StateSteps(test);
state.startCheck(ParentState.READY, ParentState.EXECUTING,
ParentState.ACTIVE, ParentState.COMPLETE);
test.run();
state.checkWait();
final List<State> results = new ArrayList<State>();
class OurListener implements StateListener {
public void jobStateChange(StateEvent event) {
results.add(event.getState());
}
}
OurListener l = new OurListener();
test.addStateListener(l);
assertEquals(ParentState.COMPLETE, results.get(0));
assertEquals(1, results.size());
test.destroy();
assertEquals(ParentState.DESTROYED, results.get(1));
assertEquals(2, results.size());
executors.stop();
}
public void testWithFoldersMixedIn() throws InterruptedException {
DefaultExecutors executors = new DefaultExecutors();
FlagState job1 = new FlagState(JobState.COMPLETE);
FlagState job2 = new FlagState(JobState.COMPLETE);
CascadeJob test = new CascadeJob();
test.setExecutorService(executors.getPoolExecutor());
StateSteps testState = new StateSteps(test);
testState.startCheck(ParentState.READY, ParentState.EXECUTING,
ParentState.ACTIVE, ParentState.COMPLETE);
test.setJobs(0, new JobFolder());
test.setJobs(1, job1);
test.setJobs(2, new JobFolder());
test.setJobs(3, job2);
test.setJobs(4, new JobFolder());
test.run();
testState.checkWait();
executors.stop();
}
public void testRemovingAndInserting() throws InterruptedException {
DefaultExecutors executors = new DefaultExecutors();
FlagState job1 = new FlagState(JobState.COMPLETE);
FlagState job2 = new FlagState(JobState.COMPLETE);
CascadeJob test = new CascadeJob();
test.setExecutorService(executors.getPoolExecutor());
StateSteps testState = new StateSteps(test);
testState.startCheck(ParentState.READY, ParentState.EXECUTING,
ParentState.ACTIVE, ParentState.COMPLETE);
test.setJobs(0, job1);
test.setJobs(1, job2);
test.run();
testState.checkWait();
test.setJobs(0, null);
assertEquals(ParentState.COMPLETE, test.lastStateEvent().getState());
testState.startCheck(ParentState.COMPLETE, ParentState.EXECUTING,
ParentState.COMPLETE);
FlagState job3 = new FlagState(JobState.COMPLETE);
StateSteps job3State = new StateSteps(job3);
job3State.startCheck(JobState.READY);
test.setJobs(1, job3);
job3State.checkNow();
FlagState job4 = new FlagState(JobState.COMPLETE);
test.setJobs(0, job4);
assertEquals(ParentState.READY, test.lastStateEvent().getState());
assertEquals(JobState.READY, job4.lastStateEvent().getState());
executors.stop();
}
public void testInsertingWhileRuning() throws InterruptedException, FailedToStopException {
DefaultExecutors executors = new DefaultExecutors();
WaitJob job1 = new WaitJob();
job1.setName("Wait-1");
WaitJob job2 = new WaitJob();
job2.setName("Wait-2");
WaitJob job3 = new WaitJob();
job3.setName("Wait-3");
WaitJob job4 = new WaitJob();
job4.setName("Wait-4");
CascadeJob test = new CascadeJob();
test.setExecutorService(executors.getPoolExecutor());
test.setJobs(0, job1);
test.setJobs(1, job2);
StateSteps testState = new StateSteps(test);
testState.startCheck(ParentState.READY, ParentState.EXECUTING,
ParentState.ACTIVE, ParentState.COMPLETE);
StateSteps job1State = new StateSteps(job1);
job1State.startCheck(JobState.READY, JobState.EXECUTING);
StateSteps job2State = new StateSteps(job2);
job2State.startCheck(JobState.READY);
test.run();
StateSteps job3State = new StateSteps(job3);
job3State.startCheck(JobState.READY, JobState.EXECUTING);
test.setJobs(1, null);
test.setJobs(1, job3);
job1State.checkWait();
job1State.startCheck(JobState.EXECUTING, JobState.COMPLETE);
job1.stop();
job1State.checkWait();
job2State.checkNow();
job3State.checkWait();
StateSteps job4State = new StateSteps(job4);
job4State.startCheck(JobState.READY, JobState.EXECUTING);
test.setJobs(0, job4);
new Thread(job4).start();
job4State.checkWait();
job3State.startCheck(JobState.EXECUTING, JobState.COMPLETE);
job4State.startCheck(JobState.EXECUTING, JobState.COMPLETE);
job3.stop();
job3State.checkWait();
test.stop();
job4State.checkNow();
testState.checkNow();
executors.stop();
}
public void testInOddjob() throws InterruptedException {
String xml =
"<oddjob xmlns:state='http://rgordon.co.uk/oddjob/state'>" +
" <job>" +
" <state:cascade>" +
" <jobs>" +
" <echo>one</echo>" +
" <echo>two</echo>" +
" <echo>three</echo>" +
" </jobs>" +
" </state:cascade>" +
" </job>" +
"</oddjob>";
Oddjob oddjob = new Oddjob();
oddjob.setConfiguration(new XMLConfiguration("XML", xml));
StateSteps oddjobStates = new StateSteps(oddjob);
oddjobStates.startCheck(ParentState.READY, ParentState.EXECUTING,
ParentState.ACTIVE, ParentState.COMPLETE);
oddjob.run();
oddjobStates.checkWait();
assertEquals(ParentState.COMPLETE, oddjob.lastStateEvent().getState());
}
public void testStop() throws InterruptedException, FailedToStopException {
DefaultExecutors executors = new DefaultExecutors();
CascadeJob test = new CascadeJob();
test.setExecutorService(executors.getPoolExecutor());
WaitJob wait1 = new WaitJob();
WaitJob wait2 = new WaitJob();
test.setJobs(0, wait1);
test.setJobs(1, wait2);
StateSteps testState = new StateSteps(test);
testState.startCheck(ParentState.READY, ParentState.EXECUTING,
ParentState.ACTIVE);
StateSteps wait1State = new StateSteps(wait1);
StateSteps wait2State = new StateSteps(wait2);
wait1State.startCheck(JobState.READY, JobState.EXECUTING);
test.run();
testState.checkNow();
wait1State.checkWait();
testState.startCheck(ParentState.ACTIVE, ParentState.READY);
test.stop();
testState.checkNow();
assertEquals(JobState.READY, wait2.lastStateEvent().getState());
//
// Second run.
testState.startCheck(ParentState.READY, ParentState.EXECUTING,
ParentState.ACTIVE);
wait2State.startCheck(JobState.READY, JobState.EXECUTING);
test.softReset();
test.run();
testState.checkNow();
wait2State.checkWait();
testState.startCheck(ParentState.ACTIVE, ParentState.COMPLETE);
test.stop();
testState.checkNow();
executors.stop();
}
public void testExample() throws InterruptedException {
Oddjob oddjob = new Oddjob();
oddjob.setConfiguration(new XMLConfiguration(
"org/oddjob/state/CascadeExample.xml",
getClass().getClassLoader()));
StateSteps oddjobStates = new StateSteps(oddjob);
oddjobStates.startCheck(ParentState.READY, ParentState.EXECUTING,
ParentState.ACTIVE, ParentState.COMPLETE);
ConsoleCapture console = new ConsoleCapture();
try (ConsoleCapture.Close close = console.captureConsole()) {
oddjob.run();
oddjobStates.checkWait();
}
console.dump(logger);
String[] lines = console.getLines();
assertEquals(2, lines.length);
assertEquals("This runs first.", lines[0].trim());
assertEquals("Then this.", lines[1].trim());
oddjob.destroy();
}
public void testWithParallel() throws InterruptedException {
Oddjob oddjob = new Oddjob();
oddjob.setConfiguration(new XMLConfiguration(
"org/oddjob/state/CascadeWithParallelExample.xml",
getClass().getClassLoader()));
StateSteps oddjobStates = new StateSteps(oddjob);
oddjobStates.startCheck(ParentState.READY, ParentState.EXECUTING,
ParentState.ACTIVE, ParentState.COMPLETE);
ConsoleCapture console = new ConsoleCapture();
try (ConsoleCapture.Close close = console.captureConsole()) {
oddjob.run();
oddjobStates.checkWait();
}
console.dump(logger);
String[] lines = console.getLines();
assertEquals(3, lines.length);
assertEquals("Apples are guaranteed to be third.", lines[2].trim());
oddjob.destroy();
}
public void testCascadeOnHaltOnExample() throws InterruptedException {
File file = new File(getClass().getResource(
"CascadeOnHaltOnExample.xml").getFile());
Oddjob oddjob = new Oddjob();
oddjob.setFile(file);
StateSteps oddjobStates = new StateSteps(oddjob);
oddjobStates.startCheck(ParentState.READY, ParentState.EXECUTING,
ParentState.ACTIVE, ParentState.EXCEPTION);
oddjob.run();
oddjobStates.checkWait();
Object[] jobs = OddjobTestHelper.getChildren(
OddjobTestHelper.getChildren(oddjob)[0]);
assertEquals(JobState.INCOMPLETE, ((Stateful)
jobs[0]).lastStateEvent().getState());
assertEquals(JobState.COMPLETE, ((Stateful)
jobs[1]).lastStateEvent().getState());
assertEquals(JobState.EXCEPTION, ((Stateful)
jobs[2]).lastStateEvent().getState());
assertEquals(JobState.READY, ((Stateful)
jobs[3]).lastStateEvent().getState());
oddjob.destroy();
}
}