package org.webpieces.nio.test.tcp; import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.util.HashMap; import java.util.Map; import org.webpieces.util.logging.Logger; import javax.net.ssl.SSLEngine; import junit.framework.TestCase; import org.webpieces.nio.api.channels.TCPChannel; import org.webpieces.nio.api.deprecated.ChannelManagerOld; import org.webpieces.nio.api.deprecated.ChannelService; import org.webpieces.nio.api.deprecated.ChannelServiceFactory; import org.webpieces.nio.api.deprecated.ConnectionCallback; import org.webpieces.nio.api.deprecated.Settings; import org.webpieces.nio.api.handlers.DataListener; import org.webpieces.nio.api.libs.AsyncSSLEngine; import org.webpieces.nio.api.libs.BufferFactory; 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.MockNIOServer; import org.webpieces.nio.api.testutil.MockSSLEngineFactory; import biz.xsoftware.mock.MockObject; import biz.xsoftware.mock.MockObjectFactory; public class TestMoreSecureChanMgr extends TestCase { private static final Logger log = LoggerFactory.getLogger(TestMoreSecureChanMgr.class); private InetSocketAddress svrAddr; private ChannelService chanMgr; private InetAddress loopBack; private InetSocketAddress loopBackAnyPort; // private BufferHelper helper = ChannelManagerFactory.bufferHelper(null); private MockObject mockHandler = MockObjectFactory.createMock(DataListener.class); private MockObject mockConnect = MockObjectFactory.createMock(ConnectionCallback.class); private MockObject mockSSLListener = MockObjectFactory.createMock(SSLListener.class); private TCPChannel client1; private MockNIOServer mockServer; private AsyncSSLEngine sslEngine; private ChannelServiceFactory basicFactory; private BufferFactory bufFactory; private FactoryCreator creator; public TestMoreSecureChanMgr() { basicFactory = ChannelServiceFactory.createFactory(null); Map<String, Object> map = new HashMap<String, Object>(); map.put(FactoryCreator.KEY_IS_DIRECT, false); creator = FactoryCreator.createFactory(null); bufFactory = creator.createBufferFactory(map); } protected ChannelService getClientChanMgr() throws Exception { Map<String, Object> factoryName = new HashMap<String, Object>(); factoryName.put(ChannelServiceFactory.KEY_IMPLEMENTATION_CLASS, ChannelServiceFactory.VAL_SECURE_CHANNEL_MGR); factoryName.put(ChannelServiceFactory.KEY_CHILD_CHANNELMGR_FACTORY, basicFactory); ChannelServiceFactory secureFactory = ChannelServiceFactory.createFactory(factoryName); Map<String, Object> p = new HashMap<String, Object>(); p.put(ChannelManagerOld.KEY_ID, "client"); p.put(ChannelManagerOld.KEY_BUFFER_FACTORY, bufFactory); ChannelService chanMgr = secureFactory.createChannelManager(p); return chanMgr; } protected ChannelService getServerChanMgr() { Map<String, Object> p = new HashMap<String, Object>(); p.put(ChannelManagerOld.KEY_ID, "server"); p.put(ChannelManagerOld.KEY_BUFFER_FACTORY, bufFactory); ChannelService svcChanMgr = basicFactory.createChannelManager(p); return svcChanMgr; } protected String getChannelImplName() { return "biz.xsoftware.impl.nio.cm.secure.TCPChannelImpl"; } protected void setUp() throws Exception { SSLEngineFactory sslEngineFactory = new MockSSLEngineFactory(); Settings clientFactoryHolder = new Settings(sslEngineFactory, null); //use this engine to feed data back from server... SSLEngine wrappedSvr = sslEngineFactory.createEngineForServerSocket(); sslEngine = creator.createSSLEngine("[serverAsynch] ", wrappedSvr, null); sslEngine.setListener((SSLListener)mockSSLListener); //here I keep using the same channel manager on purpose, just //so we get testing between tests that the channel manager shutdown //and started back up cleanly..... if(chanMgr == null) { chanMgr = getClientChanMgr(); } if(mockServer == null) { ChannelService svcChanMgr = getServerChanMgr(); mockServer = new MockNIOServer(svcChanMgr, null); } chanMgr.start(); svrAddr = mockServer.start(); log.trace("server port ="+svrAddr); loopBack = InetAddress.getByName("127.0.0.1"); loopBackAnyPort = new InetSocketAddress(loopBack, 0); mockHandler.setDefaultBehavior("incomingData", new CloneByteBuffer()); mockSSLListener.setDefaultBehavior("packetEncrypted", new CloneByteBuffer()); client1 = chanMgr.createTCPChannel("ClientChannel", clientFactoryHolder); } protected void tearDown() throws Exception { chanMgr.stop(); chanMgr = null; mockServer.stop(); } /** * On windows, happened to run across a test while writing another test where chanMgr * would throw a CancelledKeyException. This test reproduced and help fix * that problem. It only reproduced it 70% of the time, so it is race * condition specific. * * Now, on linux ran into NotYetConnectedException because as soon as you register for * reads jdk1.5.0_05, the selector keeps firing a key that is ready for reads which is * impossible since it is not connected. Then it gets connected and the test only fails * because there is a warning in the log, but otherwise everything keeps working but there * is a performance penalty because of all the NotYetConnectedExceptions being thrown. * Calling registerForReads after calling connect fixes the problem though. * * @throws Exception */ public void xtestNoCancelledKeyException() throws Exception { HandlerForTests.setupLogging(); //make sure we are testing the right one.... Class c = Class.forName(getChannelImplName()); assertEquals("should be instance of correct channel type", client1.getClass(), c); client1.bind(loopBackAnyPort); client1.oldConnect(svrAddr, (ConnectionCallback)mockConnect); client1.registerForReads((DataListener)mockHandler); String[] s = new String[2]; s[0] = MockNIOServer.CONNECTED; s[1] = MockNIOServer.INCOMING_DATA; mockServer.expect(s); client1.registerForReads((DataListener)mockHandler); log.info("verify teardown"); verifyTearDown(); HandlerForTests.checkForWarnings(); } /** * Fail the handshake in a few different locations to see if server * cleans up after itself.... * */ public void testHandshakeFailure() { } public void testRegisterForReadsDuringHandshake() { } /** * Have client just close the socket and see how server reacts!!!! * */ public void testBadClientOnClose() { } // private static TCPChannel expectServerChannel(MockNIOServer mockServer) { // String[] methodNames = new String[2]; // methodNames[0] = MockNIOServer.ABOUT_TO_ACCEPT; // methodNames[1] = MockNIOServer.CONNECTED; // CalledMethod[] methods = mockServer.expect(methodNames); // TCPChannel svrChan = (TCPChannel)methods[1].getAllParams()[0]; // return svrChan; // } private void verifyTearDown() throws IOException { client1.oldClose(); String[] methodNames = new String[2]; methodNames[0] = "incomingData"; //close handshake packet methodNames[1] = MockNIOServer.FAR_END_CLOSED; mockServer.expect(methodNames); } }