Files
JIMRI/java/test/jmri/jmrix/loconet/LnThrottleManagerWithLnPredefinedMetersTest.java
T
2026-06-17 14:00:51 +02:00

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();
}
}