blob: 5c64877c65b1c89ee1611793b406ed1b28606aee [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.command.Command;
import org.mockftpserver.core.command.CommandHandler;
import org.mockftpserver.core.command.CommandNames;
import org.mockftpserver.core.command.ConnectCommandHandler;
import org.mockftpserver.core.command.InvocationRecord;
import org.mockftpserver.core.socket.StubSocket;
import org.mockftpserver.stub.command.AbstractStubCommandHandler;
import org.mockftpserver.test.AbstractTestCase;
import java.io.*;
import java.util.HashMap;
import java.util.ListResourceBundle;
import java.util.Map;
import java.util.ResourceBundle;
/**
* Tests for the DefaultSession class that require the session (thread) to be running/active.
*
* @author Chris Mair
* @version $Revision$ - $Date$
*/
public final class DefaultSession_RunTest extends AbstractTestCase {
private static final Logger LOG = LoggerFactory.getLogger(DefaultSession_RunTest.class);
private static final Command COMMAND = new Command("USER", EMPTY);
private static final int REPLY_CODE = 100;
private static final String REPLY_TEXT = "sample text description";
private DefaultSession session;
private ByteArrayOutputStream outputStream;
private Map commandHandlerMap;
private StubSocket stubSocket;
private boolean commandHandled = false;
private String commandToRegister = COMMAND.getName();
protected void setUp() throws Exception {
super.setUp();
commandHandlerMap = new HashMap();
outputStream = new ByteArrayOutputStream();
}
public void testInvocationOfCommandHandler() throws Exception {
AbstractStubCommandHandler commandHandler = new AbstractStubCommandHandler() {
public void handleCommand(Command command, Session cmdSession, InvocationRecord invocationRecord) {
assertEquals("command", COMMAND, command);
assertSame("session", session, cmdSession);
assertEquals("InvocationRecord: command", COMMAND, invocationRecord.getCommand());
assertEquals("InvocationRecord: clientHost", DEFAULT_HOST, invocationRecord.getClientHost());
commandHandled = true;
}
};
runCommandAndVerifyOutput(commandHandler, "");
}
public void testClose() throws Exception {
CommandHandler commandHandler = new AbstractStubCommandHandler() {
public void handleCommand(Command command, Session session, InvocationRecord invocationRecord) {
session.close();
commandHandled = true;
}
};
runCommandAndVerifyOutput(commandHandler, "");
assertFalse("socket should not be closed", stubSocket.isClosed());
}
public void testClose_WithoutCommand() throws Exception {
PipedOutputStream pipedOutputStream = new PipedOutputStream();
PipedInputStream inputStream = new PipedInputStream(pipedOutputStream);
stubSocket = new StubSocket(DEFAULT_HOST, inputStream, outputStream);
session = new DefaultSession(stubSocket, commandHandlerMap);
initializeConnectCommandHandler();
Thread thread = new Thread(session);
thread.start();
Thread.sleep(1000L);
session.close();
thread.join();
}
public void testGetClientHost() throws Exception {
CommandHandler commandHandler = new AbstractStubCommandHandler() {
public void handleCommand(Command command, Session session, InvocationRecord invocationRecord) {
commandHandled = true;
}
};
runCommandAndVerifyOutput(commandHandler, "");
LOG.info("clientHost=" + session.getClientHost());
assertEquals("clientHost", DEFAULT_HOST, session.getClientHost());
}
public void testSendReply_NullReplyText() throws Exception {
CommandHandler commandHandler = new AbstractStubCommandHandler() {
public void handleCommand(Command command, Session session, InvocationRecord invocationRecord) {
session.sendReply(REPLY_CODE, null);
commandHandled = true;
}
};
runCommandAndVerifyOutput(commandHandler, Integer.toString(REPLY_CODE));
}
public void testSendReply_TrimReplyText() throws Exception {
CommandHandler commandHandler = new AbstractStubCommandHandler() {
public void handleCommand(Command command, Session session, InvocationRecord invocationRecord) {
session.sendReply(REPLY_CODE, " " + REPLY_TEXT + " ");
commandHandled = true;
}
};
runCommandAndVerifyOutput(commandHandler, REPLY_CODE + " " + REPLY_TEXT);
}
public void testSendReply_MultiLineText() throws Exception {
final String MULTILINE_REPLY_TEXT = "abc\ndef\nghi\njkl";
final String FORMATTED_MULTILINE_REPLY_TEXT = "123-abc\ndef\nghi\n123 jkl";
CommandHandler commandHandler = new AbstractStubCommandHandler() {
public void handleCommand(Command command, Session session, InvocationRecord invocationRecord) {
session.sendReply(123, MULTILINE_REPLY_TEXT);
commandHandled = true;
}
};
runCommandAndVerifyOutput(commandHandler, FORMATTED_MULTILINE_REPLY_TEXT);
}
public void testSendReply_ReplyText() throws Exception {
CommandHandler commandHandler = new AbstractStubCommandHandler() {
public void handleCommand(Command command, Session session, InvocationRecord invocationRecord) {
session.sendReply(REPLY_CODE, REPLY_TEXT);
commandHandled = true;
}
};
runCommandAndVerifyOutput(commandHandler, REPLY_CODE + " " + REPLY_TEXT);
}
public void testUnrecognizedCommand() throws Exception {
// Register a handler for unsupported commands
CommandHandler commandHandler = new AbstractStubCommandHandler() {
public void handleCommand(Command command, Session session, InvocationRecord invocationRecord) {
session.sendReply(502, "Unsupported");
commandHandled = true;
}
};
// Register the UNSUPPORTED command handler instead of the command that will be sent. So when we
// send the regular command, it will trigger the handling for unsupported/unrecognized commands.
commandToRegister = CommandNames.UNSUPPORTED;
runCommandAndVerifyOutput(commandHandler, "502 Unsupported");
}
// -------------------------------------------------------------------------
// Internal Helper Methods
// -------------------------------------------------------------------------
/**
* Create and return a DefaultSession and define the specified CommandHandler. Also, save the
* StubSocket being used in the stubSocket attribute.
*
* @param commandHandler - define this CommandHandler within the commandHandlerMap
* @return the DefaultSession
*/
private DefaultSession createDefaultSession(CommandHandler commandHandler) {
stubSocket = createTestSocket(COMMAND.getName());
commandHandlerMap.put(commandToRegister, commandHandler);
initializeConnectCommandHandler();
return new DefaultSession(stubSocket, commandHandlerMap);
}
private void initializeConnectCommandHandler() {
ConnectCommandHandler connectCommandHandler = new ConnectCommandHandler();
ResourceBundle replyTextBundle = new ListResourceBundle() {
protected Object[][] getContents() {
return new Object[][]{
{"220", "Reply for 220"},
};
}
};
connectCommandHandler.setReplyTextBundle(replyTextBundle);
commandHandlerMap.put(CommandNames.CONNECT, connectCommandHandler);
}
/**
* 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());
return new StubSocket(DEFAULT_HOST, inputStream, outputStream);
}
/**
* Run the command represented by the CommandHandler and verify that the session output from the
* control socket contains the expected output text.
*
* @param commandHandler - the CommandHandler to invoke
* @param expectedOutput - the text expected within the session output
* @throws InterruptedException - if the thread sleep is interrupted
*/
private void runCommandAndVerifyOutput(CommandHandler commandHandler, String expectedOutput)
throws InterruptedException {
session = createDefaultSession(commandHandler);
Thread thread = new Thread(session);
thread.start();
for (int i = 0; !commandHandled && i < 10; i++) {
Thread.sleep(50L);
}
session.close();
thread.join();
assertEquals("commandHandled", true, commandHandled);
String output = outputStream.toString();
LOG.info("output=[" + output.trim() + "]");
assertTrue("line ends with \\r\\n",
output.charAt(output.length() - 2) == '\r' && output.charAt(output.length() - 1) == '\n');
assertTrue("output: expected [" + expectedOutput + "]", output.indexOf(expectedOutput) != -1);
}
}