You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by jv...@apache.org on 2011/03/24 15:45:50 UTC
svn commit: r1084974 - in
/mina/sandbox/jvermillard/mina-modbus/src/test/java/org/apache/mina/modbus/transport:
rtu/RTUModbusDecoderMasterTest.java rtu/RTUModbusDecoderTest.java
tcp/TCPModbusDecoderMasterTest.java tcp/TCPModbusDecoderTest.java
Author: jvermillard
Date: Thu Mar 24 14:45:50 2011
New Revision: 1084974
URL: http://svn.apache.org/viewvc?rev=1084974&view=rev
Log:
fragmented frame decoding test
Modified:
mina/sandbox/jvermillard/mina-modbus/src/test/java/org/apache/mina/modbus/transport/rtu/RTUModbusDecoderMasterTest.java
mina/sandbox/jvermillard/mina-modbus/src/test/java/org/apache/mina/modbus/transport/rtu/RTUModbusDecoderTest.java
mina/sandbox/jvermillard/mina-modbus/src/test/java/org/apache/mina/modbus/transport/tcp/TCPModbusDecoderMasterTest.java
mina/sandbox/jvermillard/mina-modbus/src/test/java/org/apache/mina/modbus/transport/tcp/TCPModbusDecoderTest.java
Modified: mina/sandbox/jvermillard/mina-modbus/src/test/java/org/apache/mina/modbus/transport/rtu/RTUModbusDecoderMasterTest.java
URL: http://svn.apache.org/viewvc/mina/sandbox/jvermillard/mina-modbus/src/test/java/org/apache/mina/modbus/transport/rtu/RTUModbusDecoderMasterTest.java?rev=1084974&r1=1084973&r2=1084974&view=diff
==============================================================================
--- mina/sandbox/jvermillard/mina-modbus/src/test/java/org/apache/mina/modbus/transport/rtu/RTUModbusDecoderMasterTest.java (original)
+++ mina/sandbox/jvermillard/mina-modbus/src/test/java/org/apache/mina/modbus/transport/rtu/RTUModbusDecoderMasterTest.java Thu Mar 24 14:45:50 2011
@@ -19,6 +19,7 @@
*/
package org.apache.mina.modbus.transport.rtu;
+import java.net.SocketAddress;
import java.util.Arrays;
import java.util.Random;
@@ -26,6 +27,8 @@ import junit.framework.Assert;
import junit.framework.TestCase;
import org.apache.mina.core.buffer.IoBuffer;
+import org.apache.mina.core.service.DefaultTransportMetadata;
+import org.apache.mina.core.session.IoSessionConfig;
import org.apache.mina.filter.codec.ProtocolCodecSession;
import org.apache.mina.filter.codec.ProtocolDecoderException;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;
@@ -33,11 +36,15 @@ import org.apache.mina.modbus.ModbusCons
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
public class RTUModbusDecoderMasterTest extends TestCase {
RTUModbusDecoder decoder = new RTUModbusDecoder(true);
-
+
ProtocolCodecSession session = new ProtocolCodecSession();
+ {
+ session.setTransportMetadata(new DefaultTransportMetadata("mina", "dummy", false, true, SocketAddress.class,
+ IoSessionConfig.class, IoBuffer.class));
+ }
+
ProtocolDecoderOutput out = session.getDecoderOutput();
static final Logger LOG = LoggerFactory.getLogger(RTUModbusDecoderMasterTest.class);
@@ -77,9 +84,9 @@ public class RTUModbusDecoderMasterTest
in.putChar('A'); // some crap
in.putChar('B');
in.flip();
- //System.err.println("frame size : "+in.remaining());
+ // System.err.println("frame size : "+in.remaining());
// in.putChar('C');
- // in.putChar('x');
+ // in.putChar('x');
boolean exception = false;
try {
decoder.decode(session, in, out);
@@ -91,7 +98,7 @@ public class RTUModbusDecoderMasterTest
// 2 bytes frame
in = IoBuffer.allocate(10);
- in.put((byte) 0); //
+ in.put((byte) 0); //
in.put((byte) ModbusConstants.READ_HOLDING_REGISTERS);
in.flip();
// no exceptions
@@ -141,6 +148,111 @@ public class RTUModbusDecoderMasterTest
decoder.decode(session, in, out);
Assert.assertEquals(2, session.getDecoderOutputQueue().size());
}
+
+ public void testFragmentation() throws Exception {
+ LOG.info("Fragmentation");
+
+ // Read multiple register at address 1 and 10 values
+ RTUModbusMessage msgWrite10 = new RTUModbusMessage(1, ModbusConstants.READ_HOLDING_REGISTERS, new byte[] {
+ (byte) 20, (byte) 0, (byte) 1, (byte) 0, (byte) 2, (byte) 0, (byte) 3, (byte) 0, (byte) 4, (byte) 0,
+ (byte) 5, (byte) 0, (byte) 6, (byte) 0, (byte) 7, (byte) 0, (byte) 8, (byte) 0, (byte) 9, (byte) 0,
+ (byte) 10 });
+
+ // Read multiple register at address 1 and 5 values
+ RTUModbusMessage msgWrite5 = new RTUModbusMessage(1, ModbusConstants.READ_HOLDING_REGISTERS, new byte[] {
+ (byte) 10, (byte) 0, (byte) 1, (byte) 0, (byte) 2, (byte) 0, (byte) 3, (byte) 0, (byte) 4, (byte) 0,
+ (byte) 5 });
+
+ // Read multiple register at address 1 and 4 values
+ RTUModbusMessage msgWrite4 = new RTUModbusMessage(1, ModbusConstants.WRITE_MULTIPLE_REGISTERS, new byte[] {
+ (byte) 1, (byte) 0, (byte) 2, (byte) 0 });
+
+ IoBuffer buffPDU1 = msgWrite10.encode();
+ IoBuffer buffPDU2 = msgWrite5.encode();
+ IoBuffer buffPDU3 = msgWrite4.encode();
+ IoBuffer buffPDU123 = IoBuffer.allocate(buffPDU1.remaining() * 2 + buffPDU2.remaining()
+ + buffPDU3.remaining());
+ buffPDU123.put(buffPDU1);
+
+ buffPDU123.put(buffPDU2);
+ buffPDU123.put(buffPDU3);
+ buffPDU1.rewind();
+ buffPDU123.put(buffPDU1);
+ buffPDU123.flip(); // PDU123 = PDU1 + PDU2 + PDU3 + PDU1
+
+ buffPDU1.flip();
+ buffPDU2.flip();
+
+ // dezcode a plain buffer
+ decoder.decode(session, buffPDU1, out);
+ Assert.assertEquals(1, session.getDecoderOutputQueue().size());
+ buffPDU1.rewind();
+
+ IoBuffer buff1 = IoBuffer.allocate(4);
+ while (buff1.hasRemaining()) {
+ buff1.put(buffPDU1.get());
+ }
+
+ buff1.flip();
+ // decode a part of a PDU
+ decoder.decode(session, buff1, out);
+
+ IoBuffer buff2 = IoBuffer.allocate(buffPDU1.remaining());
+ while (buffPDU1.hasRemaining()) {
+ buff2.put(buffPDU1.get());
+ }
+ buff2.flip();
+
+ // decode the second part
+ decoder.decode(session, buff2, out);
+
+ Assert.assertEquals(2, session.getDecoderOutputQueue().size());
+
+ // decode four concatenated big PDU
+ decoder.decode(session, buffPDU123, out);
+ Assert.assertEquals(6, session.getDecoderOutputQueue().size());
+
+ // decode multiple PDU each byte per each byte
+ buffPDU123.rewind();
+ while (buffPDU123.hasRemaining()) {
+ IoBuffer bufOneByte = IoBuffer.allocate(1);
+ bufOneByte.put(buffPDU123.get());
+ bufOneByte.flip();
+ decoder.decode(session, bufOneByte, out);
+ }
+ Assert.assertEquals(10, session.getDecoderOutputQueue().size());
+
+ RTUModbusMessage msg = (RTUModbusMessage) session.getDecoderOutputQueue().poll();
+ Assert.assertTrue(samePDU(msg, msgWrite10));
+ msg = (RTUModbusMessage) session.getDecoderOutputQueue().poll();
+ Assert.assertTrue(samePDU(msg, msgWrite10));
+
+ msg = (RTUModbusMessage) session.getDecoderOutputQueue().poll();
+ Assert.assertTrue(samePDU(msg, msgWrite10));
+ msg = (RTUModbusMessage) session.getDecoderOutputQueue().poll();
+ Assert.assertTrue(samePDU(msg, msgWrite5));
+ msg = (RTUModbusMessage) session.getDecoderOutputQueue().poll();
+ Assert.assertTrue(samePDU(msg, msgWrite4));
+ msg = (RTUModbusMessage) session.getDecoderOutputQueue().poll();
+ Assert.assertTrue(samePDU(msg, msgWrite10));
+ msg = (RTUModbusMessage) session.getDecoderOutputQueue().poll();
+ Assert.assertTrue(samePDU(msg, msgWrite10));
+ }
+
+ private boolean samePDU(RTUModbusMessage msg1, RTUModbusMessage msg2) {
+ if (msg1.getDevice() != msg2.getDevice()) {
+ return false;
+ }
+ if (msg1.getFunctionCode() != msg2.getFunctionCode()) {
+ return false;
+ }
+ if (!Arrays.equals(msg1.getData(), msg2.getData())) {
+ return false;
+ }
+
+ return true;
+ }
+
public void testRandomPDU() {
LOG.info("Random PDU rejection");
@@ -153,7 +265,7 @@ public class RTUModbusDecoderMasterTest
buggedBuff.put((byte) rng.nextInt());
}
buggedBuff.flip();
- //System.err.println("random buffer of len : "+buggedBuff.remaining());
+ // System.err.println("random buffer of len : "+buggedBuff.remaining());
try {
decoder.decode(session, buggedBuff, out);
} catch (Exception ex) {
Modified: mina/sandbox/jvermillard/mina-modbus/src/test/java/org/apache/mina/modbus/transport/rtu/RTUModbusDecoderTest.java
URL: http://svn.apache.org/viewvc/mina/sandbox/jvermillard/mina-modbus/src/test/java/org/apache/mina/modbus/transport/rtu/RTUModbusDecoderTest.java?rev=1084974&r1=1084973&r2=1084974&view=diff
==============================================================================
--- mina/sandbox/jvermillard/mina-modbus/src/test/java/org/apache/mina/modbus/transport/rtu/RTUModbusDecoderTest.java (original)
+++ mina/sandbox/jvermillard/mina-modbus/src/test/java/org/apache/mina/modbus/transport/rtu/RTUModbusDecoderTest.java Thu Mar 24 14:45:50 2011
@@ -20,6 +20,7 @@
package org.apache.mina.modbus.transport.rtu;
+import java.net.SocketAddress;
import java.util.Arrays;
import java.util.Random;
@@ -27,6 +28,8 @@ import junit.framework.Assert;
import junit.framework.TestCase;
import org.apache.mina.core.buffer.IoBuffer;
+import org.apache.mina.core.service.DefaultTransportMetadata;
+import org.apache.mina.core.session.IoSessionConfig;
import org.apache.mina.filter.codec.ProtocolCodecSession;
import org.apache.mina.filter.codec.ProtocolDecoderException;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;
@@ -40,6 +43,11 @@ public class RTUModbusDecoderTest extend
static final Logger LOG = LoggerFactory.getLogger(RTUModbusDecoderTest.class);
ProtocolCodecSession session = new ProtocolCodecSession();
+ {
+ session.setTransportMetadata(new DefaultTransportMetadata("mina", "dummy", false, true, SocketAddress.class,
+ IoSessionConfig.class, IoBuffer.class));
+ }
+
ProtocolDecoderOutput out = session.getDecoderOutput();
public void testDecodeOneFrame() throws Exception {
@@ -128,6 +136,202 @@ public class RTUModbusDecoderTest extend
Assert.assertEquals(2, session.getDecoderOutputQueue().size());
}
+ public void testFragmentation() throws Exception {
+ LOG.info("Fragmentation");
+
+ // write multiple register at address 1 and 10 values
+ RTUModbusMessage msgWrite10 = new RTUModbusMessage(1, ModbusConstants.WRITE_MULTIPLE_REGISTERS, new byte[] {
+ (byte) 0, (byte) 1, (byte) 0, (byte) 10, (byte) 20, (byte) 0, (byte) 1, (byte) 0, (byte) 2, (byte) 0,
+ (byte) 3, (byte) 0, (byte) 4, (byte) 0, (byte) 5, (byte) 0, (byte) 6, (byte) 0, (byte) 7, (byte) 0,
+ (byte) 8, (byte) 0, (byte) 9, (byte) 0, (byte) 10 });
+
+ // write multiple register at address 1 and 5 values
+ RTUModbusMessage msgWrite5 = new RTUModbusMessage(1, ModbusConstants.WRITE_MULTIPLE_REGISTERS, new byte[] {
+ (byte) 0, (byte) 1, (byte) 0, (byte) 5, (byte) 10, (byte) 0, (byte) 1, (byte) 0, (byte) 2, (byte) 0,
+ (byte) 3, (byte) 0, (byte) 4, (byte) 0, (byte) 5 });
+
+ // write multiple register at address 1 and 5 values
+ RTUModbusMessage msgWrite4 = new RTUModbusMessage(1, ModbusConstants.WRITE_MULTIPLE_REGISTERS, new byte[] {
+ (byte) 0, (byte) 1, (byte) 0, (byte) 4, (byte) 8, (byte) 0, (byte) 1, (byte) 0, (byte) 2, (byte) 0,
+ (byte) 3, (byte) 0, (byte) 4 });
+
+ IoBuffer buffPDU1 = msgWrite10.encode();
+ IoBuffer buffPDU2 = msgWrite5.encode();
+ IoBuffer buffPDU3 = msgWrite4.encode();
+ IoBuffer buffPDU123 = IoBuffer.allocate(buffPDU1.remaining() * 2 + buffPDU2.remaining()
+ + buffPDU3.remaining());
+ buffPDU123.put(buffPDU1);
+
+ buffPDU123.put(buffPDU2);
+ buffPDU123.put(buffPDU3);
+ buffPDU1.rewind();
+ buffPDU123.put(buffPDU1);
+ buffPDU123.flip(); // PDU123 = PDU1 + PDU2 + PDU3 + PDU1
+
+ buffPDU1.flip();
+ buffPDU2.flip();
+
+ // dezcode a plain buffer
+ decoder.decode(session, buffPDU1, out);
+ Assert.assertEquals(1, session.getDecoderOutputQueue().size());
+ buffPDU1.rewind();
+
+ IoBuffer buff1 = IoBuffer.allocate(4);
+ while (buff1.hasRemaining()) {
+ buff1.put(buffPDU1.get());
+ }
+
+ buff1.flip();
+ // decode a part of a PDU
+ decoder.decode(session, buff1, out);
+
+ IoBuffer buff2 = IoBuffer.allocate(buffPDU1.remaining());
+ while (buffPDU1.hasRemaining()) {
+ buff2.put(buffPDU1.get());
+ }
+ buff2.flip();
+
+ // decode the second part
+ decoder.decode(session, buff2, out);
+
+ Assert.assertEquals(2, session.getDecoderOutputQueue().size());
+
+ // decode four concatenated big PDU
+ decoder.decode(session, buffPDU123, out);
+ Assert.assertEquals(6, session.getDecoderOutputQueue().size());
+
+ // decode a big PDU each byte per each byte
+ buffPDU1.rewind();
+ while (buffPDU1.hasRemaining()) {
+ IoBuffer bufOneByte = IoBuffer.allocate(1);
+ bufOneByte.put(buffPDU1.get());
+ bufOneByte.flip();
+ decoder.decode(session, bufOneByte, out);
+ }
+ Assert.assertEquals(7, session.getDecoderOutputQueue().size());
+
+ RTUModbusMessage msg = (RTUModbusMessage) session.getDecoderOutputQueue().poll();
+ Assert.assertTrue(samePDU(msg, msgWrite10));
+ msg = (RTUModbusMessage) session.getDecoderOutputQueue().poll();
+ Assert.assertTrue(samePDU(msg, msgWrite10));
+
+ msg = (RTUModbusMessage) session.getDecoderOutputQueue().poll();
+ Assert.assertTrue(samePDU(msg, msgWrite10));
+ msg = (RTUModbusMessage) session.getDecoderOutputQueue().poll();
+ Assert.assertTrue(samePDU(msg, msgWrite5));
+ msg = (RTUModbusMessage) session.getDecoderOutputQueue().poll();
+ Assert.assertTrue(samePDU(msg, msgWrite4));
+ msg = (RTUModbusMessage) session.getDecoderOutputQueue().poll();
+ Assert.assertTrue(samePDU(msg, msgWrite10));
+ msg = (RTUModbusMessage) session.getDecoderOutputQueue().poll();
+ Assert.assertTrue(samePDU(msg, msgWrite10));
+
+ }
+
+ public void testCorruptionOnFragmentatedFrame() throws Exception {
+ LOG.info("Fragmentation Corrupted");
+
+ // write multiple register at address 1 and 10 values
+ RTUModbusMessage msgWrite10 = new RTUModbusMessage(1, ModbusConstants.WRITE_MULTIPLE_REGISTERS, new byte[] {
+ (byte) 0, (byte) 1, (byte) 0, (byte) 10, (byte) 20, (byte) 0, (byte) 1, (byte) 0, (byte) 2, (byte) 0,
+ (byte) 3, (byte) 0, (byte) 4, (byte) 0, (byte) 5, (byte) 0, (byte) 6, (byte) 0, (byte) 7, (byte) 0,
+ (byte) 8, (byte) 0, (byte) 9, (byte) 0, (byte) 10 });
+
+ // write multiple register at address 1 and 5 values
+ RTUModbusMessage msgWrite5 = new RTUModbusMessage(1, ModbusConstants.WRITE_FILE_RECORD, new byte[] { (byte) 0,
+ (byte) 1, (byte) 0, (byte) 5, (byte) 10, (byte) 0, (byte) 1, (byte) 0, (byte) 2, (byte) 0, (byte) 3,
+ (byte) 0, (byte) 4, (byte) 0, (byte) 5 });
+
+ // write multiple register at address 1 and 5 values
+ RTUModbusMessage msgWrite4 = new RTUModbusMessage(1, ModbusConstants.WRITE_MULTIPLE_REGISTERS, new byte[] {
+ (byte) 0, (byte) 1, (byte) 0, (byte) 4, (byte) 8, (byte) 0, (byte) 1, (byte) 0, (byte) 2, (byte) 0,
+ (byte) 3, (byte) 0, (byte) 4 });
+
+ IoBuffer buffPDU1 = msgWrite10.encode();
+ IoBuffer buffPDU2 = msgWrite5.encode();
+ IoBuffer buffPDU3 = msgWrite4.encode();
+ IoBuffer buffPDU123 = IoBuffer.allocate(buffPDU1.remaining() * 2 + buffPDU2.remaining()
+ + buffPDU3.remaining());
+ buffPDU123.put(buffPDU1);
+
+ buffPDU123.put(buffPDU2);
+ buffPDU123.put(buffPDU3);
+ buffPDU1.rewind();
+ buffPDU123.put(buffPDU1);
+ buffPDU123.flip(); // PDU123 = PDU1 + PDU2 + PDU3 + PDU1
+
+ buffPDU1.flip();
+ buffPDU2.flip();
+
+ // dezcode a plain buffer
+ decoder.decode(session, buffPDU1, out);
+ Assert.assertEquals(1, session.getDecoderOutputQueue().size());
+ buffPDU1.rewind();
+
+ IoBuffer buff1 = IoBuffer.allocate(4);
+ while (buff1.hasRemaining()) {
+ buff1.put(buffPDU1.get());
+ }
+
+ buff1.flip();
+ // decode a part of a PDU
+ decoder.decode(session, buff1, out);
+
+ IoBuffer buff2 = IoBuffer.allocate(buffPDU1.remaining());
+ while (buffPDU1.hasRemaining()) {
+ buff2.put(buffPDU1.get());
+ }
+ buff2.flip();
+
+ // decode the second part
+ decoder.decode(session, buff2, out);
+
+ Assert.assertEquals(2, session.getDecoderOutputQueue().size());
+
+ boolean exp = false;
+ boolean expProto = false;
+ // decode four concatenated big PDU
+ while (buffPDU123.hasRemaining()) {
+ IoBuffer bufOneByte = IoBuffer.allocate(1);
+ bufOneByte.put(buffPDU123.get());
+ bufOneByte.flip();
+ try {
+ decoder.decode(session, bufOneByte, out);
+ } catch (ProtocolDecoderException e) {
+ expProto = true;
+ } catch (CRCException e) {
+ exp = true;
+ }
+ }
+ Assert.assertTrue(exp);
+ Assert.assertTrue(expProto);
+ Assert.assertEquals(3, session.getDecoderOutputQueue().size());
+
+ // decode a big PDU each byte per each byte
+ buffPDU1.rewind();
+
+ int pos = 0;
+ int where = 20;
+ exp = false;
+ while (buffPDU1.hasRemaining()) {
+ IoBuffer bufOneByte = IoBuffer.allocate(1);
+ if (where == pos) {
+ bufOneByte.put((byte) 65);
+ } else {
+ bufOneByte.put(buffPDU1.get());
+ }
+ bufOneByte.flip();
+ try {
+ decoder.decode(session, bufOneByte, out);
+ } catch (CRCException e) {
+ exp = true;
+ }
+ pos++;
+ }
+ Assert.assertTrue(exp);
+
+ }
+
private boolean samePDU(RTUModbusMessage msg1, RTUModbusMessage msg2) {
if (msg1.getDevice() != msg2.getDevice()) {
return false;
Modified: mina/sandbox/jvermillard/mina-modbus/src/test/java/org/apache/mina/modbus/transport/tcp/TCPModbusDecoderMasterTest.java
URL: http://svn.apache.org/viewvc/mina/sandbox/jvermillard/mina-modbus/src/test/java/org/apache/mina/modbus/transport/tcp/TCPModbusDecoderMasterTest.java?rev=1084974&r1=1084973&r2=1084974&view=diff
==============================================================================
--- mina/sandbox/jvermillard/mina-modbus/src/test/java/org/apache/mina/modbus/transport/tcp/TCPModbusDecoderMasterTest.java (original)
+++ mina/sandbox/jvermillard/mina-modbus/src/test/java/org/apache/mina/modbus/transport/tcp/TCPModbusDecoderMasterTest.java Thu Mar 24 14:45:50 2011
@@ -20,6 +20,7 @@
package org.apache.mina.modbus.transport.tcp;
+import java.net.SocketAddress;
import java.util.Arrays;
import java.util.Random;
@@ -27,6 +28,8 @@ import junit.framework.Assert;
import junit.framework.TestCase;
import org.apache.mina.core.buffer.IoBuffer;
+import org.apache.mina.core.service.DefaultTransportMetadata;
+import org.apache.mina.core.session.IoSessionConfig;
import org.apache.mina.filter.codec.ProtocolCodecSession;
import org.apache.mina.filter.codec.ProtocolDecoderException;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;
@@ -39,6 +42,11 @@ public class TCPModbusDecoderMasterTest
TCPModbusDecoder decoder = new TCPModbusDecoder(true);
ProtocolCodecSession session = new ProtocolCodecSession();
+ {
+ session.setTransportMetadata(new DefaultTransportMetadata("mina", "dummy", false, true, SocketAddress.class,
+ IoSessionConfig.class, IoBuffer.class));
+ }
+
ProtocolDecoderOutput out = session.getDecoderOutput();
@@ -46,7 +54,7 @@ public class TCPModbusDecoderMasterTest
public void testDecodeOneFrame() throws Exception {
LOG.info("Decode one frame");
- // write single register at address 1 and value 50, reply
+ // write single register at address 1 and value 50, reply<
TCPModbusMessage msg = new TCPModbusMessage(1, 6, 1);
msg.setData(new byte[] { (byte) 0, (byte) 1, (byte) 0, (byte) 50 });
IoBuffer buff = msg.encode();
Modified: mina/sandbox/jvermillard/mina-modbus/src/test/java/org/apache/mina/modbus/transport/tcp/TCPModbusDecoderTest.java
URL: http://svn.apache.org/viewvc/mina/sandbox/jvermillard/mina-modbus/src/test/java/org/apache/mina/modbus/transport/tcp/TCPModbusDecoderTest.java?rev=1084974&r1=1084973&r2=1084974&view=diff
==============================================================================
--- mina/sandbox/jvermillard/mina-modbus/src/test/java/org/apache/mina/modbus/transport/tcp/TCPModbusDecoderTest.java (original)
+++ mina/sandbox/jvermillard/mina-modbus/src/test/java/org/apache/mina/modbus/transport/tcp/TCPModbusDecoderTest.java Thu Mar 24 14:45:50 2011
@@ -20,6 +20,7 @@
package org.apache.mina.modbus.transport.tcp;
+import java.net.SocketAddress;
import java.util.Arrays;
import java.util.Random;
@@ -27,6 +28,8 @@ import junit.framework.Assert;
import junit.framework.TestCase;
import org.apache.mina.core.buffer.IoBuffer;
+import org.apache.mina.core.service.DefaultTransportMetadata;
+import org.apache.mina.core.session.IoSessionConfig;
import org.apache.mina.filter.codec.ProtocolCodecSession;
import org.apache.mina.filter.codec.ProtocolDecoderException;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;
@@ -38,6 +41,11 @@ public class TCPModbusDecoderTest extend
TCPModbusDecoder decoder = new TCPModbusDecoder(false);
ProtocolCodecSession session = new ProtocolCodecSession();
+ {
+ session.setTransportMetadata(new DefaultTransportMetadata("mina", "dummy", false, true, SocketAddress.class,
+ IoSessionConfig.class, IoBuffer.class));
+ }
+
ProtocolDecoderOutput out = session.getDecoderOutput();
static final Logger LOG = LoggerFactory.getLogger(TCPModbusDecoderTest.class);
@@ -110,7 +118,115 @@ public class TCPModbusDecoderTest extend
decoder.decode(session, in, out);
Assert.assertEquals(2, session.getDecoderOutputQueue().size());
}
+
+ public void testFragmentation() throws Exception {
+ LOG.info("Fragmentation");
+
+ // write multiple register at address 1 and 10 values
+ TCPModbusMessage msgWrite10 = new TCPModbusMessage(1, ModbusConstants.WRITE_MULTIPLE_REGISTERS, 1);
+ msgWrite10.setData(new byte[] { (byte) 0, (byte) 1, (byte) 0, (byte) 10, (byte) 20, (byte) 0, (byte) 1,
+ (byte) 0, (byte) 2, (byte) 0, (byte) 3, (byte) 0, (byte) 4, (byte) 0, (byte) 5, (byte) 0, (byte) 6,
+ (byte) 0, (byte) 7, (byte) 0, (byte) 8, (byte) 0, (byte) 9, (byte) 0, (byte) 10 });
+
+ // write multiple register at address 1 and 5 values
+ TCPModbusMessage msgWrite5 = new TCPModbusMessage(1, ModbusConstants.READ_HOLDING_REGISTERS, 1);
+ msgWrite5.setData(new byte[] { (byte) 0, (byte) 1, (byte) 0, (byte) 5 });
+
+ // write multiple register at address 1 and 5 values
+ TCPModbusMessage msgWrite4 = new TCPModbusMessage(1, ModbusConstants.WRITE_MULTIPLE_REGISTERS, 1);
+ msgWrite4.setData(new byte[] { (byte) 0, (byte) 1, (byte) 0, (byte) 4, (byte) 8, (byte) 0, (byte) 1, (byte) 0,
+ (byte) 2, (byte) 0, (byte) 3, (byte) 0, (byte) 4 });
+
+ IoBuffer buffPDU1 = msgWrite10.encode();
+ IoBuffer buffPDU2 = msgWrite5.encode();
+ IoBuffer buffPDU3 = msgWrite4.encode();
+ IoBuffer buffPDU123 = IoBuffer.allocate(buffPDU1.remaining() * 2 + buffPDU2.remaining()
+ + buffPDU3.remaining());
+ buffPDU123.put(buffPDU1);
+
+ buffPDU123.put(buffPDU2);
+ buffPDU123.put(buffPDU3);
+ buffPDU1.rewind();
+ buffPDU123.put(buffPDU1);
+ buffPDU123.flip(); // PDU123 = PDU1 + PDU2 + PDU3 + PDU1
+
+ buffPDU1.flip();
+ buffPDU2.flip();
+
+ // dezcode a plain buffer
+ decoder.decode(session, buffPDU1, out);
+ Assert.assertEquals(1, session.getDecoderOutputQueue().size());
+ buffPDU1.rewind();
+
+ IoBuffer buff1 = IoBuffer.allocate(4);
+ while (buff1.hasRemaining()) {
+ buff1.put(buffPDU1.get());
+ }
+
+ buff1.flip();
+
+ // decode a part of a PDU
+ decoder.decode(session, buff1, out);
+
+ IoBuffer buff2 = IoBuffer.allocate(buffPDU1.remaining());
+ while (buffPDU1.hasRemaining()) {
+ buff2.put(buffPDU1.get());
+ }
+ buff2.flip();
+
+ // decode the second part
+ decoder.decode(session, buff2, out);
+
+ Assert.assertEquals(2, session.getDecoderOutputQueue().size());
+
+ // decode four concatenated big PDU
+ decoder.decode(session, buffPDU123, out);
+ Assert.assertEquals(6, session.getDecoderOutputQueue().size());
+
+ // decode a big PDU each byte per each byte
+ buffPDU123.rewind();
+ while (buffPDU123.hasRemaining()) {
+ IoBuffer bufOneByte = IoBuffer.allocate(1);
+ bufOneByte.put(buffPDU123.get());
+ bufOneByte.flip();
+ decoder.decode(session, bufOneByte, out);
+ }
+ Assert.assertEquals(10, session.getDecoderOutputQueue().size());
+
+ TCPModbusMessage msg = (TCPModbusMessage) session.getDecoderOutputQueue().poll();
+ Assert.assertTrue(samePDU(msg, msgWrite10));
+ msg = (TCPModbusMessage) session.getDecoderOutputQueue().poll();
+ Assert.assertTrue(samePDU(msg, msgWrite10));
+
+ msg = (TCPModbusMessage) session.getDecoderOutputQueue().poll();
+ Assert.assertTrue(samePDU(msg, msgWrite10));
+ msg = (TCPModbusMessage) session.getDecoderOutputQueue().poll();
+ Assert.assertTrue(samePDU(msg, msgWrite5));
+ msg = (TCPModbusMessage) session.getDecoderOutputQueue().poll();
+ Assert.assertTrue(samePDU(msg, msgWrite4));
+ msg = (TCPModbusMessage) session.getDecoderOutputQueue().poll();
+ Assert.assertTrue(samePDU(msg, msgWrite10));
+ msg = (TCPModbusMessage) session.getDecoderOutputQueue().poll();
+ Assert.assertTrue(samePDU(msg, msgWrite10));
+
+ }
+
+ private boolean samePDU(TCPModbusMessage msg1, TCPModbusMessage msg2) {
+ if (msg1.getDevice() != msg2.getDevice()) {
+ return false;
+ }
+ if (msg1.getFunctionCode() != msg2.getFunctionCode()) {
+ return false;
+ }
+ if (!Arrays.equals(msg1.getData(), msg2.getData())) {
+ return false;
+ }
+
+ return true;
+ }
+
+
public void testRandomPDU() {
LOG.info("Random PDU rejection");
System.err.println("Start Random PDU test");