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

822 lines
39 KiB
Java

package jmri.jmrix.loconet;
import jmri.*;
import jmri.jmrit.roster.RosterEntry;
import jmri.util.JUnitUtil;
import jmri.util.junit.annotations.*;
import jmri.util.JUnitAppender;
import org.junit.jupiter.api.*;
import static org.junit.jupiter.api.Assertions.*;
/**
*
* @author Paul Bender Copyright (C) 2017
* @author B. Milhaupt, Copyright (C) 2018
*/
public class LnThrottleManagerTest extends jmri.managers.AbstractThrottleManagerTestBase {
@Test
@Override
@Disabled("parent class test requires further setup")
@ToDo("complete initialization and remove this overridden method so that the parent class test can run")
public void testGetThrottleInfo() {
}
// this is an always-stealing implementation.
private class ThrottleListenStealWhenDecision extends ThrottleListen {
@Override
public void notifyDecisionRequired(LocoAddress address, DecisionType question) {
if ( question == DecisionType.STEAL ){
flagGotStealRequest = address.getNumber();
log.debug("going to steal loco {}", address);
tm.responseThrottleDecision(address, this, DecisionType.STEAL );
}
}
}
@Test
public void testCreateLnThrottleRunAndRelease() {
ThrottleListen throtListen = new ThrottleListen(); // this is a never-stealing implementation.
tm.requestThrottle(1203, throtListen,true);
assertEquals( "BF 09 33 00",
lnis.outbound.elementAt(lnis.outbound.size() - 1).toString(), "address request message");
LocoNetMessage cmdStationReply = new LocoNetMessage(new int[] {
0xe7, 0x0e, 0x11, 0x00, 0x33, 0x0, 0x0, 0x7, 0x0, 0x09, 0x0, 0x0, 0x0, 0x53});
lnis.sendTestMessage(cmdStationReply);
assertEquals( "BA 11 11 00",
lnis.outbound.elementAt(lnis.outbound.size() - 1).toString(), "null move");
cmdStationReply = new LocoNetMessage(new int[] {
0xe7, 0x0e, 0x11, 0x30, 0x33, 0x0, 0x0, 0x7, 0x0, 0x09, 0x0, 0x0, 0x0, 0x00});
lnis.sendTestMessage(cmdStationReply);
assertEquals( "EF 0E 11 30 33 00 00 07 00 09 00 71 02 00",
lnis.outbound.elementAt(lnis.outbound.size() - 1).toString(), "write Throttle ID");
cmdStationReply = new LocoNetMessage(new int[] {
0xb4, 0x6f, 0x7f, 0x5B});
lnis.sendTestMessage(cmdStationReply);
DccThrottle throttle = throtListen.getThrottle();
Assertions.assertNotNull(throttle, "have created a throttle");
Assertions.assertTrue(throttle.getClass() == LocoNetThrottle.class,"is LnThrottle");
Assertions.assertEquals( 0x171, ((LocoNetThrottle) throttle).slot.id(), "throttleId is set");
throttle.setSpeedSetting(0.125f);
assertEquals( "A0 11 1A 00",
lnis.outbound.elementAt(lnis.outbound.size() - 1).toString(), "set speed to one eighth");
throttle.release(throtListen);
JUnitUtil.waitFor(()->{return 4 < lnis.outbound.size();},"didn't get the 6th LocoNet message");
assertEquals( "B5 11 10 00",
lnis.outbound.elementAt(lnis.outbound.size() - 1).toString(), "slot is set to 'common' status");
}
@Test
public void testCreateLnThrottleRunAndDispatch() {
ThrottleListen throtListen = new ThrottleListen();
tm.requestThrottle(1204, throtListen, true);
assertEquals( "BF 09 34 00",
lnis.outbound.elementAt(lnis.outbound.size() - 1).toString(), "address request message");
memo.getSlotManager().message(lnis.outbound.elementAt(lnis.outbound.size()-1));
assertEquals( 1, lnis.outbound.size(), "count is incorrect");
LocoNetMessage cmdStationReply = new LocoNetMessage(new int[] {
0xe7, 0x0e, 0x11, 0x00, 0x34, 0x0, 0x0, 0x7, 0x0, 0x09, 0x0, 0x0, 0x0, 0x53});
lnis.sendTestMessage(cmdStationReply);
memo.getSlotManager().message(lnis.outbound.elementAt(1));
assertEquals( 2, lnis.outbound.size(), "count is correct");
assertEquals( "BA 11 11 00",
lnis.outbound.elementAt(lnis.outbound.size() - 1).toString(), "Throttle manager sends a 'null move'");
memo.getSlotManager().message(lnis.outbound.elementAt(lnis.outbound.size()-1));
cmdStationReply = new LocoNetMessage(new int[] {
0xe7, 0x0e, 0x11, 0x30, 0x34, 0x0, 0x0, 0x7, 0x0, 0x09, 0x0, 0x0, 0x0, 0x00});
lnis.sendTestMessage(cmdStationReply);
assertEquals( "EF 0E 11 30 34 00 00 07 00 09 00 71 02 00",
lnis.outbound.elementAt(2).toString(), "write Throttle ID");
memo.getSlotManager().message(lnis.outbound.elementAt(lnis.outbound.size()-1));
cmdStationReply = new LocoNetMessage(new int[] {
0xb4, 0x6f, 0x7f, 0x5B});
lnis.sendTestMessage(cmdStationReply);
memo.getSlotManager().message(lnis.outbound.elementAt(lnis.outbound.size()-1));
DccThrottle throttle = throtListen.getThrottle();
assertNotNull(throttle, "have created a throttle");
assertTrue(throttle.getClass() == LocoNetThrottle.class,"is LnThrottle");
assertEquals( 0x171, ((LocoNetThrottle) throttle).slot.id(), "throttleId is set");
throttle.setSpeedSetting(0.125f);
assertEquals( "A0 11 1A 00",
lnis.outbound.elementAt(3).toString(), "set speed to one eighth");
memo.getSlotManager().message(lnis.outbound.elementAt(3));
assertEquals( 26, memo.getSlotManager()._slots[17].speed(), "check that speed was set");
throttle.dispatch(throtListen);
assertEquals( "B5 11 10 00",
lnis.outbound.elementAt(4).toString(), "slot is set to 'common' status");
assertEquals( "BA 11 00 00",
lnis.outbound.elementAt(5).toString(), "Expect the slot to be dispatched");
// common is sent twice due to the way the release works.
assertEquals( "B5 11 10 00",
lnis.outbound.elementAt(6).toString(), "slot is set to 'common' status");
JUnitUtil.waitFor(()->{return 6 < lnis.outbound.size();},"didn't get the 5th LocoNet message");
assertEquals( 6, lnis.outbound.size()-1, "check count of sent messages");
assertEquals( 26, memo.getSlotManager()._slots[17].speed(), "slot speed not zeroed");
}
@Test
public void testCreateLnThrottleRunAndDispose() {
ThrottleListen throtListen = new ThrottleListen();
tm.requestThrottle(1203, throtListen, true);
assertEquals( "BF 09 33 00",
lnis.outbound.elementAt(lnis.outbound.size() - 1).toString(), "address request message");
memo.getSlotManager().message(lnis.outbound.elementAt(lnis.outbound.size()-1));
assertEquals( 1, lnis.outbound.size(), "count is correct");
LocoNetMessage cmdStationReply = new LocoNetMessage(new int[] {
0xe7, 0x0e, 0x11, 0x00, 0x33, 0x0, 0x0, 0x7, 0x0, 0x09, 0x0, 0x0, 0x0, 0x53});
lnis.sendTestMessage(cmdStationReply);
assertEquals( "BA 11 11 00",lnis.outbound.elementAt(1).toString(),
"Correct message sent");
memo.getSlotManager().message(lnis.outbound.elementAt(1));
assertEquals( 2, lnis.outbound.size(), "count is correct");
assertEquals( "BA 11 11 00",
lnis.outbound.elementAt(lnis.outbound.size() - 1).toString(),
"Throttle manager sends a 'null move'");
memo.getSlotManager().message(lnis.outbound.elementAt(lnis.outbound.size()-1));
cmdStationReply = new LocoNetMessage(new int[] {
0xe7, 0x0e, 0x11, 0x30, 0x33, 0x0, 0x0, 0x7, 0x0, 0x09, 0x0, 0x0, 0x0, 0x00});
lnis.sendTestMessage(cmdStationReply);
assertEquals( "EF 0E 11 30 33 00 00 07 00 09 00 71 02 00",
lnis.outbound.elementAt(2).toString(), "write Throttle ID");
memo.getSlotManager().message(lnis.outbound.elementAt(lnis.outbound.size()-1));
cmdStationReply = new LocoNetMessage(new int[] {
0xb4, 0x6f, 0x7f, 0x5B});
lnis.sendTestMessage(cmdStationReply);
memo.getSlotManager().message(lnis.outbound.elementAt(lnis.outbound.size()-1));
DccThrottle throttle = throtListen.getThrottle();
Assertions.assertNotNull(throttle, "have created a throttle");
Assertions.assertTrue(throttle.getClass() == LocoNetThrottle.class,"is LnThrottle");
Assertions.assertEquals( 0x171, ((LocoNetThrottle) throttle).slot.id(), "throttleId is set");
throttle.setSpeedSetting(0.125f);
JUnitUtil.waitFor(()->{return 3 < lnis.outbound.size();},"didn't get the 4th LocoNet message");
assertEquals( "A0 11 1A 00",
lnis.outbound.elementAt(3).toString(), "set speed to one eighth");
memo.getSlotManager().message(lnis.outbound.elementAt(3));
assertEquals( 26, memo.getSlotManager()._slots[17].speed(), "check that speed was set");
((LocoNetThrottle)throttle).throttleDispose();
JUnitUtil.waitFor(()->{return 4 < lnis.outbound.size();},"didn't get the 5th LocoNet message");
assertEquals( "B5 11 10 00",
lnis.outbound.elementAt(4).toString(), "slot is set to 'common' status");
memo.getSlotManager().message(lnis.outbound.elementAt(4));
assertTrue( 5<=lnis.outbound.size(), "check count of sent messages");
assertEquals( 26, memo.getSlotManager()._slots[17].speed(), "slot speed not zeroed");
}
@Test
public void testCreateLnThrottleStealScenario1() {
ThrottleListen throtListen = new ThrottleListen();
tm.requestThrottle(129, throtListen, true);
assertEquals( "BF 01 01 00",
lnis.outbound.elementAt(lnis.outbound.size() - 1).toString(), "address request message");
memo.getSlotManager().message(lnis.outbound.elementAt(lnis.outbound.size()-1));
assertEquals( 1, lnis.outbound.size(), "count is correct");
LocoNetMessage cmdStationReply = new LocoNetMessage(new int[] {
0xe7, 0x0e, 0x11, 0x30, 0x01, 0x0, 0x0, 0x7, 0x0, 0x01, 0x0, 0x0, 0x1, 0x53}); // slot is in-use
lnis.sendTestMessage(cmdStationReply);
assertEquals( 129, throtListen.getFlagGotStealRequest(), "Got a steal request");
JUnitAppender.assertWarnMessage("slot 17 address 129 is already in-use.");
assertNull(throtListen.getThrottle());
}
@Test
public void testCreateLnThrottleStealScenario2() {
ThrottleListen throtListen = new ThrottleListen();
tm.requestThrottle(5, throtListen, true);
assertEquals( "BF 00 05 00",
lnis.outbound.elementAt(lnis.outbound.size() - 1).toString(), "address request message");
memo.getSlotManager().message(lnis.outbound.elementAt(lnis.outbound.size()-1));
assertEquals( 1, lnis.outbound.size(), "count is correct");
LocoNetMessage cmdStationReply = new LocoNetMessage(new int[] {
0xe7, 0x0e, 0x0c, 0x30, 0x05, 0x0, 0x0, 0x7, 0x0, 0x00, 0x0, 0x2, 0x0, 0x53}); // slot is in-use
lnis.sendTestMessage(cmdStationReply);
assertEquals( 5, throtListen.getFlagGotStealRequest(), "Got a steal request");
JUnitAppender.assertWarnMessage("slot 12 address 5 is already in-use.");
Assertions.assertNull(throtListen.getThrottle());
}
@Test
public void testCreateLnThrottleStealScenario3() {
ThrottleListen throtListen = new ThrottleListen();
tm.requestThrottle(85, throtListen, true);
assertEquals("BF 00 55 00",
lnis.outbound.elementAt(lnis.outbound.size() - 1).toString(), "address request message");
memo.getSlotManager().message(lnis.outbound.elementAt(lnis.outbound.size()-1));
// Throttle request messages may be missed on 1st send so we wait for
// the 2nd message sent ( in 5.13.5 it's 1000ms after the 1st)
JUnitUtil.waitFor( () -> lnis.outbound.size() == 2, "throttle request repeated");
assertEquals( lnis.outbound.get(0), lnis.outbound.get(1), "2nd request matches 1st" );
LocoNetMessage cmdStationReply = new LocoNetMessage(new int[] {
0xe7, 0x0e, 0x60, 0x30, 0x55, 0x0, 0x0, 0x7, 0x0, 0x00, 0x0, 0x2, 0x70, 0x53}); // slot is in-use
lnis.sendTestMessage(cmdStationReply);
assertEquals(85, throtListen.getFlagGotStealRequest(), "Got a steal request");
JUnitAppender.assertWarnMessage("slot 96 address 85 is already in-use.");
}
@Test
public void testCreateLnThrottleStealScenario4() {
ThrottleListenStealWhenDecision throtListen = new ThrottleListenStealWhenDecision();
Assertions.assertNull(throtListen.getThrottle());
tm.requestThrottle(256, throtListen, true);
assertEquals( "BF 02 00 00",
lnis.outbound.elementAt(lnis.outbound.size() - 1).toString(), "address request message");
memo.getSlotManager().message(lnis.outbound.elementAt(lnis.outbound.size()-1));
// Throttle request messages may be missed on 1st send so we wait for
// the 2nd message sent ( in 5.13.5 it's 1000ms after the 1st)
JUnitUtil.waitFor( () -> lnis.outbound.size() == 2, "throttle request repeated");
assertEquals( lnis.outbound.get(0), lnis.outbound.get(1), "2nd request matches 1st" );
LocoNetMessage cmdStationReply = new LocoNetMessage(new int[] {
0xe7, 0x0e, 0x8, 0x30, 0x00, 0x0, 0x0, 0x7, 0x0, 0x02, 0x00, 0x13, 0x01, 0x53}); // slot is in-use
lnis.sendTestMessage(cmdStationReply);
assertEquals( 256, throtListen.getFlagGotStealRequest(), "Got a steal request");
JUnitAppender.assertWarnMessage("slot 8 address 256 is already in-use.");
assertEquals( "BA 08 08 00",
lnis.outbound.elementAt(lnis.outbound.size() - 1).toString(), "In Use");
cmdStationReply = new LocoNetMessage(new int[] {
0xe7, 0x0e, 0x08, 0x30, 0x00, 0x0, 0x0, 0x7, 0x0, 0x02, 0x00, 0x13, 0x01, 0x53}); // slot is in-use
lnis.sendTestMessage(cmdStationReply);
assertEquals( "EF 0E 08 30 00 00 00 07 00 02 00 71 02 00",
lnis.outbound.elementAt(lnis.outbound.size() - 1).toString(), "Write Throttle ID");
DccThrottle throttle = throtListen.getThrottle();
assertNotNull( throttle, "Throttle should be created and non-null");
tm.releaseThrottle(throttle, throtListen);
}
@Test
public void testCreateLnThrottleStealScenario5() {
ThrottleListenStealWhenDecision throtListen = new ThrottleListenStealWhenDecision();
tm.requestThrottle(257, throtListen, true);
assertEquals( "BF 02 01 00",
lnis.outbound.elementAt(lnis.outbound.size() - 1).toString(), "address request message");
memo.getSlotManager().message(lnis.outbound.elementAt(lnis.outbound.size()-1));
assertEquals( 1, lnis.outbound.size(), "count is correct");
LocoNetMessage cmdStationReply = new LocoNetMessage(new int[] {
0xe7, 0x0e, 0x8, 0x10, 0x01, 0x0, 0x0, 0x7, 0x0, 0x02, 0x00, 0x13, 0x01, 0x53}); // slot is common
lnis.sendTestMessage(cmdStationReply);
assertEquals( "BA 08 08 00",
lnis.outbound.elementAt(lnis.outbound.size() - 1).toString(), "In Use");
cmdStationReply = new LocoNetMessage(new int[] {
0xe7, 0x0e, 0x08, 0x30, 0x01, 0x0, 0x0, 0x7, 0x0, 0x02, 0x00, 0x13, 0x01, 0x53}); // slot is in-use
lnis.sendTestMessage(cmdStationReply);
assertEquals( "EF 0E 08 30 01 00 00 07 00 02 00 71 02 00",
lnis.outbound.elementAt(lnis.outbound.size() - 1).toString(), "Write Throttle ID");
Assertions.assertNotNull(throtListen.getThrottle(), "Throttle should be created and non-null");
tm.releaseThrottle(throtListen.getThrottle(), throtListen);
}
@Test
public void testCreateLnThrottleStealScenario7() {
ThrottleListen throtListen = new ThrottleListen();
tm.requestThrottle(259, throtListen, true);
assertEquals( "BF 02 03 00",
lnis.outbound.elementAt(lnis.outbound.size() - 1).toString(), "address request message");
memo.getSlotManager().message(lnis.outbound.elementAt(lnis.outbound.size()-1));
assertEquals( 1, lnis.outbound.size(), "count is correct");
LocoNetMessage cmdStationReply = new LocoNetMessage(new int[] {
0xe7, 0x0e, 0x8, 0x00, 0x03, 0x0, 0x0, 0x7, 0x0, 0x02, 0x00, 0x13, 0x01, 0x53}); // slot is free
lnis.sendTestMessage(cmdStationReply);
assertEquals( "BA 08 08 00",
lnis.outbound.elementAt(lnis.outbound.size() - 1).toString(), "In Use");
cmdStationReply = new LocoNetMessage(new int[] {
0xe7, 0x0e, 0x08, 0x30, 0x03, 0x0, 0x0, 0x7, 0x0, 0x02, 0x00, 0x13, 0x01, 0x53}); // slot is in-use
lnis.sendTestMessage(cmdStationReply);
assertEquals( "EF 0E 08 30 03 00 00 07 00 02 00 71 02 00",
lnis.outbound.elementAt(lnis.outbound.size() - 1).toString(), "Write Throttle ID");
assertNotNull( throtListen.getThrottle(), "Throttle should be created and non-null");
tm.releaseThrottle(throtListen.getThrottle(), throtListen);
}
@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"
ThrottleListen throtListen = new ThrottleListen();
ThrottleListen throtListen2 = new ThrottleListen();
tm.requestThrottle(260, throtListen, true);
assertEquals( "BF 02 04 00",
lnis.outbound.elementAt(lnis.outbound.size() - 1).toString(), "address request message");
memo.getSlotManager().message(lnis.outbound.elementAt(lnis.outbound.size()-1));
assertEquals( 1, lnis.outbound.size(), "count is correct");
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);
assertNull( throtListen.getThrottle(), "Throttle should not be created and null");
JUnitAppender.assertNoErrorMessage();
// send it to INUSE
assertEquals( "BA 09 09 00",
lnis.outbound.elementAt(lnis.outbound.size() - 1).toString(), "NUll move");
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");
assertNotNull( throtListen.getThrottle(), "Throttle should be created and non-null");
int netTxMsgCount = lnis.outbound.size()-1;
tm.requestThrottle(260, throtListen2, true); // An additional user of the same throttle
assertNotNull( throtListen2.getThrottle(), "Throttle should be created and non-null");
assertEquals( throtListen.getThrottle(), throtListen2.getThrottle(),
"both throttle users point to the same throttle object");
assertEquals( netTxMsgCount, lnis.outbound.size()-1, "no new LocoNet traffic generated");
throtListen.getThrottle().setSpeedSetting(0.5f);
assertEquals( "A0 09 44 00", lnis.outbound.elementAt(lnis.outbound.size() -1). toString(),
"sent speed message");
assertEquals( netTxMsgCount +1, lnis.outbound.size()-1, "only one new loconet message");
lnis.outbound.clear();
tm.releaseThrottle(throtListen2.getThrottle(), throtListen2);
assertEquals( 0, lnis.outbound.size(), "No loconet traffic at throttle2 release");
assertTrue(InstanceManager.throttleManagerInstance().addressStillRequired(260),
"Address still required");
tm.releaseThrottle(throtListen.getThrottle(), throtListen);
assertFalse(InstanceManager.throttleManagerInstance().addressStillRequired(
new DccLocoAddress(260, true)), "Address no longer required");
// Wait for the set slot common message
JUnitUtil.waitFor(() -> lnis.outbound.size()==1, "wait for 1 slot COMMON message, was " + lnis.outbound);
Assertions.assertEquals("B5 09 10 00", lnis.outbound.elementAt(0).toString()
, "COMMON , was " + lnis.outbound);
}
@Test
public void testShareSingleLnThrottleScenario2() {
// test case:
// . acquire loco X to "throttle"
// . acquire loco X to "throttle2"
// . set speed for loco X
// . dispatch "throttle2"
// . set speed for loco X
// . release "throttle"
// . release "throttle2"
ThrottleListen throtListen = new ThrottleListen();
ThrottleListenStealWhenDecision throtListen2 = new ThrottleListenStealWhenDecision();
tm.requestThrottle(260, throtListen, true);
assertEquals( "BF 02 04 00",lnis.outbound.elementAt(lnis.outbound.size() - 1).toString(),
"address request message");
memo.getSlotManager().message(lnis.outbound.elementAt(lnis.outbound.size()-1));
assertEquals( 1, lnis.outbound.size(), "count is correct");
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);
assertNull( throtListen.getThrottle(), "Throttle should not be created and null");
JUnitAppender.assertNoErrorMessage();
// send it to INUSE
assertEquals("BA 09 09 00", lnis.outbound.elementAt(lnis.outbound.size() - 1).toString(),
"NUll move");
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);
assertEquals( "EF 0E 09 30 04 00 00 07 00 02 00 71 02 00",
lnis.outbound.elementAt(lnis.outbound.size() - 1).toString(), "Write Throttle ID");
assertNotNull( throtListen.getThrottle(), "Throttle should be created and non-null");
lnis.outbound.clear();
int netTxMsgCount = lnis.outbound.size()-1;
tm.requestThrottle(260, throtListen2, true); // An additional user of the same throttle
assertNotNull( throtListen2.getThrottle(), "Throttle should be created and non-null");
assertEquals( throtListen.getThrottle(), throtListen2.getThrottle(),
"both throttle users point to the same throttle object");
assertEquals( netTxMsgCount, lnis.outbound.size()-1, "no new LocoNet traffic generated");
throtListen.getThrottle().setSpeedSetting(0.5f);
assertEquals( "A0 09 44 00", lnis.outbound.elementAt(lnis.outbound.size() -1). toString(),
"sent speed message");
assertEquals( 1, lnis.outbound.size(), "only one new loconet message");
tm.dispatchThrottle(throtListen2.getThrottle(), throtListen2); // this fails as loco is in use on multiple throttles
assertEquals( 1, lnis.outbound.size(), "Message Count still 1");
assertEquals( 2, InstanceManager.throttleManagerInstance().getThrottleUsageCount(
new DccLocoAddress(260, true)), "Usage Count 2");
assertTrue(InstanceManager.throttleManagerInstance().addressStillRequired(new DccLocoAddress(260, true)),
"Address still required");
throtListen.getThrottle().setSpeedSetting(0.25f);
assertEquals("A0 09 28 00", lnis.outbound.elementAt(lnis.outbound.size() -1). toString(),
"sent speed message");
assertTrue(InstanceManager.throttleManagerInstance().addressStillRequired(new DccLocoAddress(260, true)),
"Address still required");
assertEquals(0.25f, throtListen.getThrottle().getSpeedSetting(), .001,
"throttle setting 'took' in the throttle");
tm.releaseThrottle(throtListen.getThrottle(), throtListen);
assertTrue(InstanceManager.throttleManagerInstance().addressStillRequired(new DccLocoAddress(260, true)),
"Address still required");
//reset outbound.
lnis.outbound.clear();
tm.dispatchThrottle(throtListen2.getThrottle(), throtListen2);
assertFalse( InstanceManager.throttleManagerInstance().addressStillRequired(new DccLocoAddress(260, true)),
"Address no longer required");
// Wait for 3 messages, the set slot common and then the get slot refresh
JUnitUtil.waitFor(() -> {
return lnis.outbound.size()==3;
},"wait for 3 messages");
assertEquals("B5 09 10 00", lnis.outbound.get(0).toString(),"Slot set to COMMON");
assertEquals("BA 09 00 00", lnis.outbound.get(1).toString(),"Slot set to DISPATCH");
// when LnPredefinedMeters is running
// assertEquals("BB 09 00 00", lnis.outbound.get(2).toString(), "Slot read");
// when LnPredefinedMeters is NOT running the 3rd message is a repeat of set to common
assertEquals("B5 09 10 00", lnis.outbound.get(2).toString(),"Slot set to COMMON again");
JUnitUtil.waitFor(150);
assertEquals(3, lnis.outbound.size(), "No more loconet messages sent at throttle release, was "+lnis.outbound);
}
@Test
public void testShareSingleLnThrottleScenario3() {
// test case:
// . acquire loco X to "throttle"
// . acquire loco X to "throttle2"
// . set speed for loco X
// . release "throttle2"
// . acquire loco X to "throttle3"
// . release "throttle"
// . set speed for loco X
// release "throttle3"
ThrottleListen throtListen = new ThrottleListen();
ThrottleListen throtListen2 = new ThrottleListen();
ThrottleListen throtListen3 = new ThrottleListen();
tm.requestThrottle(261, throtListen, true);
assertEquals( "BF 02 05 00",
lnis.outbound.elementAt(lnis.outbound.size() - 1).toString(), "address request message");
memo.getSlotManager().message(lnis.outbound.elementAt(lnis.outbound.size()-1));
// for long delays, BF 02 05 00 is re-sent 10 times before halting attempt.
LocoNetMessage cmdStationReply = new LocoNetMessage(new int[] {
0xe7, 0x0e, 0x0A, 0x00, 0x05, 0x0, 0x0, 0x7, 0x0, 0x02, 0x00, 0x13, 0x01, 0x53}); // slot is in-use
lnis.sendTestMessage(cmdStationReply);
assertNull(throtListen.getThrottle(), "Throttle should not be created and null");
JUnitAppender.assertNoErrorMessage();
// send it to INUSE
assertEquals("BA 0A 0A 00",
lnis.outbound.elementAt(lnis.outbound.size() - 1).toString(), "NUll move");
cmdStationReply = new LocoNetMessage(new int[] {
0xe7, 0x0e, 0x0A, 0x30, 0x05, 0x0, 0x0, 0x7, 0x0, 0x02, 0x00, 0x00, 0x00, 0x53}); // slot is in-use
lnis.sendTestMessage(cmdStationReply);
assertEquals("EF 0E 0A 30 05 00 00 07 00 02 00 71 02 00",
lnis.outbound.elementAt(lnis.outbound.size() - 1).toString(), "Write Throttle ID");
assertNotNull(throtListen.getThrottle(), "Throttle should be created and non-null");
int netTxMsgCount = lnis.outbound.size()-1;
tm.requestThrottle(261, throtListen2, true); // An additional user of the same throttle
assertNotNull(throtListen2.getThrottle(), "Throttle should be created and non-null");
assertEquals(throtListen.getThrottle(), throtListen2.getThrottle(),
"both throttle users point to the same throttle object");
assertEquals(netTxMsgCount, lnis.outbound.size()-1, "no new LocoNet traffic generated");
throtListen.getThrottle().setSpeedSetting(0.5f);
assertEquals("A0 0A 44 00", lnis.outbound.elementAt(lnis.outbound.size() -1). toString(),
"sent speed message");
assertEquals(netTxMsgCount +1, lnis.outbound.size()-1, "only one new loconet message");
tm.releaseThrottle(throtListen2.getThrottle(), throtListen2);
assertEquals(netTxMsgCount +1, lnis.outbound.size()-1, "No loconet traffic at throttle2 release");
assertTrue(InstanceManager.throttleManagerInstance().addressStillRequired(new DccLocoAddress(261, true)),
"Address still required");
tm.requestThrottle(261, throtListen3, true); // An additional user of the same throttle
assertNotNull(throtListen3.getThrottle(), "Throttle should be created and non-null");
assertEquals(throtListen.getThrottle(), throtListen3.getThrottle(),
"both throttle users point to the same throttle object");
assertEquals(netTxMsgCount+1, lnis.outbound.size()-1, "no new LocoNet traffic generated");
assertEquals(netTxMsgCount+1, lnis.outbound.size()-1, "got correct number of LocoNet messages");
throtListen.getThrottle().setSpeedSetting(1.0f);
assertEquals(netTxMsgCount+2, lnis.outbound.size()-1, "got correct number of LocoNet messages");
assertEquals("A0 0A 7C 00", lnis.outbound.elementAt(lnis.outbound.size() -1). toString(),
"sent speed message");
tm.releaseThrottle(throtListen.getThrottle(), throtListen);
assertTrue(InstanceManager.throttleManagerInstance().addressStillRequired(new DccLocoAddress(261, true)),
"Address still required");
throtListen.getThrottle().setSpeedSetting(-1.0f);
assertEquals(netTxMsgCount+3, lnis.outbound.size()-1, "got correct number of LocoNet messages");
assertEquals("A0 0A 01 00", lnis.outbound.elementAt(lnis.outbound.size() -1). toString(),
"sent speed message");
tm.releaseThrottle(throtListen.getThrottle(), throtListen3);
assertFalse(InstanceManager.throttleManagerInstance().addressStillRequired(new DccLocoAddress(261, true)),
"Address no longer required");
assertEquals(netTxMsgCount +4, lnis.outbound.size()-1, "One loconet message sent at throttle release");
assertEquals("B5 0A 10 00", lnis.outbound.elementAt(lnis.outbound.size() -1). toString(),
"sent set slot status to COMMON message");
}
@Test
public void testShareSingleLnThrottleScenario4() {
// test case:
// . attempt acquire loco X to "throttle"
// . notified that steal is required
// . steal is agreed to by throttle user
// . acquisition is completed under steal protocol
// . acquire loco X to "throttle2"
// . (Steal not required!)
// . set speed for loco X
// . release "throttle2"
// . set speed for loco X
// . release "throttle"
ThrottleListenStealWhenDecision throtListen = new ThrottleListenStealWhenDecision();
ThrottleListen throtListen2 = new ThrottleListen();
tm.requestThrottle(262, throtListen, true);
assertEquals( "BF 02 06 00",
lnis.outbound.elementAt(lnis.outbound.size() - 1).toString(), "address request message");
memo.getSlotManager().message(lnis.outbound.elementAt(lnis.outbound.size()-1));
assertEquals(1, lnis.outbound.size(), "count is correct");
LocoNetMessage cmdStationReply = new LocoNetMessage(new int[] {
0xe7, 0x0e, 0x0B, 0x30, 0x06, 0x0, 0x0, 0x7, 0x0, 0x02, 0x00, 0x13, 0x01, 0x53}); // slot is in-use
lnis.sendTestMessage(cmdStationReply);
assertEquals(262, throtListen.getFlagGotStealRequest(), "Got a steal request");
JUnitAppender.assertWarnMessage("slot 11 address 262 is already in-use.");
assertEquals( "BA 0B 0B 00",
lnis.outbound.elementAt(lnis.outbound.size() - 1).toString(), "In Use");
cmdStationReply = new LocoNetMessage(new int[] {
0xe7, 0x0e, 0x0B, 0x30, 0x06, 0x0, 0x0, 0x7, 0x0, 0x02, 0x00, 0x13, 0x01, 0x53}); // slot is in-use
lnis.sendTestMessage(cmdStationReply);
assertEquals( "EF 0E 0B 30 06 00 00 07 00 02 00 71 02 00",
lnis.outbound.elementAt(lnis.outbound.size() - 1).toString(), "Write Throttle ID");
assertNotNull(throtListen.getThrottle(), "Throttle should be created and non-null");
int netTxMsgCount = lnis.outbound.size()-1;
tm.requestThrottle(262, throtListen2, true); // An additional user of the same throttle
assertNotNull(throtListen2.getThrottle(), "Throttle should be created and non-null");
assertEquals( throtListen.getThrottle(), throtListen2.getThrottle(),
"both throttle users point to the same throttle object");
assertEquals(netTxMsgCount, lnis.outbound.size()-1, "no new LocoNet traffic generated");
throtListen.getThrottle().setSpeedSetting(0.1f);
assertEquals("A0 0B 17 00", lnis.outbound.elementAt(lnis.outbound.size() -1). toString()
, "sent speed message");
assertEquals( netTxMsgCount +1, lnis.outbound.size()-1, "only one new loconet message");
tm.releaseThrottle(throtListen2.getThrottle(), throtListen2);
assertEquals(netTxMsgCount +1, lnis.outbound.size()-1, "No loconet traffic at throttle2 release");
assertTrue(InstanceManager.throttleManagerInstance().addressStillRequired(new DccLocoAddress(262, true))
, "Address still required");
assertEquals( netTxMsgCount+1, lnis.outbound.size()-1, "got correct number of LocoNet messages");
throtListen.getThrottle().setSpeedSetting(0.2f);
assertEquals(netTxMsgCount+2, lnis.outbound.size()-1, "got correct number of LocoNet messages");
assertEquals("A0 0B 22 00", lnis.outbound.elementAt(lnis.outbound.size() -1). toString()
, "sent speed message");
tm.releaseThrottle(throtListen.getThrottle(), throtListen);
assertFalse( InstanceManager.throttleManagerInstance().addressStillRequired(new DccLocoAddress(262, true)),
"Address no longer required");
assertEquals( netTxMsgCount +3, lnis.outbound.size()-1, "One loconet message sent at throttle release");
assertEquals("B5 0B 10 00", lnis.outbound.elementAt(lnis.outbound.size() -1). toString()
, "sent set slot status to COMMON message");
}
@Test
public void testUseRosterEntry() {
org.jdom2.Element e = new org.jdom2.Element("locomotive")
.setAttribute("id", "our id 1")
.setAttribute("fileName", "file here")
.setAttribute("roadNumber", "431")
.setAttribute("roadName", "SP")
.setAttribute("mfg", "Athearn")
.setAttribute("dccAddress", "1234")
.addContent(
new org.jdom2.Element("locoaddress").addContent(
new org.jdom2.Element("dcclocoaddress")
.setAttribute("number", "1234")
.setAttribute("longaddress", "yes")
)
); // end create element
RosterEntry re = new RosterEntry(e);
ThrottleListen throtListen = new ThrottleListen();
tm.requestThrottle(re, throtListen, true);
assertEquals("BF 09 52 00",
lnis.outbound.elementAt(lnis.outbound.size() - 1).toString(), "address request message");
LocoNetMessage cmdStationReply = new LocoNetMessage(new int[] {
0xe7, 0x0e, 0x04, 0x03, 0x52, 0x0, 0x0, 0x7, 0x0, 0x09, 0x0, 0x0, 0x0, 0x53});
lnis.sendTestMessage(cmdStationReply);
assertEquals("BA 04 04 00",
lnis.outbound.elementAt(lnis.outbound.size() - 1).toString(), "null move");
cmdStationReply = new LocoNetMessage(new int[] {
0xe7, 0x0e, 0x04, 0x33, 0x52, 0x0, 0x0, 0x7, 0x0, 0x09, 0x0, 0x0, 0x0, 0x63});
lnis.sendTestMessage(cmdStationReply);
assertEquals("EF 0E 04 33 52 00 00 07 00 09 00 71 02 00",
lnis.outbound.elementAt(lnis.outbound.size() - 1).toString(), "write Throttle ID");
cmdStationReply = new LocoNetMessage(new int[] {
0xb4, 0x6f, 0x7f, 0x5B});
lnis.sendTestMessage(cmdStationReply);
DccThrottle throttle4 = throtListen.getThrottle();
assertNotNull(throttle4, "have created a throttle4");
assertTrue(throttle4.getClass() == LocoNetThrottle.class,"is LnThrottle");
assertEquals( 0x171, ((LocoNetThrottle) throttle4).slot.id(), "throttle4Id is set");
// JUnitAppender.assertErrorMessage("created a throttle4");
throttle4.setSpeedSetting(0.5f);
assertEquals("A0 04 40 00",
lnis.outbound.elementAt(lnis.outbound.size() - 1).toString(), "set speed a half");
assertTrue(InstanceManager.throttleManagerInstance().addressStillRequired(re), "Address still is not still required");
assertEquals(1,
InstanceManager.throttleManagerInstance().getThrottleUsageCount(re), "Throttle usage 1");
throttle4.release(throtListen);
JUnitUtil.waitFor(()->{return 4 < lnis.outbound.size();},"didn't get the 6th LocoNet message");
JUnitUtil.waitFor( () -> "B5 04 13 00".equals(
(lnis.outbound.elementAt(lnis.outbound.size()-1).toString())),
"slot is set to 'common' status");
}
private LocoNetInterfaceScaffold lnis;
private LocoNetSystemConnectionMemo memo;
@Override
@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);
assertTrue(tm == InstanceManager.getDefault(ThrottleManager.class),"tm is Instance tm");
assertInstanceOf(LnThrottleManager.class, tm, "tm is ln tm and not null");
log.debug("new throttle manager is {}", tm);
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
memo.getPredefinedMeters().dispose(); // get rid of meter to prevent it reading slots
}
@AfterEach
public void tearDown() {
LocoNetThrottledTransmitter.ServiceThread theServiceThread = memo.tm.theServiceThread;
tm.dispose();
memo.dispose();
if ( theServiceThread != null ) {
// wait for LocoNetThrottledTransmitter to terminate
JUnitUtil.waitFor(() -> {
return !theServiceThread.isAlive();
},"wait for LocoNetThrottledTransmitter to shutdown");
}
if ( lnis != null ) {
log.debug("numListeners on lnis = {}", lnis.numListeners()); // 5? no problem
lnis.dispose();
}
lnis = null;
JUnitUtil.deregisterBlockManagerShutdownTask();
JUnitUtil.tearDown();
}
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LnThrottleManagerTest.class);
}