package jmri.jmrit.logix; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import jmri.BeanSetting; import jmri.InstanceManager; import jmri.JmriException; import jmri.Sensor; import jmri.SensorManager; import jmri.Turnout; import jmri.TurnoutManager; import jmri.util.JUnitUtil; import jmri.util.ThreadingUtil; import org.junit.jupiter.api.*; import org.junit.jupiter.api.io.TempDir; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; /** * Tests for Warrant creation. * * @author Pete Cressman 2015 * * TODO - test error conditions */ public class WarrantTest { protected OBlockManager _OBlockMgr; protected PortalManager _portalMgr; protected SensorManager _sensorMgr; protected TurnoutManager _turnoutMgr; protected OBlock bWest; protected OBlock bEast; protected OBlock bNorth; protected OBlock bSouth; protected Warrant warrant; protected Sensor sWest; protected Sensor sEast; protected Sensor sNorth; protected Sensor sSouth; @Test public void testCTor() { assertThat(warrant).withFailMessage("exists").isNotNull(); } @Test public void testSetAndGetTrainName() { warrant.setTrainName("TestTrain"); assertThat(warrant.getTrainName()).withFailMessage("Train Name").isEqualTo("TestTrain"); } @Test public void testGetSpeedUtil() { SpeedUtil su = warrant.getSpeedUtil(); assertThat(su).withFailMessage("SpeedUtil null").isNotNull(); } @Test public void testAddPropertyChangeListener() { PropertyChangeListener listener = new WarrantListener(warrant); assertThat(listener).withFailMessage("PropertyChangeListener").isNotNull(); warrant.addPropertyChangeListener(listener); } @Test public void testAllocateAndDeallocateWarrant() { try { sWest.setState(Sensor.INACTIVE); sEast.setState(Sensor.ACTIVE); sNorth.setState(Sensor.INACTIVE); sSouth.setState(Sensor.ACTIVE); } catch (JmriException ignore) { } bWest.allocate(warrant); bEast.allocate(warrant); assertThat(bWest.getState()).withFailMessage("Block Detection 3").isEqualTo(OBlock.UNOCCUPIED | OBlock.ALLOCATED); assertThat(bEast.getState()).withFailMessage("Block Detection 4").isEqualTo(OBlock.OCCUPIED | OBlock.ALLOCATED); try { sEast.setState(Sensor.INACTIVE); sSouth.setState(Sensor.INACTIVE); sNorth.setState(Sensor.ACTIVE); // start block of warrant } catch (JmriException ignore) { } bWest.deAllocate(warrant); bEast.deAllocate(warrant); assertThat(bWest.getState()).withFailMessage("Block Detection 5").isEqualTo(OBlock.UNOCCUPIED); assertThat(bEast.getState()).withFailMessage("Block Detection 6").isEqualTo(OBlock.UNOCCUPIED); } @Test public void testSetRouteUsingViaOrders() { try { sEast.setState(Sensor.INACTIVE); sSouth.setState(Sensor.INACTIVE); sNorth.setState(Sensor.ACTIVE); // start block of warrant } catch (JmriException ignore) { } ArrayList orders = new ArrayList<>(); orders.add(new BlockOrder( bNorth, "NorthToWest", "", "NorthWest")); BlockOrder viaOrder = new BlockOrder( bWest, "SouthToNorth", "NorthWest", "SouthWest"); orders.add(viaOrder); BlockOrder lastOrder = new BlockOrder( bSouth, "SouthToWest", "SouthWest", null); orders.add(lastOrder); warrant.setViaOrder(viaOrder); warrant.setBlockOrders(orders); assertThat(lastOrder.toString()).withFailMessage("BlockOrder").isEqualTo(warrant.getLastOrder().toString()); assertThat(viaOrder.toString()).withFailMessage("BlockOrder").isEqualTo(warrant.getViaOrder().toString()); String msg = warrant.allocateRoute(false, orders); assertNull( msg, "allocateRoute - " + msg); msg = warrant.checkStartBlock(); assertNull( msg, "checkStartBlock - " + msg); msg = warrant.checkRoute(); assertNull( msg, "checkRoute - " + msg); } @Test public void testSetRoute() throws JmriException { sEast.setState(Sensor.INACTIVE); sSouth.setState(Sensor.INACTIVE); sNorth.setState(Sensor.ACTIVE); // start block of warrant ArrayList orders = new ArrayList<>(); orders.add(new BlockOrder( bNorth, "NorthToWest", "", "NorthWest")); BlockOrder viaOrder = new BlockOrder( bWest, "SouthToNorth", "NorthWest", "SouthWest"); orders.add(viaOrder); BlockOrder lastOrder = new BlockOrder( bSouth, "SouthToWest", "SouthWest", null); orders.add(lastOrder); String msg = warrant.allocateRoute(false, orders); assertNull( msg, "allocateRoute - " + msg); msg = warrant.checkStartBlock(); assertNull( msg, "checkStartBlock - " + msg); msg = warrant.checkRoute(); assertNull( msg, "checkRoute - " + msg); assertThat(lastOrder.toString()).withFailMessage("BlockOrder").isEqualTo(warrant.getLastOrder().toString()); } @Test public void setThrottleCommands() { warrant.setThrottleCommands(new ArrayList<>()); warrant.addThrottleCommand(new ThrottleSetting(0, "Speed", "0.0", "North")); warrant.addThrottleCommand(new ThrottleSetting(10, "Speed", "0.4", "North")); warrant.addThrottleCommand(new ThrottleSetting(100, "NoOp", "Enter Block", "West")); warrant.addThrottleCommand(new ThrottleSetting(100, "Speed", "0.5", "West")); warrant.addThrottleCommand(new ThrottleSetting(100, "NoOp", "Enter Block", "South")); warrant.addThrottleCommand(new ThrottleSetting(100, "Speed", "0.3", "South")); warrant.addThrottleCommand(new ThrottleSetting(100, "Speed", "0.0", "South")); List list = warrant.getThrottleCommands(); assertThat(list.size()).withFailMessage("ThrottleCommands").isEqualTo(7); } @Test public void testWarrant() throws JmriException { sEast.setState(Sensor.INACTIVE); sSouth.setState(Sensor.INACTIVE); sNorth.setState(Sensor.ACTIVE); // start block of warrant ArrayList orders = new ArrayList<>(); orders.add(new BlockOrder( bNorth, "NorthToWest", "", "NorthWest")); BlockOrder viaOrder = new BlockOrder( bWest, "SouthToNorth", "NorthWest", "SouthWest"); orders.add(viaOrder); BlockOrder lastOrder = new BlockOrder( bSouth, "SouthToWest", "SouthWest", null); orders.add(lastOrder); warrant.setThrottleCommands(new ArrayList<>()); warrant.addThrottleCommand(new ThrottleSetting(0, "Speed", "0.0", "North")); warrant.addThrottleCommand(new ThrottleSetting(10, "Speed", "0.4", "North")); warrant.addThrottleCommand(new ThrottleSetting(100, "NoOp", "Enter Block", "West")); warrant.addThrottleCommand(new ThrottleSetting(100, "Speed", "0.5", "West")); warrant.addThrottleCommand(new ThrottleSetting(100, "NoOp", "Enter Block", "South")); warrant.addThrottleCommand(new ThrottleSetting(100, "Speed", "0.3", "South")); warrant.addThrottleCommand(new ThrottleSetting(100, "Speed", "0.0", "South")); warrant.getSpeedUtil().setAddress("999(L)"); warrant.setBlockOrders(orders); String msg = warrant.allocateRoute(false, orders); assertNull( msg, "allocateRoute - " + msg); warrant.setTrainName("TestTrain"); PropertyChangeListener listener = new WarrantListener(warrant); warrant.addPropertyChangeListener(listener); msg = warrant.setRunMode(Warrant.MODE_RUN, null, null, null, false); assertNull( msg, "setRunMode - " + msg); JUnitUtil.waitFor(() -> { String m = warrant.getRunningMessage(); return m.endsWith("Cmd #2.") || m.endsWith("Cmd #3."); }, "Train starts to move after 2nd command"); ThreadingUtil.runOnLayoutWithJmriException( () -> sWest.setState(Sensor.ACTIVE)); JUnitUtil.waitFor(() -> { return bWest.isOccupied() == true; }, "South not occupied"); ThreadingUtil.runOnLayoutWithJmriException( () -> sSouth.setState(Sensor.ACTIVE)); JUnitUtil.waitFor(() -> { return bSouth.isOccupied() == true; }, "South not occupied"); // wait for done JUnitUtil.waitFor(() -> { return Bundle.getMessage("Idle").equals(warrant.getRunningMessage()); }, "warrant not done"); } protected static boolean atOrPastCommand(Warrant w, int minCmd) { String m = w.getRunningMessage(); if (m == null) return false; int i = m.lastIndexOf("Cmd #"); if (i < 0) return false; String rest = m.substring(i + 5); int dot = rest.indexOf('.'); if (dot < 0) return false; try { return Integer.parseInt(rest.substring(0, dot)) >= minCmd; } catch (NumberFormatException e) { return false; } } protected static class WarrantListener implements PropertyChangeListener { Warrant warrant; WarrantListener(Warrant w) { warrant = w; } @Override public void propertyChange(PropertyChangeEvent e) { // String property = e.getPropertyName(); // System.out.println("propertyChange \""+property+ // "\" old= "+e.getOldValue()+" new= "+e.getNewValue()); assertThat(e.getSource()).withFailMessage("propertyChange").isEqualTo(warrant); // System.out.println(warrant.getRunningMessage()); } } @BeforeEach public void setUp(@TempDir File tempDir) throws IOException { JUnitUtil.setUp(); JUnitUtil.resetProfileManager( new jmri.profile.NullProfile( tempDir)); JUnitUtil.initDebugThrottleManager(); JUnitUtil.initRosterConfigManager(); // setup the warrant preliminaries. _OBlockMgr = InstanceManager.getDefault(OBlockManager.class); bWest = _OBlockMgr.createNewOBlock("OB1", "West"); bEast = _OBlockMgr.createNewOBlock("OB2", "East"); bNorth = _OBlockMgr.createNewOBlock("OB3", "North"); bSouth = _OBlockMgr.createNewOBlock("OB4", "South"); assertNotNull(bWest); assertNotNull(bEast); assertNotNull(bNorth); assertNotNull(bSouth); _portalMgr = InstanceManager.getDefault(PortalManager.class); Portal pNorthWest = _portalMgr.createNewPortal("NorthWest"); pNorthWest.setToBlock(bWest, false); pNorthWest.setFromBlock(bNorth, false); Portal pSouthWest = _portalMgr.createNewPortal("SouthWest"); pSouthWest.setToBlock(bWest, false); pSouthWest.setFromBlock(bSouth, false); Portal pNorthEast = _portalMgr.createNewPortal("NorthEast"); pNorthEast.setToBlock(_OBlockMgr.getOBlock("OB2"), false); pNorthEast.setFromBlock(_OBlockMgr.getOBlock("North"), false); Portal pSouthEast = _portalMgr.createNewPortal("SouthEast"); pSouthEast.setToBlock(bEast, false); pSouthEast.setFromBlock(_OBlockMgr.getOBlock("South"), false); _turnoutMgr = InstanceManager.turnoutManagerInstance(); Turnout northSwitch = _turnoutMgr.newTurnout("IT1", "NorthSwitch"); ArrayList settings = new ArrayList<>(); settings.add(new BeanSetting(northSwitch, "NorthSwitch", Turnout.CLOSED)); OPath path = new OPath("NorthToWest", bNorth, null, _portalMgr.getPortal("NorthWest"), settings); bNorth.addPath(path); settings = new ArrayList<>(); settings.add(new BeanSetting(northSwitch, "NorthSwitch", Turnout.THROWN)); path = new OPath("NorthToEast", bNorth, null, _portalMgr.getPortal("NorthEast"), settings); bNorth.addPath(path); Turnout southSwitch = _turnoutMgr.newTurnout("IT2", "SouthSwitch"); settings = new ArrayList<>(); settings.add(new BeanSetting(southSwitch, "SouthSwitch", Turnout.THROWN)); path = new OPath("SouthToEast", bSouth, null, _portalMgr.getPortal("SouthEast"), settings); bSouth.addPath(path); settings = new ArrayList<>(); settings.add(new BeanSetting(southSwitch, "SouthSwitch", Turnout.CLOSED)); path = new OPath("SouthToWest", bSouth, null, bSouth.getPortalByName("SouthWest"), settings); bSouth.addPath(path); bSouth.setLength(100); settings = new ArrayList<>(); path = new OPath("SouthToNorth", bWest, _portalMgr.getPortal("NorthWest"), _portalMgr.getPortal("SouthWest"), settings); bWest.addPath(path); path.setLength(200); settings = new ArrayList<>(); path = new OPath("NorthToSouth", bEast, bSouth.getPortalByName("SouthEast"), bNorth.getPortalByName("NorthEast"), settings); bEast.addPath(path); _sensorMgr = InstanceManager.getDefault(SensorManager.class); sWest = _sensorMgr.newSensor("IS1", "WestSensor"); sEast = _sensorMgr.newSensor("IS2", "EastSensor"); sNorth = _sensorMgr.newSensor("IS3", "NorthSensor"); sSouth = _sensorMgr.newSensor("IS4", "SouthSensor"); Assertions.assertNotNull(bWest); bWest.setSensor("WestSensor"); Assertions.assertNotNull(bEast); bEast.setSensor("IS2"); Assertions.assertNotNull(bNorth); bNorth.setSensor("NorthSensor"); bSouth.setSensor("IS4"); warrant = new Warrant("IW0", "AllTestWarrant"); WarrantPreferences.getDefault().setShutdown(WarrantPreferences.Shutdown.NO_MERGE); } @AfterEach public void tearDown() { warrant.stopWarrant(true, true); _OBlockMgr = null; _portalMgr = null; _sensorMgr = null; _turnoutMgr = null; bWest = null; bEast = null; bNorth = null; bSouth = null; sWest = null; sEast = null; sNorth = null; sSouth = null; warrant = null; JUnitUtil.tearDown(); } }