204 lines
7.7 KiB
Java
204 lines
7.7 KiB
Java
package jmri.jmrix.loconet;
|
|
|
|
import jmri.*;
|
|
import jmri.util.JUnitUtil;
|
|
|
|
import org.junit.jupiter.api.*;
|
|
|
|
/**
|
|
*
|
|
* This test class is adapted from LnThrottleManagerTest
|
|
* for tests which require both LnThrottleManager AND LnPredefinedMeters.
|
|
* LnPredefinedMeters is disabled in LnThrottleManagerTest for test reliability.
|
|
* @author Paul Bender, Copyright (C) 2017
|
|
* @author B. Milhaupt, Copyright (C) 2018
|
|
* @author Steve Young, Copyright (C) 2025
|
|
*/
|
|
public class LnThrottleManagerWithLnPredefinedMetersTest {
|
|
|
|
private LocoNetInterfaceScaffold lnis;
|
|
private LocoNetSystemConnectionMemo memo;
|
|
private ThrottleManager tm;
|
|
|
|
/**
|
|
* See LnThrottleManagerTest testShareSingleLnThrottleScenario1.
|
|
* Ensures that slot reads are requested following Throttle dispose.
|
|
*/
|
|
@Test
|
|
public void testShareSingleLnThrottleScenario1() {
|
|
// test case:
|
|
// . acquire loco X to "throttle"
|
|
// . acquire loco X to "throttle2"
|
|
// . set speed for loco X
|
|
// . dispatch "throttle2"
|
|
// . release "throttle2"
|
|
// . release "throttle"
|
|
// . . wait for Slot Read
|
|
|
|
ThrottleListen throtListen = new ThrottleListen();
|
|
ThrottleListen throtListen2 = new ThrottleListen();
|
|
|
|
tm.requestThrottle(260, throtListen, true);
|
|
|
|
memo.getSlotManager().message(lnis.outbound.elementAt(lnis.outbound.size()-1));
|
|
|
|
LocoNetMessage cmdStationReply = new LocoNetMessage(new int[] {
|
|
0xe7, 0x0e, 0x9, 0x00, 0x04, 0x0, 0x0, 0x7, 0x0, 0x02, 0x00, 0x00, 0x00, 0x53}); // slot is free
|
|
lnis.sendTestMessage(cmdStationReply);
|
|
|
|
cmdStationReply = new LocoNetMessage(new int[] {
|
|
0xe7, 0x0e, 0x9, 0x30, 0x04, 0x0, 0x0, 0x7, 0x0, 0x02, 0x00, 0x00, 0x00, 0x53}); // slot is in-use no throttle ID
|
|
lnis.sendTestMessage(cmdStationReply);
|
|
|
|
JUnitUtil.waitFor( () -> "EF 0E 09 30 04 00 00 07 00 02 00 71 02 00".equals(
|
|
(lnis.outbound.elementAt(lnis.outbound.size()-1).toString())),
|
|
"Write Throttle ID");
|
|
|
|
tm.requestThrottle(260, throtListen2, true); // An additional user of the same throttle
|
|
|
|
throtListen.getThrottle().setSpeedSetting(0.5f);
|
|
|
|
lnis.outbound.clear();
|
|
tm.releaseThrottle(throtListen2.getThrottle(), throtListen2);
|
|
tm.releaseThrottle(throtListen.getThrottle(), throtListen);
|
|
|
|
// Wait for 2 messages, the set slot common and then the get slot refresh
|
|
JUnitUtil.waitFor(() -> {
|
|
return !lnis.outbound.isEmpty();
|
|
},"wait for message");
|
|
JUnitUtil.waitFor(() -> {
|
|
return !lnis.outbound.elementAt(lnis.outbound.size() -1).toString().equals("B5 09 10 00");
|
|
}, "COMMON");
|
|
JUnitUtil.waitFor(() -> {
|
|
return !lnis.outbound.elementAt(lnis.outbound.size() -1).toString().equals("BB 09 00 00");
|
|
}, "Slot read");
|
|
}
|
|
|
|
/**
|
|
* See LnThrottleManagerTest testShareSingleLnThrottleScenario2.
|
|
* Ensures that slot reads are requested following Throttle dispose.
|
|
*/
|
|
@Test
|
|
public void testShareSingleLnThrottleScenario2() {
|
|
// test case:
|
|
// . acquire loco X to "throttle"
|
|
// . acquire loco X to "throttle2"
|
|
// . dispatch "throttle2"
|
|
// . release "throttle"
|
|
// . release "throttle2"
|
|
// . . wait for Slot Read
|
|
|
|
ThrottleListen throtListen = new ThrottleListen();
|
|
ThrottleListenStealWhenDecision throtListen2 = new ThrottleListenStealWhenDecision();
|
|
|
|
tm.requestThrottle(260, throtListen, true);
|
|
|
|
memo.getSlotManager().message(lnis.outbound.elementAt(lnis.outbound.size()-1));
|
|
|
|
LocoNetMessage cmdStationReply = new LocoNetMessage(new int[] {
|
|
0xe7, 0x0e, 0x9, 0x00, 0x04, 0x0, 0x0, 0x7, 0x0, 0x02, 0x00, 0x13, 0x01, 0x53}); // slot is in-use
|
|
lnis.sendTestMessage(cmdStationReply);
|
|
|
|
// send it to INUSE
|
|
cmdStationReply = new LocoNetMessage(new int[] {
|
|
0xe7, 0x0e, 0x09, 0x30, 0x04, 0x0, 0x0, 0x7, 0x0, 0x02, 0x00, 0x00, 0x00, 0x53}); // slot is in-use
|
|
lnis.sendTestMessage(cmdStationReply);
|
|
|
|
tm.requestThrottle(260, throtListen2, true); // An additional user of the same throttle
|
|
|
|
tm.dispatchThrottle(throtListen2.getThrottle(), throtListen2); // this fails as loco is in use on multiple throttles
|
|
tm.releaseThrottle(throtListen.getThrottle(), throtListen);
|
|
|
|
//reset outbound.
|
|
lnis.outbound.clear();
|
|
tm.dispatchThrottle(throtListen2.getThrottle(), throtListen2);
|
|
|
|
// Wait for 3 messages, the set slot common and then the get slot refresh
|
|
JUnitUtil.waitFor(() -> {
|
|
return !lnis.outbound.isEmpty();
|
|
},"wait for message");
|
|
JUnitUtil.waitFor(() -> {
|
|
return !lnis.outbound.elementAt(lnis.outbound.size() -1).toString().equals("B5 09 10 00");
|
|
}, "COMMON");
|
|
JUnitUtil.waitFor(() -> {
|
|
return !lnis.outbound.elementAt(lnis.outbound.size() -1).toString().equals("BA 09 00 00");
|
|
}, "DISPATCH");
|
|
JUnitUtil.waitFor(() -> {
|
|
return !lnis.outbound.elementAt(lnis.outbound.size() -1).toString().equals("BB 09 00 00");
|
|
}, "Slot read");
|
|
|
|
}
|
|
|
|
private class ThrottleListen implements ThrottleListener {
|
|
|
|
private DccThrottle foundThrottle = null;
|
|
|
|
@Override
|
|
public void notifyThrottleFound(DccThrottle t){
|
|
foundThrottle = t;
|
|
}
|
|
|
|
@Override
|
|
public void notifyFailedThrottleRequest(LocoAddress address, String reason){
|
|
// do nothing
|
|
}
|
|
|
|
@Override
|
|
public void notifyDecisionRequired(LocoAddress address, ThrottleListener.DecisionType question) {
|
|
// does nothing
|
|
}
|
|
|
|
DccThrottle getThrottle() {
|
|
return foundThrottle;
|
|
}
|
|
|
|
}
|
|
|
|
// this is an always-stealing implementation.
|
|
private class ThrottleListenStealWhenDecision extends ThrottleListen {
|
|
|
|
@Override
|
|
public void notifyDecisionRequired(LocoAddress address, ThrottleListener.DecisionType question) {
|
|
if ( question == ThrottleListener.DecisionType.STEAL ){
|
|
tm.responseThrottleDecision(address, this, ThrottleListener.DecisionType.STEAL );
|
|
}
|
|
}
|
|
}
|
|
|
|
@BeforeEach
|
|
public void setUp() {
|
|
JUnitUtil.setUp();
|
|
memo = new LocoNetSystemConnectionMemo();
|
|
lnis = new LocoNetInterfaceScaffold(memo);
|
|
memo.setLnTrafficController(lnis);
|
|
memo.configureCommandStation(LnCommandStationType.COMMAND_STATION_DCS100, false, false, false, false, false);
|
|
memo.getSlotManager().pmManagerGotReply=true; //turn off more probing by saying done.
|
|
memo.configureManagers(); // lnThrottleManager created by memo + added to instancemanager here
|
|
tm = memo.get(ThrottleManager.class);
|
|
memo.getSensorManager().dispose(); // get rid of sensor manager to prevent it from sending interrogation messages
|
|
memo.getPowerManager().dispose(); // get rid of power manager to prevent it from sending slot 0 read message
|
|
// Unlike LnThrottleManagerTest we keep the PredefinedMeters so it can read slots.
|
|
}
|
|
|
|
@AfterEach
|
|
public void tearDown() {
|
|
|
|
memo.getPredefinedMeters().dispose();
|
|
|
|
LocoNetThrottledTransmitter.ServiceThread theServiceThread = memo.tm.theServiceThread;
|
|
tm.dispose();
|
|
memo.dispose();
|
|
if ( theServiceThread != null ) {
|
|
// wait for LocoNetThrottledTransmitter to terminate
|
|
JUnitUtil.waitThreadTerminated(theServiceThread);
|
|
}
|
|
if ( lnis != null ) {
|
|
lnis.dispose();
|
|
}
|
|
lnis = null;
|
|
JUnitUtil.deregisterBlockManagerShutdownTask();
|
|
JUnitUtil.tearDown();
|
|
}
|
|
|
|
}
|