1bda3441225e0607b5ced8b538123fd7c7a417910chrismair/* 2bda3441225e0607b5ced8b538123fd7c7a417910chrismair * Copyright 2007 the original author or authors. 3bda3441225e0607b5ced8b538123fd7c7a417910chrismair * 4bda3441225e0607b5ced8b538123fd7c7a417910chrismair * Licensed under the Apache License, Version 2.0 (the "License"); 5bda3441225e0607b5ced8b538123fd7c7a417910chrismair * you may not use this file except in compliance with the License. 6bda3441225e0607b5ced8b538123fd7c7a417910chrismair * You may obtain a copy of the License at 7bda3441225e0607b5ced8b538123fd7c7a417910chrismair * 8bda3441225e0607b5ced8b538123fd7c7a417910chrismair * http://www.apache.org/licenses/LICENSE-2.0 9bda3441225e0607b5ced8b538123fd7c7a417910chrismair * 10bda3441225e0607b5ced8b538123fd7c7a417910chrismair * Unless required by applicable law or agreed to in writing, software 11bda3441225e0607b5ced8b538123fd7c7a417910chrismair * distributed under the License is distributed on an "AS IS" BASIS, 12bda3441225e0607b5ced8b538123fd7c7a417910chrismair * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bda3441225e0607b5ced8b538123fd7c7a417910chrismair * See the License for the specific language governing permissions and 14bda3441225e0607b5ced8b538123fd7c7a417910chrismair * limitations under the License. 15bda3441225e0607b5ced8b538123fd7c7a417910chrismair */ 16bda3441225e0607b5ced8b538123fd7c7a417910chrismairpackage org.mockftpserver.core.session; 17bda3441225e0607b5ced8b538123fd7c7a417910chrismair 18bda3441225e0607b5ced8b538123fd7c7a417910chrismairimport org.apache.log4j.Logger; 19bda3441225e0607b5ced8b538123fd7c7a417910chrismairimport org.mockftpserver.core.command.Command; 20bda3441225e0607b5ced8b538123fd7c7a417910chrismairimport org.mockftpserver.core.command.CommandHandler; 21bda3441225e0607b5ced8b538123fd7c7a417910chrismairimport org.mockftpserver.core.command.CommandNames; 22bda3441225e0607b5ced8b538123fd7c7a417910chrismairimport org.mockftpserver.core.command.ConnectCommandHandler; 23bda3441225e0607b5ced8b538123fd7c7a417910chrismairimport org.mockftpserver.core.command.InvocationRecord; 24bda3441225e0607b5ced8b538123fd7c7a417910chrismairimport org.mockftpserver.core.socket.StubSocket; 25bda3441225e0607b5ced8b538123fd7c7a417910chrismairimport org.mockftpserver.stub.command.AbstractStubCommandHandler; 26bda3441225e0607b5ced8b538123fd7c7a417910chrismairimport org.mockftpserver.test.AbstractTestCase; 27bda3441225e0607b5ced8b538123fd7c7a417910chrismair 28bda3441225e0607b5ced8b538123fd7c7a417910chrismairimport java.io.*; 29bda3441225e0607b5ced8b538123fd7c7a417910chrismairimport java.util.HashMap; 30bda3441225e0607b5ced8b538123fd7c7a417910chrismairimport java.util.ListResourceBundle; 31bda3441225e0607b5ced8b538123fd7c7a417910chrismairimport java.util.Map; 32bda3441225e0607b5ced8b538123fd7c7a417910chrismairimport java.util.ResourceBundle; 33bda3441225e0607b5ced8b538123fd7c7a417910chrismair 34bda3441225e0607b5ced8b538123fd7c7a417910chrismair/** 35bda3441225e0607b5ced8b538123fd7c7a417910chrismair * Tests for the DefaultSession class that require the session (thread) to be running/active. 36bda3441225e0607b5ced8b538123fd7c7a417910chrismair * 37bda3441225e0607b5ced8b538123fd7c7a417910chrismair * @author Chris Mair 38bda3441225e0607b5ced8b538123fd7c7a417910chrismair * @version $Revision$ - $Date$ 39bda3441225e0607b5ced8b538123fd7c7a417910chrismair */ 40bda3441225e0607b5ced8b538123fd7c7a417910chrismairpublic final class DefaultSession_RunTest extends AbstractTestCase { 41bda3441225e0607b5ced8b538123fd7c7a417910chrismair 42bda3441225e0607b5ced8b538123fd7c7a417910chrismair private static final Logger LOG = Logger.getLogger(DefaultSession_RunTest.class); 43bda3441225e0607b5ced8b538123fd7c7a417910chrismair private static final Command COMMAND = new Command("USER", EMPTY); 44bda3441225e0607b5ced8b538123fd7c7a417910chrismair private static final int REPLY_CODE = 100; 45bda3441225e0607b5ced8b538123fd7c7a417910chrismair private static final String REPLY_TEXT = "sample text description"; 46bda3441225e0607b5ced8b538123fd7c7a417910chrismair 47bda3441225e0607b5ced8b538123fd7c7a417910chrismair private DefaultSession session; 48bda3441225e0607b5ced8b538123fd7c7a417910chrismair private ByteArrayOutputStream outputStream; 49bda3441225e0607b5ced8b538123fd7c7a417910chrismair private Map commandHandlerMap; 50bda3441225e0607b5ced8b538123fd7c7a417910chrismair private StubSocket stubSocket; 51bda3441225e0607b5ced8b538123fd7c7a417910chrismair private boolean commandHandled = false; 52bda3441225e0607b5ced8b538123fd7c7a417910chrismair private String commandToRegister = COMMAND.getName(); 53bda3441225e0607b5ced8b538123fd7c7a417910chrismair 54bda3441225e0607b5ced8b538123fd7c7a417910chrismair protected void setUp() throws Exception { 55bda3441225e0607b5ced8b538123fd7c7a417910chrismair super.setUp(); 56bda3441225e0607b5ced8b538123fd7c7a417910chrismair commandHandlerMap = new HashMap(); 57bda3441225e0607b5ced8b538123fd7c7a417910chrismair outputStream = new ByteArrayOutputStream(); 58bda3441225e0607b5ced8b538123fd7c7a417910chrismair } 59bda3441225e0607b5ced8b538123fd7c7a417910chrismair 60bda3441225e0607b5ced8b538123fd7c7a417910chrismair public void testInvocationOfCommandHandler() throws Exception { 61bda3441225e0607b5ced8b538123fd7c7a417910chrismair AbstractStubCommandHandler commandHandler = new AbstractStubCommandHandler() { 62bda3441225e0607b5ced8b538123fd7c7a417910chrismair public void handleCommand(Command command, Session cmdSession, InvocationRecord invocationRecord) { 63bda3441225e0607b5ced8b538123fd7c7a417910chrismair assertEquals("command", COMMAND, command); 64bda3441225e0607b5ced8b538123fd7c7a417910chrismair assertSame("session", session, cmdSession); 65bda3441225e0607b5ced8b538123fd7c7a417910chrismair assertEquals("InvocationRecord: command", COMMAND, invocationRecord.getCommand()); 66bda3441225e0607b5ced8b538123fd7c7a417910chrismair assertEquals("InvocationRecord: clientHost", DEFAULT_HOST, invocationRecord.getClientHost()); 67bda3441225e0607b5ced8b538123fd7c7a417910chrismair commandHandled = true; 68bda3441225e0607b5ced8b538123fd7c7a417910chrismair } 69bda3441225e0607b5ced8b538123fd7c7a417910chrismair }; 70bda3441225e0607b5ced8b538123fd7c7a417910chrismair runCommandAndVerifyOutput(commandHandler, ""); 71bda3441225e0607b5ced8b538123fd7c7a417910chrismair } 72bda3441225e0607b5ced8b538123fd7c7a417910chrismair 73bda3441225e0607b5ced8b538123fd7c7a417910chrismair public void testClose() throws Exception { 74bda3441225e0607b5ced8b538123fd7c7a417910chrismair CommandHandler commandHandler = new AbstractStubCommandHandler() { 75bda3441225e0607b5ced8b538123fd7c7a417910chrismair public void handleCommand(Command command, Session session, InvocationRecord invocationRecord) { 76bda3441225e0607b5ced8b538123fd7c7a417910chrismair session.close(); 77bda3441225e0607b5ced8b538123fd7c7a417910chrismair commandHandled = true; 78bda3441225e0607b5ced8b538123fd7c7a417910chrismair } 79bda3441225e0607b5ced8b538123fd7c7a417910chrismair }; 80bda3441225e0607b5ced8b538123fd7c7a417910chrismair runCommandAndVerifyOutput(commandHandler, ""); 81bda3441225e0607b5ced8b538123fd7c7a417910chrismair assertFalse("socket should not be closed", stubSocket.isClosed()); 82bda3441225e0607b5ced8b538123fd7c7a417910chrismair } 83bda3441225e0607b5ced8b538123fd7c7a417910chrismair 84bda3441225e0607b5ced8b538123fd7c7a417910chrismair public void testClose_WithoutCommand() throws Exception { 85bda3441225e0607b5ced8b538123fd7c7a417910chrismair PipedOutputStream pipedOutputStream = new PipedOutputStream(); 86bda3441225e0607b5ced8b538123fd7c7a417910chrismair PipedInputStream inputStream = new PipedInputStream(pipedOutputStream); 87bda3441225e0607b5ced8b538123fd7c7a417910chrismair stubSocket = new StubSocket(DEFAULT_HOST, inputStream, outputStream); 88bda3441225e0607b5ced8b538123fd7c7a417910chrismair session = new DefaultSession(stubSocket, commandHandlerMap); 89bda3441225e0607b5ced8b538123fd7c7a417910chrismair 90bda3441225e0607b5ced8b538123fd7c7a417910chrismair initializeConnectCommandHandler(); 91bda3441225e0607b5ced8b538123fd7c7a417910chrismair 92bda3441225e0607b5ced8b538123fd7c7a417910chrismair Thread thread = new Thread(session); 93bda3441225e0607b5ced8b538123fd7c7a417910chrismair thread.start(); 94bda3441225e0607b5ced8b538123fd7c7a417910chrismair Thread.sleep(1000L); 95bda3441225e0607b5ced8b538123fd7c7a417910chrismair 96bda3441225e0607b5ced8b538123fd7c7a417910chrismair session.close(); 97bda3441225e0607b5ced8b538123fd7c7a417910chrismair thread.join(); 98bda3441225e0607b5ced8b538123fd7c7a417910chrismair } 99bda3441225e0607b5ced8b538123fd7c7a417910chrismair 100bda3441225e0607b5ced8b538123fd7c7a417910chrismair public void testGetClientHost() throws Exception { 101bda3441225e0607b5ced8b538123fd7c7a417910chrismair CommandHandler commandHandler = new AbstractStubCommandHandler() { 102bda3441225e0607b5ced8b538123fd7c7a417910chrismair public void handleCommand(Command command, Session session, InvocationRecord invocationRecord) { 103bda3441225e0607b5ced8b538123fd7c7a417910chrismair commandHandled = true; 104bda3441225e0607b5ced8b538123fd7c7a417910chrismair } 105bda3441225e0607b5ced8b538123fd7c7a417910chrismair }; 106bda3441225e0607b5ced8b538123fd7c7a417910chrismair runCommandAndVerifyOutput(commandHandler, ""); 107bda3441225e0607b5ced8b538123fd7c7a417910chrismair LOG.info("clientHost=" + session.getClientHost()); 108bda3441225e0607b5ced8b538123fd7c7a417910chrismair assertEquals("clientHost", DEFAULT_HOST, session.getClientHost()); 109bda3441225e0607b5ced8b538123fd7c7a417910chrismair } 110bda3441225e0607b5ced8b538123fd7c7a417910chrismair 111bda3441225e0607b5ced8b538123fd7c7a417910chrismair public void testSendReply_NullReplyText() throws Exception { 112bda3441225e0607b5ced8b538123fd7c7a417910chrismair CommandHandler commandHandler = new AbstractStubCommandHandler() { 113bda3441225e0607b5ced8b538123fd7c7a417910chrismair public void handleCommand(Command command, Session session, InvocationRecord invocationRecord) { 114bda3441225e0607b5ced8b538123fd7c7a417910chrismair session.sendReply(REPLY_CODE, null); 115bda3441225e0607b5ced8b538123fd7c7a417910chrismair commandHandled = true; 116bda3441225e0607b5ced8b538123fd7c7a417910chrismair } 117bda3441225e0607b5ced8b538123fd7c7a417910chrismair }; 118bda3441225e0607b5ced8b538123fd7c7a417910chrismair runCommandAndVerifyOutput(commandHandler, Integer.toString(REPLY_CODE)); 119bda3441225e0607b5ced8b538123fd7c7a417910chrismair } 120bda3441225e0607b5ced8b538123fd7c7a417910chrismair 121bda3441225e0607b5ced8b538123fd7c7a417910chrismair public void testSendReply_TrimReplyText() throws Exception { 122bda3441225e0607b5ced8b538123fd7c7a417910chrismair CommandHandler commandHandler = new AbstractStubCommandHandler() { 123bda3441225e0607b5ced8b538123fd7c7a417910chrismair public void handleCommand(Command command, Session session, InvocationRecord invocationRecord) { 124bda3441225e0607b5ced8b538123fd7c7a417910chrismair session.sendReply(REPLY_CODE, " " + REPLY_TEXT + " "); 125bda3441225e0607b5ced8b538123fd7c7a417910chrismair commandHandled = true; 126bda3441225e0607b5ced8b538123fd7c7a417910chrismair } 127bda3441225e0607b5ced8b538123fd7c7a417910chrismair }; 128bda3441225e0607b5ced8b538123fd7c7a417910chrismair runCommandAndVerifyOutput(commandHandler, REPLY_CODE + " " + REPLY_TEXT); 129bda3441225e0607b5ced8b538123fd7c7a417910chrismair } 130bda3441225e0607b5ced8b538123fd7c7a417910chrismair 131bda3441225e0607b5ced8b538123fd7c7a417910chrismair public void testSendReply_MultiLineText() throws Exception { 132bda3441225e0607b5ced8b538123fd7c7a417910chrismair final String MULTILINE_REPLY_TEXT = "abc\ndef\nghi\njkl"; 133bda3441225e0607b5ced8b538123fd7c7a417910chrismair final String FORMATTED_MULTILINE_REPLY_TEXT = "123-abc\ndef\nghi\n123 jkl"; 134bda3441225e0607b5ced8b538123fd7c7a417910chrismair 135bda3441225e0607b5ced8b538123fd7c7a417910chrismair CommandHandler commandHandler = new AbstractStubCommandHandler() { 136bda3441225e0607b5ced8b538123fd7c7a417910chrismair public void handleCommand(Command command, Session session, InvocationRecord invocationRecord) { 137bda3441225e0607b5ced8b538123fd7c7a417910chrismair session.sendReply(123, MULTILINE_REPLY_TEXT); 138bda3441225e0607b5ced8b538123fd7c7a417910chrismair commandHandled = true; 139bda3441225e0607b5ced8b538123fd7c7a417910chrismair } 140bda3441225e0607b5ced8b538123fd7c7a417910chrismair }; 141bda3441225e0607b5ced8b538123fd7c7a417910chrismair runCommandAndVerifyOutput(commandHandler, FORMATTED_MULTILINE_REPLY_TEXT); 142bda3441225e0607b5ced8b538123fd7c7a417910chrismair } 143bda3441225e0607b5ced8b538123fd7c7a417910chrismair 144bda3441225e0607b5ced8b538123fd7c7a417910chrismair public void testSendReply_ReplyText() throws Exception { 145bda3441225e0607b5ced8b538123fd7c7a417910chrismair CommandHandler commandHandler = new AbstractStubCommandHandler() { 146bda3441225e0607b5ced8b538123fd7c7a417910chrismair public void handleCommand(Command command, Session session, InvocationRecord invocationRecord) { 147bda3441225e0607b5ced8b538123fd7c7a417910chrismair session.sendReply(REPLY_CODE, REPLY_TEXT); 148bda3441225e0607b5ced8b538123fd7c7a417910chrismair commandHandled = true; 149bda3441225e0607b5ced8b538123fd7c7a417910chrismair } 150bda3441225e0607b5ced8b538123fd7c7a417910chrismair }; 151bda3441225e0607b5ced8b538123fd7c7a417910chrismair runCommandAndVerifyOutput(commandHandler, REPLY_CODE + " " + REPLY_TEXT); 152bda3441225e0607b5ced8b538123fd7c7a417910chrismair } 153bda3441225e0607b5ced8b538123fd7c7a417910chrismair 154bda3441225e0607b5ced8b538123fd7c7a417910chrismair public void testUnrecognizedCommand() throws Exception { 155bda3441225e0607b5ced8b538123fd7c7a417910chrismair // Register a handler for unsupported commands 156bda3441225e0607b5ced8b538123fd7c7a417910chrismair CommandHandler commandHandler = new AbstractStubCommandHandler() { 157bda3441225e0607b5ced8b538123fd7c7a417910chrismair public void handleCommand(Command command, Session session, InvocationRecord invocationRecord) { 158bda3441225e0607b5ced8b538123fd7c7a417910chrismair session.sendReply(502, "Unsupported"); 159bda3441225e0607b5ced8b538123fd7c7a417910chrismair commandHandled = true; 160bda3441225e0607b5ced8b538123fd7c7a417910chrismair } 161bda3441225e0607b5ced8b538123fd7c7a417910chrismair }; 162bda3441225e0607b5ced8b538123fd7c7a417910chrismair // Register the UNSUPPORTED command handler instead of the command that will be sent. So when we 163bda3441225e0607b5ced8b538123fd7c7a417910chrismair // send the regular command, it will trigger the handling for unsupported/unrecognized commands. 164bda3441225e0607b5ced8b538123fd7c7a417910chrismair commandToRegister = CommandNames.UNSUPPORTED; 165bda3441225e0607b5ced8b538123fd7c7a417910chrismair runCommandAndVerifyOutput(commandHandler, "502 Unsupported"); 166bda3441225e0607b5ced8b538123fd7c7a417910chrismair } 167bda3441225e0607b5ced8b538123fd7c7a417910chrismair 168bda3441225e0607b5ced8b538123fd7c7a417910chrismair // ------------------------------------------------------------------------- 169bda3441225e0607b5ced8b538123fd7c7a417910chrismair // Internal Helper Methods 170bda3441225e0607b5ced8b538123fd7c7a417910chrismair // ------------------------------------------------------------------------- 171bda3441225e0607b5ced8b538123fd7c7a417910chrismair 172bda3441225e0607b5ced8b538123fd7c7a417910chrismair /** 173bda3441225e0607b5ced8b538123fd7c7a417910chrismair * Create and return a DefaultSession and define the specified CommandHandler. Also, save the 174bda3441225e0607b5ced8b538123fd7c7a417910chrismair * StubSocket being used in the stubSocket attribute. 175bda3441225e0607b5ced8b538123fd7c7a417910chrismair * 176bda3441225e0607b5ced8b538123fd7c7a417910chrismair * @param commandHandler - define this CommandHandler within the commandHandlerMap 177bda3441225e0607b5ced8b538123fd7c7a417910chrismair * @return the DefaultSession 178bda3441225e0607b5ced8b538123fd7c7a417910chrismair */ 179bda3441225e0607b5ced8b538123fd7c7a417910chrismair private DefaultSession createDefaultSession(CommandHandler commandHandler) { 180bda3441225e0607b5ced8b538123fd7c7a417910chrismair stubSocket = createTestSocket(COMMAND.getName()); 181bda3441225e0607b5ced8b538123fd7c7a417910chrismair commandHandlerMap.put(commandToRegister, commandHandler); 182bda3441225e0607b5ced8b538123fd7c7a417910chrismair initializeConnectCommandHandler(); 183bda3441225e0607b5ced8b538123fd7c7a417910chrismair return new DefaultSession(stubSocket, commandHandlerMap); 184bda3441225e0607b5ced8b538123fd7c7a417910chrismair } 185bda3441225e0607b5ced8b538123fd7c7a417910chrismair 186bda3441225e0607b5ced8b538123fd7c7a417910chrismair private void initializeConnectCommandHandler() { 187bda3441225e0607b5ced8b538123fd7c7a417910chrismair ConnectCommandHandler connectCommandHandler = new ConnectCommandHandler(); 188bda3441225e0607b5ced8b538123fd7c7a417910chrismair 189bda3441225e0607b5ced8b538123fd7c7a417910chrismair ResourceBundle replyTextBundle = new ListResourceBundle() { 190bda3441225e0607b5ced8b538123fd7c7a417910chrismair protected Object[][] getContents() { 191bda3441225e0607b5ced8b538123fd7c7a417910chrismair return new Object[][]{ 192bda3441225e0607b5ced8b538123fd7c7a417910chrismair {"220", "Reply for 220"}, 193bda3441225e0607b5ced8b538123fd7c7a417910chrismair }; 194bda3441225e0607b5ced8b538123fd7c7a417910chrismair } 195bda3441225e0607b5ced8b538123fd7c7a417910chrismair }; 196bda3441225e0607b5ced8b538123fd7c7a417910chrismair connectCommandHandler.setReplyTextBundle(replyTextBundle); 197bda3441225e0607b5ced8b538123fd7c7a417910chrismair commandHandlerMap.put(CommandNames.CONNECT, connectCommandHandler); 198bda3441225e0607b5ced8b538123fd7c7a417910chrismair } 199bda3441225e0607b5ced8b538123fd7c7a417910chrismair 200bda3441225e0607b5ced8b538123fd7c7a417910chrismair /** 201bda3441225e0607b5ced8b538123fd7c7a417910chrismair * Create and return a StubSocket that reads from an InputStream with the specified contents and 202bda3441225e0607b5ced8b538123fd7c7a417910chrismair * writes to the predefined outputStrean ByteArrayOutputStream. 203bda3441225e0607b5ced8b538123fd7c7a417910chrismair * 204bda3441225e0607b5ced8b538123fd7c7a417910chrismair * @param inputStreamContents - the contents of the input stream 205bda3441225e0607b5ced8b538123fd7c7a417910chrismair * @return the StubSocket 206bda3441225e0607b5ced8b538123fd7c7a417910chrismair */ 207bda3441225e0607b5ced8b538123fd7c7a417910chrismair private StubSocket createTestSocket(String inputStreamContents) { 208bda3441225e0607b5ced8b538123fd7c7a417910chrismair InputStream inputStream = new ByteArrayInputStream(inputStreamContents.getBytes()); 209bda3441225e0607b5ced8b538123fd7c7a417910chrismair return new StubSocket(DEFAULT_HOST, inputStream, outputStream); 210bda3441225e0607b5ced8b538123fd7c7a417910chrismair } 211bda3441225e0607b5ced8b538123fd7c7a417910chrismair 212bda3441225e0607b5ced8b538123fd7c7a417910chrismair /** 213bda3441225e0607b5ced8b538123fd7c7a417910chrismair * Run the command represented by the CommandHandler and verify that the session output from the 214bda3441225e0607b5ced8b538123fd7c7a417910chrismair * control socket contains the expected output text. 215bda3441225e0607b5ced8b538123fd7c7a417910chrismair * 216bda3441225e0607b5ced8b538123fd7c7a417910chrismair * @param commandHandler - the CommandHandler to invoke 217bda3441225e0607b5ced8b538123fd7c7a417910chrismair * @param expectedOutput - the text expected within the session output 218bda3441225e0607b5ced8b538123fd7c7a417910chrismair * @throws InterruptedException - if the thread sleep is interrupted 219bda3441225e0607b5ced8b538123fd7c7a417910chrismair */ 220bda3441225e0607b5ced8b538123fd7c7a417910chrismair private void runCommandAndVerifyOutput(CommandHandler commandHandler, String expectedOutput) 221bda3441225e0607b5ced8b538123fd7c7a417910chrismair throws InterruptedException { 222bda3441225e0607b5ced8b538123fd7c7a417910chrismair session = createDefaultSession(commandHandler); 223bda3441225e0607b5ced8b538123fd7c7a417910chrismair 224bda3441225e0607b5ced8b538123fd7c7a417910chrismair Thread thread = new Thread(session); 225bda3441225e0607b5ced8b538123fd7c7a417910chrismair thread.start(); 226bda3441225e0607b5ced8b538123fd7c7a417910chrismair 227bda3441225e0607b5ced8b538123fd7c7a417910chrismair for (int i = 0; !commandHandled && i < 10; i++) { 228bda3441225e0607b5ced8b538123fd7c7a417910chrismair Thread.sleep(50L); 229bda3441225e0607b5ced8b538123fd7c7a417910chrismair } 230bda3441225e0607b5ced8b538123fd7c7a417910chrismair 231bda3441225e0607b5ced8b538123fd7c7a417910chrismair session.close(); 232bda3441225e0607b5ced8b538123fd7c7a417910chrismair thread.join(); 233bda3441225e0607b5ced8b538123fd7c7a417910chrismair 234bda3441225e0607b5ced8b538123fd7c7a417910chrismair assertEquals("commandHandled", true, commandHandled); 235bda3441225e0607b5ced8b538123fd7c7a417910chrismair 236bda3441225e0607b5ced8b538123fd7c7a417910chrismair String output = outputStream.toString(); 237bda3441225e0607b5ced8b538123fd7c7a417910chrismair LOG.info("output=[" + output.trim() + "]"); 238bda3441225e0607b5ced8b538123fd7c7a417910chrismair assertTrue("line ends with \\r\\n", 239bda3441225e0607b5ced8b538123fd7c7a417910chrismair output.charAt(output.length() - 2) == '\r' && output.charAt(output.length() - 1) == '\n'); 240bda3441225e0607b5ced8b538123fd7c7a417910chrismair assertTrue("output: expected [" + expectedOutput + "]", output.indexOf(expectedOutput) != -1); 241bda3441225e0607b5ced8b538123fd7c7a417910chrismair } 242bda3441225e0607b5ced8b538123fd7c7a417910chrismair 243bda3441225e0607b5ced8b538123fd7c7a417910chrismair} 244