/* | |
* Copyright 2007 the original author or authors. | |
* | |
* Licensed 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.mockftpserver.core.session; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import org.mockftpserver.core.MockFtpServerException; | |
import org.mockftpserver.core.command.Command; | |
import org.mockftpserver.core.socket.StubServerSocket; | |
import org.mockftpserver.core.socket.StubServerSocketFactory; | |
import org.mockftpserver.core.socket.StubSocket; | |
import org.mockftpserver.core.socket.StubSocketFactory; | |
import org.mockftpserver.core.util.AssertFailedException; | |
import org.mockftpserver.test.AbstractTestCase; | |
import java.io.ByteArrayInputStream; | |
import java.io.ByteArrayOutputStream; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.net.InetAddress; | |
import java.net.SocketTimeoutException; | |
import java.util.Collections; | |
import java.util.HashMap; | |
import java.util.Map; | |
/** | |
* Tests for the DefaultSession class | |
* | |
* @version $Revision$ - $Date$ | |
* | |
* @author Chris Mair | |
*/ | |
public final class DefaultSessionTest extends AbstractTestCase { | |
private static final Logger LOG = LoggerFactory.getLogger(DefaultSessionTest.class); | |
private static final String DATA = "sample data 123"; | |
private static final int PORT = 197; | |
private static final String NAME1 = "name1"; | |
private static final String NAME2 = "name2"; | |
private static final Object VALUE = "value"; | |
private DefaultSession session; | |
private ByteArrayOutputStream outputStream; | |
private Map commandHandlerMap; | |
private StubSocket stubSocket; | |
private InetAddress clientHost; | |
/** | |
* Perform initialization before each test | |
* | |
* @see org.mockftpserver.test.AbstractTestCase#setUp() | |
*/ | |
protected void setUp() throws Exception { | |
super.setUp(); | |
commandHandlerMap = new HashMap(); | |
outputStream = new ByteArrayOutputStream(); | |
session = createDefaultSession(""); | |
clientHost = InetAddress.getLocalHost(); | |
} | |
/** | |
* @see org.mockftpserver.test.AbstractTestCase#tearDown() | |
*/ | |
protected void tearDown() throws Exception { | |
super.tearDown(); | |
} | |
/** | |
* Test the Constructor when the control socket is null | |
*/ | |
public void testConstructor_NullControlSocket() { | |
try { | |
new DefaultSession(null, commandHandlerMap); | |
fail("Expected AssertFailedException"); | |
} | |
catch (AssertFailedException expected) { | |
LOG.info("Expected: " + expected); | |
} | |
} | |
/** | |
* Test the Constructor when the command handler Map is null | |
*/ | |
public void testConstructor_NullCommandHandlerMap() { | |
try { | |
new DefaultSession(stubSocket, null); | |
fail("Expected AssertFailedException"); | |
} | |
catch (AssertFailedException expected) { | |
LOG.info("Expected: " + expected); | |
} | |
} | |
/** | |
* Test the setClientDataPort() method | |
*/ | |
public void testSetClientDataPort() { | |
StubSocket stubSocket = createTestSocket(""); | |
StubSocketFactory stubSocketFactory = new StubSocketFactory(stubSocket); | |
session.socketFactory = stubSocketFactory; | |
session.setClientDataPort(PORT); | |
session.setClientDataHost(clientHost); | |
session.openDataConnection(); | |
assertEquals("data port", PORT, stubSocketFactory.requestedDataPort); | |
} | |
/** | |
* Test the setClientDataPort() method after the session was in passive data mode | |
*/ | |
public void testSetClientDataPort_AfterPassiveConnectionMode() throws IOException { | |
StubServerSocket stubServerSocket = new StubServerSocket(PORT); | |
StubServerSocketFactory stubServerSocketFactory = new StubServerSocketFactory(stubServerSocket); | |
session.serverSocketFactory = stubServerSocketFactory; | |
session.switchToPassiveMode(); | |
assertFalse("server socket closed", stubServerSocket.isClosed()); | |
assertNotNull("passiveModeDataSocket", session.passiveModeDataSocket); | |
session.setClientDataPort(PORT); | |
// Make sure that any passive mode connection info is cleared out | |
assertTrue("server socket closed", stubServerSocket.isClosed()); | |
assertNull("passiveModeDataSocket should be null", session.passiveModeDataSocket); | |
} | |
/** | |
* Test the setClientHost() method | |
*/ | |
public void testSetClientHost() throws Exception { | |
StubSocket stubSocket = createTestSocket(""); | |
StubSocketFactory stubSocketFactory = new StubSocketFactory(stubSocket); | |
session.socketFactory = stubSocketFactory; | |
session.setClientDataHost(clientHost); | |
session.openDataConnection(); | |
assertEquals("client host", clientHost, stubSocketFactory.requestedHost); | |
} | |
/** | |
* Test the openDataConnection(), setClientDataPort() and setClientDataHost() methods | |
*/ | |
public void testOpenDataConnection() { | |
StubSocket stubSocket = createTestSocket(""); | |
StubSocketFactory stubSocketFactory = new StubSocketFactory(stubSocket); | |
session.socketFactory = stubSocketFactory; | |
// Use default client data port | |
session.setClientDataHost(clientHost); | |
session.openDataConnection(); | |
assertEquals("data port", DefaultSession.DEFAULT_CLIENT_DATA_PORT, stubSocketFactory.requestedDataPort); | |
assertEquals("client host", clientHost, stubSocketFactory.requestedHost); | |
// Set client data port explicitly | |
session.setClientDataPort(PORT); | |
session.setClientDataHost(clientHost); | |
session.openDataConnection(); | |
assertEquals("data port", PORT, stubSocketFactory.requestedDataPort); | |
assertEquals("client host", clientHost, stubSocketFactory.requestedHost); | |
} | |
/** | |
* Test the OpenDataConnection method, when in passive mode and no incoming connection is | |
* initiated | |
*/ | |
public void testOpenDataConnection_PassiveMode_NoConnection() throws IOException { | |
StubServerSocket stubServerSocket = new StubServerSocket(PORT); | |
StubServerSocketFactory stubServerSocketFactory = new StubServerSocketFactory(stubServerSocket); | |
session.serverSocketFactory = stubServerSocketFactory; | |
session.switchToPassiveMode(); | |
try { | |
session.openDataConnection(); | |
fail("Expected MockFtpServerException"); | |
} | |
catch (MockFtpServerException expected) { | |
LOG.info("Expected: " + expected); | |
assertSame("cause", SocketTimeoutException.class, expected.getCause().getClass()); | |
} | |
} | |
/** | |
* Test the OpenDataConnection method, when the clientHost has not been set | |
*/ | |
public void testOpenDataConnection_NullClientHost() { | |
try { | |
session.openDataConnection(); | |
fail("Expected AssertFailedException"); | |
} | |
catch (AssertFailedException expected) { | |
LOG.info("Expected: " + expected); | |
} | |
} | |
/** | |
* Test the readData() method | |
*/ | |
public void testReadData() { | |
StubSocket stubSocket = createTestSocket(DATA); | |
session.socketFactory = new StubSocketFactory(stubSocket); | |
session.setClientDataHost(clientHost); | |
session.openDataConnection(); | |
byte[] data = session.readData(); | |
LOG.info("data=[" + new String(data) + "]"); | |
assertEquals("data", DATA.getBytes(), data); | |
} | |
/** | |
* Test the readData() method after switching to passive mode | |
*/ | |
public void testReadData_PassiveMode() throws IOException { | |
StubSocket stubSocket = createTestSocket(DATA); | |
StubServerSocket stubServerSocket = new StubServerSocket(PORT, stubSocket); | |
StubServerSocketFactory stubServerSocketFactory = new StubServerSocketFactory(stubServerSocket); | |
session.serverSocketFactory = stubServerSocketFactory; | |
session.switchToPassiveMode(); | |
session.openDataConnection(); | |
byte[] data = session.readData(); | |
LOG.info("data=[" + new String(data) + "]"); | |
assertEquals("data", DATA.getBytes(), data); | |
} | |
/** | |
* Test the readData(int) method | |
*/ | |
public void testReadData_NumBytes() { | |
final int NUM_BYTES = 5; | |
final String EXPECTED_DATA = DATA.substring(0, NUM_BYTES); | |
StubSocket stubSocket = createTestSocket(DATA); | |
session.socketFactory = new StubSocketFactory(stubSocket); | |
session.setClientDataHost(clientHost); | |
session.openDataConnection(); | |
byte[] data = session.readData(NUM_BYTES); | |
LOG.info("data=[" + new String(data) + "]"); | |
assertEquals("data", EXPECTED_DATA.getBytes(), data); | |
} | |
public void testReadData_NumBytes_AskForMoreBytesThanThereAre() { | |
StubSocket stubSocket = createTestSocket(DATA); | |
session.socketFactory = new StubSocketFactory(stubSocket); | |
session.setClientDataHost(clientHost); | |
session.openDataConnection(); | |
byte[] data = session.readData(10000); | |
LOG.info("data=[" + new String(data) + "]"); | |
assertEquals("data", DATA.getBytes(), data); | |
} | |
/** | |
* Test the closeDataConnection() method | |
*/ | |
public void testCloseDataConnection() { | |
StubSocket stubSocket = createTestSocket(DATA); | |
session.socketFactory = new StubSocketFactory(stubSocket); | |
session.setClientDataHost(clientHost); | |
session.openDataConnection(); | |
session.closeDataConnection(); | |
assertTrue("client data socket should be closed", stubSocket.isClosed()); | |
} | |
/** | |
* Test the switchToPassiveMode() method | |
*/ | |
public void testSwitchToPassiveMode() throws IOException { | |
StubServerSocket stubServerSocket = new StubServerSocket(PORT); | |
StubServerSocketFactory stubServerSocketFactory = new StubServerSocketFactory(stubServerSocket); | |
session.serverSocketFactory = stubServerSocketFactory; | |
assertNull("passiveModeDataSocket starts out null", session.passiveModeDataSocket); | |
int port = session.switchToPassiveMode(); | |
assertSame("passiveModeDataSocket", stubServerSocket, session.passiveModeDataSocket); | |
assertEquals("port", PORT, port); | |
} | |
/** | |
* Test the getServerHost() method | |
*/ | |
public void testGetServerHost() { | |
assertEquals("host", DEFAULT_HOST, session.getServerHost()); | |
} | |
/** | |
* Test the getClientHost() method when the session is not yet started | |
*/ | |
public void testGetClientHost_NotRunning() { | |
assertNull("null", session.getClientHost()); | |
} | |
/** | |
* Test the parseCommand() method | |
*/ | |
public void testParseCommand() { | |
Command command = session.parseCommand("LIST"); | |
assertEquals("command name", "LIST", command.getName()); | |
assertEquals("command parameters", EMPTY, command.getParameters()); | |
command = session.parseCommand("USER user123"); | |
assertEquals("command name", "USER", command.getName()); | |
assertEquals("command parameters", array("user123"), command.getParameters()); | |
command = session.parseCommand("PORT 127,0,0,1,17,37"); | |
assertEquals("command name", "PORT", command.getName()); | |
assertEquals("command parameters", new String[] { "127", "0", "0", "1", "17", "37" }, command | |
.getParameters()); | |
} | |
/** | |
* Test the parseCommand() method, passing in an empty command String | |
*/ | |
public void testParseCommand_EmptyCommandString() { | |
try { | |
session.parseCommand(""); | |
fail("Expected AssertFailedException"); | |
} | |
catch (AssertFailedException expected) { | |
LOG.info("Expected: " + expected); | |
} | |
} | |
/** | |
* Test the sendData() method, as well as the openDataConnection() and closeDataConnection() | |
*/ | |
public void testSendData() { | |
StubSocket stubSocket = createTestSocket("1234567890 abcdef"); | |
session.socketFactory = new StubSocketFactory(stubSocket); | |
session.setClientDataHost(clientHost); | |
session.openDataConnection(); | |
session.sendData(DATA.getBytes(), DATA.length()); | |
LOG.info("output=[" + outputStream.toString() + "]"); | |
assertEquals("output", DATA, outputStream.toString()); | |
} | |
/** | |
* Test the SendData() method, passing in a null byte[] | |
*/ | |
public void testSendData_Null() { | |
try { | |
session.sendData(null, 1); | |
fail("Expected AssertFailedException"); | |
} | |
catch (AssertFailedException expected) { | |
LOG.info("Expected: " + expected); | |
} | |
} | |
/** | |
* Test the SendReply(int,String) method, passing in an invalid reply code | |
*/ | |
public void testSendReply_InvalidReplyCode() { | |
try { | |
session.sendReply(-66, "text"); | |
fail("Expected AssertFailedException"); | |
} | |
catch (AssertFailedException expected) { | |
LOG.info("Expected: " + expected); | |
} | |
} | |
/** | |
* Test the getAttribute() and setAttribute() methods | |
*/ | |
public void testGetAndSetAttribute() { | |
assertNull("name does not exist yet", session.getAttribute(NAME1)); | |
session.setAttribute(NAME1, VALUE); | |
session.setAttribute(NAME2, null); | |
assertEquals("NAME1", VALUE, session.getAttribute(NAME1)); | |
assertNull("NAME2", session.getAttribute(NAME2)); | |
assertNull("no such name", session.getAttribute("noSuchName")); | |
} | |
/** | |
* Test the getAttribute() method, passing in a null name | |
*/ | |
public void testGetAttribute_Null() { | |
try { | |
session.getAttribute(null); | |
fail("Expected AssertFailedException"); | |
} | |
catch (AssertFailedException expected) { | |
LOG.info("Expected: " + expected); | |
} | |
} | |
/** | |
* Test the setAttribute() method, passing in a null name | |
*/ | |
public void testSetAttribute_NullName() { | |
try { | |
session.setAttribute(null, VALUE); | |
fail("Expected AssertFailedException"); | |
} | |
catch (AssertFailedException expected) { | |
LOG.info("Expected: " + expected); | |
} | |
} | |
/** | |
* Test the removeAttribute() | |
*/ | |
public void testRemoveAttribute() { | |
session.removeAttribute("noSuchName"); // do nothing | |
session.setAttribute(NAME1, VALUE); | |
session.removeAttribute(NAME1); | |
assertNull("NAME1", session.getAttribute(NAME1)); | |
} | |
/** | |
* Test the removeAttribute() method, passing in a null name | |
*/ | |
public void testRemoveAttribute_Null() { | |
try { | |
session.removeAttribute(null); | |
fail("Expected AssertFailedException"); | |
} | |
catch (AssertFailedException expected) { | |
LOG.info("Expected: " + expected); | |
} | |
} | |
/** | |
* Test the getAttributeNames() | |
*/ | |
public void testGetAttributeNames() { | |
assertEquals("No names yet", Collections.EMPTY_SET, session.getAttributeNames()); | |
session.setAttribute(NAME1, VALUE); | |
assertEquals("1", Collections.singleton(NAME1), session.getAttributeNames()); | |
session.setAttribute(NAME2, VALUE); | |
assertEquals("2", set(NAME1, NAME2), session.getAttributeNames()); | |
} | |
// ------------------------------------------------------------------------- | |
// Internal Helper Methods | |
// ------------------------------------------------------------------------- | |
/** | |
* Create and return a DefaultSession object that reads from an InputStream with the specified | |
* contents and writes to the predefined outputStrean ByteArrayOutputStream. Also, save the | |
* StubSocket being used in the stubSocket attribute. | |
* | |
* @param inputStreamContents - the contents of the input stream | |
* @return the DefaultSession | |
*/ | |
private DefaultSession createDefaultSession(String inputStreamContents) { | |
stubSocket = createTestSocket(inputStreamContents); | |
return new DefaultSession(stubSocket, commandHandlerMap); | |
} | |
/** | |
* Create and return a StubSocket that reads from an InputStream with the specified contents and | |
* writes to the predefined outputStrean ByteArrayOutputStream. | |
* | |
* @param inputStreamContents - the contents of the input stream | |
* @return the StubSocket | |
*/ | |
private StubSocket createTestSocket(String inputStreamContents) { | |
InputStream inputStream = new ByteArrayInputStream(inputStreamContents.getBytes()); | |
StubSocket stubSocket = new StubSocket(inputStream, outputStream); | |
stubSocket._setLocalAddress(DEFAULT_HOST); | |
return stubSocket; | |
} | |
} |