package org.oddjob.sql; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import junit.framework.TestCase; import org.oddjob.arooa.convert.ArooaConversionException; import org.oddjob.arooa.standard.StandardArooaSession; import org.oddjob.io.BufferType; import org.oddjob.schedules.schedules.CountSchedule; import org.oddjob.scheduling.LoosingOutcome; import org.oddjob.scheduling.MockScheduledExecutorService; import org.oddjob.scheduling.MockScheduledFuture; import org.oddjob.scheduling.Outcome; import org.oddjob.scheduling.WinningOutcome; import org.oddjob.state.JobState; import org.oddjob.state.StateListener; import org.oddjob.state.State; import org.oddjob.state.StateEvent; public class SQLKeeperTest extends TestCase { ConnectionType ct; @Override protected void setUp() throws Exception { ct = new ConnectionType(); ct.setDriver("org.hsqldb.jdbcDriver"); ct.setUrl("jdbc:hsqldb:mem:test"); ct.setUsername("sa"); ct.setPassword(""); BufferType buffer = new BufferType(); buffer.setText("CREATE TABLE oddjob_grabbable(" + "key VARCHAR(128), " + "instance VARCHAR(32), " + "winner VARCHAR(32), " + "complete boolean, " + "CONSTRAINT oddjob_pk PRIMARY KEY (key))"); buffer.configured(); SQLJob sql = new SQLJob(); sql.setArooaSession(new StandardArooaSession()); sql.setInput(buffer.toInputStream()); sql.setConnection(ct.toValue()); sql.run(); } @Override protected void tearDown() throws Exception { BufferType buffer = new BufferType(); buffer.setText("shutdown"); buffer.configured(); SQLJob sql = new SQLJob(); sql.setArooaSession(new StandardArooaSession()); sql.setInput(buffer.toInputStream()); sql.setConnection(ct.toValue()); sql.run(); } private class OurListener implements StateListener { List<State> states = new ArrayList<State>(); @Override public void jobStateChange(StateEvent event) { states.add(event.getState()); } } private class OurFuture extends MockScheduledFuture<Void> { boolean canceled; @Override public boolean cancel(boolean mayInterruptIfRunning) { this.canceled = true; return true; } } private class OurExcecutor extends MockScheduledExecutorService { Runnable runnable; OurFuture future = new OurFuture(); @Override public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) { this.runnable = command; return future; } } public void testFreshRun() throws SQLException, ArooaConversionException { OurExcecutor executor = new OurExcecutor(); SQLKeeperService test = new SQLKeeperService(); test.setConnection(ct.toValue()); test.setScheduleExecutorService(executor); test.start(); Outcome first = test.getKeeper("secret").grab("apple", "first"); assertTrue(first.isWon()); assertEquals("apple", first.getWinner()); Outcome second = test.getKeeper("secret").grab("orange", "first"); assertFalse(second.isWon()); assertEquals("apple", second.getWinner()); OurListener listener = new OurListener(); ((LoosingOutcome) second).addStateListener(listener); assertEquals(1, listener.states.size()); assertEquals(JobState.EXECUTING, listener.states.get(0)); ((WinningOutcome) first).complete(); Runnable runnable = executor.runnable; runnable.run(); assertEquals(2, listener.states.size()); assertEquals(JobState.COMPLETE, listener.states.get(1)); assertTrue(executor.runnable == runnable); test.stop(); } public void testFreshStop() throws SQLException, ArooaConversionException { OurExcecutor executor = new OurExcecutor(); SQLKeeperService test = new SQLKeeperService(); test.setConnection(ct.toValue()); test.setScheduleExecutorService(executor); test.start(); Outcome first = test.getKeeper("secret").grab("apple", "first"); assertTrue(first.isWon()); assertEquals("apple", first.getWinner()); Outcome second = test.getKeeper("secret").grab("orange", "first"); assertFalse(second.isWon()); assertEquals("apple", second.getWinner()); OurListener listener = new OurListener(); ((LoosingOutcome) second).addStateListener(listener); assertEquals(1, listener.states.size()); assertEquals(JobState.EXECUTING, listener.states.get(0)); assertNotNull(executor.runnable); ((LoosingOutcome) second).removeStateListener(listener); test.stop(); assertTrue(executor.future.canceled); } public void testTimeout() throws SQLException, ArooaConversionException { OurExcecutor executor = new OurExcecutor(); CountSchedule count = new CountSchedule(1); SQLKeeperService test = new SQLKeeperService(); test.setConnection(ct.toValue()); test.setScheduleExecutorService(executor); test.setPollSchedule(count); test.start(); Outcome first = test.getKeeper("secret").grab("apple", "first"); assertTrue(first.isWon()); assertEquals("apple", first.getWinner()); Outcome second = test.getKeeper("secret").grab("orange", "first"); assertFalse(second.isWon()); assertEquals("apple", second.getWinner()); OurListener listener = new OurListener(); ((LoosingOutcome) second).addStateListener(listener); assertEquals(1, listener.states.size()); assertEquals(JobState.EXECUTING, listener.states.get(0)); assertNotNull(executor.runnable); executor.runnable.run(); assertEquals(JobState.EXCEPTION, listener.states.get(1)); assertEquals(2, listener.states.size()); test.stop(); } }