Added: 
qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/ssl/SslHandshakeSniffingTransportWrapperTest.java
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/ssl/SslHandshakeSniffingTransportWrapperTest.java?rev=1484842&view=auto
==============================================================================
--- 
qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/ssl/SslHandshakeSniffingTransportWrapperTest.java
 (added)
+++ 
qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/ssl/SslHandshakeSniffingTransportWrapperTest.java
 Tue May 21 15:49:52 2013
@@ -0,0 +1,179 @@
+/*
+ *
+ * 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.
+ *
+ */
+package org.apache.qpid.proton.engine.impl.ssl;
+
+import static 
org.apache.qpid.proton.engine.impl.TransportTestHelper.assertByteBufferContentEquals;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+
+import java.nio.ByteBuffer;
+
+import org.apache.qpid.proton.engine.impl.TransportWrapper;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+public class SslHandshakeSniffingTransportWrapperTest
+{
+    private static final byte[] EXAMPLE_SSL_V3_HANDSHAKE_BYTES = new byte[] 
{0x16, 0x03, 0x02, 0x00, 0x31};
+    private static final byte[] EXAMPLE_SSL_V2_HANDSHAKE_BYTES = new byte[] 
{0x00, 0x00, 0x01, 0x03, 0x00};
+
+    private SslTransportWrapper _secureTransportWrapper = 
mock(SslTransportWrapper.class);
+    private TransportWrapper _plainTransportWrapper = 
mock(TransportWrapper.class);
+    private SslTransportWrapper _sniffingWrapper = new 
SslHandshakeSniffingTransportWrapper(_secureTransportWrapper, 
_plainTransportWrapper);
+
+    @Rule
+    public ExpectedException _expectedException = ExpectedException.none();
+
+    @Test
+    public void testGetInputBufferGetOutputBufferWithNonSsl()
+    {
+        testInputAndOutput("INPUT".getBytes(), _plainTransportWrapper);
+    }
+
+    @Test
+    public void testWithSSLv2()
+    {
+        testInputAndOutput(EXAMPLE_SSL_V2_HANDSHAKE_BYTES, 
_secureTransportWrapper);
+    }
+
+    @Test
+    public void testWithSSLv3TLS()
+    {
+        testInputAndOutput(EXAMPLE_SSL_V3_HANDSHAKE_BYTES, 
_secureTransportWrapper);
+    }
+
+    private void testInputAndOutput(byte[] input, TransportWrapper 
transportThatShouldBeUsed)
+    {
+        byte[] output = "OUTPUT".getBytes();
+
+        ByteBuffer underlyingInputBuffer = ByteBuffer.allocate(1024);
+        ByteBuffer underlyingOutputBuffer = ByteBuffer.wrap(output);
+
+        // set up underlying transport
+        
when(transportThatShouldBeUsed.getInputBuffer()).thenReturn(underlyingInputBuffer);
+        
when(transportThatShouldBeUsed.getOutputBuffer()).thenReturn(underlyingOutputBuffer);
+
+        // do input and verify underlying calls were made
+        ByteBuffer inputBuffer = _sniffingWrapper.getInputBuffer();
+        inputBuffer.put(input);
+        _sniffingWrapper.processInput();
+
+        verify(transportThatShouldBeUsed).getInputBuffer();
+        verify(transportThatShouldBeUsed).processInput();
+
+        // check the wrapped input actually received the expected bytes
+        underlyingInputBuffer.flip();
+        assertByteBufferContentEquals(input, underlyingInputBuffer);
+
+        // do output and check we get the correct transport's output
+        ByteBuffer outputBuffer = _sniffingWrapper.getOutputBuffer();
+        verify(transportThatShouldBeUsed).getOutputBuffer();
+
+        assertByteBufferContentEquals(output, outputBuffer);
+        _sniffingWrapper.outputConsumed();
+        verify(transportThatShouldBeUsed).outputConsumed();
+
+        verifyZeroInteractionsWithOtherTransport(transportThatShouldBeUsed);
+    }
+
+    @Test
+    public void testTooFewBytesToMakeDetermination()
+    {
+        byte[] sourceBuffer = new byte[] {0x00};
+
+        try
+        {
+            _sniffingWrapper.getInputBuffer().put(sourceBuffer);
+
+            _expectedException.expect(IllegalArgumentException.class);
+            _sniffingWrapper.processInput();
+        }
+        finally
+        {
+            verifyZeroInteractions(_secureTransportWrapper, 
_plainTransportWrapper);
+        }
+    }
+
+    @Test
+    public void testGetSslAttributesWhenProtocolIsNotYetDetermined_returnNull()
+    {
+        assertEquals("Cipher name should be null", null, 
_sniffingWrapper.getCipherName());
+        assertEquals("Protocol name should be null", null, 
_sniffingWrapper.getProtocolName());
+        verifyZeroInteractions(_secureTransportWrapper, 
_plainTransportWrapper);
+    }
+
+    @Test
+    public void testGetSslAttributesWhenUsingNonSsl_returnNull()
+    {
+        testGetSslAttributes("INPUT".getBytes(), _plainTransportWrapper, null, 
null);
+    }
+
+    /**
+     * Tests {@link SslHandshakeSniffingTransportWrapper#getCipherName()}
+     * and {@link SslHandshakeSniffingTransportWrapper#getProtocolName()}.
+     */
+    @Test
+    public void testGetSslAttributesWhenUsingSsl()
+    {
+        String cipherName = "testCipherName";
+        String protocolName = "testProtocolName";
+        when(_secureTransportWrapper.getCipherName()).thenReturn(cipherName);
+        
when(_secureTransportWrapper.getProtocolName()).thenReturn(protocolName);
+
+        testGetSslAttributes(EXAMPLE_SSL_V2_HANDSHAKE_BYTES, 
_secureTransportWrapper, cipherName, protocolName);
+    }
+
+    private void testGetSslAttributes(
+            byte[] input, TransportWrapper transportThatShouldBeUsed,
+            String expectedCipherName, String expectedProtocolName)
+    {
+        ByteBuffer underlyingInputBuffer = ByteBuffer.allocate(1024);
+        
when(transportThatShouldBeUsed.getInputBuffer()).thenReturn(underlyingInputBuffer);
+
+        _sniffingWrapper.getInputBuffer().put(input);
+        _sniffingWrapper.processInput();
+
+        assertEquals(expectedCipherName, _sniffingWrapper.getCipherName());
+        assertEquals(expectedProtocolName, _sniffingWrapper.getProtocolName());
+
+        verifyZeroInteractionsWithOtherTransport(transportThatShouldBeUsed);
+    }
+
+    private void verifyZeroInteractionsWithOtherTransport(TransportWrapper 
transportThatShouldBeUsed)
+    {
+        final TransportWrapper transportThatShouldNotBeUsed;
+        if(transportThatShouldBeUsed == _plainTransportWrapper)
+        {
+            transportThatShouldNotBeUsed = _secureTransportWrapper;
+        }
+        else
+        {
+            transportThatShouldNotBeUsed = _plainTransportWrapper;
+        }
+
+        verifyZeroInteractions(transportThatShouldNotBeUsed);
+    }
+
+}

