package org.oddjob.scheduling; import java.util.HashSet; import java.util.Set; import junit.framework.TestCase; import org.apache.log4j.Logger; import org.oddjob.FailedToStopException; import org.oddjob.Oddjob; import org.oddjob.OddjobLookup; import org.oddjob.Stateful; import org.oddjob.Stoppable; import org.oddjob.Structural; import org.oddjob.arooa.convert.ArooaConversionException; import org.oddjob.arooa.reflect.ArooaPropertyException; import org.oddjob.arooa.xml.XMLConfiguration; import org.oddjob.state.JobState; import org.oddjob.state.ParentState; import org.oddjob.state.StateEvent; import org.oddjob.state.StateListener; import org.oddjob.structural.StructuralEvent; import org.oddjob.structural.StructuralListener; import org.oddjob.tools.StateSteps; public class ExecutorThrottleTypeTest extends TestCase { private static final Logger logger = Logger.getLogger(ExecutorThrottleTypeTest.class); @Override protected void setUp() throws Exception { logger.info("---------------------- " + getName() + "-----------------------"); } private class Capture implements StructuralListener, StateListener { Set<Stateful> ready = new HashSet<Stateful>(); Set<Stateful> executing = new HashSet<Stateful>(); Set<Stateful> complete = new HashSet<Stateful>(); @Override public void jobStateChange(StateEvent event) { logger.info("Received: " + event); synchronized(this) { switch ((JobState) event.getState()) { case READY: ready.add(event.getSource()); break; case EXECUTING: ready.remove(event.getSource()); executing.add(event.getSource()); break; case COMPLETE: executing.remove(event.getSource()); complete.add(event.getSource()); break; default: throw new RuntimeException("Unexpected " + event.getState()); } this.notifyAll(); } } @Override public void childAdded(StructuralEvent event) { ((Stateful) event.getChild()).addStateListener(this); } @Override public void childRemoved(StructuralEvent event) { ((Stateful) event.getChild()).removeStateListener(this); } } public void testThrottleInParallel() throws InterruptedException, ArooaPropertyException, ArooaConversionException, FailedToStopException { Oddjob oddjob = new Oddjob(); oddjob.setConfiguration(new XMLConfiguration( "org/oddjob/scheduling/ExecutorThrottleInParallel.xml", getClass().getClassLoader())); StateSteps oddjobState = new StateSteps(oddjob); oddjobState.startCheck(ParentState.READY, ParentState.EXECUTING, ParentState.ACTIVE); oddjob.run(); oddjobState.checkNow(); oddjobState.startCheck(ParentState.ACTIVE, ParentState.COMPLETE); OddjobLookup lookup = new OddjobLookup(oddjob); Structural parallel = lookup.lookup("parallel", Structural.class); Capture capture = new Capture(); parallel.addStructuralListener(capture); synchronized (capture) { while (capture.executing.size() < 2) { logger.info("Waiting for 2 EXECUTING."); capture.wait(); } } assertEquals(2, capture.ready.size()); ((Stoppable) capture.executing.iterator().next()).stop(); synchronized (capture) { while (capture.complete.size() < 1) { logger.info("Waiting for 1 COMPLETE."); capture.wait(); } while (capture.executing.size() < 2) { logger.info("Waiting for 2 EXECUTING."); capture.wait(); } } ((Stoppable) capture.executing.iterator().next()).stop(); synchronized (capture) { while (capture.complete.size() < 2) { logger.info("Waiting for 2 COMPLETE."); capture.wait(); } while (capture.executing.size() < 2) { logger.info("Waiting for 2 EXECUTING."); capture.wait(); } } ((Stoppable) parallel).stop(); synchronized (capture) { while (capture.complete.size() < 4) { logger.info("Waiting for 4 COMPLETE."); capture.wait(); } } oddjobState.checkWait(); oddjob.destroy(); } public void testStopParallel() throws InterruptedException, ArooaPropertyException, ArooaConversionException, FailedToStopException { Oddjob oddjob = new Oddjob(); oddjob.setConfiguration(new XMLConfiguration( "org/oddjob/scheduling/ExecutorThrottleInParallel.xml", getClass().getClassLoader())); StateSteps oddjobState = new StateSteps(oddjob); oddjobState.startCheck(ParentState.READY, ParentState.EXECUTING, ParentState.ACTIVE); oddjob.run(); oddjobState.checkNow(); oddjobState.startCheck(ParentState.ACTIVE, ParentState.READY); OddjobLookup lookup = new OddjobLookup(oddjob); Structural parallel = lookup.lookup("parallel", Structural.class); Capture capture = new Capture(); parallel.addStructuralListener(capture); synchronized (capture) { while (capture.executing.size() < 2) { logger.info("Waiting for 2 EXECUTING."); capture.wait(); } } ((Stoppable) parallel).stop(); oddjobState.checkWait(); assertEquals(2, capture.complete.size()); assertEquals(2, capture.ready.size()); oddjob.destroy(); } public void testThrottleShared() throws InterruptedException, ArooaPropertyException, ArooaConversionException, FailedToStopException { Oddjob oddjob = new Oddjob(); oddjob.setConfiguration(new XMLConfiguration( "org/oddjob/scheduling/ExecutorThrottleShared.xml", getClass().getClassLoader())); StateSteps oddjobState = new StateSteps(oddjob); oddjobState.startCheck(ParentState.READY, ParentState.EXECUTING, ParentState.ACTIVE); oddjob.run(); oddjobState.checkNow(); oddjobState.startCheck(ParentState.ACTIVE, ParentState.COMPLETE); OddjobLookup lookup = new OddjobLookup(oddjob); Structural parallelOne = lookup.lookup("parallel-1", Structural.class); Structural parallelTwo = lookup.lookup("parallel-2", Structural.class); Capture capture = new Capture(); parallelOne.addStructuralListener(capture); parallelTwo.addStructuralListener(capture); synchronized (capture) { while (capture.executing.size() < 2) { logger.info("Waiting for 2 EXECUTING."); capture.wait(); } } assertEquals(2, capture.ready.size()); ((Stoppable) capture.executing.iterator().next()).stop(); synchronized (capture) { while (capture.complete.size() < 1) { logger.info("Waiting for 1 COMPLETE."); capture.wait(); } while (capture.executing.size() < 2) { logger.info("Waiting for 2 EXECUTING."); capture.wait(); } } ((Stoppable) capture.executing.iterator().next()).stop(); synchronized (capture) { while (capture.complete.size() < 2) { logger.info("Waiting for 2 COMPLETE."); capture.wait(); } while (capture.executing.size() < 2) { logger.info("Waiting for 2 EXECUTING."); capture.wait(); } } ((Stoppable) parallelOne).stop(); ((Stoppable) parallelTwo).stop(); synchronized (capture) { while (capture.complete.size() < 4) { logger.info("Waiting for 4 COMPLETE."); capture.wait(); } } oddjobState.checkWait(); oddjob.destroy(); } }