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