Modified: qpid/proton/trunk/tests/java/org/apache/qpid/proton/JythonTest.java
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/tests/java/org/apache/qpid/proton/JythonTest.java?rev=1484842&r1=1484841&r2=1484842&view=diff
==============================================================================
--- qpid/proton/trunk/tests/java/org/apache/qpid/proton/JythonTest.java 
(original)
+++ qpid/proton/trunk/tests/java/org/apache/qpid/proton/JythonTest.java Tue May 
21 15:49:52 2013
@@ -20,6 +20,7 @@
  */
 package org.apache.qpid.proton;
 
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import java.io.File;
@@ -35,7 +36,9 @@ import org.python.util.PythonInterpreter
 
 /**
  * Runs all the python tests, or just those that match the system property 
{@value #TEST_PATTERN_SYSTEM_PROPERTY}
- * if it exists
+ * if it exists.
+ * Use {@value #TEST_INVOCATIONS_SYSTEM_PROPERTY} to specify the number of 
repetitions, or use 0
+ * for unlimited repetitions.
  */
 public class JythonTest
 {
@@ -49,7 +52,12 @@ public class JythonTest
     /** Name of the junit style xml report to be written by the python test 
script */
     private static final String XML_REPORT_NAME = 
"TEST-jython-test-results.xml";
 
-    private static final String TEST_PATTERN_SYSTEM_PROPERTY = 
"proton.pythontest.pattern";
+    public static final String TEST_PATTERN_SYSTEM_PROPERTY = 
"proton.pythontest.pattern";
+
+    /** The number of times to run the test, or forever if zero */
+    public static final String TEST_INVOCATIONS_SYSTEM_PROPERTY = 
"proton.pythontest.invocations";
+
+    public static final String ALWAYS_COLORIZE_SYSTEM_PROPERTY = 
"proton.pythontest.always_colorize";
 
     @Test
     public void test() throws Exception
@@ -64,6 +72,26 @@ public class JythonTest
         LOGGER.info("About to call Jython test script: '" + testScript
                 + "' with '" + testRoot + "' added to Jython path");
 
+        int maxInvocations = 
Integer.getInteger(TEST_INVOCATIONS_SYSTEM_PROPERTY, 1);
+        assertTrue("Number of invocations should be non-negative", 
maxInvocations >= 0);
+        boolean loopForever = maxInvocations == 0;
+        if(maxInvocations > 1)
+        {
+            LOGGER.info("Will invoke Python test " + maxInvocations + " 
times");
+        }
+        if(loopForever)
+        {
+            LOGGER.info("Will repeatedly invoke Python test forever");
+        }
+        int invocations = 1;
+        while(loopForever || invocations++ <= maxInvocations)
+        {
+            runTestOnce(testScript, interp, invocations);
+        }
+    }
+
+    private void runTestOnce(String testScript, PythonInterpreter interp, int 
invocationsSoFar)
+    {
         try
         {
             interp.execfile(testScript);
@@ -83,7 +111,7 @@ public class JythonTest
 
                 // This unusual code is necessary because PyException 
toString() contains the useful Python traceback
                 // and getMessage() is usually null
-                fail("Caught PyException: " + e.toString() + " with message: " 
+ e.getMessage());
+                fail("Caught PyException on invocation number " + 
invocationsSoFar + ": " + e.toString() + " with message: " + e.getMessage());
             }
         }
     }
