1ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair/* 2ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Copyright 2008 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.fake.command 17ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 18ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport org.mockftpserver.core.command.Command 19ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport org.mockftpserver.core.command.CommandHandler 20ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport org.mockftpserver.core.command.ReplyCodes 21ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport org.mockftpserver.core.session.SessionKeys 22ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport org.mockftpserver.core.session.StubSession 23ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport org.mockftpserver.fake.StubServerConfiguration 24ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport org.mockftpserver.fake.UserAccount 25ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport org.mockftpserver.fake.filesystem.DirectoryEntry 26ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport org.mockftpserver.fake.filesystem.FileEntry 27ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport org.mockftpserver.fake.filesystem.FileSystemException 28ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport org.mockftpserver.fake.filesystem.TestUnixFakeFileSystem 29ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport org.mockftpserver.test.AbstractGroovyTest 30ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 31ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair/** 32ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Abstract superclass for CommandHandler tests 33ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * 34ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @version $Revision$ - $Date$ 35ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * 36ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @author Chris Mair 37ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair */ 38ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairabstract class AbstractFakeCommandHandlerTest extends AbstractGroovyTest { 39ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 40ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair protected static final ERROR_MESSAGE_KEY = 'msgkey' 41ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 42ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair protected session 43ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair protected serverConfiguration 44ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair protected commandHandler 45ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair protected fileSystem 46ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair protected userAccount 47ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 48ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair /** Set this to false to skip the test that verifies that the CommandHandler requires a logged in user */ 49ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair boolean testNotLoggedIn = true 50ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 51ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair //------------------------------------------------------------------------- 52ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair // Tests (common to all subclasses) 53ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair //------------------------------------------------------------------------- 54ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 55ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair void testHandleCommand_ServerConfigurationIsNull() { 56ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair commandHandler.serverConfiguration = null 57ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair def command = createValidCommand() 58ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair shouldFailWithMessageContaining("serverConfiguration") { commandHandler.handleCommand(command, session) } 59ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 60ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 61ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair void testHandleCommand_CommandIsNull() { 62ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair shouldFailWithMessageContaining("command") { commandHandler.handleCommand(null, session) } 63ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 64ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 65ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair void testHandleCommand_SessionIsNull() { 66ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair def command = createValidCommand() 67ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair shouldFailWithMessageContaining("session") { commandHandler.handleCommand(command, null) } 68ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 69ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 70ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair void testHandleCommand_NotLoggedIn() { 71ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair if (getProperty('testNotLoggedIn')) { 72ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair def command = createValidCommand() 73ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair session.removeAttribute(SessionKeys.USER_ACCOUNT) 74ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair commandHandler.handleCommand(command, session) 75ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair assertSessionReply(ReplyCodes.NOT_LOGGED_IN) 76ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 77ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 78ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 79ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair //------------------------------------------------------------------------- 80ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair // Abstract Method Declarations (must be implemented by all subclasses) 81ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair //------------------------------------------------------------------------- 82ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 83ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair /** 84ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Create and return a new instance of the CommandHandler class under test. Concrete subclasses must implement. 85ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair */ 86ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair abstract CommandHandler createCommandHandler() 87ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 88ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair /** 89ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Create and return a valid instance of the Command for the CommandHandler class 90ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * under test. Concrete subclasses must implement. 91ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair */ 92ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair abstract Command createValidCommand() 93ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 94ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair //------------------------------------------------------------------------- 95ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair // Test Setup 96ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair //------------------------------------------------------------------------- 97ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 98ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair void setUp() { 99ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair super.setUp() 100ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair session = new StubSession() 101ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair serverConfiguration = new StubServerConfiguration() 102ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair fileSystem = new TestUnixFakeFileSystem() 103ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair fileSystem.createParentDirectoriesAutomatically = true 104ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair serverConfiguration.setFileSystem(fileSystem) 105ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 106ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair userAccount = new UserAccount() 107ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair session.setAttribute(SessionKeys.USER_ACCOUNT, userAccount) 108ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 109ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair commandHandler = createCommandHandler() 110ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair commandHandler.serverConfiguration = serverConfiguration 111ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 112ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 113ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair //------------------------------------------------------------------------- 114ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair // Helper Methods 115ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair //------------------------------------------------------------------------- 116ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 117ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair /** 118ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Perform a test of the handleCommand() method on the specified command 119ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * parameters, which are missing a required parameter for this CommandHandler. 120ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair */ 121ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair protected void testHandleCommand_MissingRequiredParameter(List commandParameters) { 122ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair commandHandler.handleCommand(createCommand(commandParameters), session) 123ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair assertSessionReply(ReplyCodes.COMMAND_SYNTAX_ERROR) 124ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 125ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 126ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair /** 127ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Perform a test of the handleCommand() method on the specified command 128ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * parameters, which are missing a required parameter for this CommandHandler. 129ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair */ 130ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair protected testHandleCommand_MissingRequiredSessionAttribute() { 131ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair def command = createValidCommand() 132ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair commandHandler.handleCommand(command, session) 133ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair assertSessionReply(ReplyCodes.ILLEGAL_STATE) 134ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 135ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 136ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair /** 137ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @return a new Command with the specified parameters for this CommandHandler 138ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair */ 139ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair protected Command createCommand(List commandParameters) { 140ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair new Command(createValidCommand().name, commandParameters) 141ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 142ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 143ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair /** 144ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Invoke the handleCommand() method for the current CommandHandler, passing in 145ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * the specified parameters 146ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param parameters - the List of command parameters; may be empty, but not null 147ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair */ 148ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair protected void handleCommand(List parameters) { 149ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair commandHandler.handleCommand(createCommand(parameters), session) 150ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 151ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 152ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair /** 153ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Assert that the specified reply code and message containing text was sent through the session. 154ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param expectedReplyCode - the expected reply code 155ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param text - the text expected within the reply message; defaults to the reply code as a String 156ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @deprecated 157ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair */ 158ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair protected assertSessionReply(int expectedReplyCode, text = expectedReplyCode as String) { 159ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair assertSessionReply(0, expectedReplyCode, text) 160ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 161ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 162ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair /** 163ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Assert that the specified reply code and message containing text was sent through the session. 164ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param replyIndex - the index of the reply to compare 165ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param expectedReplyCode - the expected reply code 166ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param text - the text expected within the reply message; defaults to the reply code as a String 167ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair */ 168ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair protected assertSessionReply(int replyIndex, int expectedReplyCode, text = expectedReplyCode as String) { 169ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair LOG.info(session) 170ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair String actualMessage = session.getReplyMessage(replyIndex) 171ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair def actualReplyCode = session.getReplyCode(replyIndex) 172ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair assert actualReplyCode == expectedReplyCode 173ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair if (text instanceof List) { 174ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair text.each { assert actualMessage.contains(it), "[$actualMessage] does not contain [$it]" } 175ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 176ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair else { 177ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair assert actualMessage.contains(text), "[$actualMessage] does not contain [$text]" 178ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 179ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 180ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 181ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair /** 182ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Assert that the specified reply codes were sent through the session. 183ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param replyCodes - the List of expected sent reply codes 184ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair */ 185ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair protected assertSessionReplies(List replyCodes) { 186ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair LOG.info(session) 187ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair replyCodes.eachWithIndex {replyCode, replyIndex -> 188ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair assertSessionReply(replyIndex, replyCode) 189ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 190ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 191ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 192ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair /** 193ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Assert that the specified data was sent through the session. 194ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param expectedData - the expected data 195ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair */ 196ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair protected assertSessionData(String expectedData) { 197ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair def actual = session.sentData[0] 198ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair assert actual != null, "No data for index [0] sent for $session" 199ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair assert actual == expectedData 200ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 201ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 202ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair /** 203ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Execute the handleCommand() method with the specified parameters and 204ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * assert that the standard SEND DATA replies were sent through the session. 205ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param parameters - the command parameters to use; defaults to [] 206ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param finalReplyCode - the expected final reply code; defaults to ReplyCodes.TRANSFER_DATA_FINAL_OK 207ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair */ 208ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair protected handleCommandAndVerifySendDataReplies(parameters = [], int finalReplyCode = ReplyCodes.TRANSFER_DATA_FINAL_OK) { 209ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair handleCommand(parameters) 210ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair assertSessionReplies([ReplyCodes.TRANSFER_DATA_INITIAL_OK, finalReplyCode]) 211ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 212ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 213ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair /** 214ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Execute the handleCommand() method with the specified parameters and 215ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * assert that the standard SEND DATA replies were sent through the session. 216ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param parameters - the command parameters to use 217ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param initialReplyMessageKey - the expected reply message key for the initial reply 218ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param finalReplyMessageKey - the expected reply message key for the final reply 219ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param finalReplyCode - the expected final reply code; defaults to ReplyCodes.TRANSFER_DATA_FINAL_OK 220ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair */ 221ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair protected handleCommandAndVerifySendDataReplies(parameters, String initialReplyMessageKey, String finalReplyMessageKey, int finalReplyCode = ReplyCodes.TRANSFER_DATA_FINAL_OK) { 222ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair handleCommand(parameters) 223ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair assertSessionReply(0, ReplyCodes.TRANSFER_DATA_INITIAL_OK, initialReplyMessageKey) 224ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair assertSessionReply(1, finalReplyCode, finalReplyMessageKey) 225ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 226ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 227ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair /** 228ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Override the named method for the specified object instance 229ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param object - the object instance 230ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param methodName - the name of the method to override 231ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param newMethod - the Closure representing the new method for this single instance 232ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair */ 233ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair protected void overrideMethod(object, String methodName, Closure newMethod) { 234ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair LOG.info("Overriding method [$methodName] for class [${object.class}]") 235ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair def emc = new ExpandoMetaClass(object.class, false) 236ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair emc."$methodName" = newMethod 237ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair emc.initialize() 238ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair object.metaClass = emc 239ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 240ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 241ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair /** 242ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Override the named method (that takes a single String arg) of the fileSystem object to throw a (generic) FileSystemException 243ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param methodName - the name of the fileSystem method to override 244ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair */ 245ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair protected void overrideMethodToThrowFileSystemException(String methodName) { 246ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair def newMethod = {String path -> throw new FileSystemException("Error thrown by method [$methodName]", ERROR_MESSAGE_KEY) } 247ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair overrideMethod(fileSystem, methodName, newMethod) 248ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 249ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 250ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair /** 251ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Set the current directory within the session 252ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param path - the new path value for the current directory 253ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair */ 254ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair protected void setCurrentDirectory(String path) { 255ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair session.setAttribute(SessionKeys.CURRENT_DIRECTORY, path) 256ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 257ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 258ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair /** 259ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Convenience method to return the end-of-line character(s) for the current CommandHandler. 260ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair */ 261ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair protected endOfLine() { 262ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair commandHandler.endOfLine() 263ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 264ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 265ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair /** 266ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Create a new directory entry with the specified path in the file system 267ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param path - the path of the new directory entry 268ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @return the newly created DirectoryEntry 269ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair */ 270ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair protected DirectoryEntry createDirectory(String path) { 271ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair DirectoryEntry entry = new DirectoryEntry(path) 272ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair fileSystem.add(entry) 273ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair return entry 274ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 275ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 276ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair /** 277ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Create a new file entry with the specified path in the file system 278ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param path - the path of the new file entry 279ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param contents - the contents for the file; defaults to null 280ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @return the newly created FileEntry 281ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair */ 282ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair protected FileEntry createFile(String path, contents = null) { 283ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair FileEntry entry = new FileEntry(path: path, contents: contents) 284ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair fileSystem.add(entry) 285ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair return entry 286ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 287ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 288ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair}