package org.webpieces.nio.test; import java.io.IOException; import java.nio.ByteBuffer; import org.webpieces.util.logging.Logger; import javax.net.ssl.SSLEngine; import junit.framework.TestCase; import org.webpieces.nio.api.deprecated.ChannelServiceFactory; import org.webpieces.nio.api.libs.AsyncSSLEngine; import org.webpieces.nio.api.libs.BufferHelper; import org.webpieces.nio.api.libs.FactoryCreator; import org.webpieces.nio.api.libs.SSLEngineFactory; import org.webpieces.nio.api.libs.SSLListener; import org.webpieces.nio.api.testutil.CloneByteBuffer; import org.webpieces.nio.api.testutil.HandlerForTests; import org.webpieces.nio.api.testutil.MockSSLEngineFactory; import biz.xsoftware.mock.CalledMethod; import biz.xsoftware.mock.MockObject; import biz.xsoftware.mock.MockObjectFactory; /** * Normally I would not separate out one class for testing, but when this * is integrated with the ChanMgr, testing becomes non-deterministic with * packets being separated and such. This allows more deterministic * testing to fully test AsynchSSLEngine. * * @author dean.hiller */ public class TestNewAsynchSSLEngine2 extends TestCase { private static final Logger log = LoggerFactory.getLogger(TestNewAsynchSSLEngine2.class); private BufferHelper helper = ChannelServiceFactory.bufferHelper(null); private MockObject serverList = MockObjectFactory.createMock(SSLListener.class); private MockObject clientList = MockObjectFactory.createMock(SSLListener.class); private AsyncSSLEngine serverEngine; private AsyncSSLEngine clientEngine; @Override protected void setUp() throws Exception { HandlerForTests.setupLogging(); serverList.setDefaultBehavior("packetEncrypted", new CloneByteBuffer()); clientList.setDefaultBehavior("packetEncrypted", new CloneByteBuffer()); SSLEngineFactory sslEngineFactory = new MockSSLEngineFactory(); FactoryCreator creator = FactoryCreator.createFactory(null); SSLEngine wrappedSvr = sslEngineFactory.createEngineForServerSocket(); serverEngine = creator.createSSLEngine("[serverAsynch] ", wrappedSvr, null); serverEngine.setListener((SSLListener)serverList); SSLEngine wrappedClient = sslEngineFactory.createEngineForSocket(); clientEngine = creator.createSSLEngine("[clientEngine] ", wrappedClient, null); clientEngine.setListener((SSLListener)clientList); } @Override protected void tearDown() throws Exception { if(!clientEngine.isClosed()) closeWithExpects(clientEngine, clientList); if(!serverEngine.isClosed()) closeWithExpects(serverEngine, serverList); HandlerForTests.checkForWarnings(); clientList.expect(MockObject.NONE); serverList.expect(MockObject.NONE); } private void closeWithExpects(AsyncSSLEngine engine, MockObject sslListener) throws IOException { TestNewAsynchSSLEngine.closeWithExpects(engine, sslListener); // engine.close(); // // String[] methodNames = new String[2]; // methodNames[0] = "packetEncrypted"; // methodNames[1] = "closed"; // sslListener.expect(methodNames); } /** * This tests the Runnable task being run in between packets such that it * should not cause packet feeds to create new Runnables, and can * run before all packets are in. */ public void testDelayedRunTask() throws Exception { log.trace("B*******************************************"); clientEngine.beginHandshake(); CalledMethod m = clientList.expect("packetEncrypted"); ByteBuffer b = (ByteBuffer)m.getAllParams()[0]; serverEngine.feedEncryptedPacket(b, null); m = serverList.expect("runTask"); Runnable r = (Runnable)m.getAllParams()[0]; r.run(); m = serverList.expect("packetEncrypted"); b = (ByteBuffer)m.getAllParams()[0]; clientEngine.feedEncryptedPacket(b, null); m = clientList.expect("runTask"); r = (Runnable)m.getAllParams()[0]; r.run(); String[] methodNames = new String[3]; methodNames[0] = "packetEncrypted"; methodNames[1] = "packetEncrypted"; methodNames[2] = "packetEncrypted"; CalledMethod[] methods = clientList.expect(methodNames); ByteBuffer b0 = (ByteBuffer)methods[0].getAllParams()[0]; serverEngine.feedEncryptedPacket(b0, null); ByteBuffer b1 = (ByteBuffer)methods[1].getAllParams()[0]; m = serverList.expect("runTask"); r = (Runnable)m.getAllParams()[0]; serverEngine.feedEncryptedPacket(b1, null); ByteBuffer b2 = (ByteBuffer)methods[2].getAllParams()[0]; //THIS IS THE DELAYED RUN TASK run after second feed of data to sslEngine... r.run(); serverEngine.feedEncryptedPacket(b2, null); String[] methodNames1 = new String[3]; methodNames1[0] = "packetEncrypted"; methodNames1[1] = "packetEncrypted"; methodNames1[2] = "encryptedLinkEstablished"; CalledMethod[] methods1 = serverList.expect(methodNames1); ByteBuffer b01 = (ByteBuffer)methods1[0].getAllParams()[0]; clientEngine.feedEncryptedPacket(b01, null); ByteBuffer b11 = (ByteBuffer)methods1[1].getAllParams()[0]; clientEngine.feedEncryptedPacket(b11, null); clientList.expect("encryptedLinkEstablished"); log.trace("E*******************************************"); } /** * This tests the situation where the Runnable must tell the engine * to reprocess the buffer itself. */ public void testReallyDelayedRunTask() throws Exception { log.trace("B*******************************************"); clientEngine.beginHandshake(); CalledMethod m = clientList.expect("packetEncrypted"); ByteBuffer b = (ByteBuffer)m.getAllParams()[0]; serverEngine.feedEncryptedPacket(b, null); m = serverList.expect("runTask"); Runnable r = (Runnable)m.getAllParams()[0]; r.run(); m = serverList.expect("packetEncrypted"); b = (ByteBuffer)m.getAllParams()[0]; clientEngine.feedEncryptedPacket(b, null); m = clientList.expect("runTask"); r = (Runnable)m.getAllParams()[0]; r.run(); String[] methodNames = new String[3]; methodNames[0] = "packetEncrypted"; methodNames[1] = "packetEncrypted"; methodNames[2] = "packetEncrypted"; CalledMethod[] methods = clientList.expect(methodNames); ByteBuffer b0 = (ByteBuffer)methods[0].getAllParams()[0]; serverEngine.feedEncryptedPacket(b0, null); ByteBuffer b1 = (ByteBuffer)methods[1].getAllParams()[0]; m = serverList.expect("runTask"); r = (Runnable)m.getAllParams()[0]; serverEngine.feedEncryptedPacket(b1, null); ByteBuffer b2 = (ByteBuffer)methods[2].getAllParams()[0]; serverEngine.feedEncryptedPacket(b2, null); String[] methodNames1 = new String[3]; //THIS IS THE REALLY DELAYED RUN TASK run after all 3 packets are fed //to ssl engine r.run(); methodNames1[0] = "packetEncrypted"; methodNames1[1] = "packetEncrypted"; methodNames1[2] = "encryptedLinkEstablished"; CalledMethod[] methods1 = serverList.expect(methodNames1); ByteBuffer b01 = (ByteBuffer)methods1[0].getAllParams()[0]; clientEngine.feedEncryptedPacket(b01, null); ByteBuffer b11 = (ByteBuffer)methods1[1].getAllParams()[0]; clientEngine.feedEncryptedPacket(b11, null); clientList.expect("encryptedLinkEstablished"); log.trace("E*******************************************"); } public void testHalfPackets() throws Exception { clientEngine.beginHandshake(); CalledMethod m = clientList.expect("packetEncrypted"); ByteBuffer b = (ByteBuffer)m.getAllParams()[0]; feedPacket(serverEngine, b); m = serverList.expect("runTask"); Runnable r = (Runnable)m.getAllParams()[0]; r.run(); m = serverList.expect("packetEncrypted"); b = (ByteBuffer)m.getAllParams()[0]; log.trace("remain1="+b.remaining()); feedPacket(clientEngine, b); m = clientList.expect("runTask"); r = (Runnable)m.getAllParams()[0]; r.run(); String[] methodNames = new String[3]; methodNames[0] = "packetEncrypted"; methodNames[1] = "packetEncrypted"; methodNames[2] = "packetEncrypted"; CalledMethod[] methods = clientList.expect(methodNames); ByteBuffer b0 = (ByteBuffer)methods[0].getAllParams()[0]; feedPacket(serverEngine, b0); m = serverList.expect("runTask"); r = (Runnable)m.getAllParams()[0]; r.run(); ByteBuffer b1 = (ByteBuffer)methods[1].getAllParams()[0]; feedPacket(serverEngine, b1); ByteBuffer b2 = (ByteBuffer)methods[2].getAllParams()[0]; feedPacket(serverEngine, b2); methodNames = new String[3]; methodNames[0] = "packetEncrypted"; methodNames[1] = "packetEncrypted"; methodNames[2] = "encryptedLinkEstablished"; methods = serverList.expect(methodNames); b0 = (ByteBuffer)methods[0].getAllParams()[0]; feedPacket(clientEngine, b0); b1 = (ByteBuffer)methods[1].getAllParams()[0]; feedPacket(clientEngine, b1); clientList.expect("encryptedLinkEstablished"); } public void testCombinedPackets() throws Exception { clientEngine.beginHandshake(); CalledMethod m; ByteBuffer b; CalledMethod m1 = clientList.expect("packetEncrypted"); ByteBuffer b3 = (ByteBuffer)m1.getAllParams()[0]; serverEngine.feedEncryptedPacket(b3, null); m = serverList.expect("runTask"); Runnable r = (Runnable)m.getAllParams()[0]; r.run(); m = serverList.expect("packetEncrypted"); b = (ByteBuffer)m.getAllParams()[0]; clientEngine.feedEncryptedPacket(b, null); m = clientList.expect("runTask"); r = (Runnable)m.getAllParams()[0]; r.run(); String[] methodNames = new String[3]; methodNames[0] = "packetEncrypted"; methodNames[1] = "packetEncrypted"; methodNames[2] = "packetEncrypted"; CalledMethod[] methods = clientList.expect(methodNames); ByteBuffer b0 = (ByteBuffer)methods[0].getAllParams()[0]; ByteBuffer b1 = (ByteBuffer)methods[1].getAllParams()[0]; ByteBuffer b2 = (ByteBuffer)methods[2].getAllParams()[0]; int total = b0.remaining()+b1.remaining()+b2.remaining(); ByteBuffer combined = ByteBuffer.allocate(total); combined.put(b0); combined.put(b1); combined.put(b2); helper.doneFillingBuffer(combined); serverEngine.feedEncryptedPacket(combined, null); m = serverList.expect("runTask"); r = (Runnable)m.getAllParams()[0]; r.run(); methodNames = new String[3]; methodNames[0] = "packetEncrypted"; methodNames[1] = "packetEncrypted"; methodNames[2] = "encryptedLinkEstablished"; methods = serverList.expect(methodNames); b0 = (ByteBuffer)methods[0].getAllParams()[0]; b1 = (ByteBuffer)methods[1].getAllParams()[0]; total = b0.remaining()+b1.remaining(); combined = ByteBuffer.allocate(total); combined.put(b0); combined.put(b1); helper.doneFillingBuffer(combined); clientEngine.feedEncryptedPacket(combined, null); clientList.expect("encryptedLinkEstablished"); } public void testOneAndHalfPackets() throws Exception { clientEngine.beginHandshake(); CalledMethod m = clientList.expect("packetEncrypted"); ByteBuffer b = (ByteBuffer)m.getAllParams()[0]; serverEngine.feedEncryptedPacket(b, null); m = serverList.expect("runTask"); Runnable r = (Runnable)m.getAllParams()[0]; r.run(); m = serverList.expect("packetEncrypted"); b = (ByteBuffer)m.getAllParams()[0]; clientEngine.feedEncryptedPacket(b, null); m = clientList.expect("runTask"); r = (Runnable)m.getAllParams()[0]; r.run(); String[] methodNames = new String[3]; methodNames[0] = "packetEncrypted"; methodNames[1] = "packetEncrypted"; methodNames[2] = "packetEncrypted"; CalledMethod[] methods = clientList.expect(methodNames); ByteBuffer b0 = (ByteBuffer)methods[0].getAllParams()[0]; ByteBuffer b1 = (ByteBuffer)methods[1].getAllParams()[0]; ByteBuffer b2 = (ByteBuffer)methods[2].getAllParams()[0]; int total = b0.remaining()+b1.remaining()+b2.remaining(); ByteBuffer combined = ByteBuffer.allocate(total); combined.put(b0); int lim = b1.limit(); b1.limit(3); //we only want to put part of b1 in payload combined.put(b1); helper.doneFillingBuffer(combined); serverEngine.feedEncryptedPacket(combined, null); combined.clear(); b1.limit(lim); combined.put(b1); combined.put(b2); helper.doneFillingBuffer(combined); serverEngine.feedEncryptedPacket(combined, null); m = serverList.expect("runTask"); r = (Runnable)m.getAllParams()[0]; r.run(); methodNames = new String[3]; methodNames[0] = "packetEncrypted"; methodNames[1] = "packetEncrypted"; methodNames[2] = "encryptedLinkEstablished"; methods = serverList.expect(methodNames); b0 = (ByteBuffer)methods[0].getAllParams()[0]; b1 = (ByteBuffer)methods[1].getAllParams()[0]; total = b0.remaining()+b1.remaining(); combined = ByteBuffer.allocate(total); combined.put(b0); combined.put(b1); helper.doneFillingBuffer(combined); clientEngine.feedEncryptedPacket(combined, null); clientList.expect("encryptedLinkEstablished"); } public void testRunInMiddleOfPacket() throws Exception { log.trace("B*******************************************"); clientEngine.beginHandshake(); CalledMethod m = clientList.expect("packetEncrypted"); ByteBuffer b = (ByteBuffer)m.getAllParams()[0]; serverEngine.feedEncryptedPacket(b, null); m = serverList.expect("runTask"); Runnable r = (Runnable)m.getAllParams()[0]; r.run(); m = serverList.expect("packetEncrypted"); b = (ByteBuffer)m.getAllParams()[0]; clientEngine.feedEncryptedPacket(b, null); m = clientList.expect("runTask"); r = (Runnable)m.getAllParams()[0]; r.run(); String[] methodNames = new String[3]; methodNames[0] = "packetEncrypted"; methodNames[1] = "packetEncrypted"; methodNames[2] = "packetEncrypted"; CalledMethod[] methods = clientList.expect(methodNames); ByteBuffer b0 = (ByteBuffer)methods[0].getAllParams()[0]; ByteBuffer b1 = (ByteBuffer)methods[1].getAllParams()[0]; ByteBuffer b2 = (ByteBuffer)methods[2].getAllParams()[0]; serverEngine.feedEncryptedPacket(b0, null); m = serverList.expect("runTask"); r = (Runnable)m.getAllParams()[0]; int total = b1.remaining()+b2.remaining(); ByteBuffer combined = ByteBuffer.allocate(total); int lim = b1.limit(); b1.limit(3); //we only want to put part of b1 in payload combined.put(b1); helper.doneFillingBuffer(combined); serverEngine.feedEncryptedPacket(combined, null); //run the task after some of the previous packet fed, then feed rest of packet r.run(); combined.clear(); b1.limit(lim); combined.put(b1); combined.put(b2); helper.doneFillingBuffer(combined); serverEngine.feedEncryptedPacket(combined, null); String[] methodNames1 = new String[3]; methodNames1[0] = "packetEncrypted"; methodNames1[1] = "packetEncrypted"; methodNames1[2] = "encryptedLinkEstablished"; CalledMethod[] methods1 = serverList.expect(methodNames1); b0 = (ByteBuffer)methods1[0].getAllParams()[0]; clientEngine.feedEncryptedPacket(b0, null); b1 = (ByteBuffer)methods1[1].getAllParams()[0]; clientEngine.feedEncryptedPacket(b1, null); clientList.expect("encryptedLinkEstablished"); } private void feedPacket(AsyncSSLEngine engine, ByteBuffer b) throws Exception { TestNewAsynchSSLEngine.feedPacket(engine, b); } }