Author: sebb
Date: Wed Nov  5 08:18:49 2008
New Revision: 711601

URL: http://svn.apache.org/viewvc?rev=711601&view=rev
Log:
Bug 46030 - Extend TCP Sampler to Support Length-Prefixed Binary Data
Commit of 3rd party code (ICLA and CCLA have been received)

Added:
    
jakarta/jmeter/trunk/src/protocol/tcp/org/apache/jmeter/protocol/tcp/sampler/BinaryTCPClientImpl.java
   (with props)
    
jakarta/jmeter/trunk/src/protocol/tcp/org/apache/jmeter/protocol/tcp/sampler/LengthPrefixedBinaryTCPClientImpl.java
   (with props)
    
jakarta/jmeter/trunk/src/protocol/tcp/org/apache/jmeter/protocol/tcp/sampler/TCPClientDecorator.java
   (with props)
    jakarta/jmeter/trunk/test/src/org/apache/jmeter/protocol/tcp/
    jakarta/jmeter/trunk/test/src/org/apache/jmeter/protocol/tcp/sampler/
    
jakarta/jmeter/trunk/test/src/org/apache/jmeter/protocol/tcp/sampler/BinaryTCPClientImplTest.java
   (with props)
    
jakarta/jmeter/trunk/test/src/org/apache/jmeter/protocol/tcp/sampler/TCPClientDecoratorTest.java
   (with props)
Modified:
    jakarta/jmeter/trunk/xdocs/changes.xml

Added: 
jakarta/jmeter/trunk/src/protocol/tcp/org/apache/jmeter/protocol/tcp/sampler/BinaryTCPClientImpl.java
URL: 
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/tcp/org/apache/jmeter/protocol/tcp/sampler/BinaryTCPClientImpl.java?rev=711601&view=auto
==============================================================================
--- 
jakarta/jmeter/trunk/src/protocol/tcp/org/apache/jmeter/protocol/tcp/sampler/BinaryTCPClientImpl.java
 (added)
+++ 
jakarta/jmeter/trunk/src/protocol/tcp/org/apache/jmeter/protocol/tcp/sampler/BinaryTCPClientImpl.java
 Wed Nov  5 08:18:49 2008