@@ -91,7 +119,6 @@ public class JythonTest
     private PythonInterpreter createInterpreterWithArgs(String xmlReportFile)
     {
         PySystemState systemState = new PySystemState();
-        String testPattern = System.getProperty(TEST_PATTERN_SYSTEM_PROPERTY);
 
         if (xmlReportFile != null)
         {
@@ -99,11 +126,17 @@ public class JythonTest
             systemState.argv.append(new PyString(xmlReportFile));
         }
 
+        String testPattern = System.getProperty(TEST_PATTERN_SYSTEM_PROPERTY);
         if(testPattern != null)
         {
             systemState.argv.append(new PyString(testPattern));
         }
 
+        if(Boolean.getBoolean(ALWAYS_COLORIZE_SYSTEM_PROPERTY))
+        {
+            systemState.argv.append(new PyString("--always-colorize"));
+        }
+
         PythonInterpreter interp = new PythonInterpreter(null, systemState);
         return interp;
     }

Modified: 
qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/BinaryFormatter.java
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/BinaryFormatter.java?rev=1484842&r1=1484841&r2=1484842&view=diff
==============================================================================
--- 
qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/BinaryFormatter.java
 (original)
+++ 
qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/BinaryFormatter.java
 Tue May 21 15:49:52 2013
@@ -21,10 +21,10 @@ package org.apache.qpid.proton.systemtes
 public class BinaryFormatter
 {
 
-    public String format(byte[] binaryData, int length)
+    public String format(byte[] binaryData)
     {
         StringBuilder stringBuilder = new StringBuilder();
-        for(int i = 0; i < length; i++)
+        for(int i = 0; i < binaryData.length; i++)
         {
             byte theByte = binaryData[i];
             String formattedByte = formatByte(theByte);

Modified: 
qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/BinaryFormatterTest.java
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/BinaryFormatterTest.java?rev=1484842&r1=1484841&r2=1484842&view=diff
==============================================================================
--- 
qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/BinaryFormatterTest.java
 (original)
+++ 
qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/BinaryFormatterTest.java
 Tue May 21 15:49:52 2013
@@ -30,14 +30,14 @@ public class BinaryFormatterTest
     @Test
     public void testSingleCharacter()
     {
-        assertEquals("[ A ]", _binaryFormatter.format("A".getBytes(), 1));
+        assertEquals("[ A ]", _binaryFormatter.format("A".getBytes()));
     }
 
     @Test
     public void testSingleSmallNonCharacter()
     {
         byte[] bytes = new byte[] { (byte)0x1 };
-        assertEquals("[x01]", _binaryFormatter.format(bytes, 1));
+        assertEquals("[x01]", _binaryFormatter.format(bytes));
     }
 
     @Test
@@ -46,7 +46,7 @@ public class BinaryFormatterTest
         int numberToUse = 0xa2;
         byte byteToUse = (byte)numberToUse;
         byte[] bytes = new byte[] { byteToUse };
-        assertEquals("[xa2]", _binaryFormatter.format(bytes, 1));
+        assertEquals("[xa2]", _binaryFormatter.format(bytes));
     }
 
     @Test
@@ -56,7 +56,7 @@ public class BinaryFormatterTest
         System.arraycopy("ABC".getBytes(), 0, binaryData, 0, 3);
         binaryData[3] = (byte)0xff;
 
-        String formattedString = _binaryFormatter.format(binaryData, 
binaryData.length);
+        String formattedString = _binaryFormatter.format(binaryData);
         String expected = "[ A ][ B ][ C ][xff]";
         assertEquals(expected, formattedString);
     }

Modified: 
qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/ProtonEngineExampleTest.java
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/ProtonEngineExampleTest.java?rev=1484842&r1=1484841&r2=1484842&view=diff
==============================================================================
--- 
qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/ProtonEngineExampleTest.java
 (original)
+++ 
qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/ProtonEngineExampleTest.java
 Tue May 21 15:49:52 2013
@@ -29,7 +29,8 @@ import static org.apache.qpid.proton.sys
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertSame;
 
-import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
 import java.util.logging.Logger;
 
 import org.apache.qpid.proton.ProtonFactoryLoader;
@@ -59,6 +60,10 @@ import org.junit.Test;
  *
  * org.apache.qpid.proton.logging.LoggingProtocolTracer.sent.level = ALL
  *
+ * and to see the byte level trace, add the following:
+ *
+ * org.apache.qpid.proton.systemtests.ProtonEngineExampleTest.level = ALL
+ *
  * Does not illustrate use of the Messenger API.
  */
 public class ProtonEngineExampleTest
@@ -181,9 +186,9 @@ public class ProtonEngineExampleTest
         _client.message = _messageFactory.createMessage();
         Section messageBody = new AmqpValue("Hello");
         _client.message.setBody(messageBody);
-        _client.messageData = newByteArray();
+        _client.messageData = new byte[BUFFER_SIZE];
         int lengthOfEncodedMessage = 
_client.message.encode(_client.messageData, 0, BUFFER_SIZE);
-        _testLoggingHelper.prettyPrintBytes(TestLoggingHelper.MESSAGE_PREFIX, 
_client.messageData, lengthOfEncodedMessage);
+        _testLoggingHelper.prettyPrint(TestLoggingHelper.MESSAGE_PREFIX, 
Arrays.copyOf(_client.messageData, lengthOfEncodedMessage));
 
         byte[] deliveryTag = "delivery1".getBytes();
         _client.delivery = _client.sender.delivery(deliveryTag);
@@ -218,7 +223,7 @@ public class ProtonEngineExampleTest
         assertFalse(_server.delivery.isPartial());
         assertTrue(_server.delivery.isReadable());
 
-        _server.messageData = newByteArray();
+        _server.messageData = new byte[BUFFER_SIZE];
         int numberOfBytesProducedByReceiver = 
_server.receiver.recv(_server.messageData, 0, BUFFER_SIZE);
         assertEquals(numberOfBytesAcceptedBySender, 
numberOfBytesProducedByReceiver);
 
@@ -364,47 +369,43 @@ public class ProtonEngineExampleTest
         pumpServerToClient();
     }
 
