package jmri.jmrit.logix; import java.io.File; import jmri.*; import jmri.jmrit.display.controlPanelEditor.ControlPanelEditor; import jmri.util.JUnitAppender; import jmri.util.JUnitUtil; import jmri.util.swing.JemmyUtil; import jmri.util.ThreadingUtil; import org.junit.jupiter.api.*; import org.junit.jupiter.api.condition.DisabledIfSystemProperty; import org.netbeans.jemmy.operators.JDialogOperator; import org.netbeans.jemmy.operators.JFrameOperator; import org.netbeans.jemmy.operators.JRadioButtonOperator; import static org.junit.jupiter.api.Assertions.*; /** * Tests for the NXFrame class, and its interactions with Warrants. * * @author Pete Cressman 2015 * * TODO - test error conditions */ @Timeout(30) @jmri.util.junit.annotations.DisabledIfHeadless public class NXFrameTest { private OBlockManager _OBlockMgr; private SensorManager _sensorMgr; @Test public void testGetDefault() { NXFrame nxFrame = new NXFrame(); assertNotNull( nxFrame, "NXFrame"); JUnitUtil.dispose(nxFrame); } @Test @DisabledIfSystemProperty(named ="jmri.skipTestsRequiringSeparateRunning", matches ="true") public void testRoutePanel() { NXFrame nxFrame = new NXFrame(); assertNotNull( nxFrame, "NXFrame"); JFrameOperator jfo = new JFrameOperator(nxFrame); ThreadingUtil.runOnGUI( () -> nxFrame.setVisible(true)); JemmyUtil.pressButton(jfo, Bundle.getMessage("Calculate")); JemmyUtil.confirmJOptionPane(jfo, Bundle.getMessage("WarningTitle"), Bundle.getMessage("SetEndPoint", Bundle.getMessage("OriginBlock")), "OK"); nxFrame._origin.blockBox.setText("NowhereBlock"); JemmyUtil.pressButton(jfo, Bundle.getMessage("Calculate")); JemmyUtil.confirmJOptionPane(jfo, Bundle.getMessage("WarningTitle"), Bundle.getMessage("BlockNotFound", "NowhereBlock"), "OK"); JemmyUtil.confirmJOptionPane(jfo, Bundle.getMessage("WarningTitle"), Bundle.getMessage("SetEndPoint", Bundle.getMessage("OriginBlock")), "OK"); jfo.requestClose(); jfo.waitClosed(); } @Test @DisabledIfSystemProperty(named ="jmri.skipTestsRequiringSeparateRunning", matches ="true") public void testNXWarrantSetup() throws JmriException { // load and display File f = new File("java/test/jmri/jmrit/logix/valid/NXWarrantTest.xml"); InstanceManager.getDefault(ConfigureManager.class).load(f); JUnitAppender.suppressErrorMessage("Portal elem = null"); WarrantPreferences.getDefault().setShutdown(WarrantPreferences.Shutdown.NO_MERGE); _OBlockMgr = InstanceManager.getDefault(OBlockManager.class); _sensorMgr = InstanceManager.getDefault(SensorManager.class); NXFrame nxFrame = new NXFrame(); nxFrame.setVisible(true); JFrameOperator nfo = new JFrameOperator(nxFrame); nxFrame.mouseClickedOnBlock(_OBlockMgr.getBySystemName("OB0")); nxFrame._origin.portalBox.setSelectedItem("Enter"); nxFrame.mouseClickedOnBlock(_OBlockMgr.getBySystemName("OB10")); nxFrame._destination.portalBox.setSelectedItem("Exit"); JemmyUtil.pressButton(nfo, Bundle.getMessage("Calculate")); JDialogOperator jdo = new JDialogOperator(nfo,Bundle.getMessage("DialogTitle")); JemmyUtil.pressButton(jdo, Bundle.getMessage("ButtonReview")); JemmyUtil.confirmJOptionPane(nfo, Bundle.getMessage("WarningTitle"), Bundle.getMessage("SelectRoute"), "OK"); // click the third radio button in the dialog JRadioButtonOperator jrbo = new JRadioButtonOperator(jdo,3); jrbo.clickMouse(); // then the Review Button JemmyUtil.pressButton(jdo, Bundle.getMessage("ButtonReview")); // click the 1st radio button in the dialog jrbo = new JRadioButtonOperator(jdo,1); jrbo.clickMouse(); // then the Review Button JemmyUtil.pressButton(jdo, Bundle.getMessage("ButtonReview")); nxFrame._speedUtil.setRampThrottleIncrement(0.05f); JemmyUtil.pressButton(jdo, Bundle.getMessage("ButtonSelect")); nxFrame.setMaxSpeed(2); JemmyUtil.pressButton(nfo, Bundle.getMessage("ButtonRunNX")); JemmyUtil.confirmJOptionPane(nfo, Bundle.getMessage("WarningTitle"), Bundle.getMessage("badSpeed", "2"), "OK"); nxFrame.setMaxSpeed(0.6f); JemmyUtil.pressButton(nfo, Bundle.getMessage("ButtonRunNX")); JemmyUtil.confirmJOptionPane(nfo, Bundle.getMessage("WarningTitle"), Bundle.getMessage("BadDccAddress", ""), "OK"); nxFrame._speedUtil.setAddress("666"); nxFrame.setTrainInfo("Nick"); JemmyUtil.pressButton(nfo, Bundle.getMessage("ButtonRunNX")); nfo.requestClose(); // we may want to use jemmy to close the panel as well. ControlPanelEditor panel = (ControlPanelEditor) jmri.util.JmriJFrame.getFrame("NXWarrantTest"); // disposing this way allows test to be rerun (i.e. reload panel file) multiple times Boolean retVal = ThreadingUtil.runOnGUIwithReturn(() -> { panel.dispose(); return true; }); assertTrue(retVal); // close Warrant Table JFrameOperator jfo = new JFrameOperator(WarrantTableFrame.getDefault()); JUnitUtil.dispose(jfo.getWindow()); jfo.waitClosed(); } @Test @Timeout(60) @DisabledIfSystemProperty(named ="jmri.skipTestsRequiringSeparateRunning", matches ="true") public void testNXWarrant() throws JmriException { // The first part of this test duplicates testNXWarrantSetup(). It // then goes on to test a Warrant through the WarrantTableFrame. // it is the WarrantTableframe portion of this test that hangs. // load and display File f = new File("java/test/jmri/jmrit/logix/valid/NXWarrantTest.xml"); InstanceManager.getDefault(ConfigureManager.class).load(f); JUnitAppender.suppressErrorMessage("Portal elem = null"); WarrantPreferences.getDefault().setShutdown(WarrantPreferences.Shutdown.NO_MERGE); _OBlockMgr = InstanceManager.getDefault(OBlockManager.class); _sensorMgr = InstanceManager.getDefault(SensorManager.class); OBlock block = _OBlockMgr.getBySystemName("OB0"); NXFrame nxFrame = new NXFrame(); ThreadingUtil.runOnGUI( () -> nxFrame.setVisible(true)); JFrameOperator nfo = new JFrameOperator(nxFrame); nxFrame.mouseClickedOnBlock(block); nxFrame._origin.portalBox.setSelectedItem("Enter"); nxFrame.mouseClickedOnBlock(_OBlockMgr.getBySystemName("OB10")); nxFrame._destination.portalBox.setSelectedItem("Exit"); JemmyUtil.pressButton(nfo, Bundle.getMessage("Calculate")); JDialogOperator jdo = new JDialogOperator(nfo,Bundle.getMessage("DialogTitle")); JemmyUtil.pressButton(jdo, Bundle.getMessage("ButtonReview")); JemmyUtil.confirmJOptionPane(nfo, Bundle.getMessage("WarningTitle"), Bundle.getMessage("SelectRoute"), "OK"); // click the third radio button in the dialog JRadioButtonOperator jrbo = new JRadioButtonOperator(jdo,3); jrbo.clickMouse(); // then the Review Button JemmyUtil.pressButton(jdo, Bundle.getMessage("ButtonReview")); // click the 1st radio button in the dialog jrbo = new JRadioButtonOperator(jdo,1); jrbo.clickMouse(); // then the Review Button JemmyUtil.pressButton(jdo, Bundle.getMessage("ButtonReview")); JemmyUtil.pressButton(jdo, Bundle.getMessage("ButtonSelect")); nxFrame._speedUtil.setRampThrottleIncrement(0.05f); nxFrame._speedUtil.setRampTimeIncrement(100); nxFrame.setMaxSpeed(0.6f); nxFrame._speedUtil.setAddress("666"); nxFrame.setTrainInfo("Nick"); JemmyUtil.pressButton(nfo, Bundle.getMessage("ButtonRunNX")); WarrantTableFrame tableFrame = WarrantTableFrame.getDefault(); assertNotNull( tableFrame, "tableFrame"); WarrantTableModel model = tableFrame.getModel(); assertNotNull( model, "tableFrame model"); JUnitUtil.waitFor(() -> model.getRowCount() > 1, "NXWarrant loaded into table"); Warrant warrant = tableFrame.getModel().getWarrantAt(model.getRowCount()-1); assertNotNull( warrant, "warrant"); assertNotNull( warrant.getBlockOrders(), "warrant.getBlockOrders()"); assertEquals( 7, warrant.getBlockOrders().size(),"7 Blocks in Route"); assertTrue( warrant.getThrottleCommands().size()>5 , "Num Comands"); assertNotNull(block); String name = block.getDisplayName(); JUnitUtil.waitFor(()->{ return warrant.getRunningMessage().equals(Bundle.getMessage("waitForDelayStart", warrant.getTrainName(), name));}, "Waiting message"); Sensor sensor0 = _sensorMgr.getBySystemName("IS0"); assertNotNull( sensor0, "Senor IS0 not found"); NXFrameTest.setAndConfirmSensorAction(sensor0, Sensor.ACTIVE, block); final OBlock testblock = block; JUnitUtil.waitFor(() -> { return ((testblock.getState() & (OBlock.ALLOCATED | OBlock.OCCUPIED)) != 0); }, "Start Block Active"); JUnitUtil.waitFor(() -> { JUnitUtil.waitFor(200); return Bundle.getMessage("RampHalt", warrant.getTrainName(), testblock.getDisplayName()).equals(warrant.getRunningMessage()); }, "Warrant processed sensor change"); ThreadingUtil.runOnGUI(() -> { warrant.controlRunTrain(Warrant.RESUME); }); JUnitUtil.waitFor(() -> WarrantTest.atOrPastCommand(warrant, 8), "Train starts to move at 8th command"); // OBlock sensor names String[] route = {"OB0", "OB1", "OB2", "OB3", "OB7", "OB5", "OB10"}; block = _OBlockMgr.getOBlock("OB10"); assertNotNull(block); Sensor sb10 = block.getSensor(); assertNotNull(sb10); // runtimes() in next line runs the train, then checks location assertEquals( sb10.getDisplayName(), runtimes(route, _OBlockMgr).getDisplayName(), "Train in last block"); ThreadingUtil.runOnGUI(() -> { warrant.controlRunTrain(Warrant.ABORT); }); // passed test - cleanup. Do it here so failure leaves traces. JFrameOperator jfo = new JFrameOperator(tableFrame); jfo.requestClose(); jfo.waitClosed(); // we may want to use jemmy to close the panel as well. ControlPanelEditor panel = (ControlPanelEditor) jmri.util.JmriJFrame.getFrame("NXWarrantTest"); // disposing this way allows test to be rerun (i.e. reload panel file) multiple times Boolean retVal = jmri.util.ThreadingUtil.runOnGUIwithReturn(() -> { panel.dispose(); return true; }); assertTrue(retVal); // close Create eNtry/eXit Warrant JUnitUtil.dispose(nxFrame); jfo.waitClosed(); } @Test @DisabledIfSystemProperty(named ="jmri.skipTestsRequiringSeparateRunning", matches ="true") public void testWarrantLoopRun() throws JmriException { // load and display File f = new File("java/test/jmri/jmrit/logix/valid/NXWarrantTest.xml"); InstanceManager.getDefault(ConfigureManager.class).load(f); JUnitAppender.suppressErrorMessage("Portal elem = null"); WarrantPreferences.getDefault().setShutdown(WarrantPreferences.Shutdown.NO_MERGE); _OBlockMgr = InstanceManager.getDefault(OBlockManager.class); _sensorMgr = InstanceManager.getDefault(SensorManager.class); Sensor sensor3 = _sensorMgr.getBySystemName("IS3"); assertNotNull( sensor3, "Senor IS3 not found"); NXFrameTest.setAndConfirmSensorAction(sensor3, Sensor.ACTIVE, _OBlockMgr.getBySystemName("OB3")); WarrantTableFrame tableFrame = WarrantTableFrame.getDefault(); assertNotNull( tableFrame, "tableFrame"); Warrant warrant = tableFrame.getModel().getWarrantAt(0); assertNotNull( warrant, "warrant"); tableFrame.runTrain(warrant, Warrant.MODE_RUN); JUnitUtil.waitFor(() -> WarrantTest.atOrPastCommand(warrant, 3), "Train is moving at 3rd command"); // OBlock sensor names String[] route = {"OB3", "OB4", "OB5", "OB10", "OB0", "OB1", "OB2", "OB3"}; OBlock block = _OBlockMgr.getOBlock("OB3"); assertNotNull(block); Sensor sb3 = block.getSensor(); assertNotNull(sb3); // runtimes() in next line runs the train, then checks location assertEquals( sb3.getDisplayName(), runtimes(route, _OBlockMgr).getDisplayName(), "Train in last block"); // passed test - cleanup. Do it here so failure leaves traces. warrant.dispose(); JFrameOperator jfo = new JFrameOperator(tableFrame); jfo.requestClose(); jfo.waitClosed(); // we may want to use jemmy to close the panel as well. ControlPanelEditor panel = (ControlPanelEditor) jmri.util.JmriJFrame.getFrame("NXWarrantTest"); // disposing this way allows test to be rerun (i.e. reload panel file) multiple times Boolean retVal = jmri.util.ThreadingUtil.runOnGUIwithReturn(() -> { panel.dispose(); return true; }); assertTrue(retVal); JUnitUtil.waitThreadTerminated("Loop Killer"); } @Test @DisabledIfSystemProperty(named ="jmri.skipTestsRequiringSeparateRunning", matches ="true") public void testWarrantRampHalt() throws JmriException { // load and display File f = new File("java/test/jmri/jmrit/logix/valid/NXWarrantTest.xml"); InstanceManager.getDefault(ConfigureManager.class).load(f); JUnitAppender.suppressErrorMessage("Portal elem = null"); WarrantPreferences.getDefault().setShutdown(WarrantPreferences.Shutdown.NO_MERGE); _OBlockMgr = InstanceManager.getDefault(OBlockManager.class); _sensorMgr = InstanceManager.getDefault(SensorManager.class); Sensor sensor1 = _sensorMgr.getBySystemName("IS1"); assertNotNull( sensor1, "Senor IS1 not found"); NXFrameTest.setAndConfirmSensorAction(sensor1, Sensor.ACTIVE, _OBlockMgr.getBySystemName("OB1")); WarrantTableFrame tableFrame = WarrantTableFrame.getDefault(); assertNotNull( tableFrame, "tableFrame"); Warrant warrant = tableFrame.getModel().getWarrantAt(1); assertNotNull( warrant, "warrant"); tableFrame.runTrain(warrant, Warrant.MODE_RUN); SpeedUtil sp = warrant.getSpeedUtil(); sp.setRampThrottleIncrement(0.15f); sp.setRampTimeIncrement(100); JUnitUtil.waitFor(() -> WarrantTest.atOrPastCommand(warrant, 8), "Train starts to move at 8th command"); // OBlock sensor names String[] route1 = {"OB1", "OB6", "OB3"}; final OBlock block3 = _OBlockMgr.getOBlock("OB3"); assertNotNull(block3); Sensor sb3 = block3.getSensor(); assertNotNull(sb3); // runtimes() in next line runs the train, then checks location assertEquals( sb3.getDisplayName(), runtimes(route1,_OBlockMgr).getDisplayName(), "Train in block OB3"); warrant.controlRunTrain(Warrant.HALT); // user interrupts script JUnitUtil.waitFor(100); // waitEmpty(10) causes a lot of failures on Travis GUI JUnitUtil.waitFor(() -> { String m = warrant.getRunningMessage(); return (m.equals(Bundle.getMessage("RampHalt", warrant.getTrainName(), block3.getDisplayName()))); }, "Train Halted"); warrant.controlRunTrain(Warrant.RESUME); JUnitUtil.waitFor(() -> { String m = warrant.getRunningMessage(); if ( m == null ) { return false; } return m.startsWith("At speed Normal") || m.startsWith("Overdue for arrival at block"); }, "Train Resumed"); String[] route2 = {"OB3", "OB7", "OB5"}; OBlock block5 = _OBlockMgr.getOBlock("OB5"); assertNotNull(block5); Sensor sb5 = block5.getSensor(); assertNotNull(sb5); // runtimes() in next line runs the train, then checks location assertEquals( sb5.getDisplayName(), runtimes(route2, _OBlockMgr).getDisplayName(), "Train in last block"); // passed test - cleanup. Do it here so failure leaves traces. warrant.dispose(); JFrameOperator jfo = new JFrameOperator(tableFrame); jfo.requestClose(); jfo.waitClosed(); // we may want to use jemmy to close the panel as well. ControlPanelEditor panel = (ControlPanelEditor) jmri.util.JmriJFrame.getFrame("NXWarrantTest"); // disposing this way allows test to be rerun (i.e. reload panel file) multiple times Boolean retVal = jmri.util.ThreadingUtil.runOnGUIwithReturn(() -> { panel.dispose(); return true; }); assertTrue(retVal); JUnitUtil.waitThreadTerminated("RampHalt Killer"); } /** * Simulates the movement of a warranted train over its route. *
Works through a list of OBlocks, gets its sensor, * activates it, then inactivates the previous OBlock sensor. * Leaves last sensor ACTIVE to show the train stopped there. * @param route Array of OBlock names of the route * @param mgr OBLock manager * @return active end sensor */ protected static Sensor runtimes(String[] route, OBlockManager mgr) { Sensor sensor = null; for (int i = 1; i < route.length; i++) { sensor = moveToNextBlock(i, route, mgr); } return sensor; } /** * Simulates the movement of a warranted train over its route. *
Works through a list of OBlocks, gets its sensor, * activates it, then inactivates the previous OBlock sensor. * Leaves last sensor ACTIVE to show the train stopped there. * @param route Array of OBlock names of the route * @param penultimateBlockSensor the Sensor to set active when train in the penultimate block of the route. * @param penultimateBlock the OBlock to ensure occupied when the penultimateBlockSensor goes active. * @param mgr OBLock manager * @return active end sensor */ protected static Sensor runtimesActionPenultimate(String[] route, Sensor penultimateBlockSensor, String penultimateBlock, OBlockManager mgr) { Sensor sensor = null; for (int i = 1; i < route.length; i++) { if ( i == route.length-2 ) { // penultimate OBlock of route setAndConfirmSensorAction(penultimateBlockSensor, Sensor.ACTIVE, mgr.getBySystemName(penultimateBlock)); } sensor = moveToNextBlock(i, route, mgr); } return sensor; } protected static Sensor moveToNextBlock(int idx, String[] route, OBlockManager mgr) { assertTrue( idx > 0 && idx < route.length , "Index "+ idx + " invalid "); OBlock fromBlock = mgr.getOBlock(route[idx - 1]); assertNotNull(fromBlock); Sensor fromSensor = fromBlock.getSensor(); assertNotNull( fromSensor, "fromSensor not found"); OBlock toBlock = mgr.getOBlock(route[idx]); assertNotNull(toBlock); Sensor toSensor = toBlock.getSensor(); assertNotNull( toSensor, "toSensor not found"); JUnitUtil.waitFor(300); NXFrameTest.setAndConfirmSensorAction(toSensor, Sensor.ACTIVE, toBlock); JUnitUtil.waitFor(200); NXFrameTest.setAndConfirmSensorAction(fromSensor, Sensor.INACTIVE, fromBlock); return toSensor; } protected static void setAndConfirmSensorAction(final Sensor sensor, final int state, final OBlock b) { if (state == Sensor.ACTIVE) { ThreadingUtil.runOnLayout(() -> setSensor(sensor, Sensor.ACTIVE)); JUnitUtil.waitFor(() -> { return (b.getState() & OBlock.OCCUPIED) != 0; }, b.getDisplayName() + " occupied"); } else if (state == Sensor.INACTIVE) { ThreadingUtil.runOnLayout(() -> setSensor(sensor, Sensor.INACTIVE)); JUnitUtil.waitFor(() -> { return (b.getState() & OBlock.OCCUPIED) == 0; }, b.getDisplayName() + " unoccupied"); } } private static void setSensor( Sensor sensor, int state ) { assertDoesNotThrow( () -> sensor.setState(state), () -> "Exception setting Sensor " + sensor + " to " + sensor.describeState(state)); } @BeforeEach public void setUp() { JUnitUtil.setUp(); JUnitUtil.resetInstanceManager(); JUnitUtil.resetProfileManager(); JUnitUtil.initConfigureManager(); JUnitUtil.initInternalTurnoutManager(); JUnitUtil.initInternalLightManager(); JUnitUtil.initInternalSensorManager(); JUnitUtil.initInternalSignalHeadManager(); JUnitUtil.initLayoutBlockManager(); JUnitUtil.initDebugPowerManager(); JUnitUtil.initDebugThrottleManager(); JUnitUtil.initMemoryManager(); JUnitUtil.initOBlockManager(); JUnitUtil.initLogixManager(); JUnitUtil.initConditionalManager(); WarrantPreferences.getDefault().setShutdown(WarrantPreferences.Shutdown.NO_MERGE); JUnitUtil.initWarrantManager(); } @AfterEach public void tearDown() { JUnitUtil.removeMatchingThreads("Engineer("); JUnitUtil.deregisterBlockManagerShutdownTask(); InstanceManager.getDefault(WarrantManager.class).dispose(); JUnitUtil.tearDown(); } }