blob: 5763e5eebdb644ac1137fa39fcaa25d08a0515ef [file] [log] [blame]
/*
* 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;
}
}