-    private void pumpClientToServer() throws UnsupportedEncodingException
+    private void pumpClientToServer()
     {
-        final byte[] clientOutput = newByteArray();
-        int clientOutputLength = _client.transport.output(clientOutput, 0, 
BUFFER_SIZE);
-        _testLoggingHelper.prettyPrintBytes(TestLoggingHelper.CLIENT_PREFIX + 
">>> ", clientOutput, clientOutputLength);
+        ByteBuffer clientBuffer = _client.transport.getOutputBuffer();
 
-        assertTrue("Client expected to produce some output", 
clientOutputLength > 0);
+        _testLoggingHelper.prettyPrint(TestLoggingHelper.CLIENT_PREFIX + ">>> 
", clientBuffer);
+        assertTrue("Client expected to produce some output", 
clientBuffer.hasRemaining());
 
-        int serverInputLength = _server.transport.input(clientOutput, 0, 
clientOutputLength);
-        LOGGER.fine("          >>>" + TestLoggingHelper.SERVER_PREFIX + " " + 
serverInputLength + " byte(s)");
+        ByteBuffer serverBuffer = _server.transport.getInputBuffer();
 
-        assertEquals("Server expected to consume all client's output", 
clientOutputLength, serverInputLength);
-    }
+        serverBuffer.put(clientBuffer);
 
-    private void assertClientHasNothingToOutput() throws 
UnsupportedEncodingException
-    {
-        final byte[] clientOutput1 = newByteArray();
-        int clientOutputLength = _client.transport.output(clientOutput1, 0, 
BUFFER_SIZE);
-        assertEquals(0, clientOutputLength);
-    }
+        assertEquals("Server expected to consume all client's output", 0, 
clientBuffer.remaining());
 
+        _client.transport.outputConsumed();
+        _server.transport.processInput().checkIsOk();
+    }
 
-    private void pumpServerToClient() throws UnsupportedEncodingException
+    private void pumpServerToClient()
     {
-        final byte[] serverOutput = newByteArray();
-        int serverOutputLength = _server.transport.output(serverOutput, 0, 
BUFFER_SIZE);
+        ByteBuffer serverBuffer = _server.transport.getOutputBuffer();
 
-        _testLoggingHelper.prettyPrintBytes("          <<<" + 
TestLoggingHelper.SERVER_PREFIX + " ", serverOutput, serverOutputLength);
+        _testLoggingHelper.prettyPrint("          <<<" + 
TestLoggingHelper.SERVER_PREFIX + " ", serverBuffer);
+        assertTrue("Server expected to produce some output", 
serverBuffer.hasRemaining());
 
-        assertTrue("Server expected to produce some output", 
serverOutputLength > 0);
+        ByteBuffer clientBuffer = _client.transport.getInputBuffer();
 
-        int clientInputLength = _client.transport.input(serverOutput, 0, 
serverOutputLength);
-        LOGGER.fine(TestLoggingHelper.CLIENT_PREFIX + "<<< " + 
clientInputLength + " byte(s)");
+        clientBuffer.put(serverBuffer);
 
-        assertEquals("Client expected to consume all server's output", 
serverOutputLength, clientInputLength);
+        assertEquals("Client expected to consume all server's output", 0, 
serverBuffer.remaining());
+
+        _client.transport.processInput().checkIsOk();
+        _server.transport.outputConsumed();
     }
 
-    /** returns a byte array sized to be big enough to avoid left-overs */
-    private byte[] newByteArray()
+    private void assertClientHasNothingToOutput()
     {
-        return new byte[BUFFER_SIZE];
+        assertEquals(0, _client.transport.getOutputBuffer().remaining());
+        _client.transport.outputConsumed();
     }
-
 }

