ADMOPSLA and ADMCHART are happier
Build and Test j3270 / Build JAR & Run Tests (push) Successful in 1m7s
Build and Test j3270 / Build JAR & Run Tests (push) Successful in 1m7s
This commit is contained in:
@@ -232,4 +232,30 @@ public class QueryReplyBuilderTest {
|
||||
assertEquals(0x07, replies[descOffset + 49] & 0xFF);
|
||||
assertEquals(0xC0, replies[descOffset + 49 + 1] & 0xFF);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryReplyImageAndRpqNames() {
|
||||
qrBuilder.setGraphicsMode(GraphicsMode.BOTH);
|
||||
byte[] requested = new byte[] { (byte) QR_IMAGE, (byte) QR_RPQNAMES, (byte) QR_GIMAGE };
|
||||
byte[] replies = qrBuilder.buildQueryReplies(requested, 80, 43, 80 * 43);
|
||||
|
||||
assertNotNull(replies);
|
||||
assertEquals((byte) AID_SF, replies[0]);
|
||||
|
||||
// First SF should be QR_NULL (0xFF) because 0x82 is 3270 Image SF (not supported on 3179G)
|
||||
int len1 = ((replies[1] & 0xFF) << 8) | (replies[2] & 0xFF);
|
||||
assertEquals(0x81, replies[3] & 0xFF); // SFID_QREPLY
|
||||
assertEquals(QR_NULL, replies[4] & 0xFF); // 0xFF
|
||||
|
||||
// Second SF should be QR_RPQNAMES (0xA1) matching requested code
|
||||
int pos2 = 1 + len1;
|
||||
int len2 = ((replies[pos2] & 0xFF) << 8) | (replies[pos2 + 1] & 0xFF);
|
||||
assertEquals(0x81, replies[pos2 + 2] & 0xFF);
|
||||
assertEquals(QR_RPQNAMES, replies[pos2 + 3] & 0xFF); // 0xA1
|
||||
|
||||
// Third SF should be QR_GIMAGE (0xB1)
|
||||
int pos3 = pos2 + len2;
|
||||
assertEquals(0x81, replies[pos3 + 2] & 0xFF);
|
||||
assertEquals(QR_GIMAGE, replies[pos3 + 3] & 0xFF); // 0xB1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,6 +158,7 @@ public class GocaDecoderTest {
|
||||
|
||||
byte[] stream = out.toByteArray();
|
||||
decoder.decodeStream(stream, 0, stream.length);
|
||||
|
||||
assertTrue(plane.hasContent());
|
||||
}
|
||||
|
||||
@@ -203,7 +204,7 @@ public class GocaDecoderTest {
|
||||
|
||||
// 0xA1: Relative Line from Current Position: (+10, +20), (-5, -10)
|
||||
out.write(GocaConstants.G_GCRLIN);
|
||||
out.write(0x04); // len = 4 (2 steps)
|
||||
out.write(0x04); // len = 4 (2 deltas * 2 bytes)
|
||||
out.write(0x0A); out.write(0x14); // dx = +10, dy = +20
|
||||
out.write(0xFB); out.write(0xF6); // dx = -5, dy = -10
|
||||
|
||||
@@ -217,21 +218,74 @@ public class GocaDecoderTest {
|
||||
|
||||
@Test
|
||||
public void test3179GCoordinateMapping() {
|
||||
GraphicsPlane plane = new GraphicsPlane(720, 688);
|
||||
GraphicsPlane plane = new GraphicsPlane(720, 516);
|
||||
plane.setScreenDimensions(80, 43);
|
||||
|
||||
// Screen center (0, 0) should map to canvas center (360, 343)
|
||||
// Screen center (0, 0) should map to canvas center (360, 257)
|
||||
assertEquals(360, plane.mapX(0));
|
||||
assertEquals(343, plane.mapY(0));
|
||||
assertEquals(257, plane.mapY(0));
|
||||
|
||||
// Left edge (-360) should map to 0
|
||||
assertEquals(0, plane.mapX(-360));
|
||||
// Right edge (+359) should map to 719
|
||||
assertEquals(719, plane.mapX(359));
|
||||
|
||||
// Top edge (+343) should map to 0
|
||||
assertEquals(0, plane.mapY(343));
|
||||
// Bottom edge (-344) should map to 687
|
||||
assertEquals(687, plane.mapY(-344));
|
||||
// Top edge (+257) should map to 0
|
||||
assertEquals(0, plane.mapY(257));
|
||||
// Bottom edge (-258) should map to 515
|
||||
assertEquals(515, plane.mapY(-258));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImageOrdersGbimgGimdGeimg() {
|
||||
GraphicsPlane plane = new GraphicsPlane(400, 300);
|
||||
GocaDecoder decoder = new GocaDecoder(plane);
|
||||
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
// G_GBIMG (0xD1): Begin Image: order, len=8, x=100, y=100, w=16, h=2
|
||||
out.write(GocaConstants.G_GBIMG);
|
||||
out.write(0x08);
|
||||
out.write(0x00); out.write(0x64); // x = 100
|
||||
out.write(0x00); out.write(0x64); // y = 100
|
||||
out.write(0x00); out.write(0x10); // w = 16
|
||||
out.write(0x00); out.write(0x02); // h = 2
|
||||
|
||||
// G_GIMD (0x92): Image Data: order, len=4, 4 bytes of bitmap (16x2 pixels = 32 bits = 4 bytes)
|
||||
out.write(GocaConstants.G_GIMD);
|
||||
out.write(0x04);
|
||||
out.write(0xFF); out.write(0x00);
|
||||
out.write(0xAA); out.write(0x55);
|
||||
|
||||
// G_GEIMG (0x91): End Image
|
||||
out.write(GocaConstants.G_GEIMG);
|
||||
out.write(0x00);
|
||||
|
||||
byte[] stream = out.toByteArray();
|
||||
decoder.decodeStream(stream, 0, stream.length);
|
||||
|
||||
assertTrue(plane.hasContent(), "Expected plane to have content after image decoding");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDirectObjectControlSf24() {
|
||||
org.lib3270j.screen.ScreenBuffer sb = new org.lib3270j.screen.ScreenBuffer(
|
||||
org.lib3270j.TerminalModel.IBM_3279_4, new org.lib3270j.charset.EbcdicTranslator());
|
||||
org.lib3270j.datastream.DataStreamProcessor dsp = new org.lib3270j.datastream.DataStreamProcessor(
|
||||
sb, new org.lib3270j.charset.EbcdicTranslator());
|
||||
|
||||
// First draw something on graphics plane
|
||||
dsp.getGraphicsPlane().setPixel(10, 10, 0xFFFFFFFF);
|
||||
assertTrue(dsp.getGraphicsPlane().hasContent());
|
||||
|
||||
// Send WSF with SF_OBJCNTL (0x24) containing P_ERASE (0x0A)
|
||||
byte[] wsf = new byte[] {
|
||||
(byte) org.lib3270j.protocol.DS3270Constants.CMD_WSF,
|
||||
0x00, 0x04, // Field length = 4
|
||||
(byte) org.lib3270j.graphics.GocaConstants.SF_OBJCNTL, // 0x24
|
||||
(byte) org.lib3270j.graphics.GocaConstants.P_ERASE // 0x0A
|
||||
};
|
||||
dsp.processRecord(wsf, 0, wsf.length, false);
|
||||
|
||||
assertFalse(dsp.getGraphicsPlane().hasContent(), "Expected graphics plane to be cleared after SF_OBJCNTL P_ERASE");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,4 +131,26 @@ public class InputProcessorTest {
|
||||
assertEquals(0, screen.getDisplayCell(2).ucs4);
|
||||
assertEquals('A', screen.getDisplayCell(1).ucs4);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGraphicInputBuilderStructure() {
|
||||
byte[] sf = org.lib3270j.graphics.GraphicInputBuilder.buildGraphicInput(100, -50, AID_ENTER, false, false, false);
|
||||
assertEquals(56, sf.length);
|
||||
assertEquals(0x00, sf[0]);
|
||||
assertEquals(0x34, sf[1]); // Length = 52
|
||||
assertEquals(0x0F, sf[2]); // SF ID = 0x0F
|
||||
assertEquals(0x0F, sf[3]); // SF ID = 0x0F
|
||||
|
||||
// Coordinates
|
||||
int x = (sf[24] << 8) | (sf[25] & 0xFF);
|
||||
int y = (sf[26] << 8) | (sf[27] & 0xFF);
|
||||
assertEquals(100, (short) x);
|
||||
assertEquals(-50, (short) y);
|
||||
|
||||
// Keyboard AID
|
||||
assertEquals(0x07, sf[31]);
|
||||
assertEquals(0x07, sf[33]);
|
||||
assertEquals((byte) 0xFF, sf[34]);
|
||||
assertEquals((byte) AID_ENTER, sf[35]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,4 +219,79 @@ public class TelnetFSMTest {
|
||||
assertEquals('L', trans.ebcdicToUnicode(screenBuffer.getCellEC(3)));
|
||||
assertEquals('O', trans.ebcdicToUnicode(screenBuffer.getCellEC(4)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTelnetTimingMarkOption6() {
|
||||
fsm.onConnected();
|
||||
connection.sentData.clear();
|
||||
|
||||
// Host sends DO TELOPT_TM (DO 6) -> Client must reply WILL TELOPT_TM (WILL 6) per RFC 860
|
||||
feedBytes(TelnetConstants.IAC, TelnetConstants.DO, TelnetConstants.TELOPT_TM);
|
||||
boolean foundWillTm = false;
|
||||
for (byte[] pkt : connection.sentData) {
|
||||
if (pkt.length == 3 && (pkt[0] & 0xFF) == TelnetConstants.IAC &&
|
||||
(pkt[1] & 0xFF) == TelnetConstants.WILL && (pkt[2] & 0xFF) == TelnetConstants.TELOPT_TM) {
|
||||
foundWillTm = true;
|
||||
}
|
||||
}
|
||||
assertTrue(foundWillTm, "Expected IAC WILL TELOPT_TM reply upon receiving IAC DO TELOPT_TM");
|
||||
|
||||
// Host sends WILL TELOPT_TM (WILL 6) -> Client must reply DO TELOPT_TM (DO 6)
|
||||
connection.sentData.clear();
|
||||
feedBytes(TelnetConstants.IAC, TelnetConstants.WILL, TelnetConstants.TELOPT_TM);
|
||||
boolean foundDoTm = false;
|
||||
for (byte[] pkt : connection.sentData) {
|
||||
if (pkt.length == 3 && (pkt[0] & 0xFF) == TelnetConstants.IAC &&
|
||||
(pkt[1] & 0xFF) == TelnetConstants.DO && (pkt[2] & 0xFF) == TelnetConstants.TELOPT_TM) {
|
||||
foundDoTm = true;
|
||||
}
|
||||
}
|
||||
assertTrue(foundDoTm, "Expected IAC DO TELOPT_TM reply upon receiving IAC WILL TELOPT_TM");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIACAYT() {
|
||||
fsm.onConnected();
|
||||
connection.sentData.clear();
|
||||
|
||||
// Host sends IAC AYT
|
||||
feedBytes(TelnetConstants.IAC, TelnetConstants.AYT);
|
||||
boolean foundNop = false;
|
||||
for (byte[] pkt : connection.sentData) {
|
||||
if (pkt.length == 2 && (pkt[0] & 0xFF) == TelnetConstants.IAC && (pkt[1] & 0xFF) == TelnetConstants.NOP) {
|
||||
foundNop = true;
|
||||
}
|
||||
}
|
||||
assertTrue(foundNop, "Expected IAC NOP acknowledgment for IAC AYT");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTTypeCycling() {
|
||||
fsm.onConnected();
|
||||
connection.sentData.clear();
|
||||
|
||||
// Enable TTYPE
|
||||
feedBytes(TelnetConstants.IAC, TelnetConstants.DO, TelnetConstants.TELOPT_TTYPE);
|
||||
|
||||
// First SEND request -> Expect configured type IBM-3279-4-E
|
||||
feedBytes(TelnetConstants.IAC, TelnetConstants.SB, TelnetConstants.TELOPT_TTYPE,
|
||||
TelnetConstants.TELQUAL_SEND, TelnetConstants.IAC, TelnetConstants.SE);
|
||||
byte[] lastPkt = connection.sentData.get(connection.sentData.size() - 1);
|
||||
String resp1 = new String(lastPkt, 4, lastPkt.length - 6);
|
||||
assertEquals("IBM-3279-4-E", resp1);
|
||||
|
||||
// Second SEND request -> Expect fallback IBM-3279-4
|
||||
feedBytes(TelnetConstants.IAC, TelnetConstants.SB, TelnetConstants.TELOPT_TTYPE,
|
||||
TelnetConstants.TELQUAL_SEND, TelnetConstants.IAC, TelnetConstants.SE);
|
||||
lastPkt = connection.sentData.get(connection.sentData.size() - 1);
|
||||
String resp2 = new String(lastPkt, 4, lastPkt.length - 6);
|
||||
assertEquals("IBM-3279-4", resp2);
|
||||
|
||||
// Third SEND request -> Expect monochrome fallback IBM-3278-4-E
|
||||
feedBytes(TelnetConstants.IAC, TelnetConstants.SB, TelnetConstants.TELOPT_TTYPE,
|
||||
TelnetConstants.TELQUAL_SEND, TelnetConstants.IAC, TelnetConstants.SE);
|
||||
lastPkt = connection.sentData.get(connection.sentData.size() - 1);
|
||||
String resp3 = new String(lastPkt, 4, lastPkt.length - 6);
|
||||
assertEquals("IBM-3278-4-E", resp3);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ public class TlsConfigTest {
|
||||
assertEquals(992, c1.getPort());
|
||||
|
||||
// ssl: prefix with explicit port
|
||||
ConnectionConfig c2 = ConnectionConfig.parseHostString("ssl:zos.local:2323", 0, TerminalModel.IBM_3279_2);
|
||||
ConnectionConfig c2 = ConnectionConfig.parseHostString("ssl:zos.local:2323", 0, TerminalModel.IBM_3279_4);
|
||||
assertTrue(c2.isUseTls());
|
||||
assertEquals("zos.local", c2.getHost());
|
||||
assertEquals(2323, c2.getPort());
|
||||
|
||||
Reference in New Issue
Block a user