153295844df24dff0a1f59e1104795e640b54c2efchrismair/*
253295844df24dff0a1f59e1104795e640b54c2efchrismair * Copyright 2007 the original author or authors.
353295844df24dff0a1f59e1104795e640b54c2efchrismair *
453295844df24dff0a1f59e1104795e640b54c2efchrismair * Licensed under the Apache License, Version 2.0 (the "License");
553295844df24dff0a1f59e1104795e640b54c2efchrismair * you may not use this file except in compliance with the License.
653295844df24dff0a1f59e1104795e640b54c2efchrismair * You may obtain a copy of the License at
753295844df24dff0a1f59e1104795e640b54c2efchrismair *
853295844df24dff0a1f59e1104795e640b54c2efchrismair *      http://www.apache.org/licenses/LICENSE-2.0
953295844df24dff0a1f59e1104795e640b54c2efchrismair *
1053295844df24dff0a1f59e1104795e640b54c2efchrismair * Unless required by applicable law or agreed to in writing, software
1153295844df24dff0a1f59e1104795e640b54c2efchrismair * distributed under the License is distributed on an "AS IS" BASIS,
1253295844df24dff0a1f59e1104795e640b54c2efchrismair * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1353295844df24dff0a1f59e1104795e640b54c2efchrismair * See the License for the specific language governing permissions and
1453295844df24dff0a1f59e1104795e640b54c2efchrismair * limitations under the License.
1553295844df24dff0a1f59e1104795e640b54c2efchrismair */
1653295844df24dff0a1f59e1104795e640b54c2efchrismairpackage org.mockftpserver.core.session;
1753295844df24dff0a1f59e1104795e640b54c2efchrismair
1853295844df24dff0a1f59e1104795e640b54c2efchrismairimport java.io.ByteArrayInputStream;
1953295844df24dff0a1f59e1104795e640b54c2efchrismairimport java.io.ByteArrayOutputStream;
2053295844df24dff0a1f59e1104795e640b54c2efchrismairimport java.io.IOException;
2153295844df24dff0a1f59e1104795e640b54c2efchrismairimport java.io.InputStream;
2253295844df24dff0a1f59e1104795e640b54c2efchrismairimport java.util.HashMap;
2353295844df24dff0a1f59e1104795e640b54c2efchrismairimport java.util.ListResourceBundle;
2453295844df24dff0a1f59e1104795e640b54c2efchrismairimport java.util.Map;
2553295844df24dff0a1f59e1104795e640b54c2efchrismairimport java.util.ResourceBundle;
2653295844df24dff0a1f59e1104795e640b54c2efchrismair
2753295844df24dff0a1f59e1104795e640b54c2efchrismair
2853295844df24dff0a1f59e1104795e640b54c2efchrismairimport org.apache.log4j.Logger;
2953295844df24dff0a1f59e1104795e640b54c2efchrismairimport org.mockftpserver.core.command.Command;
3053295844df24dff0a1f59e1104795e640b54c2efchrismairimport org.mockftpserver.core.command.CommandHandler;
3153295844df24dff0a1f59e1104795e640b54c2efchrismairimport org.mockftpserver.core.command.CommandNames;
3253295844df24dff0a1f59e1104795e640b54c2efchrismairimport org.mockftpserver.core.command.InvocationRecord;
3353295844df24dff0a1f59e1104795e640b54c2efchrismairimport org.mockftpserver.core.session.DefaultSession;
3453295844df24dff0a1f59e1104795e640b54c2efchrismairimport org.mockftpserver.core.session.Session;
3553295844df24dff0a1f59e1104795e640b54c2efchrismairimport org.mockftpserver.core.socket.StubSocket;
3653295844df24dff0a1f59e1104795e640b54c2efchrismairimport org.mockftpserver.stub.command.AbstractStubCommandHandler;
3753295844df24dff0a1f59e1104795e640b54c2efchrismairimport org.mockftpserver.stub.command.ConnectCommandHandler;
3853295844df24dff0a1f59e1104795e640b54c2efchrismairimport org.mockftpserver.test.AbstractTest;
3953295844df24dff0a1f59e1104795e640b54c2efchrismair
4053295844df24dff0a1f59e1104795e640b54c2efchrismair/**
4153295844df24dff0a1f59e1104795e640b54c2efchrismair * Tests for the DefaultSession class that require the session (thread) to be running/active.
4253295844df24dff0a1f59e1104795e640b54c2efchrismair *
4353295844df24dff0a1f59e1104795e640b54c2efchrismair * @version $Revision$ - $Date$
4453295844df24dff0a1f59e1104795e640b54c2efchrismair *
4553295844df24dff0a1f59e1104795e640b54c2efchrismair * @author Chris Mair
4653295844df24dff0a1f59e1104795e640b54c2efchrismair */
4753295844df24dff0a1f59e1104795e640b54c2efchrismairpublic final class DefaultSession_RunTest extends AbstractTest {
4853295844df24dff0a1f59e1104795e640b54c2efchrismair
4953295844df24dff0a1f59e1104795e640b54c2efchrismair    private static final Logger LOG = Logger.getLogger(DefaultSession_RunTest.class);
5053295844df24dff0a1f59e1104795e640b54c2efchrismair    private static final Command COMMAND = new Command("USER", EMPTY);
5153295844df24dff0a1f59e1104795e640b54c2efchrismair    private static final int REPLY_CODE = 100;
5253295844df24dff0a1f59e1104795e640b54c2efchrismair    private static final String REPLY_TEXT = "sample text description";
5353295844df24dff0a1f59e1104795e640b54c2efchrismair
5453295844df24dff0a1f59e1104795e640b54c2efchrismair    private DefaultSession session;
5553295844df24dff0a1f59e1104795e640b54c2efchrismair    private ByteArrayOutputStream outputStream;
5653295844df24dff0a1f59e1104795e640b54c2efchrismair    private Map commandHandlerMap;
5753295844df24dff0a1f59e1104795e640b54c2efchrismair    private StubSocket stubSocket;
5853295844df24dff0a1f59e1104795e640b54c2efchrismair    private boolean commandHandled = false;
5953295844df24dff0a1f59e1104795e640b54c2efchrismair
6053295844df24dff0a1f59e1104795e640b54c2efchrismair    /**
6153295844df24dff0a1f59e1104795e640b54c2efchrismair     * Perform initialization before each test
6253295844df24dff0a1f59e1104795e640b54c2efchrismair     *
6353295844df24dff0a1f59e1104795e640b54c2efchrismair     * @see org.mockftpserver.test.AbstractTest#setUp()
6453295844df24dff0a1f59e1104795e640b54c2efchrismair     */
6553295844df24dff0a1f59e1104795e640b54c2efchrismair    protected void setUp() throws Exception {
6653295844df24dff0a1f59e1104795e640b54c2efchrismair        super.setUp();
6753295844df24dff0a1f59e1104795e640b54c2efchrismair        commandHandlerMap = new HashMap();
6853295844df24dff0a1f59e1104795e640b54c2efchrismair        outputStream = new ByteArrayOutputStream();
6953295844df24dff0a1f59e1104795e640b54c2efchrismair    }
7053295844df24dff0a1f59e1104795e640b54c2efchrismair
7153295844df24dff0a1f59e1104795e640b54c2efchrismair    /**
7253295844df24dff0a1f59e1104795e640b54c2efchrismair     * Test that the CommandHandler is properly initialized and passed the expected parameters
7353295844df24dff0a1f59e1104795e640b54c2efchrismair     */
7453295844df24dff0a1f59e1104795e640b54c2efchrismair    public void testInvocationOfCommandHandler() throws Exception {
7553295844df24dff0a1f59e1104795e640b54c2efchrismair        AbstractStubCommandHandler commandHandler = new AbstractStubCommandHandler() {
7653295844df24dff0a1f59e1104795e640b54c2efchrismair            public void handleCommand(Command command, Session cmdSession, InvocationRecord invocationRecord) {
7753295844df24dff0a1f59e1104795e640b54c2efchrismair                assertEquals("command", COMMAND, command);
7853295844df24dff0a1f59e1104795e640b54c2efchrismair                assertSame("session", session, cmdSession);
7953295844df24dff0a1f59e1104795e640b54c2efchrismair                assertEquals("InvocationRecord: command", COMMAND, invocationRecord.getCommand());
8053295844df24dff0a1f59e1104795e640b54c2efchrismair                assertEquals("InvocationRecord: clientHost", DEFAULT_HOST, invocationRecord.getClientHost());
8153295844df24dff0a1f59e1104795e640b54c2efchrismair                commandHandled = true;
8253295844df24dff0a1f59e1104795e640b54c2efchrismair            }
8353295844df24dff0a1f59e1104795e640b54c2efchrismair        };
8453295844df24dff0a1f59e1104795e640b54c2efchrismair        runCommandAndVerifyOutput(commandHandler, "");
8553295844df24dff0a1f59e1104795e640b54c2efchrismair    }
8653295844df24dff0a1f59e1104795e640b54c2efchrismair
8753295844df24dff0a1f59e1104795e640b54c2efchrismair    /**
8853295844df24dff0a1f59e1104795e640b54c2efchrismair     * Test the close() method
8953295844df24dff0a1f59e1104795e640b54c2efchrismair     *
9053295844df24dff0a1f59e1104795e640b54c2efchrismair     * @throws IOException
9153295844df24dff0a1f59e1104795e640b54c2efchrismair     */
9253295844df24dff0a1f59e1104795e640b54c2efchrismair    public void testClose() throws Exception {
9353295844df24dff0a1f59e1104795e640b54c2efchrismair        CommandHandler commandHandler = new AbstractStubCommandHandler() {
9453295844df24dff0a1f59e1104795e640b54c2efchrismair            public void handleCommand(Command command, Session session, InvocationRecord invocationRecord) {
9553295844df24dff0a1f59e1104795e640b54c2efchrismair                session.close();
9653295844df24dff0a1f59e1104795e640b54c2efchrismair                commandHandled = true;
9753295844df24dff0a1f59e1104795e640b54c2efchrismair            }
9853295844df24dff0a1f59e1104795e640b54c2efchrismair        };
9953295844df24dff0a1f59e1104795e640b54c2efchrismair        runCommandAndVerifyOutput(commandHandler, "");
10053295844df24dff0a1f59e1104795e640b54c2efchrismair        assertFalse("socket should not be closed", stubSocket.isClosed());
10153295844df24dff0a1f59e1104795e640b54c2efchrismair    }
10253295844df24dff0a1f59e1104795e640b54c2efchrismair
10353295844df24dff0a1f59e1104795e640b54c2efchrismair    /**
10453295844df24dff0a1f59e1104795e640b54c2efchrismair     * Test the getClientHost() method
10553295844df24dff0a1f59e1104795e640b54c2efchrismair     *
10653295844df24dff0a1f59e1104795e640b54c2efchrismair     * @throws IOException
10753295844df24dff0a1f59e1104795e640b54c2efchrismair     */
10853295844df24dff0a1f59e1104795e640b54c2efchrismair    public void testGetClientHost() throws Exception {
10953295844df24dff0a1f59e1104795e640b54c2efchrismair        CommandHandler commandHandler = new AbstractStubCommandHandler() {
11053295844df24dff0a1f59e1104795e640b54c2efchrismair            public void handleCommand(Command command, Session session, InvocationRecord invocationRecord) {
11153295844df24dff0a1f59e1104795e640b54c2efchrismair                commandHandled = true;
11253295844df24dff0a1f59e1104795e640b54c2efchrismair            }
11353295844df24dff0a1f59e1104795e640b54c2efchrismair        };
11453295844df24dff0a1f59e1104795e640b54c2efchrismair        runCommandAndVerifyOutput(commandHandler, "");
11553295844df24dff0a1f59e1104795e640b54c2efchrismair        LOG.info("clientHost=" + session.getClientHost());
11653295844df24dff0a1f59e1104795e640b54c2efchrismair        assertEquals("clientHost", DEFAULT_HOST, session.getClientHost());
11753295844df24dff0a1f59e1104795e640b54c2efchrismair    }
11853295844df24dff0a1f59e1104795e640b54c2efchrismair
11953295844df24dff0a1f59e1104795e640b54c2efchrismair    /**
12053295844df24dff0a1f59e1104795e640b54c2efchrismair     * Test the sendReply() method, when the specified reply text is null
12153295844df24dff0a1f59e1104795e640b54c2efchrismair     */
12253295844df24dff0a1f59e1104795e640b54c2efchrismair    public void testSendReply_NullReplyText() throws Exception {
12353295844df24dff0a1f59e1104795e640b54c2efchrismair        CommandHandler commandHandler = new AbstractStubCommandHandler() {
12453295844df24dff0a1f59e1104795e640b54c2efchrismair            public void handleCommand(Command command, Session session, InvocationRecord invocationRecord) {
12553295844df24dff0a1f59e1104795e640b54c2efchrismair                session.sendReply(REPLY_CODE, null);
12653295844df24dff0a1f59e1104795e640b54c2efchrismair                commandHandled = true;
12753295844df24dff0a1f59e1104795e640b54c2efchrismair            }
12853295844df24dff0a1f59e1104795e640b54c2efchrismair        };
12953295844df24dff0a1f59e1104795e640b54c2efchrismair        runCommandAndVerifyOutput(commandHandler, Integer.toString(REPLY_CODE));
13053295844df24dff0a1f59e1104795e640b54c2efchrismair    }
13153295844df24dff0a1f59e1104795e640b54c2efchrismair
13253295844df24dff0a1f59e1104795e640b54c2efchrismair    /**
13353295844df24dff0a1f59e1104795e640b54c2efchrismair     * Test the sendReply() method, verifying that extra extra whitespace is trimmed from the reply text
13453295844df24dff0a1f59e1104795e640b54c2efchrismair     */
13553295844df24dff0a1f59e1104795e640b54c2efchrismair    public void testSendReply_TrimReplyText() throws Exception {
13653295844df24dff0a1f59e1104795e640b54c2efchrismair        CommandHandler commandHandler = new AbstractStubCommandHandler() {
13753295844df24dff0a1f59e1104795e640b54c2efchrismair            public void handleCommand(Command command, Session session, InvocationRecord invocationRecord) {
13853295844df24dff0a1f59e1104795e640b54c2efchrismair                session.sendReply(REPLY_CODE, " " + REPLY_TEXT + " ");
13953295844df24dff0a1f59e1104795e640b54c2efchrismair                commandHandled = true;
14053295844df24dff0a1f59e1104795e640b54c2efchrismair            }
14153295844df24dff0a1f59e1104795e640b54c2efchrismair        };
14253295844df24dff0a1f59e1104795e640b54c2efchrismair        runCommandAndVerifyOutput(commandHandler, REPLY_CODE + " " + REPLY_TEXT);
14353295844df24dff0a1f59e1104795e640b54c2efchrismair    }
14453295844df24dff0a1f59e1104795e640b54c2efchrismair
14553295844df24dff0a1f59e1104795e640b54c2efchrismair    /**
14653295844df24dff0a1f59e1104795e640b54c2efchrismair     * Test the sendReply() method, when the text contains multiple lines
14753295844df24dff0a1f59e1104795e640b54c2efchrismair     */
14853295844df24dff0a1f59e1104795e640b54c2efchrismair    public void testSendReply_MultiLineText() throws Exception {
14953295844df24dff0a1f59e1104795e640b54c2efchrismair        final String MULTILINE_REPLY_TEXT = "abc\ndef\nghi\njkl";
15053295844df24dff0a1f59e1104795e640b54c2efchrismair        final String FORMATTED_MULTILINE_REPLY_TEXT = "123-abc\ndef\nghi\n123 jkl";
15153295844df24dff0a1f59e1104795e640b54c2efchrismair
15253295844df24dff0a1f59e1104795e640b54c2efchrismair        CommandHandler commandHandler = new AbstractStubCommandHandler() {
15353295844df24dff0a1f59e1104795e640b54c2efchrismair            public void handleCommand(Command command, Session session, InvocationRecord invocationRecord) {
15453295844df24dff0a1f59e1104795e640b54c2efchrismair                session.sendReply(123, MULTILINE_REPLY_TEXT);
15553295844df24dff0a1f59e1104795e640b54c2efchrismair                commandHandled = true;
15653295844df24dff0a1f59e1104795e640b54c2efchrismair            }
15753295844df24dff0a1f59e1104795e640b54c2efchrismair        };
15853295844df24dff0a1f59e1104795e640b54c2efchrismair        runCommandAndVerifyOutput(commandHandler, FORMATTED_MULTILINE_REPLY_TEXT);
15953295844df24dff0a1f59e1104795e640b54c2efchrismair    }
16053295844df24dff0a1f59e1104795e640b54c2efchrismair
16153295844df24dff0a1f59e1104795e640b54c2efchrismair    /**
16253295844df24dff0a1f59e1104795e640b54c2efchrismair     * Test the sendReply() method when the reply code has associated reply text
16353295844df24dff0a1f59e1104795e640b54c2efchrismair     */
16453295844df24dff0a1f59e1104795e640b54c2efchrismair    public void testSendReply_ReplyText() throws Exception {
16553295844df24dff0a1f59e1104795e640b54c2efchrismair        CommandHandler commandHandler = new AbstractStubCommandHandler() {
16653295844df24dff0a1f59e1104795e640b54c2efchrismair            public void handleCommand(Command command, Session session, InvocationRecord invocationRecord) {
16753295844df24dff0a1f59e1104795e640b54c2efchrismair                session.sendReply(REPLY_CODE, REPLY_TEXT);
16853295844df24dff0a1f59e1104795e640b54c2efchrismair                commandHandled = true;
16953295844df24dff0a1f59e1104795e640b54c2efchrismair            }
17053295844df24dff0a1f59e1104795e640b54c2efchrismair        };
17153295844df24dff0a1f59e1104795e640b54c2efchrismair        runCommandAndVerifyOutput(commandHandler, REPLY_CODE + " " + REPLY_TEXT);
17253295844df24dff0a1f59e1104795e640b54c2efchrismair    }
17353295844df24dff0a1f59e1104795e640b54c2efchrismair
17453295844df24dff0a1f59e1104795e640b54c2efchrismair    // -------------------------------------------------------------------------
17553295844df24dff0a1f59e1104795e640b54c2efchrismair    // Internal Helper Methods
17653295844df24dff0a1f59e1104795e640b54c2efchrismair    // -------------------------------------------------------------------------
17753295844df24dff0a1f59e1104795e640b54c2efchrismair
17853295844df24dff0a1f59e1104795e640b54c2efchrismair    /**
17953295844df24dff0a1f59e1104795e640b54c2efchrismair     * Create and return a DefaultSession object that reads from an InputStream with the specified
18053295844df24dff0a1f59e1104795e640b54c2efchrismair     * contents and writes to the predefined outputStrean ByteArrayOutputStream. Also, save the
18153295844df24dff0a1f59e1104795e640b54c2efchrismair     * StubSocket being used in the stubSocket attribute.
18253295844df24dff0a1f59e1104795e640b54c2efchrismair     *
18353295844df24dff0a1f59e1104795e640b54c2efchrismair     * @param inputStreamContents - the contents of the input stream
18453295844df24dff0a1f59e1104795e640b54c2efchrismair     * @return the DefaultSession
18553295844df24dff0a1f59e1104795e640b54c2efchrismair     */
18653295844df24dff0a1f59e1104795e640b54c2efchrismair    private DefaultSession createDefaultSession(CommandHandler commandHandler) {
18753295844df24dff0a1f59e1104795e640b54c2efchrismair        stubSocket = createTestSocket(COMMAND.getName());
18853295844df24dff0a1f59e1104795e640b54c2efchrismair        commandHandlerMap.put(COMMAND.getName(), commandHandler);
18953295844df24dff0a1f59e1104795e640b54c2efchrismair
19053295844df24dff0a1f59e1104795e640b54c2efchrismair        ConnectCommandHandler connectCommandHandler = new ConnectCommandHandler();
19153295844df24dff0a1f59e1104795e640b54c2efchrismair
19253295844df24dff0a1f59e1104795e640b54c2efchrismair        ResourceBundle replyTextBundle = new ListResourceBundle() {
19353295844df24dff0a1f59e1104795e640b54c2efchrismair            protected Object[][] getContents() {
19453295844df24dff0a1f59e1104795e640b54c2efchrismair                return new Object[][] {
19553295844df24dff0a1f59e1104795e640b54c2efchrismair                        { "220", "Reply for 220" },
19653295844df24dff0a1f59e1104795e640b54c2efchrismair                };
19753295844df24dff0a1f59e1104795e640b54c2efchrismair            }
19853295844df24dff0a1f59e1104795e640b54c2efchrismair        };
19953295844df24dff0a1f59e1104795e640b54c2efchrismair        connectCommandHandler.setReplyTextBundle(replyTextBundle);
20053295844df24dff0a1f59e1104795e640b54c2efchrismair        commandHandlerMap.put(CommandNames.CONNECT, connectCommandHandler);
20153295844df24dff0a1f59e1104795e640b54c2efchrismair
20253295844df24dff0a1f59e1104795e640b54c2efchrismair        return new DefaultSession(stubSocket, commandHandlerMap);
20353295844df24dff0a1f59e1104795e640b54c2efchrismair    }
20453295844df24dff0a1f59e1104795e640b54c2efchrismair
20553295844df24dff0a1f59e1104795e640b54c2efchrismair    /**
20653295844df24dff0a1f59e1104795e640b54c2efchrismair     * Create and return a StubSocket that reads from an InputStream with the specified contents and
20753295844df24dff0a1f59e1104795e640b54c2efchrismair     * writes to the predefined outputStrean ByteArrayOutputStream.
20853295844df24dff0a1f59e1104795e640b54c2efchrismair     *
20953295844df24dff0a1f59e1104795e640b54c2efchrismair     * @param inputStreamContents - the contents of the input stream
21053295844df24dff0a1f59e1104795e640b54c2efchrismair     * @return the StubSocket
21153295844df24dff0a1f59e1104795e640b54c2efchrismair     */
21253295844df24dff0a1f59e1104795e640b54c2efchrismair    private StubSocket createTestSocket(String inputStreamContents) {
21353295844df24dff0a1f59e1104795e640b54c2efchrismair        InputStream inputStream = new ByteArrayInputStream(inputStreamContents.getBytes());
21453295844df24dff0a1f59e1104795e640b54c2efchrismair        return new StubSocket(DEFAULT_HOST, inputStream, outputStream);
21553295844df24dff0a1f59e1104795e640b54c2efchrismair    }
21653295844df24dff0a1f59e1104795e640b54c2efchrismair
21753295844df24dff0a1f59e1104795e640b54c2efchrismair    /**
21853295844df24dff0a1f59e1104795e640b54c2efchrismair     * Run the command represented by the CommandHandler and verify that the session output from the
21953295844df24dff0a1f59e1104795e640b54c2efchrismair     * control socket contains the expected output text.
22053295844df24dff0a1f59e1104795e640b54c2efchrismair     *
22153295844df24dff0a1f59e1104795e640b54c2efchrismair     * @param commandHandler - the CommandHandler to invoke
22253295844df24dff0a1f59e1104795e640b54c2efchrismair     * @param expectedOutput - the text expected within the session output
22353295844df24dff0a1f59e1104795e640b54c2efchrismair     * @throws InterruptedException
22453295844df24dff0a1f59e1104795e640b54c2efchrismair     */
22553295844df24dff0a1f59e1104795e640b54c2efchrismair    private void runCommandAndVerifyOutput(CommandHandler commandHandler, String expectedOutput)
22653295844df24dff0a1f59e1104795e640b54c2efchrismair            throws InterruptedException {
22753295844df24dff0a1f59e1104795e640b54c2efchrismair        session = createDefaultSession(commandHandler);
22853295844df24dff0a1f59e1104795e640b54c2efchrismair
22953295844df24dff0a1f59e1104795e640b54c2efchrismair        Thread thread = new Thread(session);
23053295844df24dff0a1f59e1104795e640b54c2efchrismair        thread.start();
23153295844df24dff0a1f59e1104795e640b54c2efchrismair
23253295844df24dff0a1f59e1104795e640b54c2efchrismair        for (int i = 0; !commandHandled && i < 10; i++) {
23353295844df24dff0a1f59e1104795e640b54c2efchrismair            Thread.sleep(50L);
23453295844df24dff0a1f59e1104795e640b54c2efchrismair        }
23553295844df24dff0a1f59e1104795e640b54c2efchrismair
23653295844df24dff0a1f59e1104795e640b54c2efchrismair        session.close();
23753295844df24dff0a1f59e1104795e640b54c2efchrismair        thread.join();
23853295844df24dff0a1f59e1104795e640b54c2efchrismair
23953295844df24dff0a1f59e1104795e640b54c2efchrismair        assertEquals("commandHandled", true, commandHandled);
24053295844df24dff0a1f59e1104795e640b54c2efchrismair
24153295844df24dff0a1f59e1104795e640b54c2efchrismair        String output = outputStream.toString();
24253295844df24dff0a1f59e1104795e640b54c2efchrismair        LOG.info("output=[" + output.trim() + "]");
24353295844df24dff0a1f59e1104795e640b54c2efchrismair        assertTrue("line ends with \\r\\n",
24453295844df24dff0a1f59e1104795e640b54c2efchrismair                output.charAt(output.length()-2) == '\r' && output.charAt(output.length()-1) == '\n');
24553295844df24dff0a1f59e1104795e640b54c2efchrismair        assertTrue("output: expected [" + expectedOutput + "]", output.indexOf(expectedOutput) != -1);
24653295844df24dff0a1f59e1104795e640b54c2efchrismair    }
24753295844df24dff0a1f59e1104795e640b54c2efchrismair
24853295844df24dff0a1f59e1104795e640b54c2efchrismair}
249