Modified: 
qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/TestLoggingHelper.java
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/TestLoggingHelper.java?rev=1484842&r1=1484841&r2=1484842&view=diff
==============================================================================
--- 
qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/TestLoggingHelper.java
 (original)
+++ 
qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/TestLoggingHelper.java
 Tue May 21 15:49:52 2013
@@ -18,7 +18,7 @@
  */
 package org.apache.qpid.proton.systemtests;
 
-import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
 import java.util.logging.Logger;
 
 /**
@@ -63,9 +63,19 @@ public class TestLoggingHelper
         _logger = logger;
     }
 
-    public void prettyPrintBytes(String prefix, final byte[] bytes, int 
length) throws UnsupportedEncodingException
+    public void prettyPrint(String prefix, byte[] bytes)
     {
-        _logger.fine(prefix + " " + length + " byte(s) " + 
_binaryFormatter.format(bytes, length));
+        _logger.fine(prefix + " " + bytes.length + " byte(s) " + 
_binaryFormatter.format(bytes));
+    }
+
+    /**
+     * Note that ByteBuffer is assumed to be readable. Its state is unchanged 
by this operation.
+     */
+    public void prettyPrint(String prefix, ByteBuffer buf)
+    {
+        byte[] bytes = new byte[buf.remaining()];
+        buf.duplicate().get(bytes);
+        prettyPrint(prefix, bytes);
     }
 
     public static String bold(String string)
@@ -73,4 +83,5 @@ public class TestLoggingHelper
         return BOLD + string + TestLoggingHelper.COLOUR_RESET;
     }
 
+
 }

Modified: 
qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/engine/ConnectionTest.java
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/engine/ConnectionTest.java?rev=1484842&r1=1484841&r2=1484842&view=diff
==============================================================================
--- 
qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/engine/ConnectionTest.java
 (original)
+++ 
qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/engine/ConnectionTest.java
 Tue May 21 15:49:52 2013
@@ -45,6 +45,7 @@ import org.apache.qpid.proton.engine.Eng
 import org.apache.qpid.proton.engine.Session;
 import org.apache.qpid.proton.engine.Transport;
 import org.apache.qpid.proton.engine.TransportException;
+import org.apache.qpid.proton.engine.impl.AmqpFramer;
 import org.junit.Ignore;
 import org.junit.Test;
 

Modified: qpid/proton/trunk/tests/pom.xml
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/tests/pom.xml?rev=1484842&r1=1484841&r2=1484842&view=diff
==============================================================================
--- qpid/proton/trunk/tests/pom.xml (original)
+++ qpid/proton/trunk/tests/pom.xml Tue May 21 15:49:52 2013
@@ -24,16 +24,22 @@
   <artifactId>tests</artifactId>
   <name>tests</name>
 
-  <description>The Proton system tests execute against either the Java or the 
C implementations, based on the chosen profile.
+  <description>The Proton system tests execute against either the Java or the 
C implementations,
+based on the chosen profile.
 
-To execute, run either &quot;mvn test -P proton-j&quot; or &quot;mvn test -P 
proton-jni&quot;.
+To execute, run either &quot;mvn test&quot; or &quot;mvn test -P 
proton-jni&quot;.
 
-To reduce the set of Python tests run, set system property 
proton.pythontest.pattern, for example:
+Example of advanced usage (all of the -D flags are optional):
 
-mvn test -Dproton.pythontest.pattern='proton_tests.transport.TransportTest.*'
+mvn test \
+-P proton-jni \
+-Dproton.pythontest.pattern='proton_tests.transport.TransportTest.*' \
+-Dproton.pythontest.invocations=20 \
+-Dproton.pythontest.always_colorize=true \
+-Dproton-c-build-dir=/path/to/build/dir
 
-The proton-jni profile looks for the JNI jar and native libraries under 
directory &lt;basedir&gt;/build/proton-c.
-To override this, run Maven like so: &quot;mvn test -P proton-jni 
-Dproton-c-build-dir=/path/to/build/dir&quot;.</description>
+By default, the proton-jni profile looks for the JNI jar and native libraries 
under
+directory &lt;basedir&gt;/build/proton-c.</description>
 
   <properties>
     
<testReportOutputDirectory>${basedir}/target/surefire-reports</testReportOutputDirectory>
@@ -80,6 +86,23 @@ To override this, run Maven like so: &qu
         <version>2.5.3</version>
       <scope>test</scope>
     </dependency>
+
+    <dependency>
+      <!-- proton-j-impl is even required for profile proton-jni so we can use 
EncoderImpl and DecoderImpl to
+           generate test data, hence this dependency appearing here and not 
just in the proton-j profile -->
+      <groupId>org.apache.qpid</groupId>
+      <artifactId>proton-j-impl</artifactId>
+      <version>1.0-SNAPSHOT</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <!-- Depend on test helper classes contained with test-jar from 
proton-j-impl -->
+      <groupId>org.apache.qpid</groupId>
+      <artifactId>proton-j-impl</artifactId>
+      <version>1.0-SNAPSHOT</version>
+      <scope>test</scope>
+      <type>test-jar</type>
+    </dependency>
   </dependencies>
 
   <profiles>
