1ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair/*
2ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Copyright 2007 the original author or authors.
3ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair *
4ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Licensed under the Apache License, Version 2.0 (the "License");
5ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * you may not use this file except in compliance with the License.
6ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * You may obtain a copy of the License at
7ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair *
8ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair *      http://www.apache.org/licenses/LICENSE-2.0
9ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair *
10ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Unless required by applicable law or agreed to in writing, software
11ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * distributed under the License is distributed on an "AS IS" BASIS,
12ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * See the License for the specific language governing permissions and
14ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * limitations under the License.
15ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair */
16ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairpackage org.mockftpserver.stub;
17ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
18ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport org.apache.commons.net.ftp.FTP;
19ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport org.apache.commons.net.ftp.FTPClient;
20ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport org.apache.commons.net.ftp.FTPFile;
21ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport org.apache.log4j.Logger;
22ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport org.mockftpserver.core.command.CommandHandler;
23ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport org.mockftpserver.core.command.CommandNames;
24ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport org.mockftpserver.core.command.InvocationRecord;
25ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport org.mockftpserver.core.command.SimpleCompositeCommandHandler;
26ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport org.mockftpserver.core.command.StaticReplyCommandHandler;
27ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport org.mockftpserver.stub.command.*;
28ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport org.mockftpserver.test.AbstractTest;
29ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport org.mockftpserver.test.IntegrationTest;
30ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport org.mockftpserver.test.PortTestUtil;
31ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
32ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport java.io.ByteArrayInputStream;
33ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport java.io.ByteArrayOutputStream;
34ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport java.io.IOException;
35ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
36ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair/**
37ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Tests for StubFtpServer using the Apache Jakarta Commons Net FTP client.
38ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair *
39ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @author Chris Mair
40ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @version $Revision$ - $Date$
41ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair */
42ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairpublic final class StubFtpServerIntegrationTest extends AbstractTest implements IntegrationTest {
43ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
44ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    private static final Logger LOG = Logger.getLogger(StubFtpServerIntegrationTest.class);
45ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    private static final String SERVER = "localhost";
46ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    private static final String USERNAME = "user123";
47ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    private static final String PASSWORD = "password";
48ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    private static final String FILENAME = "abc.txt";
49ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    private static final String ASCII_CONTENTS = "abcdef\tghijklmnopqr";
50ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    private static final byte[] BINARY_CONTENTS = new byte[256];
51ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
52ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    private StubFtpServer stubFtpServer;
53ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    private FTPClient ftpClient;
54ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    private RetrCommandHandler retrCommandHandler;
55ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    private StorCommandHandler storCommandHandler;
56ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
57ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    //-------------------------------------------------------------------------
58ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    // Tests
59ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    //-------------------------------------------------------------------------
60ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
61ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    /**
62ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * Test connecting and logging in
63ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     */
64ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    public void testLogin() throws Exception {
65ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // Connect
66ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        LOG.info("Conecting to " + SERVER);
67ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ftpClientConnect();
68ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        verifyReplyCode("connect", 220);
69ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
70ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // Login
71ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        String userAndPassword = USERNAME + "/" + PASSWORD;
72ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        LOG.info("Logging in as " + userAndPassword);
73ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        boolean success = ftpClient.login(USERNAME, PASSWORD);
74ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertTrue("Unable to login with " + userAndPassword, success);
75ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        verifyReplyCode("login with " + userAndPassword, 230);
76ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
77ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // Quit
78ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        LOG.info("Quit");
79ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ftpClient.quit();
80ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        verifyReplyCode("quit", 221);
81ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    }
82ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
83ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    /**
84ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * Test the ACCT command
85ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     */
86ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    public void testAcct() throws Exception {
87ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ftpClientConnect();
88ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
89ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // ACCT
90ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        int replyCode = ftpClient.acct("123456");
91ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertEquals("acct", 230, replyCode);
92ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    }
93ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
94ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    /**
95ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * Test the stop() method when no session has ever been started
96ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     */
97ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    public void testStop_NoSessionEverStarted() throws Exception {
98ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        LOG.info("Testing a stop() when no session has ever been started");
99ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    }
100ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
101ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    /**
102ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * Test help (HELP)
103ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     */
104ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    public void testHelp() throws Exception {
105ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // Modify HELP CommandHandler to return a predefined help message
106ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        final String HELP = "help message";
107ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        HelpCommandHandler helpCommandHandler = (HelpCommandHandler) stubFtpServer.getCommandHandler(CommandNames.HELP);
108ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        helpCommandHandler.setHelpMessage(HELP);
109ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
110ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ftpClientConnect();
111ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
112ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // HELP
113ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        String help = ftpClient.listHelp();
114ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertTrue("Wrong response", help.indexOf(HELP) != -1);
115ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        verifyReplyCode("listHelp", 214);
116ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    }
117ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
118ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    /**
119ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * Test the LIST and SYST commands.
120ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     */
121ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    public void testList() throws Exception {
122ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ftpClientConnect();
123ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
124ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // Set directory listing
125ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ListCommandHandler listCommandHandler = (ListCommandHandler) stubFtpServer.getCommandHandler(CommandNames.LIST);
126ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        listCommandHandler.setDirectoryListing("11-09-01 12:30PM  406348 File2350.log\n"
127ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair                + "11-01-01 1:30PM <DIR> 0 archive");
128ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
129ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // LIST
130ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        FTPFile[] files = ftpClient.listFiles();
131ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertEquals("number of files", 2, files.length);
132ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        verifyFTPFile(files[0], FTPFile.FILE_TYPE, "File2350.log", 406348L);
133ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        verifyFTPFile(files[1], FTPFile.DIRECTORY_TYPE, "archive", 0L);
134ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        verifyReplyCode("list", 226);
135ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    }
136ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
137ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    /**
138ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * Test the LIST, PASV and SYST commands, transferring a directory listing in passive mode
139ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     */
140ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    public void testList_PassiveMode() throws Exception {
141ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ftpClientConnect();
142ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
143ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ftpClient.enterLocalPassiveMode();
144ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
145ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // Set directory listing
146ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ListCommandHandler listCommandHandler = (ListCommandHandler) stubFtpServer.getCommandHandler(CommandNames.LIST);
147ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        listCommandHandler.setDirectoryListing("11-09-01 12:30PM  406348 File2350.log");
148ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
149ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // LIST
150ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        FTPFile[] files = ftpClient.listFiles();
151ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertEquals("number of files", 1, files.length);
152ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        verifyReplyCode("list", 226);
153ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    }
154ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
155ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    /**
156ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * Test the NLST command.
157ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     */
158ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    public void testNlst() throws Exception {
159ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ftpClientConnect();
160ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
161ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // Set directory listing
162ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        NlstCommandHandler nlstCommandHandler = (NlstCommandHandler) stubFtpServer.getCommandHandler(CommandNames.NLST);
163ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        nlstCommandHandler.setDirectoryListing("File1.txt\nfile2.data");
164ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
165ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // NLST
166ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        String[] filenames = ftpClient.listNames();
167ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertEquals("number of files", 2, filenames.length);
168ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertEquals(filenames[0], "File1.txt");
169ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertEquals(filenames[1], "file2.data");
170ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        verifyReplyCode("listNames", 226);
171ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    }
172ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
173ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    /**
174ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * Test printing the current working directory (PWD)
175ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     */
176ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    public void testPwd() throws Exception {
177ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // Modify PWD CommandHandler to return a predefined directory
178ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        final String DIR = "some/dir";
179ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        PwdCommandHandler pwdCommandHandler = (PwdCommandHandler) stubFtpServer.getCommandHandler(CommandNames.PWD);
180ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        pwdCommandHandler.setDirectory(DIR);
181ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
182ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ftpClientConnect();
183ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
184ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // PWD
185ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        String dir = ftpClient.printWorkingDirectory();
186ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertEquals("Unable to PWD", DIR, dir);
187ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        verifyReplyCode("printWorkingDirectory", 257);
188ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    }
189ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
190ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    /**
191ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * Test getting the status (STAT)
192ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     */
193ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    public void testStat() throws Exception {
194ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // Modify Stat CommandHandler to return predefined text
195ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        final String STATUS = "some information 123";
196ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        StatCommandHandler statCommandHandler = (StatCommandHandler) stubFtpServer.getCommandHandler(CommandNames.STAT);
197ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        statCommandHandler.setStatus(STATUS);
198ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
199ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ftpClientConnect();
200ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
201ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // STAT
202ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        String status = ftpClient.getStatus();
203ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertEquals("STAT reply", "211 " + STATUS + ".", status.trim());
204ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        verifyReplyCode("getStatus", 211);
205ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    }
206ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
207ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    /**
208ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * Test getting the status (STAT), when the reply text contains multiple lines
209ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     */
210ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    public void testStat_MultilineReplyText() throws Exception {
211ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // Modify Stat CommandHandler to return predefined text
212ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        final String STATUS = "System name: abc.def\nVersion 3.5.7\nNumber of failed logins: 2";
213ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        final String FORMATTED_REPLY_STATUS = "211-System name: abc.def\r\nVersion 3.5.7\r\n211 Number of failed logins: 2.";
214ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        StatCommandHandler statCommandHandler = (StatCommandHandler) stubFtpServer.getCommandHandler(CommandNames.STAT);
215ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        statCommandHandler.setStatus(STATUS);
216ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
217ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ftpClientConnect();
218ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
219ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // STAT
220ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        String status = ftpClient.getStatus();
221ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertEquals("STAT reply", FORMATTED_REPLY_STATUS, status.trim());
222ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        verifyReplyCode("getStatus", 211);
223ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    }
224ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
225ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    /**
226ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * Test the System (SYST) command
227ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     */
228ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    public void testSyst() throws Exception {
229ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ftpClientConnect();
230ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
231ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // SYST
232ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertEquals("getSystemName()", "\"WINDOWS\" system type.", ftpClient.getSystemName());
233ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        verifyReplyCode("syst", 215);
234ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    }
235ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
236ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    /**
237ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * Test changing the current working directory (CWD)
238ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     */
239ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    public void testCwd() throws Exception {
240ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // Connect
241ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        LOG.info("Conecting to " + SERVER);
242ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ftpClientConnect();
243ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        verifyReplyCode("connect", 220);
244ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
245ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // CWD
246ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        boolean success = ftpClient.changeWorkingDirectory("dir1/dir2");
247ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertTrue("Unable to CWD", success);
248ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        verifyReplyCode("changeWorkingDirectory", 250);
249ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    }
250ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
251ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    /**
252ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * Test changing the current working directory (CWD), when it causes a remote error
253ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     */
254ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    public void testCwd_Error() throws Exception {
255ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // Override CWD CommandHandler to return error reply code
256ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        final int REPLY_CODE = 500;
257ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        StaticReplyCommandHandler cwdCommandHandler = new StaticReplyCommandHandler(REPLY_CODE);
258ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        stubFtpServer.setCommandHandler("CWD", cwdCommandHandler);
259ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
260ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ftpClientConnect();
261ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
262ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // CWD
263ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        boolean success = ftpClient.changeWorkingDirectory("dir1/dir2");
264ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertFalse("Expected failure", success);
265ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        verifyReplyCode("changeWorkingDirectory", REPLY_CODE);
266ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    }
267ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
268ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    /**
269ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * Test changing to the parent directory (CDUP)
270ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     */
271ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    public void testCdup() throws Exception {
272ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ftpClientConnect();
273ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
274ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // CDUP
275ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        boolean success = ftpClient.changeToParentDirectory();
276ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertTrue("Unable to CDUP", success);
277ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        verifyReplyCode("changeToParentDirectory", 200);
278ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    }
279ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
280ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    /**
281ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * Test delete (DELE)
282ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     */
283ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    public void testDele() throws Exception {
284ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ftpClientConnect();
285ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
286ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // DELE
287ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        boolean success = ftpClient.deleteFile(FILENAME);
288ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertTrue("Unable to DELE", success);
289ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        verifyReplyCode("deleteFile", 250);
290ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    }
291ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
292ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    /**
293ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * Test make directory (MKD)
294ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     */
295ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    public void testMkd() throws Exception {
296ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ftpClientConnect();
297ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
298ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // MKD
299ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        boolean success = ftpClient.makeDirectory("dir1/dir2");
300ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertTrue("Unable to CWD", success);
301ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        verifyReplyCode("makeDirectory", 257);
302ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    }
303ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
304ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    /**
305ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * Test NOOP
306ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     */
307ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    public void testNoop() throws Exception {
308ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ftpClientConnect();
309ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
310ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // NOOP
311ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        boolean success = ftpClient.sendNoOp();
312ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertTrue("Unable to NOOP", success);
313ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        verifyReplyCode("NOOP", 200);
314ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    }
315ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
316ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    /**
317ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * Test restart (REST)
318ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     */
319ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    public void testRest() throws Exception {
320ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ftpClientConnect();
321ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
322ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // REST
323ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        int replyCode = ftpClient.rest("marker");
324ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertEquals("Unable to REST", 350, replyCode);
325ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    }
326ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
327ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    /**
328ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * Test changing the current working directory (RMD)
329ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     */
330ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    public void testRmd() throws Exception {
331ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ftpClientConnect();
332ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
333ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // RMD
334ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        boolean success = ftpClient.removeDirectory("dir1/dir2");
335ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertTrue("Unable to RMD", success);
336ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        verifyReplyCode("removeDirectory", 250);
337ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    }
338ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
339ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    /**
340ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * Test rename (RNFR/RNTO)
341ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     */
342ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    public void testRename() throws Exception {
343ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ftpClientConnect();
344ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
345ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // Rename (RNFR, RNTO)
346ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        boolean success = ftpClient.rename(FILENAME, "new_" + FILENAME);
347ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertTrue("Unable to RENAME", success);
348ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        verifyReplyCode("rename", 250);
349ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    }
350ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
351ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    /**
352ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * Test the ALLO command
353ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     */
354ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    public void testAllo() throws Exception {
355ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ftpClientConnect();
356ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
357ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // ALLO
358ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertTrue("ALLO", ftpClient.allocate(1024));
359ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertTrue("ALLO with recordSize", ftpClient.allocate(1024, 64));
360ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    }
361ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
362ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    /**
363ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * Test GET and PUT of ASCII files
364ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     */
365ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    public void testTransferAsciiFile() throws Exception {
366ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        retrCommandHandler.setFileContents(ASCII_CONTENTS);
367ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
368ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ftpClientConnect();
369ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
370ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // Get File
371ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        LOG.info("Get File for remotePath [" + FILENAME + "]");
372ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
373ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertTrue(ftpClient.retrieveFile(FILENAME, outputStream));
374ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        LOG.info("File contents=[" + outputStream.toString());
375ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertEquals("File contents", ASCII_CONTENTS, outputStream.toString());
376ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
377ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // Put File
378ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        LOG.info("Put File for local path [" + FILENAME + "]");
379ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ByteArrayInputStream inputStream = new ByteArrayInputStream(ASCII_CONTENTS.getBytes());
380ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertTrue(ftpClient.storeFile(FILENAME, inputStream));
381ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        InvocationRecord invocationRecord = storCommandHandler.getInvocation(0);
382ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        byte[] contents = (byte[]) invocationRecord.getObject(StorCommandHandler.FILE_CONTENTS_KEY);
383ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        LOG.info("File contents=[" + contents + "]");
384ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertEquals("File contents", ASCII_CONTENTS.getBytes(), contents);
385ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    }
386ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
387ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    /**
388ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * Test GET and PUT of binary files
389ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     */
390ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    public void testTransferBinaryFiles() throws Exception {
391ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        retrCommandHandler.setFileContents(BINARY_CONTENTS);
392ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
393ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ftpClientConnect();
394ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
395ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
396ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // Get File
397ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        LOG.info("Get File for remotePath [" + FILENAME + "]");
398ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
399ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertTrue("GET", ftpClient.retrieveFile(FILENAME, outputStream));
400ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        LOG.info("GET File length=" + outputStream.size());
401ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertEquals("File contents", BINARY_CONTENTS, outputStream.toByteArray());
402ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
403ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // Put File
404ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        LOG.info("Put File for local path [" + FILENAME + "]");
405ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ByteArrayInputStream inputStream = new ByteArrayInputStream(BINARY_CONTENTS);
406ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertTrue("PUT", ftpClient.storeFile(FILENAME, inputStream));
407ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        InvocationRecord invocationRecord = storCommandHandler.getInvocation(0);
408ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        byte[] contents = (byte[]) invocationRecord.getObject(StorCommandHandler.FILE_CONTENTS_KEY);
409ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        LOG.info("PUT File length=" + contents.length);
410ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertEquals("File contents", BINARY_CONTENTS, contents);
411ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    }
412ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
413ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    /**
414ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * Test the STOU command
415ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     */
416ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    public void testStou() throws Exception {
417ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        StouCommandHandler stouCommandHandler = (StouCommandHandler) stubFtpServer.getCommandHandler(CommandNames.STOU);
418ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        stouCommandHandler.setFilename(FILENAME);
419ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
420ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ftpClientConnect();
421ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
422ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // Stor a File (STOU)
423ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ByteArrayInputStream inputStream = new ByteArrayInputStream(ASCII_CONTENTS.getBytes());
424ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertTrue(ftpClient.storeUniqueFile(FILENAME, inputStream));
425ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        InvocationRecord invocationRecord = stouCommandHandler.getInvocation(0);
426ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        byte[] contents = (byte[]) invocationRecord.getObject(StorCommandHandler.FILE_CONTENTS_KEY);
427ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        LOG.info("File contents=[" + contents + "]");
428ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertEquals("File contents", ASCII_CONTENTS.getBytes(), contents);
429ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    }
430ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
431ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    /**
432ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * Test the APPE command
433ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     */
434ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    public void testAppe() throws Exception {
435ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        AppeCommandHandler appeCommandHandler = (AppeCommandHandler) stubFtpServer.getCommandHandler(CommandNames.APPE);
436ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
437ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ftpClientConnect();
438ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
439ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // Append a File (APPE)
440ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ByteArrayInputStream inputStream = new ByteArrayInputStream(ASCII_CONTENTS.getBytes());
441ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertTrue(ftpClient.appendFile(FILENAME, inputStream));
442ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        InvocationRecord invocationRecord = appeCommandHandler.getInvocation(0);
443ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        byte[] contents = (byte[]) invocationRecord.getObject(AppeCommandHandler.FILE_CONTENTS_KEY);
444ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        LOG.info("File contents=[" + contents + "]");
445ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertEquals("File contents", ASCII_CONTENTS.getBytes(), contents);
446ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    }
447ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
448ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    /**
449ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * Test the ABOR command
450ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     */
451ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    public void testAbor() throws Exception {
452ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ftpClientConnect();
453ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
454ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // ABOR
455ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertTrue("ABOR", ftpClient.abort());
456ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    }
457ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
458ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    /**
459ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * Test the Passive (PASV) command
460ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     */
461ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    public void testPasv() throws Exception {
462ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ftpClientConnect();
463ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
464ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // PASV
465ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ftpClient.enterLocalPassiveMode();
466ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // no reply code; the PASV command is sent only when the data connection is opened
467ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    }
468ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
469ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    /**
470ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * Test Mode (MODE)
471ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     */
472ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    public void testMode() throws Exception {
473ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ftpClientConnect();
474ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
475ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // MODE
476ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        boolean success = ftpClient.setFileTransferMode(FTP.STREAM_TRANSFER_MODE);
477ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertTrue("Unable to MODE", success);
478ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        verifyReplyCode("setFileTransferMode", 200);
479ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    }
480ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
481ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    /**
482ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * Test file structure (STRU)
483ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     */
484ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    public void testStru() throws Exception {
485ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ftpClientConnect();
486ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
487ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // STRU
488ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        boolean success = ftpClient.setFileStructure(FTP.FILE_STRUCTURE);
489ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertTrue("Unable to STRU", success);
490ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        verifyReplyCode("setFileStructure", 200);
491ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    }
492ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
493ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    /**
494ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * Test the SimpleCompositeCommandHandler
495ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     */
496ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    public void testSimpleCompositeCommandHandler() throws Exception {
497ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // Replace CWD CommandHandler with a SimpleCompositeCommandHandler
498ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        CommandHandler commandHandler1 = new StaticReplyCommandHandler(500);
499ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        CommandHandler commandHandler2 = new CwdCommandHandler();
500ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        SimpleCompositeCommandHandler simpleCompositeCommandHandler = new SimpleCompositeCommandHandler();
501ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        simpleCompositeCommandHandler.addCommandHandler(commandHandler1);
502ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        simpleCompositeCommandHandler.addCommandHandler(commandHandler2);
503ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        stubFtpServer.setCommandHandler("CWD", simpleCompositeCommandHandler);
504ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
505ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // Connect
506ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ftpClientConnect();
507ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
508ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // CWD
509ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertFalse("first", ftpClient.changeWorkingDirectory("dir1/dir2"));
510ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertTrue("first", ftpClient.changeWorkingDirectory("dir1/dir2"));
511ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    }
512ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
513ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    /**
514ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * Test site parameters (SITE)
515ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     */
516ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    public void testSite() throws Exception {
517ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ftpClientConnect();
518ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
519ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // SITE
520ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        int replyCode = ftpClient.site("parameters,1,2,3");
521ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertEquals("SITE", 200, replyCode);
522ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    }
523ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
524ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    /**
525ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * Test structure mount (SMNT)
526ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     */
527ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    public void testSmnt() throws Exception {
528ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ftpClientConnect();
529ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
530ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // SMNT
531ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertTrue("SMNT", ftpClient.structureMount("dir1/dir2"));
532ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        verifyReplyCode("structureMount", 250);
533ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    }
534ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
535ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    /**
536ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * Test reinitialize (REIN)
537ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     */
538ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    public void testRein() throws Exception {
539ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ftpClientConnect();
540ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
541ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        // REIN
542ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertEquals("REIN", 220, ftpClient.rein());
543ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    }
544ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
545ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    /**
546ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * Test that command names in lowercase or mixed upper/lower case are accepted
547ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     */
548ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    public void testCommandNamesInLowerOrMixedCase() throws Exception {
549ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ftpClientConnect();
550ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
551ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertEquals("rein", 220, ftpClient.sendCommand("rein"));
552ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertEquals("rEIn", 220, ftpClient.sendCommand("rEIn"));
553ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertEquals("reiN", 220, ftpClient.sendCommand("reiN"));
554ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertEquals("Rein", 220, ftpClient.sendCommand("Rein"));
555ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    }
556ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
557ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    // -------------------------------------------------------------------------
558ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    // Test setup and tear-down
559ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    // -------------------------------------------------------------------------
560ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
561ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    /**
562ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * Perform initialization before each test
563ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     *
564ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * @see org.mockftpserver.test.AbstractTest#setUp()
565ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     */
566ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    protected void setUp() throws Exception {
567ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        super.setUp();
568ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
569ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        for (int i = 0; i < BINARY_CONTENTS.length; i++) {
570ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair            BINARY_CONTENTS[i] = (byte) i;
571ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        }
572ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
573ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        stubFtpServer = new StubFtpServer();
574ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        stubFtpServer.setServerControlPort(PortTestUtil.getFtpServerControlPort());
575ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        stubFtpServer.start();
576ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ftpClient = new FTPClient();
577ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        retrCommandHandler = (RetrCommandHandler) stubFtpServer.getCommandHandler(CommandNames.RETR);
578ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        storCommandHandler = (StorCommandHandler) stubFtpServer.getCommandHandler(CommandNames.STOR);
579ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    }
580ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
581ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    /**
582ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * Perform cleanup after each test
583ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     *
584ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * @see org.mockftpserver.test.AbstractTest#tearDown()
585ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     */
586ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    protected void tearDown() throws Exception {
587ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        super.tearDown();
588ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        stubFtpServer.stop();
589ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    }
590ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
591ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    // -------------------------------------------------------------------------
592ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    // Internal Helper Methods
593ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    // -------------------------------------------------------------------------
594ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
595ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    /**
596ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * Connect to the server from the FTPClient
597ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     */
598ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    private void ftpClientConnect() throws IOException {
599ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        ftpClient.connect(SERVER, PortTestUtil.getFtpServerControlPort());
600ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    }
601ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
602ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    /**
603ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * Assert that the FtpClient reply code is equal to the expected value
604ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     *
605ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * @param operation         - the description of the operation performed; used in the error message
606ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * @param expectedReplyCode - the expected FtpClient reply code
607ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     */
608ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    private void verifyReplyCode(String operation, int expectedReplyCode) {
609ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        int replyCode = ftpClient.getReplyCode();
610ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        LOG.info("Reply: operation=\"" + operation + "\" replyCode=" + replyCode);
611ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertEquals("Unexpected replyCode for " + operation, expectedReplyCode, replyCode);
612ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    }
613ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
614ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    /**
615ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * Verify that the FTPFile has the specified properties
616ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     *
617ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * @param ftpFile - the FTPFile to verify
618ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * @param type    - the expected file type
619ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * @param name    - the expected file name
620ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     * @param size    - the expected file size (will be zero for a directory)
621ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair     */
622ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    private void verifyFTPFile(FTPFile ftpFile, int type, String name, long size) {
623ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        LOG.info(ftpFile);
624ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertEquals("type: " + ftpFile, type, ftpFile.getType());
625ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertEquals("name: " + ftpFile, name, ftpFile.getName());
626ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair        assertEquals("size: " + ftpFile, size, ftpFile.getSize());
627ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair    }
628ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair
629ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair}
630