summaryrefslogtreecommitdiff
path: root/tags/2.1/src/test/groovy/org/mockftpserver/fake/FakeFtpServerIntegrationTest.groovy
diff options
context:
space:
mode:
Diffstat (limited to 'tags/2.1/src/test/groovy/org/mockftpserver/fake/FakeFtpServerIntegrationTest.groovy')
-rw-r--r--tags/2.1/src/test/groovy/org/mockftpserver/fake/FakeFtpServerIntegrationTest.groovy500
1 files changed, 500 insertions, 0 deletions
diff --git a/tags/2.1/src/test/groovy/org/mockftpserver/fake/FakeFtpServerIntegrationTest.groovy b/tags/2.1/src/test/groovy/org/mockftpserver/fake/FakeFtpServerIntegrationTest.groovy
new file mode 100644
index 0000000..204cd18
--- /dev/null
+++ b/tags/2.1/src/test/groovy/org/mockftpserver/fake/FakeFtpServerIntegrationTest.groovy
@@ -0,0 +1,500 @@
+/*
+ * Copyright 2008 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.mockftpserver.fake
+
+import org.apache.commons.net.ftp.FTP
+import org.apache.commons.net.ftp.FTPClient
+import org.apache.commons.net.ftp.FTPFile
+import org.mockftpserver.core.command.CommandNames
+import org.mockftpserver.core.command.StaticReplyCommandHandler
+import org.mockftpserver.fake.FakeFtpServer
+import org.mockftpserver.fake.UserAccount
+import org.mockftpserver.fake.filesystem.DirectoryEntry
+import org.mockftpserver.fake.filesystem.FileEntry
+import org.mockftpserver.fake.filesystem.FileSystem
+import org.mockftpserver.fake.filesystem.UnixFakeFileSystem
+import org.mockftpserver.fake.filesystem.WindowsFakeFileSystem
+import org.mockftpserver.stub.command.CwdCommandHandler
+import org.mockftpserver.test.AbstractGroovyTest
+import org.mockftpserver.test.PortTestUtil
+
+/**
+ * Integration tests for FakeFtpServer.
+ *
+ * @version $Revision$ - $Date$
+ *
+ * @author Chris Mair
+ */
+class FakeFtpServerIntegrationTest extends AbstractGroovyTest {
+
+ static final SERVER = "localhost"
+ static final USERNAME = "user123"
+ static final PASSWORD = "password"
+ static final ACCOUNT = "account123"
+ static final ASCII_DATA = "abcdef\tghijklmnopqr"
+ static final BINARY_DATA = new byte[256]
+ static final ROOT_DIR = "c:/"
+ static final HOME_DIR = p(ROOT_DIR, "home")
+ static final SUBDIR_NAME = 'sub'
+ static final SUBDIR_NAME2 = "archive"
+ static final SUBDIR = p(HOME_DIR, SUBDIR_NAME)
+ static final FILENAME1 = "abc.txt"
+ static final FILENAME2 = "SomeOtherFile.xml"
+ static final FILE1 = p(HOME_DIR, FILENAME1)
+ static final SYSTEM_NAME = "WINDOWS"
+
+ private FakeFtpServer ftpServer
+ private FTPClient ftpClient
+ private FileSystem fileSystem
+ private UserAccount userAccount
+
+ //-------------------------------------------------------------------------
+ // Tests
+ //-------------------------------------------------------------------------
+
+ void testAbor() {
+ ftpClientConnectAndLogin()
+ assert ftpClient.abort()
+ verifyReplyCode("ABOR", 226)
+ }
+
+ void testAcct() {
+ ftpClientConnectAndLogin()
+ assert ftpClient.acct(ACCOUNT) == 230
+ }
+
+ void testAllo() {
+ ftpClientConnectAndLogin()
+ assert ftpClient.allocate(99)
+ verifyReplyCode("ALLO", 200)
+ }
+
+ void testAppe() {
+ def ORIGINAL_CONTENTS = '123 456 789'
+ fileSystem.add(new FileEntry(path: FILE1, contents: ORIGINAL_CONTENTS))
+
+ ftpClientConnectAndLogin()
+
+ LOG.info("Put File for local path [$FILE1]")
+ def inputStream = new ByteArrayInputStream(ASCII_DATA.getBytes())
+ assert ftpClient.appendFile(FILE1, inputStream)
+ def contents = fileSystem.getEntry(FILE1).createInputStream().text
+ LOG.info("File contents=[" + contents + "]")
+ assert contents == ORIGINAL_CONTENTS + ASCII_DATA
+ }
+
+ void testCdup() {
+ ftpClientConnectAndLogin()
+ assert ftpClient.changeToParentDirectory()
+ verifyReplyCode("changeToParentDirectory", 200)
+ }
+
+ void testCwd() {
+ ftpClientConnectAndLogin()
+ assert ftpClient.changeWorkingDirectory(SUBDIR_NAME)
+ verifyReplyCode("changeWorkingDirectory", 250)
+ }
+
+ /**
+ * Test that a CWD to ".." properly resolves the current dir (without the "..") so that PWD returns the parent
+ */
+ void testCwd_DotDot_Pwd() {
+ ftpClientConnectAndLogin()
+ assert ftpClient.changeWorkingDirectory("..")
+ verifyReplyCode("changeWorkingDirectory", 250)
+ assert p(ftpClient.printWorkingDirectory()) == p(ROOT_DIR)
+ assert ftpClient.changeWorkingDirectory("home")
+ assert p(ftpClient.printWorkingDirectory()) == p(HOME_DIR)
+ }
+
+ /**
+ * Test that a CWD to "." properly resolves the current dir (without the ".") so that PWD returns the parent
+ */
+ void testCwd_Dot_Pwd() {
+ ftpClientConnectAndLogin()
+ assert ftpClient.changeWorkingDirectory(".")
+ verifyReplyCode("changeWorkingDirectory", 250)
+ assert p(ftpClient.printWorkingDirectory()) == p(HOME_DIR)
+ }
+
+ void testCwd_UseStaticReplyCommandHandler() {
+ final int REPLY_CODE = 500;
+ StaticReplyCommandHandler cwdCommandHandler = new StaticReplyCommandHandler(REPLY_CODE);
+ ftpServer.setCommandHandler(CommandNames.CWD, cwdCommandHandler);
+
+ ftpClientConnectAndLogin()
+ assert !ftpClient.changeWorkingDirectory(SUBDIR_NAME)
+ verifyReplyCode("changeWorkingDirectory", REPLY_CODE)
+ }
+
+ void testCwd_UseStubCommandHandler() {
+ final int REPLY_CODE = 502;
+ CwdCommandHandler cwdCommandHandler = new CwdCommandHandler(); // Stub command handler
+ cwdCommandHandler.setReplyCode(REPLY_CODE);
+ ftpServer.setCommandHandler(CommandNames.CWD, cwdCommandHandler);
+
+ ftpClientConnectAndLogin()
+ assert !ftpClient.changeWorkingDirectory(SUBDIR_NAME)
+ verifyReplyCode("changeWorkingDirectory", REPLY_CODE)
+ assert cwdCommandHandler.getInvocation(0)
+ }
+
+ void testDele() {
+ fileSystem.add(new FileEntry(FILE1))
+
+ ftpClientConnectAndLogin()
+ assert ftpClient.deleteFile(FILENAME1)
+ verifyReplyCode("deleteFile", 250)
+ assert !fileSystem.exists(FILENAME1)
+ }
+
+ void testEprt() {
+ ftpClientConnectAndLogin()
+ assert ftpClient.sendCommand("EPRT", "|2|1080::8:800:200C:417A|5282|") == 200
+ }
+
+ void testEpsv() {
+ ftpClientConnectAndLogin()
+ assert ftpClient.sendCommand("EPSV") == 229
+ }
+
+ void testFeat_UseStaticReplyCommandHandler() {
+ // The FEAT command is not supported out of the box
+ StaticReplyCommandHandler featCommandHandler = new StaticReplyCommandHandler(211, "No Features");
+ ftpServer.setCommandHandler("FEAT", featCommandHandler);
+
+ ftpClientConnectAndLogin()
+ assert ftpClient.sendCommand("FEAT") == 211
+ }
+
+ void testHelp() {
+ ftpServer.helpText = [a: 'aaa', '': 'default']
+ ftpClientConnect()
+
+ String help = ftpClient.listHelp()
+ assert help.contains('default')
+ verifyReplyCode("listHelp", 214)
+
+ help = ftpClient.listHelp('a')
+ assert help.contains('aaa')
+ verifyReplyCode("listHelp", 214)
+
+ help = ftpClient.listHelp('bad')
+ assert help.contains('bad')
+ verifyReplyCode("listHelp", 214)
+ }
+
+ void testList() {
+ def LAST_MODIFIED = new Date()
+ fileSystem.add(new FileEntry(path: p(SUBDIR, FILENAME1), lastModified: LAST_MODIFIED, contents: ASCII_DATA))
+ fileSystem.add(new DirectoryEntry(path: p(SUBDIR, SUBDIR_NAME2), lastModified: LAST_MODIFIED))
+
+ ftpClientConnectAndLogin()
+
+ FTPFile[] files = ftpClient.listFiles(SUBDIR)
+ assert files.length == 2
+ verifyFTPFile(files[0], FTPFile.FILE_TYPE, FILENAME1, ASCII_DATA.size())
+ verifyFTPFile(files[1], FTPFile.DIRECTORY_TYPE, SUBDIR_NAME2, 0)
+ verifyReplyCode("list", 226)
+ }
+
+ void testList_Unix() {
+ ftpServer.systemName = 'UNIX'
+ userAccount.homeDirectory = '/'
+
+ def unixFileSystem = new UnixFakeFileSystem()
+ unixFileSystem.createParentDirectoriesAutomatically = true
+ unixFileSystem.add(new DirectoryEntry('/'))
+ ftpServer.fileSystem = unixFileSystem
+
+ def LAST_MODIFIED = new Date()
+ unixFileSystem.add(new FileEntry(path: p('/', FILENAME1), lastModified: LAST_MODIFIED, contents: ASCII_DATA))
+ unixFileSystem.add(new DirectoryEntry(path: p('/', SUBDIR_NAME2), lastModified: LAST_MODIFIED))
+
+ ftpClientConnectAndLogin()
+
+ FTPFile[] files = ftpClient.listFiles('/')
+ assert files.length == 2
+ verifyFTPFile(files[0], FTPFile.DIRECTORY_TYPE, SUBDIR_NAME2, 0)
+ verifyFTPFile(files[1], FTPFile.FILE_TYPE, FILENAME1, ASCII_DATA.size())
+ verifyReplyCode("list", 226)
+ }
+
+ void testLogin() {
+ ftpClientConnect()
+ LOG.info("Logging in as $USERNAME/$PASSWORD")
+ assert ftpClient.login(USERNAME, PASSWORD)
+ verifyReplyCode("login with $USERNAME/$PASSWORD", 230)
+
+ assertTrue("isStarted", ftpServer.isStarted());
+ assertFalse("isShutdown", ftpServer.isShutdown());
+ }
+
+ void testLogin_WithAccount() {
+ userAccount.accountRequiredForLogin = true
+ ftpClientConnect()
+ LOG.info("Logging in as $USERNAME/$PASSWORD with $ACCOUNT")
+ assert ftpClient.login(USERNAME, PASSWORD, ACCOUNT)
+ verifyReplyCode("login with $USERNAME/$PASSWORD with $ACCOUNT", 230)
+ }
+
+ void testMkd() {
+ ftpClientConnectAndLogin()
+
+ def DIR = p(HOME_DIR, 'NewDir')
+ assert ftpClient.makeDirectory(DIR)
+ verifyReplyCode("makeDirectory", 257)
+ assert fileSystem.isDirectory(DIR)
+ }
+
+ void testMode() {
+ ftpClientConnectAndLogin()
+ assert ftpClient.setFileTransferMode(FTP.STREAM_TRANSFER_MODE);
+ verifyReplyCode("MODE", 200)
+ }
+
+ void testNlst() {
+ fileSystem.add(new FileEntry(path: p(SUBDIR, FILENAME1)))
+ fileSystem.add(new DirectoryEntry(path: p(SUBDIR, SUBDIR_NAME2)))
+
+ ftpClientConnectAndLogin()
+
+ String[] filenames = ftpClient.listNames(SUBDIR)
+ assert filenames == [FILENAME1, SUBDIR_NAME2]
+ verifyReplyCode("listNames", 226)
+ }
+
+ void testNoop() {
+ ftpClientConnectAndLogin()
+ assert ftpClient.sendNoOp()
+ verifyReplyCode("NOOP", 200)
+ }
+
+ void testPasv_Nlst() {
+ fileSystem.add(new FileEntry(path: p(SUBDIR, FILENAME1)))
+ fileSystem.add(new FileEntry(path: p(SUBDIR, FILENAME2)))
+
+ ftpClientConnectAndLogin()
+ ftpClient.enterLocalPassiveMode();
+
+ String[] filenames = ftpClient.listNames(SUBDIR)
+ assert filenames == [FILENAME1, FILENAME2]
+ verifyReplyCode("listNames", 226)
+ }
+
+ void testPwd() {
+ ftpClientConnectAndLogin()
+ assert ftpClient.printWorkingDirectory() == HOME_DIR
+ verifyReplyCode("printWorkingDirectory", 257)
+ }
+
+ void testQuit() {
+ ftpClientConnect()
+ ftpClient.quit()
+ verifyReplyCode("quit", 221)
+ }
+
+ void testRein() {
+ ftpClientConnectAndLogin()
+ assert ftpClient.rein() == 220
+ assert ftpClient.cdup() == 530 // now logged out
+ }
+
+ void testRest() {
+ ftpClientConnectAndLogin()
+ assert ftpClient.rest("marker") == 350
+ }
+
+ void testRetr() {
+ fileSystem.add(new FileEntry(path: FILE1, contents: ASCII_DATA))
+
+ ftpClientConnectAndLogin()
+
+ LOG.info("Get File for remotePath [$FILE1]")
+ def outputStream = new ByteArrayOutputStream()
+ assert ftpClient.retrieveFile(FILE1, outputStream)
+ LOG.info("File contents=[${outputStream.toString()}]")
+ assert outputStream.toString() == ASCII_DATA
+ }
+
+ void testRmd() {
+ ftpClientConnectAndLogin()
+
+ assert ftpClient.removeDirectory(SUBDIR)
+ verifyReplyCode("removeDirectory", 250)
+ assert !fileSystem.exists(SUBDIR)
+ }
+
+ void testRename() { // RNFR and RNTO
+ fileSystem.add(new FileEntry(FILE1))
+
+ ftpClientConnectAndLogin()
+
+ assert ftpClient.rename(FILE1, FILE1 + "NEW")
+ verifyReplyCode("rename", 250)
+ assert !fileSystem.exists(FILE1)
+ assert fileSystem.exists(FILE1 + "NEW")
+ }
+
+ void testSite() {
+ ftpClientConnectAndLogin()
+ assert ftpClient.site("parameters,1,2,3") == 200
+ }
+
+ void testSmnt() {
+ ftpClientConnectAndLogin()
+ assert ftpClient.smnt("dir") == 250
+ }
+
+ void testStat() {
+ ftpClientConnectAndLogin()
+ def status = ftpClient.getStatus()
+ assert status.contains('Connected')
+ verifyReplyCode("stat", 211)
+ }
+
+ void testStor() {
+ ftpClientConnectAndLogin()
+
+ LOG.info("Put File for local path [$FILE1]")
+ def inputStream = new ByteArrayInputStream(ASCII_DATA.getBytes())
+ assert ftpClient.storeFile(FILE1, inputStream)
+ def contents = fileSystem.getEntry(FILE1).createInputStream().text
+ LOG.info("File contents=[" + contents + "]")
+ assert contents == ASCII_DATA
+ }
+
+ void testStou() {
+ ftpClientConnectAndLogin()
+
+ def inputStream = new ByteArrayInputStream(ASCII_DATA.getBytes())
+ assert ftpClient.storeUniqueFile(FILENAME1, inputStream)
+
+ def names = fileSystem.listNames(HOME_DIR)
+ def filename = names.find {name -> name.startsWith(FILENAME1) }
+ assert filename
+
+ def contents = fileSystem.getEntry(p(HOME_DIR, filename)).createInputStream().text
+ LOG.info("File contents=[" + contents + "]")
+ assert contents == ASCII_DATA
+ }
+
+ void testStru() {
+ ftpClientConnectAndLogin()
+ assert ftpClient.setFileStructure(FTP.FILE_STRUCTURE);
+ verifyReplyCode("STRU", 200)
+ }
+
+ void testSyst() {
+ ftpClientConnectAndLogin()
+
+ def systemName = ftpClient.getSystemName()
+ LOG.info("system name = [$systemName]")
+ assert systemName.contains('"' + SYSTEM_NAME + '"')
+ verifyReplyCode("getSystemName", 215)
+ }
+
+ void testType() {
+ ftpClientConnectAndLogin()
+ assert ftpClient.type(FTP.ASCII_FILE_TYPE)
+ verifyReplyCode("TYPE", 200)
+ }
+
+ void testUnrecognizedCommand() {
+ ftpClientConnectAndLogin()
+ assert ftpClient.sendCommand("XXX") == 502
+ verifyReplyCode("XXX", 502)
+ }
+
+ // -------------------------------------------------------------------------
+ // Test setup and tear-down
+ // -------------------------------------------------------------------------
+
+ /**
+ * Perform initialization before each test
+ * @see org.mockftpserver.test.AbstractTest#setUp()
+ */
+ void setUp() {
+ super.setUp()
+
+ for (int i = 0; i < BINARY_DATA.length; i++) {
+ BINARY_DATA[i] = (byte) i
+ }
+
+ ftpServer = new FakeFtpServer()
+ ftpServer.serverControlPort = PortTestUtil.getFtpServerControlPort()
+ ftpServer.systemName = SYSTEM_NAME
+
+ fileSystem = new WindowsFakeFileSystem()
+ fileSystem.createParentDirectoriesAutomatically = true
+ fileSystem.add(new DirectoryEntry(SUBDIR))
+ ftpServer.fileSystem = fileSystem
+
+ userAccount = new UserAccount(USERNAME, PASSWORD, HOME_DIR)
+ ftpServer.addUserAccount(userAccount)
+
+ ftpServer.start()
+ ftpClient = new FTPClient()
+ }
+
+ /**
+ * Perform cleanup after each test
+ * @see org.mockftpserver.test.AbstractTest#tearDown()
+ */
+ void tearDown() {
+ super.tearDown()
+ ftpServer.stop()
+ }
+
+ // -------------------------------------------------------------------------
+ // Internal Helper Methods
+ // -------------------------------------------------------------------------
+
+ private ftpClientConnectAndLogin() {
+ ftpClientConnect()
+ assert ftpClient.login(USERNAME, PASSWORD)
+ }
+
+ /**
+ * Connect to the server from the FTPClient
+ */
+ private void ftpClientConnect() {
+ def port = PortTestUtil.getFtpServerControlPort()
+ LOG.info("Conecting to $SERVER on port $port")
+ ftpClient.connect(SERVER, port)
+ verifyReplyCode("connect", 220)
+ }
+
+ /**
+ * Assert that the FtpClient reply code is equal to the expected value
+ *
+ * @param operation - the description of the operation performed used in the error message
+ * @param expectedReplyCode - the expected FtpClient reply code
+ */
+ private void verifyReplyCode(String operation, int expectedReplyCode) {
+ int replyCode = ftpClient.getReplyCode()
+ LOG.info("Reply: operation=\"" + operation + "\" replyCode=" + replyCode)
+ assertEquals("Unexpected replyCode for " + operation, expectedReplyCode, replyCode)
+ }
+
+ private void verifyFTPFile(FTPFile ftpFile, int type, String name, long size) {
+ LOG.info(ftpFile)
+ assertEquals("type: " + ftpFile, type, ftpFile.getType())
+ assertEquals("name: " + ftpFile, name, ftpFile.getName())
+ assertEquals("size: " + ftpFile, size, ftpFile.getSize())
+ }
+
+} \ No newline at end of file