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");