Files
JIMRI/java/test/jmri/jmrix/can/cbus/node/CbusAllocateNodeNumberTest.java
T
2026-06-17 14:00:51 +02:00

314 lines
11 KiB
Java

package jmri.jmrix.can.cbus.node;
import java.io.IOException;
import java.io.File;
import jmri.jmrix.can.*;
import jmri.jmrix.can.cbus.*;
import jmri.jmrix.can.cbus.simulator.moduletypes.MergCanpan;
import jmri.util.JUnitAppender;
import jmri.util.JUnitUtil;
import jmri.util.junit.annotations.DisabledIfHeadless;
import jmri.util.swing.JemmyUtil;
import org.junit.jupiter.api.*;
import org.junit.jupiter.api.io.TempDir;
import org.netbeans.jemmy.operators.*;
import static org.junit.jupiter.api.Assertions.*;
/**
*
* @author Paul Bender Copyright (C) 2017
* @author Steve Young Copyright (C) 2019
*/
public class CbusAllocateNodeNumberTest {
@Test
public void testCTor() {
assertEquals(2, tcis.numListeners(),"2 listener " + tcis.getListeners());
CbusAllocateNodeNumber t = new CbusAllocateNodeNumber(memo,nodeModel);
assertNotNull(t);
assertEquals(3, tcis.numListeners(),"3 listeners " + tcis.getListeners());
t.dispose();
assertEquals(2, tcis.numListeners(),"2 listener after dispose " + tcis.getListeners());
}
@Test
@DisabledIfHeadless
public void testDisplayDialogue() {
memo.get(CbusPreferences.class).setAddNodes(false);
CbusAllocateNodeNumber t = new CbusAllocateNodeNumber(memo,nodeModel);
assertNotNull(t);
CbusNode node789 = nodeModel.provideNodeByNodeNum(789);
assertNotNull(node789);
// configure dummy node as CANPAN so no parameters are requested for it
new MergCanpan().configureDummyNode(node789);
// create a thread that waits to close the dialog box opened later
Thread dialog_thread = new Thread(() -> {
// constructor for jdo will wait until the dialog is visible
JDialogOperator jdo = new JDialogOperator(Bundle.getMessage("NdEntrNumTitle",String.valueOf(1234)));
JLabelOperator labelOper = new JLabelOperator(jdo, Bundle.getMessage("NdRqNdDetails"));
assertNotNull(labelOper);
JUnitUtil.waitFor(()->{ return( tcis.outbound.size() == 1); }, "1 outbound " + tcis.getTranslatedOutbound());
assertEquals("[5f8] 10", tcis.outbound.elementAt(0).toString(),"Request node parameters(RQNP)");
CanReply rs = new CanReply();
rs.setNumDataElements(7);
rs.setElement(0, CbusConstants.CBUS_PARAMS); // Node sends Parameters
rs.setElement(1, 0x01); // param 1 - The manufacturer ID as a HEX numeric
rs.setElement(2, 0x02); // param 2 - Minor code version
rs.setElement(3, 0x03); // param 3 -
rs.setElement(4, 0x04); // param 4 -
rs.setElement(5, 0x05); // param 5 -
rs.setElement(6, 0x06); // param 6 -
rs.setElement(7, 0x07); // param 7 -
assertNotNull(t);
t.reply(rs);
JLabelOperator labelOper2 = new JLabelOperator(jdo, CbusNodeConstants.getManu(1));
assertNotNull(labelOper2);
JUnitUtil.waitFor(()->{ return( tcis.outbound.size() == 2); }, "2 outbound " + tcis.getTranslatedOutbound());
assertEquals("[5f8] 11", tcis.outbound.elementAt(1).toString(),"Request module name (RQMN)");
CanReply rsn = new CanReply();
rsn.setNumDataElements(7);
rsn.setElement(0, CbusConstants.CBUS_NAME); // Node sends Name
rsn.setElement(1, 67); // C
rsn.setElement(2, 65); // A
rsn.setElement(3, 84); // T
rsn.setElement(4, 70); // F
rsn.setElement(5, 76); // L
rsn.setElement(6, 65); // A
rsn.setElement(7, 80); // P
assertNotNull(t);
t.reply(rsn);
JLabelOperator labelOper3 = new JLabelOperator(jdo, "Manufacturer 1 CANCATFLAP");
assertNotNull(labelOper3);
JSpinnerOperator spinner = new JSpinnerOperator(jdo, 0);
JTextFieldOperator jtfo = new JTextFieldOperator(spinner);
assertEquals("1234",jtfo.getText());
jtfo.setText("123");
JLabelOperator labelOper4 = new JLabelOperator(jdo, CbusNodeConstants.getReservedModule(123));
assertNotNull(labelOper4);
// JUnitUtil.waitFor(1000);
jtfo.setText("789");
JLabelOperator labelOper5 = new JLabelOperator(jdo,
Bundle.getMessage("NdNumInUse",nodeModel.getNodeNumberName(789)));
assertNotNull(labelOper5);
// JUnitUtil.waitFor(1000);
jtfo.setText("120");
// JUnitUtil.waitFor(1000);
CanMessage rmes = new CanMessage(tcis.getCanid());
rmes.setNumDataElements(1);
rmes.setElement(0, CbusConstants.CBUS_QNN); // All Modules respond to Query Node Numbers
t.message(rmes); // ignored as dialogue already open
jtfo.setText("65432");
// JUnitUtil.waitFor(1000);
JemmyUtil.pressButton(jdo, "OK");
jdo.waitClosed();
});
dialog_thread.setName("CbusAllocateNodeNumber Dialog Close Thread");
dialog_thread.start();
CanReply r = new CanReply();
r.setHeader(tcis.getCanid());
r.setNumDataElements(3);
r.setElement(0, CbusConstants.CBUS_ERR); // Command Station Error, to be ignored.
r.setElement(1, 0x04); // node 1234
r.setElement(2, 0xd2); // node 1234
t.reply(r); // ignored
r.setElement(0, CbusConstants.CBUS_RQNN); // Node Requests Node Number
r.setExtended(true);
t.reply(r); // ignored
r.setExtended(false);
t.reply(r);
JUnitUtil.waitFor(()->{return !(dialog_thread.isAlive());}, "checkCbus Allocate Node Num Dialog finished");
JUnitUtil.waitFor(()->{ return( tcis.outbound.size() >2); }, "Outbound did not increase: " + tcis.getTranslatedOutbound());
assertEquals("[5f8] 42 FF 98", tcis.outbound.elementAt(2).toString(),"3rd message not right "
+ tcis.getTranslatedOutbound());
// The Node sends a message back acknowledging the Name.
// If this message is not heard, presents user with JDialog / error in log.
r = new CanReply();
r.setHeader(tcis.getCanid());
r.setNumDataElements(3);
r.setElement(0, CbusConstants.CBUS_NNACK); // Node number acknowledge
r.setElement(1, 65432 >> 8);
r.setElement(2, 65432 & 0xff);
t.reply(r);
t.dispose();
}
@Test
public void testAddNodes() {
CbusAllocateNodeNumber t = new CbusAllocateNodeNumber(memo,nodeModel);
memo.get(CbusPreferences.class).setAddNodes(true);
CanReply rsna = new CanReply();
rsna.setNumDataElements(3);
rsna.setElement(0, CbusConstants.CBUS_NNACK); // node number acknowledge
rsna.setElement(1, 0xff); // 65432
rsna.setElement(2, 0x98); // 65432
t.reply(rsna);
// check that RTSTAT sent to command stations
JUnitUtil.waitFor(()->{ return( !tcis.outbound.isEmpty()); }, "TCIS count did not increase " + tcis.getTranslatedOutbound());
assertEquals("[5f8] 0C", tcis.outbound.elementAt(0).toString());
assertNotNull(nodeModel.getNodeByNodeNum(65432));
t.dispose();
}
@Test
@DisabledIfHeadless
public void testCanMessage() {
CbusAllocateNodeNumber t = new CbusAllocateNodeNumber(memo,nodeModel);
CanMessage r = new CanMessage(tcis.getCanid());
r.setNumDataElements(1);
r.setElement(0, CbusConstants.CBUS_HLT); // Bus Halt Command, to be ignored.
t.message(r); // ignored as not interested in this OPC
assertEquals(0, tcis.outbound.size());
r.setElement(0, CbusConstants.CBUS_QNN); // All Modules respond to Query Node Numbers
r.setExtended(true);
t.message(r); // ignored as Extended
assertEquals(0, tcis.outbound.size());
r.setExtended(false);
t.message(r); // output expected to be a Request Params Setup
assertEquals(1, tcis.outbound.size());
assertEquals("[5f8] 10", tcis.outbound.elementAt(0).toString(), tcis.getTranslatedOutbound());
t.dispose();
}
@Test
@DisabledIfHeadless
public void testAllocateTimeout() {
CbusAllocateNodeNumber t = new CbusAllocateNodeNumber(memo,nodeModel);
t.setTimeout(5); // default is reduced to speed up test
// create a thread that waits to close the dialog box opened later
Thread dialog_thread = new Thread(() -> {
// constructor for jdo will wait until the dialog is visible
JDialogOperator jdo = new JDialogOperator(Bundle.getMessage("NdEntrSlimTitle"));
JSpinnerOperator spinner = new JSpinnerOperator(jdo, 0);
JTextFieldOperator jtfo = new JTextFieldOperator(spinner);
jtfo.setText("12345");
JemmyUtil.pressButton(jdo, "OK");
jdo.waitClosed();
});
dialog_thread.setName("CbusAllocateNodeNumber Allocate Timeout Dialog Close Thread");
dialog_thread.start();
Thread popup_thread = new Thread(() -> {
// constructor for jdo will wait until the dialog is visible
JDialogOperator jdoo = new JDialogOperator(Bundle.getMessage("WarningTitle"));
JemmyUtil.pressButton(jdoo, "OK");
jdoo.waitClosed();
});
popup_thread.setName("CbusAllocateNodeNumber Allocate Timeout Popup Close Thread");
popup_thread.start();
CanReply r = new CanReply();
r.setHeader(tcis.getCanid());
r.setNumDataElements(3);
r.setElement(0, CbusConstants.CBUS_RQNN); // Node Requests Node Number
r.setElement(1, 0x00); // node 0
r.setElement(2, 0x00); // node 0
t.reply(r);
JUnitUtil.waitFor(()->{return tcis.outbound.size()>1;}, "2 outbound sent" + tcis.outbound);
JUnitUtil.waitFor(()->{return !(dialog_thread.isAlive());}, "checkCbus Allocate Node Num Dialog finished");
JUnitUtil.waitFor(()->{return !(popup_thread.isAlive());}, "Cbus Allocate Node Num Timout Dialog finished");
JUnitAppender.assertErrorMessageStartsWith("No confirmation from node when setting node number 12345");
t.dispose();
}
private CanSystemConnectionMemo memo;
private CbusTrafficControllerScaffold tcis;
private CbusNodeTableDataModel nodeModel;
@BeforeEach
public void setUp(@TempDir File tempDir) throws IOException {
JUnitUtil.setUp();
JUnitUtil.resetInstanceManager();
JUnitUtil.resetProfileManager( new jmri.profile.NullProfile( tempDir));
memo = new CanSystemConnectionMemo();
tcis = new CbusTrafficControllerScaffold(memo);
memo.setProtocol(jmri.jmrix.can.CanConfigurationManager.SPROGCBUS);
memo.get(CbusPreferences.class).setAllocateNNListener(false);
nodeModel = memo.get(CbusConfigurationManager.class)
.provide(CbusNodeTableDataModel.class);
}
@AfterEach
public void tearDown() {
nodeModel.dispose();
nodeModel = null;
memo.dispose();
memo = null;
tcis.terminateThreads();
tcis = null;
JUnitUtil.tearDown();
}
// private static final Logger log = LoggerFactory.getLogger(CbusAllocateNodeNumberTest.class);
}