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

213 lines
7.7 KiB
Java

package jmri.jmrix.lenz;
import java.io.IOException;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import jmri.util.JUnitUtil;
import org.junit.jupiter.api.*;
/**
* Tests for the jmri.jmrix.XNetPacketizer package
*
* @author Bob Jacobsen Copyrgiht (C) 2002
* @author Paul Bender Copyright (C) 2016
*/
public class XNetPacketizerTest extends XNetTrafficControllerTest {
protected XNetPortControllerScaffold port = null;
/**
* Local test class to make XNetPacketizer more felicitous to test
*/
static class StoppingXNetPacketizer extends XNetPacketizer {
StoppingXNetPacketizer(jmri.jmrix.lenz.LenzCommandStation p) {
super(p);
}
// methods removed for testing
@Override
protected void handleTimeout(jmri.jmrix.AbstractMRMessage msg, jmri.jmrix.AbstractMRListener l) {
} // don't care about timeout
@Override
protected void reportReceiveLoopException(Exception e) {
}
@Override
protected void portWarn(Exception e) {
}
}
@Test
public void testOutbound() throws IOException {
XNetPacketizer c = (XNetPacketizer) tc;
// connect to iostream via port controller scaffold
tc.connectPort(port);
XNetMessage m = XNetMessage.getTurnoutCommandMsg(22, true, false, true);
m.setTimeout(1); // don't want to wait a long time
c.sendXNetMessage(m, null);
port.flush();
JUnitUtil.waitFor(() -> port.tostream.available() == 4, "total length 4");
assertEquals( 4, port.tostream.available(), "total length ");
assertEquals( 0x52, port.tostream.readByte() & 0xff, "Char 0");
assertEquals( 0x05, port.tostream.readByte() & 0xff, "Char 1");
assertEquals( 0x8A, port.tostream.readByte() & 0xff, "Char 2");
assertEquals( 0xDD, port.tostream.readByte() & 0xff, "parity");
assertEquals( 0, port.tostream.available(), "remaining ");
}
@Test
public void testInbound() throws IOException {
XNetPacketizer c = (XNetPacketizer) tc;
// connect to iostream via port controller scaffold
tc.connectPort(port);
// object to receive reply
XNetListenerScaffold l = new XNetListenerScaffold();
c.addXNetListener(~0, l);
// now send reply
port.tistream.write(0x52);
port.tistream.write(0x12);
port.tistream.write(0x12);
port.tistream.write(0x52);
port.flush();
JUnitUtil.waitFor(() -> l.rcvdRply != null, "reply received");
// check that the message was picked up by the read thread.
assertNotNull( l.rcvdRply, "reply received ");
assertEquals( 0x52, l.rcvdRply.getElement(0), "first char of reply ");
}
@Test
public void testInterference() throws IOException {
// This test checks to make sure that when two listeners register for events
// at the same time, the first listener is still the active listener until
// it receives a message.
XNetPacketizer c = (XNetPacketizer) tc;
// connect to iostream via port controller scaffold
tc.connectPort(port);
// We need three objects to receive messages.
// The first one receives broadcast messages.
// The others only receive directed messages.
XNetListenerScaffold l = new XNetListenerScaffold();
XNetListenerScaffold l1 = new XNetListenerScaffold();
XNetListenerScaffold l2 = new XNetListenerScaffold();
c.addXNetListener(~0, l);
// we're going to loop through this, because we're trying to catch
// a threading/synchronization issue in AbstractMRTrafficController.
for (int i = 0; i < 5; i++) {
l.rcvdRply = null;
l1.rcvdRply = null;
l2.rcvdRply = null;
// first, we send an unsolicited message
port.tistream.write(0x42);
port.tistream.write(0x12);
port.tistream.write(0x12);
port.tistream.write(0x42);
port.flush();
JUnitUtil.waitFor(() -> l.rcvdRply != null, "reply received");
// check that the message was picked up by the read thread.
assertNotNull( l.rcvdRply, "iteration " + i + " reply received ");
assertEquals( 0x42, l.rcvdRply.getElement(0), "iteration " + i + " first char of broadcast reply to l");
// now we need to send a message with both the second and third listeners
// as reply receiver.
XNetMessage m = XNetMessage.getTurnoutCommandMsg(22, true, false, true);
c.sendXNetMessage(m, l1);
XNetMessage m1 = XNetMessage.getTurnoutCommandMsg(23, true, false, true);
c.sendXNetMessage(m1, l2);
port.flush();
// and now we verify l1 is the last sender.
JUnitUtil.waitFor(() -> l1 == c.getLastSender(), "iteration " + i + " Last Sender l1, before l1 reply");
l.rcvdRply = null;
l1.rcvdRply = null;
l2.rcvdRply = null;
// Now we reply to the messages above
port.tistream.write(0x01);
port.tistream.write(0x04);
port.tistream.write(0x05);
port.flush();
JUnitUtil.waitFor(() -> l1.rcvdRply != null, "iteration " + i + " reply received ");
// check that the message was picked up by the read thread.
assertNotNull( l1.rcvdRply, "iteration " + i + " reply received ");
assertEquals( 0x01, l1.rcvdRply.getElement(0), "iteration " + i + " first char of reply to l1");
assertNotNull( l.rcvdRply, "iteration " + i + " broadcast reply after l1 message");
assertNotNull( l1.rcvdRply, "iteration " + i + " l1 reply after l1 message");
assertNull( l2.rcvdRply, "iteration " + i + " l2 reply after l1 message");
// and now we verify l2 is the last sender.
JUnitUtil.waitFor(() -> l2 == c.getLastSender(), "Last Sender l2");
l.rcvdRply = null;
l1.rcvdRply = null;
l2.rcvdRply = null;
port.tistream.write(0x01);
port.tistream.write(0x04);
port.tistream.write(0x05);
port.flush();
JUnitUtil.waitFor(() -> l2.rcvdRply != null, "iteration " + i + " reply received ");
// check that the message was picked up by the read thread.
assertNotNull( l2.rcvdRply, "iteration " + i + " reply received ");
assertEquals( 0x01, l2.rcvdRply.getElement(0), "iteration " + i + " first char of reply to l2");
assertNotNull( l.rcvdRply, "iteration " + i + " broadcast reply after l2 message");
assertNull( l1.rcvdRply, "iteration " + i + " l1 reply after l2 message");
assertNotNull( l2.rcvdRply, "iteration " + i + " l2 reply after l2 message");
l.rcvdRply = null;
l1.rcvdRply = null;
l2.rcvdRply = null;
assertEquals( 3 * (i + 1), l.getRcvCount(), "iteration " + i + " l received count ");
}
}
@BeforeEach
@Override
public void setUp() {
JUnitUtil.setUp();
LenzCommandStation lcs = new LenzCommandStation();
tc = new StoppingXNetPacketizer(lcs);
port = assertDoesNotThrow( () -> new XNetPortControllerScaffold(), "Error creating test port");
}
@AfterEach
@Override
public void tearDown() {
tc.terminateThreads();
tc = null;
port.dispose();
port = null;
JUnitUtil.tearDown();
}
}