Files
2026-06-17 14:00:51 +02:00

742 lines
31 KiB
Java

package jmri.jmrix.can.cbus.node;
import java.io.File;
import jmri.jmrix.can.CanMessage;
import jmri.jmrix.can.CanReply;
import jmri.jmrix.can.CanSystemConnectionMemo;
import jmri.jmrix.can.TrafficControllerScaffold;
import jmri.jmrix.can.cbus.*;
import jmri.util.JUnitUtil;
import jmri.util.JUnitAppender;
import org.junit.jupiter.api.*;
import org.junit.jupiter.api.io.TempDir;
import static org.junit.jupiter.api.Assertions.*;
/**
*
* @author Paul Bender Copyright (C) 2017
* @author Steve Young Copyright (C) 2019
*/
public class CbusNodeTest {
private CanSystemConnectionMemo memo;
private TrafficControllerScaffold tcis;
@Test
public void testCTor() {
CbusNode t = new CbusNode(memo,256);
assertNotNull( t, "exists");
t.dispose();
}
@Test
public void testCanListenAndRemove() {
assertEquals( 0, tcis.numListeners(), "no listener to start with");
CbusNode t = new CbusNode(memo,256);
assertEquals( 1, tcis.numListeners(), "table listening");
t.dispose();
assertEquals( 0, tcis.numListeners(), "no listener to finish with");
}
@Test
public void testDefaultGets() {
CbusNode t = new CbusNode(memo,256);
assertEquals( 256, t.getNodeNumber(), "nodenum");
assertEquals( -1, t.getCsNum(), "default cs num");
assertEquals( -1, t.getNodeEventManager().getTotalNodeEvents(), "default getTotalNodeEvents");
assertEquals( -1, t.getNodeEventManager().getLoadedNodeEvents(), "default getLoadedNodeEvents");
assertEquals( -1, t.getNodeParamManager().getParameter(0), "default parameter 0");
assertEquals( -1, t.getNodeNvManager().getNV(0), "default getNV 0");
assertEquals( 0, t.getNodeNvManager().getTotalNVs(), "default getTotalNVs 0");
assertEquals( 1, t.getNodeCanId(), "default getNodeCanId");
assertTrue( t.getNodeStats().getNodeTypeName().isEmpty(), "default getNodeTypeName");
assertTrue( t.getNodeInFLiMMode(),"default getNodeInFLiMMode");
assertFalse( t.getNodeInSetupMode(),"default getNodeInSetupMode");
assertEquals( "256", t.getNodeStats().getNodeNumberName(), "default getNodeNumberName");
assertTrue( t.getsendsWRACKonNVSET(),"default getsendsWRACKonNVSET");
assertFalse( t.getnvWriteInLearnOnly(),"default getsendsWRACKonNVSET");
assertEquals( -1, t.getNodeStats().totalNodeBytes(),"default totalNodeBytes");
assertEquals( -1, t.getNodeStats().totalRemainingNodeBytes(),"default totalRemainingNodeBytes");
assertEquals( "256", t.toString(), "default toString");
assertEquals( -1, t.getNodeFlags(), "default getNodeFlags");
assertEquals( -1, t.getNodeEventManager().getOutstandingEvVars(), "default getOutstandingEvVars");
assertFalse( t.getNodeTimerManager().hasActiveTimers(), "default hasActiveTimers");
assertFalse( t.getNodeEventManager().isEventIndexValid(), "default isEventIndexValid");
assertNull( t.getNodeBackupManager().getFirstBackupTime(), "No First Backup Timestamp");
assertNull( t.getNodeBackupManager().getLastBackupTime(), "No Last Backup Timestamp");
assertEquals( 0, t.getNodeBackupManager().getNumCompleteBackups(), "0 Backups");
assertEquals( t.getNodeBackupManager().getSessionBackupStatus(),
CbusNodeConstants.BackupType.OUTSTANDING, "Backup Outstanding");
t.dispose();
}
@Test
public void testInOutLearnModeExtendedRtr() {
CbusNode t = new CbusNode(memo,1234);
assertFalse( t.getNodeInLearnMode(),"default getNodeInLearnMode");
// frame to set node into learn
CanReply r = new CanReply();
r.setHeader(tcis.getCanid());
r.setNumDataElements(3);
r.setElement(0, CbusConstants.CBUS_NNLRN);
r.setElement(1, 0x04);
r.setElement(2, 0xd2);
t.getCanListener().reply(r);
assertTrue( t.getNodeInLearnMode(), "reply in learn mode");
r = new CanReply();
r.setHeader(tcis.getCanid());
r.setNumDataElements(3);
r.setElement(0, CbusConstants.CBUS_NNULN);
r.setElement(1, 0x04);
r.setElement(2, 0xd2);
t.getCanListener().reply(r);
assertFalse( t.getNodeInLearnMode(), "reply exit learn mode");
// frame to set node into learn
CanMessage m = new CanMessage( tcis.getCanid() );
m.setNumDataElements(3);
m.setElement(0, CbusConstants.CBUS_NNLRN);
m.setElement(1, 0x04);
m.setElement(2, 0xd2);
t.getCanListener().message(m);
assertTrue( t.getNodeInLearnMode(), "message enter learn mode");
m = new CanMessage( tcis.getCanid() );
m.setNumDataElements(3);
m.setElement(0, CbusConstants.CBUS_NNULN);
m.setElement(1, 0x04);
m.setElement(2, 0xd2);
t.getCanListener().message(m);
assertFalse( t.getNodeInLearnMode(), "message exit learn mode");
// any message which does nothing to node does not crash it
m = new CanMessage( tcis.getCanid() );
m.setNumDataElements(1);
m.setElement(0, CbusConstants.CBUS_RTOF); // request track off
t.getCanListener().message(m);
assertFalse( t.getNodeInLearnMode(), "not in learn mode");
m = new CanMessage( tcis.getCanid() );
m.setElement(0, CbusConstants.CBUS_NNLRN); // enter learn mode
m.setElement(1, 0x04);
m.setElement(2, 0xd2);
m.setExtended(true);
t.getCanListener().message(m);
assertFalse( t.getNodeInLearnMode(), "no change ext");
m.setExtended(false);
m.setRtr(true);
t.getCanListener().message(m);
assertFalse( t.getNodeInLearnMode(), "no change rtr");
m.setRtr(false);
t.getCanListener().message(m);
assertTrue( t.getNodeInLearnMode(), "message enter learn mode");
r = new CanReply();
r.setHeader(tcis.getCanid());
r.setNumDataElements(3);
r.setElement(0, CbusConstants.CBUS_NNULN);
r.setElement(1, 0x04);
r.setElement(2, 0xd2);
r.setExtended(true);
t.getCanListener().reply(r);
assertTrue( t.getNodeInLearnMode(), "no change ext");
r.setExtended(false);
r.setRtr(true);
t.getCanListener().reply(r);
assertTrue( t.getNodeInLearnMode(), "no change rtr");
t.dispose();
}
@Test
public void testSetName() {
CbusNode t = new CbusNode(memo,12345);
assertTrue( t.getUserName().isEmpty(), "default getUserName");
t.setUserName("Alonso Smith");
assertEquals( "Alonso Smith", t.getUserName(), "username set");
assertEquals( "12345 Alonso Smith", t.toString(), "Alonso toString");
t.setNameIfNoName("purple");
assertEquals( "Alonso Smith",t.getUserName(), "username unchanged");
CbusNode tb = new CbusNode(memo,123);
tb.setNameIfNoName("shirley");
assertEquals( "shirley", tb.getUserName(), "username set if no name");
assertEquals( "123 shirley", tb.getNodeStats().getNodeNumberName(), "username number");
t.dispose();
tb.dispose();
}
@Test
public void testStartGetParams() {
assertEquals( 0, tcis.outbound.size(), "tcis empty at start");
CbusNode t = new CbusNode(memo,12345);
assertEquals( -1, t.getNodeParamManager().getParameter(0), "default parameter 0");
// only 1 parameter awaiting knowledge of until total confirmed
assertEquals( 8,t.getNodeParamManager().getOutstandingParams(), "default outstanding parameters");
assertEquals( 0 ,tcis.outbound.size(), "tcis empty after creating new node");
t.getNodeParamManager().sendRequestNextParam();
assertEquals( 1 ,tcis.outbound.size(), "Node has requested parameter 0");
t.getNodeParamManager().sendRequestNextParam();
assertEquals( 1 ,tcis.outbound.size(), "Node has already requested parameter 0");
assertEquals( "[5f8] 73 30 39 00", tcis.outbound.elementAt(tcis.outbound.size() - 1).toString(),
"Message sent is parameter request");
// frame from physical node to CbusNode advising has 7 parameters
CanReply r = new CanReply();
r.setHeader(tcis.getCanid());
r.setNumDataElements(5);
r.setElement(0, CbusConstants.CBUS_PARAN);
r.setElement(1, 0x30); // nodenum 12345
r.setElement(2, 0x39); // nodenum 12345
r.setElement(3, 0x00); // parameter 0
r.setElement(4, 0x07); // value 7
t.getCanListener().reply(r);
assertEquals( 7, t.getNodeParamManager().getParameter(0), "parameter 0 value 7");
assertEquals( 7, t.getNodeParamManager().getOutstandingParams(), "default outstanding parameters 7" );
t.getNodeParamManager().sendRequestNextParam();
// JUnitUtil.waitFor(()->{ return(tcis.outbound.size()>1); }, " outbound 1 didn't arrive");
assertEquals( 2 ,tcis.outbound.size(), "CbusNode has requested parameter 1 manufacturer");
assertEquals( "[5f8] 73 30 39 01", tcis.outbound.elementAt(tcis.outbound.size() - 1).toString(),
"Message sent is parameter 1 request");
r = new CanReply();
r.setHeader(tcis.getCanid());
r.setNumDataElements(5);
r.setElement(0, CbusConstants.CBUS_PARAN);
r.setElement(1, 0x30);
r.setElement(2, 0x39);
r.setElement(3, 0x01); // parameter 1
r.setElement(4, 0xa5); // dec 165 MERG
t.getCanListener().reply(r);
assertEquals( 165, t.getNodeParamManager().getParameter(1), "parameter 1 value 165");
t.getNodeParamManager().sendRequestNextParam();
assertEquals( 3 ,tcis.outbound.size(), "CbusNode has requested parameter 3 module type identifier");
assertEquals( "[5f8] 73 30 39 03", tcis.outbound.elementAt(tcis.outbound.size() - 1).toString(),
"Message sent is parameter 3 request");
r = new CanReply();
r.setHeader(tcis.getCanid());
r.setNumDataElements(5);
r.setElement(0, CbusConstants.CBUS_PARAN);
r.setElement(1, 0x30);
r.setElement(2, 0x39);
r.setElement(3, 0x03); // parameter 3
r.setElement(4, 0x1d); // dec 29 CANPAN
t.getCanListener().reply(r);
// now we know params 1 and 3, try nodetype lookup
assertEquals( "CANPAN" ,t.getNodeStats().getNodeTypeName(), "CbusNode identified as a CANPAN");
t.getNodeParamManager().sendRequestNextParam();
assertEquals( 4 ,tcis.outbound.size(), "CbusNode has requested parameter 6 number nv's");
assertEquals( "[5f8] 73 30 39 06", tcis.outbound.elementAt(tcis.outbound.size() - 1).toString(),
"Message sent is parameter 6 request");
r = new CanReply();
r.setHeader(tcis.getCanid());
r.setNumDataElements(5);
r.setElement(0, CbusConstants.CBUS_PARAN);
r.setElement(1, 0x30);
r.setElement(2, 0x39);
r.setElement(3, 0x06); // parameter 6
r.setElement(4, 0x03); // 3 NV's
t.getCanListener().reply(r);
// now we know number of NV's
assertEquals( 3, t.getNodeNvManager().getTotalNVs(), "getTotalNVs 3");
assertEquals( 3, t.getNodeNvManager().getOutstandingNvCount(), "get oustanding NVs 3");
assertEquals( 3, t.getNodeNvManager().getNV(0), "get NVs 0 3");
assertEquals( -1, t.getNodeNvManager().getNV(1), "get NVs 1 -1");
assertEquals( -1, t.getNodeNvManager().getNV(3), "get NVs 3 -1");
t.getNodeParamManager().sendRequestNextParam();
assertEquals( 5 ,tcis.outbound.size(), "CbusNode has requested parameter 6 number ev vars per event");
assertEquals( "[5f8] 73 30 39 05", tcis.outbound.elementAt(tcis.outbound.size() - 1).toString(),
"Message sent is parameter 5 request");
r = new CanReply();
r.setHeader(tcis.getCanid());
r.setNumDataElements(5);
r.setElement(0, CbusConstants.CBUS_PARAN);
r.setElement(1, 0x30);
r.setElement(2, 0x39);
r.setElement(3, 0x05); // parameter 5
r.setElement(4, 0x07); // 7 ev vars per ev
t.getCanListener().reply(r);
assertEquals( 3, t.getNodeParamManager().getOutstandingParams(), "outstanding parameters 3");
t.getNodeParamManager().sendRequestNextParam();
assertEquals( 6 ,tcis.outbound.size(), "CbusNode has requested parameter 7 firmware major");
assertEquals( "[5f8] 73 30 39 07", tcis.outbound.elementAt(tcis.outbound.size() - 1).toString(),
"Message sent is parameter 7 request");
r = new CanReply();
r.setHeader(tcis.getCanid());
r.setNumDataElements(5);
r.setElement(0, CbusConstants.CBUS_PARAN);
r.setElement(1, 0x30);
r.setElement(2, 0x39);
r.setElement(3, 0x07); // parameter 7
r.setElement(4, 0x02); // firmware pt1 2
t.getCanListener().reply(r);
t.getNodeParamManager().sendRequestNextParam();
assertEquals( 7 ,tcis.outbound.size(), "CbusNode has requested parameter 2 firmware minor");
assertEquals( "[5f8] 73 30 39 02", tcis.outbound.elementAt(tcis.outbound.size() - 1).toString(),
"Message sent is parameter 2 request");
assertTrue( t.getsendsWRACKonNVSET(), "default getsendsWRACKonNVSET");
assertFalse( t.getnvWriteInLearnOnly(), "default getnvWriteInLearnOnly");
r = new CanReply();
r.setHeader(tcis.getCanid());
r.setNumDataElements(5);
r.setElement(0, CbusConstants.CBUS_PARAN);
r.setElement(1, 0x30);
r.setElement(2, 0x39);
r.setElement(3, 0x02); // parameter 2
r.setElement(4, 0x01); // firmware pt2 1
t.getCanListener().reply(r);
assertEquals( 1, t.getNodeParamManager().getOutstandingParams(), " outstanding parameter 1");
assertEquals( "[7, 165, 1, 29, -1, 7, 3, 2]",
java.util.Arrays.toString(t.getNodeParamManager().getParameters() ),
"getParameters ");
t.getNodeParamManager().sendRequestNextParam();
// with this we should expect CbusNodeConstants.setTraits to have been called
assertFalse( t.getsendsWRACKonNVSET(), "setTraits getsendsWRACKonNVSET ");
assertEquals( 8 ,tcis.outbound.size(), "CbusNode has requested number of events");
assertEquals( "[5f8] 58 30 39",
tcis.outbound.elementAt(tcis.outbound.size() - 1).toString(),
"Message sent numev request");
t.dispose();
}
@Test
public void testAddEvents() {
CbusNode t = new CbusNode(memo,12345);
assertEquals( -1, t.getNodeEventManager().getTotalNodeEvents(), "default getTotalNodeEvents");
assertFalse( t.getNodeTimerManager().hasActiveTimers(), "default active timers false, ie nothing requested");
// set node to 4 ev vars per event, para 5
t.getNodeParamManager().setParameters(new int[]{8,1,2,3,4,4,6,7,8});
CbusNodeEvent ev = new CbusNodeEvent(memo,0,7,12345,77,4); // nn, en, thisnode, index, maxevvar
t.getNodeEventManager().addNewEvent(ev);
// index on the event is set to -1, ie unknown when an event is added to the node
assertEquals( -1, ev.getIndex(), "index in array -1");
assertEquals( 1, t.getNodeEventManager().getTotalNodeEvents(), "after new ev getTotalNodeEvents 1");
assertEquals( 4, t.getNodeEventManager().getOutstandingEvVars(), "after new ev getOutstandingEvVars 1");
CbusNodeEvent evb = new CbusNodeEvent(memo,0,8,12345,2,4);
t.getNodeEventManager().addNewEvent(evb);
assertEquals( 2, t.getNodeEventManager().getTotalNodeEvents(), "after new ev getTotalNodeEvents 2");
assertEquals( 2, t.getNodeEventManager().getLoadedNodeEvents(), "after new ev getLoadedNodeEvents 2");
assertEquals( 0, t.getNodeEventManager().getOutstandingIndexNodeEvents(), "getOutstandingIndexNodeEvents 0");
assertEquals( ev, t.getNodeEventManager().getNodeEvent(0,7), "node event fetch node 0 ev 7");
assertNull( t.getNodeEventManager().getNodeEvent(321,654), "node event fetch null node 321 ev 645");
assertEquals( evb, t.getNodeEventManager().provideNodeEvent(0,8), "node event provide node 0 ev87");
assertEquals( 2, t.getNodeEventManager().getTotalNodeEvents(), "after provide 321 645 getTotalNodeEvents 3");
t.getNodeEventManager().provideNodeEvent(321,654);
assertEquals( 3, t.getNodeEventManager().getTotalNodeEvents(), "after provide 321 645 getTotalNodeEvents 3");
java.util.ArrayList<CbusNodeEvent> _tArr = t.getNodeEventManager().getEventArray();
assertNotNull( _tArr, "Array should not be null");
assertEquals( 3, _tArr.size(), "event array size 3");
ev.setIndex(77);
evb.setIndex(88);
assertEquals( 1, t.getNodeEventManager().getEventRowFromIndex(88), "index in array 1");
assertEquals( 0, t.getNodeEventManager().getEventRowFromIndex(77), "index in array 0");
assertEquals( -1, t.getNodeEventManager().getEventRowFromIndex(999), "index 999 not in array");
t.getNodeEventManager().addNewEvent(new CbusNodeEvent(memo,123,-1,12345,3,4));
t.getNodeEventManager().addNewEvent(new CbusNodeEvent(memo,-1,123,12345,4,4));
assertEquals( 5, t.getNodeEventManager().getTotalNodeEvents(), "after remove getTotalNodeEvents 2");
assertEquals( 3, t.getNodeEventManager().getLoadedNodeEvents(), "after new ev getLoadedNodeEvents 3");
t.getNodeEventManager().removeEvent(0,8);
assertNull( t.getNodeEventManager().getNodeEvent(0,8), "node event remove node 0 ev 8");
assertNotNull( t.getNodeEventManager().getNodeEvent(321,654), "node event not removed others");
assertEquals( 4, t.getNodeEventManager().getTotalNodeEvents(), "after remove getTotalNodeEvents 4");
assertNull( t.getNodeEventManager().getNodeEventByIndex(999), "event fetched by index");
t.setNodeInLearnMode(true);
CanReply r = new CanReply();
r.setHeader(tcis.getCanid());
r.setNumDataElements(3);
r.setElement(0, CbusConstants.CBUS_NNCLR);
r.setElement(1, 0x30);
r.setElement(2, 0x00);
t.getCanListener().reply(r);
assertEquals( 4, t.getNodeEventManager().getTotalNodeEvents(), "after remove getTotalNodeEvents 4 wrong node number");
r.setElement(2, 0x39);
t.getCanListener().reply(r);
assertEquals( 0,t.getNodeEventManager().getTotalNodeEvents(), "after CBUS_NNCLR getTotalNodeEvents 0");
t.dispose();
}
@Test
public void testAddEventsFromCan() {
CbusNode t = new CbusNode(memo,12345);
// set node to 4 ev vars per event
t.getNodeParamManager().setParameters(new int[]{8,1,2,3,4,4,6,7,8});
t.setNodeInLearnMode(true);
// frame to set node into learn
CanReply r = new CanReply();
r.setHeader(tcis.getCanid());
r.setNumDataElements(7);
r.setElement(0, CbusConstants.CBUS_EVLRN);
r.setElement(1, 0x30); // nn 12344
r.setElement(2, 0x38); // nn 12344
r.setElement(3, 0x00); // en 7
r.setElement(4, 0x07); // en 7
r.setElement(5, 0x01); // ev index 1
r.setElement(6, 0xff); // ev val 255
t.getCanListener().reply(r);
assertEquals( 1, t.getNodeEventManager().getTotalNodeEvents(), "getTotalNodeEvents 1");
assertEquals( 1, t.getNodeEventManager().getLoadedNodeEvents(), "getLoadedNodeEvents 1");
assertEquals( 3, t.getNodeEventManager().getOutstandingEvVars(), "getOutstandingEvVars 3");
assertEquals( 0 ,tcis.outbound.size(), "Node has not sent a message");
r = new CanReply();
r.setHeader(tcis.getCanid());
r.setNumDataElements(5);
r.setElement(0, CbusConstants.CBUS_EVULN);
r.setElement(1, 0x30); // nn 12344
r.setElement(2, 0x38); // nn 12344
r.setElement(3, 0x00); // en 6
r.setElement(4, 0x06); // en 6
t.getCanListener().reply(r);
assertEquals( 1, t.getNodeEventManager().getTotalNodeEvents(), "getTotalNodeEvents 1 wrong event");
r.setElement(4, 0x07); // en 7
t.getCanListener().reply(r);
assertEquals( 0, t.getNodeEventManager().getTotalNodeEvents(), "getTotalNodeEvents 0");
t.dispose();
}
@Test
public void testFetchEventsFromCanWithNodeTable() {
// needs table model adding to check for any other nodes in learn mode
CbusNodeTableDataModel tModel = memo.get(CbusConfigurationManager.class)
.provide(CbusNodeTableDataModel.class);
CbusNode t = new CbusNode(memo,12345);
// set node to 3 ev vars per event( param 5) , 0 NV's ( param 6)
t.getNodeParamManager().setParameters(new int[]{8,1,2,3,4,3,0,7,8});
tModel.addNode(t);
CanReply r = new CanReply();
r.setHeader(tcis.getCanid());
r.setNumDataElements(4);
r.setElement(0, CbusConstants.CBUS_NUMEV);
r.setElement(1, 0x30); // nn 12345
r.setElement(2, 0x39); // nn 12345
r.setElement(3, 0x02); // node has 2 events
t.getCanListener().reply(r);
assertEquals( 2, t.getNodeEventManager().getTotalNodeEvents(), "CBUS_NUMEV 2");
assertEquals(0.5 ,t.getNodeStats().floatPercentageRemaining(), 0.0001f );
t.getNodeEventManager().sendNextEvVarToFetch();
assertEquals( 1 ,tcis.outbound.size(), "Node has sent a message");
assertEquals( "[5f8] 57 30 39",
tcis.outbound.elementAt(tcis.outbound.size() - 1).toString(),
"Node sends NERD request");
assertTrue( t.getNodeTimerManager().hasActiveTimers(), "active timer true for NERD / ENRSP responses");
// reply to NERD
r = new CanReply();
r.setHeader(tcis.getCanid());
r.setNumDataElements(8);
r.setElement(0, CbusConstants.CBUS_ENRSP);
r.setElement(1, 0x30); // nn 12345
r.setElement(2, 0x39); // nn 12345
r.setElement(3, 0x30); // nn 12344
r.setElement(4, 0x38); // nn 12344
r.setElement(5, 0x00); // en 7
r.setElement(6, 0x07); // en 7
r.setElement(7, 0x01); // ev index 1
t.getCanListener().reply(r);
assertEquals( 2, t.getNodeEventManager().getTotalNodeEvents(), "CBUS_ENRSP 2");
assertEquals(0.5625 ,t.getNodeStats().floatPercentageRemaining(), 0.0001f );
assertEquals( 1, t.getNodeEventManager().getLoadedNodeEvents(), "getLoadedNodeEvents 1");
assertEquals( 6, t.getNodeEventManager().getOutstandingEvVars(), "getOutstandingEvVars 3");
assertFalse( t.getNodeEventManager().isEventIndexValid(), "isEventIndexValid false");
r = new CanReply();
r.setHeader(tcis.getCanid());
r.setNumDataElements(8);
r.setElement(0, CbusConstants.CBUS_ENRSP);
r.setElement(1, 0x30); // nn 12345
r.setElement(2, 0x39); // nn 12345
r.setElement(3, 0x30); // nn 12344
r.setElement(4, 0x38); // nn 12344
r.setElement(5, 0x00); // en 4
r.setElement(6, 0x04); // en 4
r.setElement(7, 0x03); // ev index 3
t.getCanListener().reply(r);
assertEquals( 2, t.getNodeEventManager().getTotalNodeEvents(), "CBUS_ENRSP 2 again");
assertEquals(0.625 ,t.getNodeStats().floatPercentageRemaining(), 0.0001f );
assertTrue( t.getNodeEventManager().isEventIndexValid(), "isEventIndexValid true");
assertFalse( t.getNodeTimerManager().hasActiveTimers(), "No active timer after NERD / ENRSP responses");
assertEquals( 2, t.getNodeEventManager().getLoadedNodeEvents(), "getLoadedNodeEvents 2");
JUnitUtil.waitFor( () -> tcis.outbound.size() > 1, "Node sends message via Model");
assertEquals( 2 ,tcis.outbound.size(), "Node has sent a message via model " + tcis.outbound);
assertEquals( "[5f8] 9C 30 39 01 01",
tcis.outbound.elementAt(tcis.outbound.size() - 1).toString(),
"Node sends ev var request");
assertTrue( t.getNodeTimerManager().hasActiveTimers(), "active timer true awaiting response");
r = new CanReply();
r.setHeader(tcis.getCanid());
r.setNumDataElements(6);
r.setElement(0, CbusConstants.CBUS_NEVAL);
r.setElement(1, 0x30); // nn 12345
r.setElement(2, 0x39); // nn 12345
r.setElement(3, 0x01); // ev index
r.setElement(4, 0x01); // ev var index
r.setElement(5, 0x00); // ev var value
t.getCanListener().reply(r);
assertEquals(0.6875 ,t.getNodeStats().floatPercentageRemaining(), 0.0001f );
assertFalse( t.getNodeTimerManager().hasActiveTimers(), "No active timer after NEVAL response");
JUnitUtil.waitFor( () -> tcis.outbound.size() > 2, "Node sends message 2 via Model");
assertEquals( 3 ,tcis.outbound.size(), "Node has sent a message via model");
assertEquals( "[5f8] 9C 30 39 01 02",
tcis.outbound.elementAt(tcis.outbound.size() - 1).toString(),
"Node sends ev var request");
r.setElement(4, 0x02); // ev var index
r.setElement(5, 0xff); // ev var value
t.getCanListener().reply(r);
assertEquals(0.75 ,t.getNodeStats().floatPercentageRemaining(), 0.0001f );
JUnitUtil.waitFor(() -> tcis.outbound.size() > 3, "tcis outbound has 4, was " + tcis.outbound);
assertEquals( 4, tcis.outbound.size(), "Node has sent message 4 via model " + tcis.outbound );
assertEquals( "[5f8] 9C 30 39 01 03", tcis.outbound.elementAt(tcis.outbound.size() - 1).toString(),
"Node sends ev var request " + tcis.outbound);
r.setElement(4, 0x03); // ev var index
r.setElement(5, 0xd1); // ev var value
t.getCanListener().reply(r);
assertEquals(0.8125 ,t.getNodeStats().floatPercentageRemaining(), 0.0001f );
JUnitUtil.waitFor(() -> tcis.outbound.size() > 4, "tcis outbound has 5, was " + tcis.outbound);
assertEquals( "[5f8] 9C 30 39 03 01",
tcis.outbound.elementAt(tcis.outbound.size() - 1).toString(),
"Node sends ev var request index 3");
r.setElement(3, 0x03); // ev index
r.setElement(4, 0x01); // ev var index
r.setElement(5, 0xd1); // ev var value
t.getCanListener().reply(r);
assertEquals(0.875 ,t.getNodeStats().floatPercentageRemaining(), 0.0001f );
assertEquals( 0, t.getNodeBackupManager().getNumCompleteBackups(),
"0 Backups in middle of fetch");
JUnitUtil.waitFor(() -> tcis.outbound.size() > 5, "tcis outbound has 6, was " + tcis.outbound);
r.setElement(4, 0x02); // ev var index
r.setElement(5, 0xd1); // ev var value
t.getCanListener().reply(r);
assertEquals(0.9375 ,t.getNodeStats().floatPercentageRemaining(), 0.0001f );
JUnitUtil.waitFor(() -> tcis.outbound.size() > 6, "tcis outbound has 7, was " + tcis.outbound);
r.setElement(4, 0x03); // ev var index
r.setElement(5, 0xd1); // ev var value
t.getCanListener().reply(r);
assertEquals(1.0 ,t.getNodeStats().floatPercentageRemaining(), 0.0001f );
tModel.sendNextBackgroundFetch(); // all done, should send nothing
assertEquals( 7 ,tcis.outbound.size(), "Node has NOT sent a message via model");
assertFalse( t.getNodeTimerManager().hasActiveTimers(), "No active timer after event fetch complete");
// check if node has loaded an xml file
assertNotNull( t.getNodeBackupManager().getFirstBackupTime(), "First Backup Timestamp exists");
assertNotNull( t.getNodeBackupManager().getLastBackupTime(), "Last Backup Timestamp exists");
assertEquals( t.getNodeBackupManager().getSessionBackupStatus(),CbusNodeConstants.BackupType.COMPLETE,
"Backup Complete");
assertTrue(t.getNodeBackupManager().removeNode(false));
tModel.dispose();
t.dispose();
}
@Test
public void testAddNodeVariables() {
CbusNode t = new CbusNode(memo,12345);
assertNull( t.getNodeNvManager().getNvArray(), "default getNvArray ");
assertEquals( -1, t.getNodeNvManager().getNV(0), "default getNv 0 ");
assertEquals( -1, t.getNodeNvManager().getNV(3), "default getNv 3 ");
assertEquals( -1, t.getNodeNvManager().getOutstandingNvCount(), "default getOutstandingNvCount");
// set node to 3 node vars , param6
t.getNodeParamManager().setParameters(new int[]{7,1,2,3,4,5,3,7});
assertNotNull( t.getNodeNvManager().getNvArray(), "3 node vars getNvArray ");
assertEquals( 3, t.getNodeNvManager().getNV(0), "3 node vars getNv 0");
assertEquals( -1, t.getNodeNvManager().getNV(3), "3 node vars getNv 3");
assertEquals( 3, t.getNodeNvManager().getOutstandingNvCount(), "3 node vars getOutstandingNvCount ");
t.getNodeNvManager().setNV(1,1);
t.getNodeNvManager().setNV(2,2);
t.getNodeNvManager().setNV(3,3);
assertEquals( 0, t.getNodeNvManager().getOutstandingNvCount(), "node vars getOutstandingNvCount");
// setNVs
t.dispose();
}
@Test
public void testErrorsFromCan() {
CbusNode t = new CbusNode(memo,12345);
// set node to 4 ev vars per event
t.getNodeParamManager().setParameters(new int[]{8,1,2,3,4,4,6,7,8});
CanReply r = new CanReply();
r.setHeader(tcis.getCanid());
r.setNumDataElements(4);
r.setElement(0, CbusConstants.CBUS_CMDERR);
r.setElement(1, 0x30); // nn 12345
r.setElement(2, 0x39); // nn 12345
r.setElement(3, 0xff); // error 255 does not exist
t.getCanListener().reply(r);
JUnitAppender.assertErrorMessageStartsWith("Node 12345 Reporting Error Code 255 (decimal)");
r.setElement(3, 0x00); // error 0 does not exist
t.getCanListener().reply(r);
JUnitAppender.assertErrorMessageStartsWith("Node 12345 Reporting Error Code 0 (decimal)");
r.setElement(3, 0x04); // error code 4
t.getCanListener().reply(r);
JUnitAppender.assertErrorMessageStartsWith("Node 12345 reporting ERROR : Too Many Events");
t.dispose();
}
@Test
public void testgetNodeTypeString() {
CbusNode t = new CbusNode(memo,12345);
t.getNodeParamManager().setParameters(new int[]{8,165,89,10,4,5,3,4,8});
assertEquals( "MERG Command Station CANCMD Firmware ver: 4Y Node 12345",
t.getNodeParamManager().getNodeTypeString(),
"165 10 getNodeTypeString ");
t.getNodeParamManager().setParameters(new int[]{20,70,90,4,4,5,3,4,8,9,10,11,12,13,14,15,16,17,18,19,77});
assertEquals( "ROCRAIL 8 channel RFID reader. CANGC4 Firmware ver: 4Z Beta 77 Node 12345",
t.getNodeParamManager().getNodeTypeString(),
"70 4 getNodeTypeString ");
t.getNodeParamManager().setParameters(new int[]{8,0,89,0,4,5,3,4,8});
assertEquals("",t.getNodeStats().getNodeTypeName(), "0 0 getNodeTypeName");
t.setNodeNameFromName("Alonso");
assertEquals( "Alonso",t.getNodeStats().getNodeTypeName(),"0 0 Alonso getNodeTypeName");
t.dispose();
}
@BeforeEach
public void setUp(@TempDir File folder) throws java.io.IOException {
JUnitUtil.setUp();
JUnitUtil.resetInstanceManager();
JUnitUtil.resetProfileManager(new jmri.profile.NullProfile(folder));
memo = new CanSystemConnectionMemo();
tcis = new TrafficControllerScaffold();
memo.setTrafficController(tcis);
memo.setProtocol(jmri.jmrix.can.CanConfigurationManager.MERGCBUS);
}
@AfterEach
public void tearDown() {
tcis.terminateThreads();
memo.dispose();
tcis = null;
memo = null;
JUnitUtil.tearDown();
}
// private static final Logger log = LoggerFactory.getLogger(CbusNodeTest.class);
}