@@ -0,0 +1,199 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/*
+ * TCP Sampler Client implementation which reads and writes binary data.  
+ * 
+ * Input/Output strings are passed as hex-encoded binary strings.
+ *
+ */
+package org.apache.jmeter.protocol.tcp.sampler;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InterruptedIOException;
+import java.io.OutputStream;
+import java.net.SocketTimeoutException;
+
+import org.apache.jmeter.util.JMeterUtils;
+import org.apache.jorphan.logging.LoggingManager;
+import org.apache.jorphan.util.JOrphanUtils;
+import org.apache.log.Logger;
+
+/**
+ * Sample TCPClient implementation
+ * 
+ */
+public class BinaryTCPClientImpl implements TCPClient {
+    private static final Logger log = LoggingManager.getLoggerForClass();
+
+    private int eolInt = JMeterUtils.getPropDefault("tcp.eolByte", 1000); // 
default
+
+    // is
+    // not
+    // in
+    // range
+
+    private byte eolByte = (byte) eolInt; // -128 to +127
+
+    private boolean eolIgnore = eolInt < -128 || eolInt > 127;
+    
+    public BinaryTCPClientImpl() {
+        super();
+        if (!eolIgnore) {
+            log.info("Using eolByte=" + eolByte);
+        }
+    }
+
+    /**
+     * Convert hex string to binary byte array.
+     * 
+     * @param s - hex-encoded binary string
+     * @return Byte array containing binary representation of input 
hex-encoded string 
+     */
+    public static final byte[] hexStringToByteArray(String s) {
+        if (s.length() % 2 == 0) {
+            char[] sc = s.toCharArray();
+            byte[] ba = new byte[sc.length / 2];
+
+            for (int i = 0; i < ba.length; i++) {
+                int nibble0 = Character.digit(sc[i * 2], 16);
+                int nibble1 = Character.digit(sc[i * 2 + 1], 16);
+                ba[i] = (byte) ((nibble0 << 4) | (nibble1));
+            }
+
+            return ba;
+        } else {
+            throw new IllegalArgumentException(
+                    "Hex-encoded binary string contains an uneven no. of 
digits");
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.apache.jmeter.protocol.tcp.sampler.TCPClient#setupTest()
+     */
+    public void setupTest() {
+        log.info("setuptest");
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.apache.jmeter.protocol.tcp.sampler.TCPClient#teardownTest()
+     */
+    public void teardownTest() {
+        log.info("teardowntest");
+
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * 
org.apache.jmeter.protocol.tcp.sampler.TCPClient#write(java.io.OutputStream
+     * , java.lang.String)
+     */
+    public void write(OutputStream os, String s) {
+        try {
+            os.write(hexStringToByteArray(s));
+            os.flush();
+        } catch (IOException e) {
+            log.warn("Write error", e);
+        }
+        log.debug("Wrote: " + s);
+        return;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * 
org.apache.jmeter.protocol.tcp.sampler.TCPClient#write(java.io.OutputStream
+     * , java.io.InputStream)
+     */
+    public void write(OutputStream os, InputStream is) {
+        throw new UnsupportedOperationException(
+                "Method not supported for Length-Prefixed data.");
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * 
org.apache.jmeter.protocol.tcp.sampler.TCPClient#read(java.io.InputStream
+     * )
+     */
+    public String read(InputStream is) {
+        byte[] buffer = new byte[4096];
+        ByteArrayOutputStream w = new ByteArrayOutputStream();
+        int x = 0;
+        try {
+            while ((x = is.read(buffer)) > -1) {
+                w.write(buffer, 0, x);
+                if (!eolIgnore && (buffer[x - 1] == eolByte)) {
+                    break;
+                }
+            }
+            /*
+             * Timeout is reported as follows: JDK1.3: InterruptedIOException
+             * JDK1.4: SocketTimeoutException, which extends
+             * InterruptedIOException
+             *
+             * So to make the code work on both, just check for
+             * InterruptedIOException
+             *
+             * If 1.3 support is dropped, can change to using
+             * SocketTimeoutException
+             *
+             * For more accurate detection of timeouts under 1.3, one could
+             * perhaps examine the Exception message text...
+             *
+             */
+        } catch (SocketTimeoutException e) {
+            // drop out to handle buffer
+        } catch (InterruptedIOException e) {
+            // drop out to handle buffer
+        } catch (IOException e) {
+            log.warn("Read error:" + e);
+            return "";
+        }
+
+        // do we need to close byte array (or flush it?)
+        log.debug("Read: " + w.size() + "\n" + w.toString());
+        return JOrphanUtils.baToHexString(w.toByteArray());
+    }
+
+    /**
+     * @return Returns the eolByte.
+     */
+    public byte getEolByte() {
+        return eolByte;
+    }
+
+    /**
+     * @param eolByte
+     *            The eolByte to set.
+     */
+    public void setEolByte(byte eolByte) {
+        this.eolByte = eolByte;
+        eolIgnore = false;
+    }
+}

Propchange: 
jakarta/jmeter/trunk/src/protocol/tcp/org/apache/jmeter/protocol/tcp/sampler/BinaryTCPClientImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
jakarta/jmeter/trunk/src/protocol/tcp/org/apache/jmeter/protocol/tcp/sampler/BinaryTCPClientImpl.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: 
jakarta/jmeter/trunk/src/protocol/tcp/org/apache/jmeter/protocol/tcp/sampler/LengthPrefixedBinaryTCPClientImpl.java
URL: 
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/tcp/org/apache/jmeter/protocol/tcp/sampler/LengthPrefixedBinaryTCPClientImpl.java?rev=711601&view=auto
==============================================================================
--- 
jakarta/jmeter/trunk/src/protocol/tcp/org/apache/jmeter/protocol/tcp/sampler/LengthPrefixedBinaryTCPClientImpl.java
 (added)
+++ 
jakarta/jmeter/trunk/src/protocol/tcp/org/apache/jmeter/protocol/tcp/sampler/LengthPrefixedBinaryTCPClientImpl.java
 Wed Nov  5 08:18:49 2008
@@ -0,0 +1,177 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/*
+ * TCP Sampler Client implementation which reads and writes length-prefixed 
binary data.  
+ * 
+ * Input/Output strings are passed as hex-encoded binary strings.
+ * 
+ * 2-Byte or 4-Byte length prefixes are supported.
+ * 
+ * Length prefix is binary of length specified by property 
"tcp.length.prefix.length".
+ *
+ */
+package org.apache.jmeter.protocol.tcp.sampler;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InterruptedIOException;
+import java.io.OutputStream;
+import java.net.SocketTimeoutException;
+
+import org.apache.jmeter.util.JMeterUtils;
+import org.apache.jorphan.logging.LoggingManager;
+import org.apache.jorphan.util.JOrphanUtils;
+import org.apache.log.Logger;
+
+/**
+ * Sample TCPClient implementation
+ * 
+ */
+public class LengthPrefixedBinaryTCPClientImpl extends TCPClientDecorator {
+    private static final Logger log = LoggingManager.getLoggerForClass();
+
+    private int eolInt = JMeterUtils.getPropDefault("tcp.eolByte", 1000); // 
default
+
+    // is
+    // not
+    // in
+    // range
+
+    private byte eolByte = (byte) eolInt; // -128 to +127
+
+    private boolean eolIgnore = eolInt < -128 || eolInt > 127;
+    
+    private int lengthPrefixLen = 
JMeterUtils.getPropDefault("tcp.length.prefix.length", 2);
+
+    public LengthPrefixedBinaryTCPClientImpl() {
+        super(new BinaryTCPClientImpl());
+        if (!eolIgnore) {
+            log.info("Using eolByte=" + eolByte);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.apache.jmeter.protocol.tcp.sampler.TCPClient#setupTest()
+     */
+    public void setupTest() {
+        log.info("setuptest");
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.apache.jmeter.protocol.tcp.sampler.TCPClient#teardownTest()
+     */
+    public void teardownTest() {
+        log.info("teardowntest");
+
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * 
org.apache.jmeter.protocol.tcp.sampler.TCPClient#write(java.io.OutputStream
+     * , java.lang.String)
+     */
+    public void write(OutputStream os, String s) {
+        try {
+            os.write(intToByteArray(s.length()/2,lengthPrefixLen));
+            this.tcpClient.write(os, s);
+        } catch (IOException e) {
+            log.warn("Write error", e);
+        }
+        log.debug("Wrote: " + s);
+        return;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * 
org.apache.jmeter.protocol.tcp.sampler.TCPClient#write(java.io.OutputStream
+     * , java.io.InputStream)
+     */
+    public void write(OutputStream os, InputStream is) {
+        this.tcpClient.write(os, is);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * 
org.apache.jmeter.protocol.tcp.sampler.TCPClient#read(java.io.InputStream
+     * )
+     */
+    public String read(InputStream is) {
+        byte[] msg = null;
+        int msgLen = 0;
+        try {
+            byte[] lengthBuffer = new byte[lengthPrefixLen];
+            if (is.read(lengthBuffer, 0, lengthPrefixLen) == lengthPrefixLen) {
+                msgLen = byteArrayToInt(lengthBuffer);
+                msg = new byte[msgLen];
+                is.read(msg);
+            }
+            /*
+             * Timeout is reported as follows: JDK1.3: InterruptedIOException
+             * JDK1.4: SocketTimeoutException, which extends
+             * InterruptedIOException
+             * 
+             * So to make the code work on both, just check for
+             * InterruptedIOException
+             * 
+             * If 1.3 support is dropped, can change to using
+             * SocketTimeoutException
+             * 
+             * For more accurate detection of timeouts under 1.3, one could
+             * perhaps examine the Exception message text...
+             */
+        } catch (SocketTimeoutException e) {
+            // drop out to handle buffer
+        } catch (InterruptedIOException e) {
+            // drop out to handle buffer
+        } catch (IOException e) {
+            log.warn("Read error:" + e);
+            return JOrphanUtils.baToHexString(msg);
+        }
+
+        // do we need to close byte array (or flush it?)
+        log.debug("Read: " + msgLen + "\n" + msg.toString());
+        return JOrphanUtils.baToHexString(msg);
+    }
+
+    /**
+     * @return Returns the eolByte.
+     */
+    public byte getEolByte() {
+        return eolByte;
+    }
+
+    /**
+     * @param eolByte
+     *            The eolByte to set.
+     */
+    public void setEolByte(byte eolByte) {
+        this.eolByte = eolByte;
+        eolIgnore = false;
+    }
+}

Propchange: 
jakarta/jmeter/trunk/src/protocol/tcp/org/apache/jmeter/protocol/tcp/sampler/LengthPrefixedBinaryTCPClientImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
jakarta/jmeter/trunk/src/protocol/tcp/org/apache/jmeter/protocol/tcp/sampler/LengthPrefixedBinaryTCPClientImpl.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: 
jakarta/jmeter/trunk/src/protocol/tcp/org/apache/jmeter/protocol/tcp/sampler/TCPClientDecorator.java
URL: 
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/tcp/org/apache/jmeter/protocol/tcp/sampler/TCPClientDecorator.java?rev=711601&view=auto
==============================================================================
--- 
jakarta/jmeter/trunk/src/protocol/tcp/org/apache/jmeter/protocol/tcp/sampler/TCPClientDecorator.java
 (added)
+++ 
jakarta/jmeter/trunk/src/protocol/tcp/org/apache/jmeter/protocol/tcp/sampler/TCPClientDecorator.java
 Wed Nov  5 08:18:49 2008
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/*
+ * TCP Sampler Client decorator to permit wrapping base client implementations 
with length prefixes.  
+ *
+ */
+package org.apache.jmeter.protocol.tcp.sampler;
+
+public abstract class TCPClientDecorator implements TCPClient {
+    public static final int SHORT_MAX_VALUE = 32767;
+
+    public static final int SHORT_MIN_VALUE = -32768;
+
+    protected TCPClient tcpClient;
+
+    public TCPClientDecorator(TCPClient tcpClient) {
+        this.tcpClient = tcpClient;
+    }
+
+    /**
+     * Convert int to byte array.
+     * 
+     * @param value
+     *            - int to be converted
+     * @param len
+     *            - length of required byte array
+     * @return Byte array representation of input value
+     */
+    public static byte[] intToByteArray(int value, int len) {
+        if (len == 2 || len == 4) {
+            if (len == 2 && (value < SHORT_MIN_VALUE || value > 
SHORT_MAX_VALUE)) {
+                throw new IllegalArgumentException("Value outside range for 
signed short int.");
+            } else {
+                byte[] b = new byte[len];
+                for (int i = 0; i < len; i++) {
+                    int offset = (b.length - 1 - i) * 8;
+                    b[i] = (byte) (value >>> offset);
+                }
+                return b;
+            }
+        } else {
+            throw new IllegalArgumentException(
+                    "Length must be specified as either 2 or 4.");
+        }
+    }
+
+    /**
+     * Convert byte array to int.
+     * 
+     * @param b
+     *            - Byte array to be converted
+     * @return Integer value of input byte array
+     */
+    public static int byteArrayToInt(byte[] b) {
+        if (b != null && (b.length == 2 || b.length == 4)) {
+            // Preserve sign on first byte
+            int value = b[0] << ((b.length - 1) * 8);
+
+            for (int i = 1; i < b.length; i++) {
+                int offset = (b.length - 1 - i) * 8;
+                value += (b[i] & 0xFF) << offset;
+            }
+            return value;
+        } else {
+            throw new IllegalArgumentException(
+                    "Byte array is null or invalid length.");
+        }
+    }
+}

Propchange: 
jakarta/jmeter/trunk/src/protocol/tcp/org/apache/jmeter/protocol/tcp/sampler/TCPClientDecorator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
jakarta/jmeter/trunk/src/protocol/tcp/org/apache/jmeter/protocol/tcp/sampler/TCPClientDecorator.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: 
jakarta/jmeter/trunk/test/src/org/apache/jmeter/protocol/tcp/sampler/BinaryTCPClientImplTest.java
URL: 
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/test/src/org/apache/jmeter/protocol/tcp/sampler/BinaryTCPClientImplTest.java?rev=711601&view=auto
==============================================================================
--- 
jakarta/jmeter/trunk/test/src/org/apache/jmeter/protocol/tcp/sampler/BinaryTCPClientImplTest.java
 (added)
+++ 
jakarta/jmeter/trunk/test/src/org/apache/jmeter/protocol/tcp/sampler/BinaryTCPClientImplTest.java
 Wed Nov  5 08:18:49 2008
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/*
+ * Test class for BinaryTCPClientImpl utility methods.  
+ *
+ */
+package org.apache.jmeter.protocol.tcp.sampler;
+
+import org.apache.jorphan.util.JOrphanUtils;
+
+import junit.framework.TestCase;
+
+public class BinaryTCPClientImplTest extends TestCase {
+
+    public void testHexStringToByteArray() throws Exception {
+        byte [] ba;
+        ba = BinaryTCPClientImpl.hexStringToByteArray("");
+        assertEquals(0, ba.length);
+ 
+        ba = BinaryTCPClientImpl.hexStringToByteArray("00");
+        assertEquals(1, ba.length);
+        assertEquals(0, ba[0]);
+ 
+        ba = BinaryTCPClientImpl.hexStringToByteArray("0f107f8081ff");
+        assertEquals(6, ba.length);
+        assertEquals(15,   ba[0]);
+        assertEquals(16,   ba[1]);
+        assertEquals(127,  ba[2]);
+        assertEquals(-128, ba[3]);
+        assertEquals(-127, ba[4]);
+        assertEquals(-1,   ba[5]);
+        
+    }
+
+    public void testLoopBack() throws Exception {
+        assertEquals("0f107f8081ff", 
JOrphanUtils.baToHexString(BinaryTCPClientImpl.hexStringToByteArray("0f107f8081ff")));
      
+    }
+
+}

Propchange: 
jakarta/jmeter/trunk/test/src/org/apache/jmeter/protocol/tcp/sampler/BinaryTCPClientImplTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
jakarta/jmeter/trunk/test/src/org/apache/jmeter/protocol/tcp/sampler/BinaryTCPClientImplTest.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: 
jakarta/jmeter/trunk/test/src/org/apache/jmeter/protocol/tcp/sampler/TCPClientDecoratorTest.java
URL: 
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/test/src/org/apache/jmeter/protocol/tcp/sampler/TCPClientDecoratorTest.java?rev=711601&view=auto
==============================================================================
--- 
jakarta/jmeter/trunk/test/src/org/apache/jmeter/protocol/tcp/sampler/TCPClientDecoratorTest.java
 (added)
+++ 
jakarta/jmeter/trunk/test/src/org/apache/jmeter/protocol/tcp/sampler/TCPClientDecoratorTest.java
 Wed Nov  5 08:18:49 2008
@@ -0,0 +1,188 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/*
+ * Test class for TCPClientDecorator utility methods.  
+ *
+ */
+package org.apache.jmeter.protocol.tcp.sampler;
+
+import junit.framework.TestCase;
+
+public class TCPClientDecoratorTest extends TestCase {
+
+    
+    public void testIntToByteArray() throws Exception {
+        byte[] ba;
+        int len = 2;
+        ba = TCPClientDecorator.intToByteArray(0, len);
+        assertEquals(len, ba.length);
+        assertEquals(0, ba[0]);
+        assertEquals(0, ba[1]);
+
+        ba = TCPClientDecorator.intToByteArray(15, len);
+        assertEquals(len, ba.length);
+        assertEquals(0, ba[0]);
+        assertEquals(15, ba[1]);
+
+        ba = TCPClientDecorator.intToByteArray(255, len);
+        assertEquals(len, ba.length);
+        assertEquals(0, ba[0]);
+        assertEquals(-1, ba[1]);
+
+        ba = TCPClientDecorator.intToByteArray(256, len);
+        assertEquals(len, ba.length);
+        assertEquals(1, ba[0]);
+        assertEquals(0, ba[1]);
+
+        ba = TCPClientDecorator.intToByteArray(-1, len);
+        assertEquals(len, ba.length);
+        assertEquals(-1, ba[0]);
+        assertEquals(-1, ba[1]);
+
+        ba = 
TCPClientDecorator.intToByteArray(TCPClientDecorator.SHORT_MAX_VALUE, len);
+        assertEquals(len, ba.length);
+        assertEquals(127, ba[0]);
+        assertEquals(-1, ba[1]);
+        
+        ba = 
TCPClientDecorator.intToByteArray(TCPClientDecorator.SHORT_MIN_VALUE, len);
+        assertEquals(len, ba.length);
+        assertEquals(-128, ba[0]);
+        assertEquals(0, ba[1]);
+        
+        try {
+            ba = 
TCPClientDecorator.intToByteArray(TCPClientDecorator.SHORT_MIN_VALUE-1, len);
+            fail();
+        } catch (IllegalArgumentException iae) {
+        }
+        
+        try {
+            ba = 
TCPClientDecorator.intToByteArray(TCPClientDecorator.SHORT_MAX_VALUE+1, len);
+            fail();
+        } catch (IllegalArgumentException iae) {
+        }
+
+        len = 4;
+        ba = TCPClientDecorator.intToByteArray(0, len);
+        assertEquals(len, ba.length);
+        assertEquals(0, ba[0]);
+        assertEquals(0, ba[1]);
+        assertEquals(0, ba[2]);
+        assertEquals(0, ba[3]);
+
+        ba = TCPClientDecorator.intToByteArray(15, len);
+        assertEquals(len, ba.length);
+        assertEquals(0, ba[0]);
+        assertEquals(0, ba[1]);
+        assertEquals(0, ba[2]);
+        assertEquals(15, ba[3]);
+
+        ba = TCPClientDecorator.intToByteArray(255, len);
+        assertEquals(len, ba.length);
+        assertEquals(0, ba[0]);
+        assertEquals(0, ba[1]);
+        assertEquals(0, ba[2]);
+        assertEquals(-1, ba[3]);
+
+        ba = TCPClientDecorator.intToByteArray(-1, len);
+        assertEquals(len, ba.length);
+        assertEquals(-1, ba[0]);
+        assertEquals(-1, ba[1]);
+        assertEquals(-1, ba[2]);
+        assertEquals(-1, ba[3]);
+
+        ba = TCPClientDecorator.intToByteArray(256, len);
+        assertEquals(len, ba.length);
+        assertEquals(0, ba[0]);
+        assertEquals(0, ba[1]);
+        assertEquals(1, ba[2]);
+        assertEquals(0, ba[3]);
+
+        ba = TCPClientDecorator.intToByteArray(65535, len);
+        assertEquals(len, ba.length);
+        assertEquals(0, ba[0]);
+        assertEquals(0, ba[1]);
+        assertEquals(-1, ba[2]);
+        assertEquals(-1, ba[3]);
+
+        ba = TCPClientDecorator.intToByteArray(65536, len);
+        assertEquals(len, ba.length);
+        assertEquals(0, ba[0]);
+        assertEquals(1, ba[1]);
+        assertEquals(0, ba[2]);
+        assertEquals(0, ba[3]);
+
+        ba = TCPClientDecorator.intToByteArray(Integer.MIN_VALUE, len);
+        assertEquals(len, ba.length);
+        assertEquals(-128, ba[0]);
+        assertEquals(0, ba[1]);
+        assertEquals(0, ba[2]);
+        assertEquals(0, ba[3]);
+
+        ba = TCPClientDecorator.intToByteArray(Integer.MAX_VALUE, len);
+        assertEquals(len, ba.length);
+        assertEquals(127, ba[0]);
+        assertEquals(-1, ba[1]);
+        assertEquals(-1, ba[2]);
+        assertEquals(-1, ba[3]);
+
+    }
+
+    public void testByteArrayToInt() throws Exception {
+        byte[] ba;
+
+        ba = new byte[] { 0, 0 };
+        assertEquals(0, TCPClientDecorator.byteArrayToInt(ba));
+
+        ba = new byte[] { 0, 15 };
+        assertEquals(15, TCPClientDecorator.byteArrayToInt(ba));
+
+        ba = new byte[] { 0, -1 };
+        assertEquals(255, TCPClientDecorator.byteArrayToInt(ba));
+
+        ba = new byte[] { 1, 0 };
+        assertEquals(256, TCPClientDecorator.byteArrayToInt(ba));
+
+        ba = new byte[] { -1, -1 };
+        assertEquals(-1, TCPClientDecorator.byteArrayToInt(ba));
+
+        ba = new byte[] { 0, 0, -1, -1 };
+        assertEquals(65535, TCPClientDecorator.byteArrayToInt(ba));
+
+        ba = new byte[] { 0, 1, 0, 0 };
+        assertEquals(65536, TCPClientDecorator.byteArrayToInt(ba));
+        
+        ba = new byte[] { 0, 0, 0, 0 };
+        assertEquals(0, TCPClientDecorator.byteArrayToInt(ba));
+
+        ba = new byte[] { -128, 0, 0, 0 };
+        assertEquals(Integer.MIN_VALUE, TCPClientDecorator.byteArrayToInt(ba));
+
+        ba = new byte[] { 127, -1, -1, -1 };
+        assertEquals(Integer.MAX_VALUE, TCPClientDecorator.byteArrayToInt(ba));
+    }
+
+    
+    public void testLoopBack() throws Exception {
+        assertEquals(TCPClientDecorator.SHORT_MIN_VALUE, 
TCPClientDecorator.byteArrayToInt(TCPClientDecorator.intToByteArray(TCPClientDecorator.SHORT_MIN_VALUE,
 2)));      
+        assertEquals(TCPClientDecorator.SHORT_MAX_VALUE, 
TCPClientDecorator.byteArrayToInt(TCPClientDecorator.intToByteArray(TCPClientDecorator.SHORT_MAX_VALUE,
 2)));      
+        assertEquals(Integer.MIN_VALUE, 
TCPClientDecorator.byteArrayToInt(TCPClientDecorator.intToByteArray(Integer.MIN_VALUE,
 4)));      
+        assertEquals(Integer.MAX_VALUE, 
TCPClientDecorator.byteArrayToInt(TCPClientDecorator.intToByteArray(Integer.MAX_VALUE,
 4)));      
+    }
+
+}

Propchange: 
jakarta/jmeter/trunk/test/src/org/apache/jmeter/protocol/tcp/sampler/TCPClientDecoratorTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
jakarta/jmeter/trunk/test/src/org/apache/jmeter/protocol/tcp/sampler/TCPClientDecoratorTest.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Modified: jakarta/jmeter/trunk/xdocs/changes.xml
URL: 
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/changes.xml?rev=711601&r1=711600&r2=711601&view=diff
==============================================================================
--- jakarta/jmeter/trunk/xdocs/changes.xml (original)
+++ jakarta/jmeter/trunk/xdocs/changes.xml Wed Nov  5 08:18:49 2008
@@ -175,6 +175,7 @@
 <li>JDBC Request can optionally save the results of Select statements to 
variables.</li>
 <li>JDBC Request now handles quoted strings.</li>
 <li>JDBC Request now handles arbitray variable types.</li>
+<li>Bug 46030 - Extend TCP Sampler to Support Length-Prefixed Binary Data</li>
 </ul>
 
 <h3>Non-functional changes</h3>



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to