160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair/*
260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair * Copyright 2007 the original author or authors.
360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair *
460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair * Licensed under the Apache License, Version 2.0 (the "License");
560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair * you may not use this file except in compliance with the License.
660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair * You may obtain a copy of the License at
760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair *
860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair *      http://www.apache.org/licenses/LICENSE-2.0
960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair *
1060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair * Unless required by applicable law or agreed to in writing, software
1160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair * distributed under the License is distributed on an "AS IS" BASIS,
1260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair * See the License for the specific language governing permissions and
1460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair * limitations under the License.
1560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair */
1660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismairpackage org.mockftpserver.stub;
1760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
1860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismairimport org.apache.commons.net.ftp.FTP;
1960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismairimport org.apache.commons.net.ftp.FTPClient;
2060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismairimport org.apache.commons.net.ftp.FTPFile;
2160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismairimport org.apache.log4j.Logger;
2260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismairimport org.mockftpserver.core.command.CommandHandler;
2360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismairimport org.mockftpserver.core.command.CommandNames;
2460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismairimport org.mockftpserver.core.command.InvocationRecord;
2560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismairimport org.mockftpserver.core.command.SimpleCompositeCommandHandler;
2660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismairimport org.mockftpserver.core.command.StaticReplyCommandHandler;
2760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismairimport org.mockftpserver.stub.command.*;
2860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismairimport org.mockftpserver.test.AbstractTest;
2960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismairimport org.mockftpserver.test.IntegrationTest;
3060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismairimport org.mockftpserver.test.PortTestUtil;
3160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
3260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismairimport java.io.ByteArrayInputStream;
3360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismairimport java.io.ByteArrayOutputStream;
3460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismairimport java.io.IOException;
3560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
3660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair/**
3760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair * Tests for StubFtpServer using the Apache Jakarta Commons Net FTP client.
3860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair *
3960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair * @author Chris Mair
4060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair * @version $Revision$ - $Date$
4160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair */
4260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismairpublic final class StubFtpServerIntegrationTest extends AbstractTest implements IntegrationTest {
4360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
4460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    private static final Logger LOG = Logger.getLogger(StubFtpServerIntegrationTest.class);
4560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    private static final String SERVER = "localhost";
4660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    private static final String USERNAME = "user123";
4760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    private static final String PASSWORD = "password";
4860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    private static final String FILENAME = "abc.txt";
4960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    private static final String ASCII_CONTENTS = "abcdef\tghijklmnopqr";
5060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    private static final byte[] BINARY_CONTENTS = new byte[256];
5160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
5260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    private StubFtpServer stubFtpServer;
5360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    private FTPClient ftpClient;
5460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    private RetrCommandHandler retrCommandHandler;
5560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    private StorCommandHandler storCommandHandler;
5660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
5760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    //-------------------------------------------------------------------------
5860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    // Tests
5960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    //-------------------------------------------------------------------------
6060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
6160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    public void testLogin() throws Exception {
6260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // Connect
6360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        LOG.info("Conecting to " + SERVER);
6460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ftpClientConnect();
6560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        verifyReplyCode("connect", 220);
6660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
6760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // Login
6860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        String userAndPassword = USERNAME + "/" + PASSWORD;
6960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        LOG.info("Logging in as " + userAndPassword);
7060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        boolean success = ftpClient.login(USERNAME, PASSWORD);
7160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertTrue("Unable to login with " + userAndPassword, success);
7260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        verifyReplyCode("login with " + userAndPassword, 230);
7360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
7460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertTrue("isStarted", stubFtpServer.isStarted());
7560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertFalse("isShutdown", stubFtpServer.isShutdown());
7660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
7760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // Quit
7860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        LOG.info("Quit");
7960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ftpClient.quit();
8060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        verifyReplyCode("quit", 221);
8160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    }
8260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
8360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    public void testAcct() throws Exception {
8460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ftpClientConnect();
8560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
8660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // ACCT
8760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        int replyCode = ftpClient.acct("123456");
8860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertEquals("acct", 230, replyCode);
8960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    }
9060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
9160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    /**
9260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair     * Test the stop() method when no session has ever been started
9360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair     */
9460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    public void testStop_NoSessionEverStarted() throws Exception {
9560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        LOG.info("Testing a stop() when no session has ever been started");
9660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    }
9760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
9860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    public void testHelp() throws Exception {
9960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // Modify HELP CommandHandler to return a predefined help message
10060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        final String HELP = "help message";
10160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        HelpCommandHandler helpCommandHandler = (HelpCommandHandler) stubFtpServer.getCommandHandler(CommandNames.HELP);
10260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        helpCommandHandler.setHelpMessage(HELP);
10360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
10460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ftpClientConnect();
10560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
10660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // HELP
10760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        String help = ftpClient.listHelp();
10860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertTrue("Wrong response", help.indexOf(HELP) != -1);
10960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        verifyReplyCode("listHelp", 214);
11060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    }
11160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
11260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    /**
11360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair     * Test the LIST and SYST commands.
11460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair     */
11560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    public void testList() throws Exception {
11660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ftpClientConnect();
11760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
11860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // Set directory listing
11960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ListCommandHandler listCommandHandler = (ListCommandHandler) stubFtpServer.getCommandHandler(CommandNames.LIST);
12060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        listCommandHandler.setDirectoryListing("11-09-01 12:30PM  406348 File2350.log\n"
12160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair                + "11-01-01 1:30PM <DIR> 0 archive");
12260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
12360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // LIST
12460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        FTPFile[] files = ftpClient.listFiles();
12560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertEquals("number of files", 2, files.length);
12660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        verifyFTPFile(files[0], FTPFile.FILE_TYPE, "File2350.log", 406348L);
12760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        verifyFTPFile(files[1], FTPFile.DIRECTORY_TYPE, "archive", 0L);
12860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        verifyReplyCode("list", 226);
12960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    }
13060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
13160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    /**
13260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair     * Test the LIST, PASV and SYST commands, transferring a directory listing in passive mode
13360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair     */
13460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    public void testList_PassiveMode() throws Exception {
13560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ftpClientConnect();
13660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
13760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ftpClient.enterLocalPassiveMode();
13860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
13960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // Set directory listing
14060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ListCommandHandler listCommandHandler = (ListCommandHandler) stubFtpServer.getCommandHandler(CommandNames.LIST);
14160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        listCommandHandler.setDirectoryListing("11-09-01 12:30PM  406348 File2350.log");
14260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
14360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // LIST
14460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        FTPFile[] files = ftpClient.listFiles();
14560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertEquals("number of files", 1, files.length);
14660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        verifyReplyCode("list", 226);
14760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    }
14860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
14960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    public void testNlst() throws Exception {
15060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ftpClientConnect();
15160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
15260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // Set directory listing
15360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        NlstCommandHandler nlstCommandHandler = (NlstCommandHandler) stubFtpServer.getCommandHandler(CommandNames.NLST);
15460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        nlstCommandHandler.setDirectoryListing("File1.txt\nfile2.data");
15560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
15660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // NLST
15760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        String[] filenames = ftpClient.listNames();
15860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertEquals("number of files", 2, filenames.length);
15960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertEquals(filenames[0], "File1.txt");
16060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertEquals(filenames[1], "file2.data");
16160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        verifyReplyCode("listNames", 226);
16260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    }
16360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
16460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    /**
16560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair     * Test printing the current working directory (PWD)
16660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair     */
16760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    public void testPwd() throws Exception {
16860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // Modify PWD CommandHandler to return a predefined directory
16960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        final String DIR = "some/dir";
17060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        PwdCommandHandler pwdCommandHandler = (PwdCommandHandler) stubFtpServer.getCommandHandler(CommandNames.PWD);
17160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        pwdCommandHandler.setDirectory(DIR);
17260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
17360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ftpClientConnect();
17460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
17560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // PWD
17660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        String dir = ftpClient.printWorkingDirectory();
17760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertEquals("Unable to PWD", DIR, dir);
17860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        verifyReplyCode("printWorkingDirectory", 257);
17960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    }
18060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
18160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    public void testStat() throws Exception {
18260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // Modify Stat CommandHandler to return predefined text
18360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        final String STATUS = "some information 123";
18460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        StatCommandHandler statCommandHandler = (StatCommandHandler) stubFtpServer.getCommandHandler(CommandNames.STAT);
18560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        statCommandHandler.setStatus(STATUS);
18660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
18760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ftpClientConnect();
18860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
18960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // STAT
19060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        String status = ftpClient.getStatus();
19160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertEquals("STAT reply", "211 " + STATUS + ".", status.trim());
19260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        verifyReplyCode("getStatus", 211);
19360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    }
19460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
19560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    /**
19660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair     * Test getting the status (STAT), when the reply text contains multiple lines
19760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair     */
19860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    public void testStat_MultilineReplyText() throws Exception {
19960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // Modify Stat CommandHandler to return predefined text
20060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        final String STATUS = "System name: abc.def\nVersion 3.5.7\nNumber of failed logins: 2";
20160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        final String FORMATTED_REPLY_STATUS = "211-System name: abc.def\r\nVersion 3.5.7\r\n211 Number of failed logins: 2.";
20260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        StatCommandHandler statCommandHandler = (StatCommandHandler) stubFtpServer.getCommandHandler(CommandNames.STAT);
20360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        statCommandHandler.setStatus(STATUS);
20460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
20560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ftpClientConnect();
20660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
20760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // STAT
20860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        String status = ftpClient.getStatus();
20960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertEquals("STAT reply", FORMATTED_REPLY_STATUS, status.trim());
21060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        verifyReplyCode("getStatus", 211);
21160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    }
21260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
21360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    public void testSyst() throws Exception {
21460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ftpClientConnect();
21560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
21660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // SYST
21760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertEquals("getSystemName()", "\"WINDOWS\" system type.", ftpClient.getSystemName());
21860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        verifyReplyCode("syst", 215);
21960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    }
22060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
22160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    public void testCwd() throws Exception {
22260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // Connect
22360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        LOG.info("Conecting to " + SERVER);
22460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ftpClientConnect();
22560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        verifyReplyCode("connect", 220);
22660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
22760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // CWD
22860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        boolean success = ftpClient.changeWorkingDirectory("dir1/dir2");
22960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertTrue("Unable to CWD", success);
23060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        verifyReplyCode("changeWorkingDirectory", 250);
23160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    }
23260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
23360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    /**
23460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair     * Test changing the current working directory (CWD), when it causes a remote error
23560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair     */
23660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    public void testCwd_Error() throws Exception {
23760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // Override CWD CommandHandler to return error reply code
23860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        final int REPLY_CODE = 500;
23960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        StaticReplyCommandHandler cwdCommandHandler = new StaticReplyCommandHandler(REPLY_CODE);
24060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        stubFtpServer.setCommandHandler("CWD", cwdCommandHandler);
24160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
24260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ftpClientConnect();
24360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
24460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // CWD
24560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        boolean success = ftpClient.changeWorkingDirectory("dir1/dir2");
24660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertFalse("Expected failure", success);
24760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        verifyReplyCode("changeWorkingDirectory", REPLY_CODE);
24860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    }
24960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
25060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    public void testCdup() throws Exception {
25160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ftpClientConnect();
25260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
25360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // CDUP
25460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        boolean success = ftpClient.changeToParentDirectory();
25560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertTrue("Unable to CDUP", success);
25660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        verifyReplyCode("changeToParentDirectory", 200);
25760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    }
25860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
25960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    public void testDele() throws Exception {
26060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ftpClientConnect();
26160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
26260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // DELE
26360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        boolean success = ftpClient.deleteFile(FILENAME);
26460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertTrue("Unable to DELE", success);
26560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        verifyReplyCode("deleteFile", 250);
26660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    }
26760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
26860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    public void testFeat_UseStaticReplyCommandHandler() throws IOException {
26960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // The FEAT command is not supported out of the box
27060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        final String FEAT_TEXT = "Extensions supported:\n" +
27160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair                "MLST size*;create;modify*;perm;media-type\n" +
27260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair                "SIZE\n" +
27360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair                "COMPRESSION\n" +
27460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair                "END";
27560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        StaticReplyCommandHandler featCommandHandler = new StaticReplyCommandHandler(211, FEAT_TEXT);
27660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        stubFtpServer.setCommandHandler("FEAT", featCommandHandler);
27760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
27860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ftpClientConnect();
27960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertEquals(ftpClient.sendCommand("FEAT"), 211);
28060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        LOG.info(ftpClient.getReplyString());
28160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    }
28260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
28360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    public void testMkd() throws Exception {
28460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ftpClientConnect();
28560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
28660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // MKD
28760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        boolean success = ftpClient.makeDirectory("dir1/dir2");
28860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertTrue("Unable to CWD", success);
28960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        verifyReplyCode("makeDirectory", 257);
29060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    }
29160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
29260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    public void testNoop() throws Exception {
29360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ftpClientConnect();
29460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
29560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // NOOP
29660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        boolean success = ftpClient.sendNoOp();
29760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertTrue("Unable to NOOP", success);
29860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        verifyReplyCode("NOOP", 200);
29960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    }
30060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
30160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    public void testRest() throws Exception {
30260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ftpClientConnect();
30360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
30460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // REST
30560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        int replyCode = ftpClient.rest("marker");
30660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertEquals("Unable to REST", 350, replyCode);
30760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    }
30860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
30960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    public void testRmd() throws Exception {
31060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ftpClientConnect();
31160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
31260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // RMD
31360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        boolean success = ftpClient.removeDirectory("dir1/dir2");
31460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertTrue("Unable to RMD", success);
31560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        verifyReplyCode("removeDirectory", 250);
31660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    }
31760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
31860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    public void testRename() throws Exception {
31960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ftpClientConnect();
32060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
32160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // Rename (RNFR, RNTO)
32260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        boolean success = ftpClient.rename(FILENAME, "new_" + FILENAME);
32360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertTrue("Unable to RENAME", success);
32460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        verifyReplyCode("rename", 250);
32560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    }
32660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
32760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    public void testAllo() throws Exception {
32860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ftpClientConnect();
32960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
33060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // ALLO
33160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertTrue("ALLO", ftpClient.allocate(1024));
33260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertTrue("ALLO with recordSize", ftpClient.allocate(1024, 64));
33360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    }
33460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
33560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    /**
33660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair     * Test GET and PUT of ASCII files
33760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair     */
33860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    public void testTransferAsciiFile() throws Exception {
33960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        retrCommandHandler.setFileContents(ASCII_CONTENTS);
34060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
34160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ftpClientConnect();
34260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
34360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // Get File
34460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        LOG.info("Get File for remotePath [" + FILENAME + "]");
34560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
34660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertTrue(ftpClient.retrieveFile(FILENAME, outputStream));
34760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        LOG.info("File contents=[" + outputStream.toString());
34860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertEquals("File contents", ASCII_CONTENTS, outputStream.toString());
34960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
35060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // Put File
35160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        LOG.info("Put File for local path [" + FILENAME + "]");
35260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ByteArrayInputStream inputStream = new ByteArrayInputStream(ASCII_CONTENTS.getBytes());
35360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertTrue(ftpClient.storeFile(FILENAME, inputStream));
35460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        InvocationRecord invocationRecord = storCommandHandler.getInvocation(0);
35560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        byte[] contents = (byte[]) invocationRecord.getObject(StorCommandHandler.FILE_CONTENTS_KEY);
35660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        LOG.info("File contents=[" + contents + "]");
35760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertEquals("File contents", ASCII_CONTENTS.getBytes(), contents);
35860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    }
35960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
36060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    /**
36160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair     * Test GET and PUT of binary files
36260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair     */
36360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    public void testTransferBinaryFiles() throws Exception {
36460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        retrCommandHandler.setFileContents(BINARY_CONTENTS);
36560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
36660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ftpClientConnect();
36760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
36860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
36960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // Get File
37060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        LOG.info("Get File for remotePath [" + FILENAME + "]");
37160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
37260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertTrue("GET", ftpClient.retrieveFile(FILENAME, outputStream));
37360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        LOG.info("GET File length=" + outputStream.size());
37460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertEquals("File contents", BINARY_CONTENTS, outputStream.toByteArray());
37560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
37660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // Put File
37760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        LOG.info("Put File for local path [" + FILENAME + "]");
37860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ByteArrayInputStream inputStream = new ByteArrayInputStream(BINARY_CONTENTS);
37960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertTrue("PUT", ftpClient.storeFile(FILENAME, inputStream));
38060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        InvocationRecord invocationRecord = storCommandHandler.getInvocation(0);
38160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        byte[] contents = (byte[]) invocationRecord.getObject(StorCommandHandler.FILE_CONTENTS_KEY);
38260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        LOG.info("PUT File length=" + contents.length);
38360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertEquals("File contents", BINARY_CONTENTS, contents);
38460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    }
38560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
38660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    public void testStou() throws Exception {
38760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        StouCommandHandler stouCommandHandler = (StouCommandHandler) stubFtpServer.getCommandHandler(CommandNames.STOU);
38860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        stouCommandHandler.setFilename(FILENAME);
38960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
39060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ftpClientConnect();
39160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
39260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // Stor a File (STOU)
39360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ByteArrayInputStream inputStream = new ByteArrayInputStream(ASCII_CONTENTS.getBytes());
39460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertTrue(ftpClient.storeUniqueFile(FILENAME, inputStream));
39560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        InvocationRecord invocationRecord = stouCommandHandler.getInvocation(0);
39660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        byte[] contents = (byte[]) invocationRecord.getObject(StorCommandHandler.FILE_CONTENTS_KEY);
39760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        LOG.info("File contents=[" + contents + "]");
39860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertEquals("File contents", ASCII_CONTENTS.getBytes(), contents);
39960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    }
40060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
40160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    public void testAppe() throws Exception {
40260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        AppeCommandHandler appeCommandHandler = (AppeCommandHandler) stubFtpServer.getCommandHandler(CommandNames.APPE);
40360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
40460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ftpClientConnect();
40560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
40660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // Append a File (APPE)
40760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ByteArrayInputStream inputStream = new ByteArrayInputStream(ASCII_CONTENTS.getBytes());
40860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertTrue(ftpClient.appendFile(FILENAME, inputStream));
40960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        InvocationRecord invocationRecord = appeCommandHandler.getInvocation(0);
41060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        byte[] contents = (byte[]) invocationRecord.getObject(AppeCommandHandler.FILE_CONTENTS_KEY);
41160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        LOG.info("File contents=[" + contents + "]");
41260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertEquals("File contents", ASCII_CONTENTS.getBytes(), contents);
41360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    }
41460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
41560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    public void testAbor() throws Exception {
41660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ftpClientConnect();
41760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
41860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // ABOR
41960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertTrue("ABOR", ftpClient.abort());
42060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    }
42160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
42260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    public void testPasv() throws Exception {
42360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ftpClientConnect();
42460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
42560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // PASV
42660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ftpClient.enterLocalPassiveMode();
42760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // no reply code; the PASV command is sent only when the data connection is opened
42860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    }
42960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
43060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    public void testMode() throws Exception {
43160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ftpClientConnect();
43260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
43360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // MODE
43460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        boolean success = ftpClient.setFileTransferMode(FTP.STREAM_TRANSFER_MODE);
43560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertTrue("Unable to MODE", success);
43660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        verifyReplyCode("setFileTransferMode", 200);
43760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    }
43860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
43960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    public void testStru() throws Exception {
44060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ftpClientConnect();
44160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
44260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // STRU
44360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        boolean success = ftpClient.setFileStructure(FTP.FILE_STRUCTURE);
44460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertTrue("Unable to STRU", success);
44560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        verifyReplyCode("setFileStructure", 200);
44660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    }
44760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
44860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    public void testSimpleCompositeCommandHandler() throws Exception {
44960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // Replace CWD CommandHandler with a SimpleCompositeCommandHandler
45060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        CommandHandler commandHandler1 = new StaticReplyCommandHandler(500);
45160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        CommandHandler commandHandler2 = new CwdCommandHandler();
45260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        SimpleCompositeCommandHandler simpleCompositeCommandHandler = new SimpleCompositeCommandHandler();
45360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        simpleCompositeCommandHandler.addCommandHandler(commandHandler1);
45460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        simpleCompositeCommandHandler.addCommandHandler(commandHandler2);
45560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        stubFtpServer.setCommandHandler("CWD", simpleCompositeCommandHandler);
45660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
45760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // Connect
45860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ftpClientConnect();
45960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
46060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // CWD
46160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertFalse("first", ftpClient.changeWorkingDirectory("dir1/dir2"));
46260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertTrue("first", ftpClient.changeWorkingDirectory("dir1/dir2"));
46360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    }
46460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
46560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    public void testSite() throws Exception {
46660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ftpClientConnect();
46760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
46860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // SITE
46960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        int replyCode = ftpClient.site("parameters,1,2,3");
47060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertEquals("SITE", 200, replyCode);
47160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    }
47260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
47360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    public void testSmnt() throws Exception {
47460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ftpClientConnect();
47560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
47660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // SMNT
47760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertTrue("SMNT", ftpClient.structureMount("dir1/dir2"));
47860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        verifyReplyCode("structureMount", 250);
47960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    }
48060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
48160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    public void testRein() throws Exception {
48260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ftpClientConnect();
48360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
48460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        // REIN
48560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertEquals("REIN", 220, ftpClient.rein());
48660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    }
48760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
48860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    /**
48960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair     * Test that command names in lowercase or mixed upper/lower case are accepted
49060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair     */
49160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    public void testCommandNamesInLowerOrMixedCase() throws Exception {
49260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ftpClientConnect();
49360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
49460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertEquals("rein", 220, ftpClient.sendCommand("rein"));
49560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertEquals("rEIn", 220, ftpClient.sendCommand("rEIn"));
49660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertEquals("reiN", 220, ftpClient.sendCommand("reiN"));
49760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertEquals("Rein", 220, ftpClient.sendCommand("Rein"));
49860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    }
49960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
50060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    public void testUnrecognizedCommand() throws Exception {
50160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ftpClientConnect();
50260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
50360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertEquals("Unrecognized:XXXX", 502, ftpClient.sendCommand("XXXX"));
50460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    }
50560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
50660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    // -------------------------------------------------------------------------
50760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    // Test setup and tear-down
50860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    // -------------------------------------------------------------------------
50960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
51060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    /**
51160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair     * Perform initialization before each test
51260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair     *
51360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair     * @see org.mockftpserver.test.AbstractTest#setUp()
51460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair     */
51560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    protected void setUp() throws Exception {
51660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        super.setUp();
51760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
51860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        for (int i = 0; i < BINARY_CONTENTS.length; i++) {
51960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair            BINARY_CONTENTS[i] = (byte) i;
52060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        }
52160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
52260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        stubFtpServer = new StubFtpServer();
52360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        stubFtpServer.setServerControlPort(PortTestUtil.getFtpServerControlPort());
52460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        stubFtpServer.start();
52560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ftpClient = new FTPClient();
52660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        retrCommandHandler = (RetrCommandHandler) stubFtpServer.getCommandHandler(CommandNames.RETR);
52760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        storCommandHandler = (StorCommandHandler) stubFtpServer.getCommandHandler(CommandNames.STOR);
52860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    }
52960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
53060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    /**
53160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair     * Perform cleanup after each test
53260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair     *
53360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair     * @see org.mockftpserver.test.AbstractTest#tearDown()
53460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair     */
53560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    protected void tearDown() throws Exception {
53660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        super.tearDown();
53760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        stubFtpServer.stop();
53860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    }
53960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
54060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    // -------------------------------------------------------------------------
54160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    // Internal Helper Methods
54260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    // -------------------------------------------------------------------------
54360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
54460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    /**
54560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair     * Connect to the server from the FTPClient
54660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair     */
54760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    private void ftpClientConnect() throws IOException {
54860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        ftpClient.connect(SERVER, PortTestUtil.getFtpServerControlPort());
54960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    }
55060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
55160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    /**
55260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair     * Assert that the FtpClient reply code is equal to the expected value
55360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair     *
55460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair     * @param operation         - the description of the operation performed; used in the error message
55560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair     * @param expectedReplyCode - the expected FtpClient reply code
55660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair     */
55760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    private void verifyReplyCode(String operation, int expectedReplyCode) {
55860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        int replyCode = ftpClient.getReplyCode();
55960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        LOG.info("Reply: operation=\"" + operation + "\" replyCode=" + replyCode);
56060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertEquals("Unexpected replyCode for " + operation, expectedReplyCode, replyCode);
56160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    }
56260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
56360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    /**
56460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair     * Verify that the FTPFile has the specified properties
56560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair     *
56660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair     * @param ftpFile - the FTPFile to verify
56760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair     * @param type    - the expected file type
56860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair     * @param name    - the expected file name
56960b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair     * @param size    - the expected file size (will be zero for a directory)
57060b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair     */
57160b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    private void verifyFTPFile(FTPFile ftpFile, int type, String name, long size) {
57260b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        LOG.info(ftpFile);
57360b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertEquals("type: " + ftpFile, type, ftpFile.getType());
57460b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertEquals("name: " + ftpFile, name, ftpFile.getName());
57560b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair        assertEquals("size: " + ftpFile, size, ftpFile.getSize());
57660b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair    }
57760b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair
57860b81e2faf8511148f0d1e8f296e0b40ce9c7971chrismair}
579