@@ -101,14 +124,6 @@ To override this, run Maven like so: &qu
           </plugin>
         </plugins>
       </build>
-      <dependencies>
-        <dependency>
-          <groupId>org.apache.qpid</groupId>
-          <artifactId>proton-j-impl</artifactId>
-          <version>1.0-SNAPSHOT</version>
-          <scope>runtime</scope>
-        </dependency>
-      </dependencies>
     </profile>
     <profile>
       <id>proton-jni</id>
@@ -142,13 +157,6 @@ To override this, run Maven like so: &qu
           <scope>system</scope>
           <systemPath>${jni-jar}</systemPath>
         </dependency>
-        <!-- proton-j-impl is required so we can use EncoderImpl and 
DecoderImpl to generate test data -->
-        <dependency>
-          <groupId>org.apache.qpid</groupId>
-          <artifactId>proton-j-impl</artifactId>
-          <version>1.0-SNAPSHOT</version>
-          <scope>runtime</scope>
-        </dependency>
       </dependencies>
     </profile>
   </profiles>

Modified: qpid/proton/trunk/tests/python/proton-test
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/tests/python/proton-test?rev=1484842&r1=1484841&r2=1484842&view=diff
==============================================================================
--- qpid/proton/trunk/tests/python/proton-test (original)
+++ qpid/proton/trunk/tests/python/proton-test Tue May 21 15:49:52 2013
@@ -62,6 +62,8 @@ parser.add_option("-D", "--define", meta
                   action="append", default=[], help="define test parameters")
 parser.add_option("-x", "--xml", metavar="XML", dest="xml",
                   help="write test results in Junit style xml suitable for use 
by CI tools etc")
+parser.add_option("-a", "--always-colorize", action="store_true", 
dest="always_colorize", default=False,
+                  help="always colorize the test results rather than relying 
on terminal tty detection. Useful when invoked from Jython/Maven.")
 
 class Config:
 
@@ -164,15 +166,13 @@ KEYWORDS = {"pass": (32,),
             "elapsed": (34,),
             "average": (34,)}
 
-COLORIZE = is_smart()
-
 def colorize_word(word, text=None):
   if text is None:
     text = word
   return colorize(text, *KEYWORDS.get(word, ()))
 
 def colorize(text, *attrs):
-  if attrs and COLORIZE:
+  if attrs and (is_smart() or opts.always_colorize):
     return "%s%s%s" % (vt100_attrs(*attrs), text, vt100_reset)
   else:
     return text

Modified: qpid/proton/trunk/tests/python/proton_tests/common.py
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/tests/python/proton_tests/common.py?rev=1484842&r1=1484841&r2=1484842&view=diff
==============================================================================
--- qpid/proton/trunk/tests/python/proton_tests/common.py (original)
+++ qpid/proton/trunk/tests/python/proton_tests/common.py Tue May 21 15:49:52 
2013
@@ -22,7 +22,7 @@ from threading import Thread
 from socket import socket, AF_INET, SOCK_STREAM
 from subprocess import Popen,PIPE
 import sys, os
-from proton import Driver, Connection, SASL, Endpoint, Delivery
+from proton import Driver, Connection, Transport, SASL, Endpoint, Delivery
 
 
 def free_tcp_ports(count=1):
@@ -46,6 +46,42 @@ def free_tcp_ports(count=1):
   return ports
 
 
+def pump(transport1, transport2, buffer_size=1024):
+  """ Transfer all pending bytes between two Proton engines
+      by repeatedly calling input and output.
+      Asserts that each engine accepts some bytes every time
+      (unless it's already closed).
+  """
+
+  out1_leftover_by_t2 = ""
+  out2_leftover_by_t1 = ""
+  i = 0
+
+  while True:
+    out1 = out1_leftover_by_t2 + (transport1.output(buffer_size) or "")
+    out2 = out2_leftover_by_t1 + (transport2.output(buffer_size) or "")
+
+    if out1:
+      number_t2_consumed = transport2.input(out1)
+      if number_t2_consumed is None:
+        # special None return value means input is closed so discard the 
leftovers
+        out1_leftover_by_t2 = ""
+      else:
+        assert number_t2_consumed > 0, (number_t2_consumed, len(out1), 
out1[:100])
+        out1_leftover_by_t2 = out1[number_t2_consumed:]
+
+    if out2:
+      number_t1_consumed = transport1.input(out2)
+      if number_t1_consumed is None:
+        # special None return value means input is closed so discard the 
leftovers
+        out2_leftover_by_t1 = ""
+      else:
+        assert number_t1_consumed > 0, (number_t1_consumed, len(out1), 
out1[:100])
+        out2_leftover_by_t1 = out2[number_t1_consumed:]
+
+    if not out1 and not out2: break
+    i = i + 1
+
 class Test:
 
   def __init__(self, name):

Modified: qpid/proton/trunk/tests/python/proton_tests/engine.py
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/tests/python/proton_tests/engine.py?rev=1484842&r1=1484841&r2=1484842&view=diff
==============================================================================
--- qpid/proton/trunk/tests/python/proton_tests/engine.py (original)
+++ qpid/proton/trunk/tests/python/proton_tests/engine.py Tue May 21 15:49:52 
2013
@@ -20,6 +20,7 @@
 import os, common
 from time import time, sleep
 from proton import *
+from common import pump
 
 # future test areas
 #  + different permutations of setup
@@ -30,21 +31,6 @@ from proton import *
 
 OUTPUT_SIZE = 10*1024
 
-def pump(t1, t2, buffer_size=OUTPUT_SIZE):
-  while True:
-    out1 = t1.output(buffer_size)
-    out2 = t2.output(buffer_size)
-
-    if out1 or out2:
-      if out1:
-        n = t2.input(out1)
-        assert n is None or n == len(out1), (n, out1, len(out1))
-      if out2:
-        n = t1.input(out2)
-        assert n is None or n == len(out2), (n, out2, len(out2))
-    else:
-      return
-
 class Test(common.Test):
 
   def __init__(self, *args):

Modified: qpid/proton/trunk/tests/python/proton_tests/messenger.py
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/tests/python/proton_tests/messenger.py?rev=1484842&r1=1484841&r2=1484842&view=diff
==============================================================================
--- qpid/proton/trunk/tests/python/proton_tests/messenger.py (original)
+++ qpid/proton/trunk/tests/python/proton_tests/messenger.py Tue May 21 
15:49:52 2013
@@ -17,7 +17,7 @@
 # under the License.
 #
 
-import os, common
+import os, common, sys, traceback
 from proton import *
 from threading import Thread, Event
 from time import sleep, time
@@ -46,20 +46,39 @@ class Test(common.Test):
     self.server_is_running_event.wait(self.timeout)
     self.client.start()
 
+  def _safelyStopClient(self):
+    existing_exception = None
+    try:
+      # send a message to cause the server to promptly exit
+      msg = Message()
+      msg.address="amqp://0.0.0.0:12345"
+      self.client.put(msg)
+      try:
+        self.client.send()
+      except:
+        print "Client failed to send shutdown message due to: %s" % 
sys.exc_info()[1]
+        existing_exception = sys.exc_info()[1]
+        raise
+    finally:
+      try:
+        self.client.stop()
+        self.client = None
+      except:
+        print "Client failed to stop due to: %s" % sys.exc_info()[1]
+        if existing_exception:
+          raise existing_exception
+        else:
+          raise
+
   def teardown(self):
     try:
       if self.running:
         if not self.server_thread_started: self.start()
         # send a message to cause the server to promptly exit
         self.running = False
-        msg = Message()
-        msg.address="amqp://0.0.0.0:12345"
-        self.client.put(msg)
-        self.client.send()
+        self._safelyStopClient()
     finally:
-      self.client.stop()
       self.server_thread.join(self.timeout)
-      self.client = None
       self.server = None
 
 REJECT_ME = "*REJECT-ME*"
@@ -165,6 +184,7 @@ class MessengerTest(Test):
     for t in trackers:
       assert self.client.status(t) is None
 
+    # reduce outgoing_window to 5 and then try to send 10 messages
     self.client.outgoing_window = 5
 
     trackers = []

Modified: qpid/proton/trunk/tests/python/proton_tests/sasl.py
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/tests/python/proton_tests/sasl.py?rev=1484842&r1=1484841&r2=1484842&view=diff
==============================================================================
--- qpid/proton/trunk/tests/python/proton_tests/sasl.py (original)
+++ qpid/proton/trunk/tests/python/proton_tests/sasl.py Tue May 21 15:49:52 2013
@@ -19,6 +19,7 @@
 
 import os, common
 from proton import *
+from common import pump
 
 class Test(common.Test):
   pass
@@ -32,12 +33,7 @@ class SaslTest(Test):
     self.s2 = SASL(self.t2)
 
   def pump(self):
-    while True:
-      out1 = self.t1.output(1024)
-      out2 = self.t2.output(1024)
-      if out1: self.t2.input(out1)
-      if out2: self.t1.input(out2)
-      if not out1 and not out2: break
+    pump(self.t1, self.t2, 1024)
 
   def testPipelined(self):
     self.s1.mechanisms("ANONYMOUS")
@@ -62,6 +58,49 @@ class SaslTest(Test):
 
     assert self.s2.outcome == SASL.OK
 
+  def testSaslAndAmqpInSingleChunk(self):
+    self.s1.mechanisms("ANONYMOUS")
+    self.s1.client()
+
+    self.s2.mechanisms("ANONYMOUS")
+    self.s2.server()
+    self.s2.done(SASL.OK)
+
+    # send the server's OK to the client
+    out2 = self.t2.output(1024)
+    self.t1.input(out2)
+
+    # do some work to generate AMQP data
+    c1 = Connection()
+    c2 = Connection()
+    self.t1.bind(c1)
+    c1._transport = self.t1
+    self.t2.bind(c2)
+    c2._transport = self.t2
+
+    c1.open()
+
+    # get all t1's output in one buffer then pass it all to t2
+    out1_sasl_and_amqp = ""
+    t1_still_producing = True
+    while t1_still_producing:
+      out1 = self.t1.output(1024)
+      out1_sasl_and_amqp += out1
+      t1_still_producing = out1
+
+    t2_still_consuming = True
+    while t2_still_consuming:
+      num_consumed = self.t2.input(out1_sasl_and_amqp)
+      out1_sasl_and_amqp = out1_sasl_and_amqp[num_consumed:]
+      t2_still_consuming = num_consumed > 0 and len(out1_sasl_and_amqp) > 0
+
+    assert len(out1_sasl_and_amqp) == 0, (len(out1_sasl_and_amqp), 
out1_sasl_and_amqp)
+
+    # check that t2 processed both the SASL data and the AMQP data
+    assert self.s2.outcome == SASL.OK
+    assert c2.state & Endpoint.REMOTE_ACTIVE
+
+
   def testChallengeResponse(self):
     self.s1.mechanisms("FAKE_MECH")
     self.s1.client()

Modified: qpid/proton/trunk/tests/python/proton_tests/ssl.py
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/tests/python/proton_tests/ssl.py?rev=1484842&r1=1484841&r2=1484842&view=diff
==============================================================================
--- qpid/proton/trunk/tests/python/proton_tests/ssl.py (original)
+++ qpid/proton/trunk/tests/python/proton_tests/ssl.py Tue May 21 15:49:52 2013
@@ -20,7 +20,7 @@
 import os, common
 import subprocess
 from proton import *
-from common import Skipped
+from common import Skipped, pump
 
 
 class SslTest(common.Test):
@@ -57,34 +57,7 @@ class SslTest(common.Test):
                 raise Skipped(e)
 
     def _pump(self, ssl_client, ssl_server, buffer_size=1024):
-        """ Allow two SslTestConnections to transfer data until done.
-        """
-        out_client_leftover_by_server = ""
-        out_server_leftover_by_client = ""
-        i = 0
-
-        while True:
-            out_client = out_client_leftover_by_server + 
(ssl_client.transport.output(buffer_size) or "")
-            out_server = out_server_leftover_by_client + 
(ssl_server.transport.output(buffer_size) or "")
-
-            if out_client:
-                number_server_consumed = ssl_server.transport.input(out_client)
-                if number_server_consumed is None:
-                    # special None return value means input is closed so 
discard the leftovers
-                    out_client_leftover_by_server = ""
-                else:
-                    out_client_leftover_by_server = 
out_client[number_server_consumed:]
-
-            if out_server:
-                number_client_consumed = ssl_client.transport.input(out_server)
-                if number_client_consumed is None:
-                    # special None return value means input is closed so 
discard the leftovers
-                    out_server_leftover_by_client = ""
-                else:
-                    out_server_leftover_by_client = 
out_server[number_client_consumed:]
-
-            if not out_client and not out_server: break
-            i = i + 1
+        pump(ssl_client.transport, ssl_server.transport, buffer_size)
 
     def _testpath(self, file):
         """ Set the full path to the certificate,keyfile, etc. for the test.
@@ -363,7 +336,7 @@ class SslTest(common.Test):
         server.connection.close()
         self._pump( client, server )
 
-    def test_allow_unsecured_client(self):
+    def test_allow_unsecured_client_which_connects_unsecured(self):
         """ Server allows an unsecured client to connect if configured.
         """
         
self.server_domain.set_credentials(self._testpath("server-certificate.pem"),
@@ -387,6 +360,39 @@ class SslTest(common.Test):
         server.connection.close()
         self._pump( client, server )
 
+    def test_allow_unsecured_client_which_connects_secured(self):
+        """ As per test_allow_unsecured_client_which_connects_unsecured
+            but client actually uses SSL
+        """
+        
self.server_domain.set_credentials(self._testpath("server-certificate.pem"),
+                                           
self._testpath("server-private-key.pem"),
+                                           "server-password")
+        
self.server_domain.set_trusted_ca_db(self._testpath("ca-certificate.pem"))
+        self.server_domain.set_peer_authentication( SSLDomain.VERIFY_PEER,
+                                                    
self._testpath("ca-certificate.pem") )
+
+        
self.client_domain.set_credentials(self._testpath("client-certificate.pem"),
+                                           
self._testpath("client-private-key.pem"),
+                                           "client-password")
+        
self.client_domain.set_trusted_ca_db(self._testpath("ca-certificate.pem"))
+        self.client_domain.set_peer_authentication( SSLDomain.VERIFY_PEER )
+
+        # allow unsecured clients on this connection
+        #self.server_domain.allow_unsecured_client()
+
+        # client uses ssl. Server should detect this.
+        client = SslTest.SslTestConnection( self.client_domain )
+        server = SslTest.SslTestConnection( self.server_domain )
+
+        client.connection.open()
+        server.connection.open()
+        self._pump( client, server )
+        assert server.ssl.protocol_name() is not None
+        client.connection.close()
+        server.connection.close()
+        self._pump( client, server )
+
+
     def test_disallow_unsecured_client(self):
         """ Non-SSL Client is disallowed from connecting to server.
         """



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org
For additional commands, e-mail: commits-h...@qpid.apache.org

Reply via email to