Home | History | Annotate | Download | only in session
      1 /*
      2  * Copyright 2007 the original author or authors.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 package org.mockftpserver.core.session;
     17 
     18 import org.slf4j.Logger;
     19 import org.slf4j.LoggerFactory;
     20 import org.mockftpserver.core.MockFtpServerException;
     21 import org.mockftpserver.core.command.Command;
     22 import org.mockftpserver.core.socket.StubServerSocket;
     23 import org.mockftpserver.core.socket.StubServerSocketFactory;
     24 import org.mockftpserver.core.socket.StubSocket;
     25 import org.mockftpserver.core.socket.StubSocketFactory;
     26 import org.mockftpserver.core.util.AssertFailedException;
     27 import org.mockftpserver.test.AbstractTestCase;
     28 
     29 import java.io.ByteArrayInputStream;
     30 import java.io.ByteArrayOutputStream;
     31 import java.io.IOException;
     32 import java.io.InputStream;
     33 import java.net.InetAddress;
     34 import java.net.SocketTimeoutException;
     35 import java.util.Collections;
     36 import java.util.HashMap;
     37 import java.util.Map;
     38 
     39 /**
     40  * Tests for the DefaultSession class
     41  *
     42  * @version $Revision$ - $Date$
     43  *
     44  * @author Chris Mair
     45  */
     46 public final class DefaultSessionTest extends AbstractTestCase {
     47 
     48     private static final Logger LOG = LoggerFactory.getLogger(DefaultSessionTest.class);
     49     private static final String DATA = "sample data 123";
     50     private static final int PORT = 197;
     51     private static final String NAME1 = "name1";
     52     private static final String NAME2 = "name2";
     53     private static final Object VALUE = "value";
     54 
     55     private DefaultSession session;
     56     private ByteArrayOutputStream outputStream;
     57     private Map commandHandlerMap;
     58     private StubSocket stubSocket;
     59     private InetAddress clientHost;
     60 
     61     /**
     62      * Perform initialization before each test
     63      *
     64      * @see org.mockftpserver.test.AbstractTestCase#setUp()
     65      */
     66     protected void setUp() throws Exception {
     67         super.setUp();
     68 
     69         commandHandlerMap = new HashMap();
     70         outputStream = new ByteArrayOutputStream();
     71         session = createDefaultSession("");
     72         clientHost = InetAddress.getLocalHost();
     73     }
     74 
     75     /**
     76      * @see org.mockftpserver.test.AbstractTestCase#tearDown()
     77      */
     78     protected void tearDown() throws Exception {
     79         super.tearDown();
     80     }
     81 
     82     /**
     83      * Test the Constructor when the control socket is null
     84      */
     85     public void testConstructor_NullControlSocket() {
     86         try {
     87             new DefaultSession(null, commandHandlerMap);
     88             fail("Expected AssertFailedException");
     89         }
     90         catch (AssertFailedException expected) {
     91             LOG.info("Expected: " + expected);
     92         }
     93     }
     94 
     95     /**
     96      * Test the Constructor when the command handler Map is null
     97      */
     98     public void testConstructor_NullCommandHandlerMap() {
     99         try {
    100             new DefaultSession(stubSocket, null);
    101             fail("Expected AssertFailedException");
    102         }
    103         catch (AssertFailedException expected) {
    104             LOG.info("Expected: " + expected);
    105         }
    106     }
    107 
    108     /**
    109      * Test the setClientDataPort() method
    110      */
    111     public void testSetClientDataPort() {
    112         StubSocket stubSocket = createTestSocket("");
    113         StubSocketFactory stubSocketFactory = new StubSocketFactory(stubSocket);
    114         session.socketFactory = stubSocketFactory;
    115         session.setClientDataPort(PORT);
    116         session.setClientDataHost(clientHost);
    117         session.openDataConnection();
    118         assertEquals("data port", PORT, stubSocketFactory.requestedDataPort);
    119     }
    120 
    121     /**
    122      * Test the setClientDataPort() method after the session was in passive data mode
    123      */
    124     public void testSetClientDataPort_AfterPassiveConnectionMode() throws IOException {
    125         StubServerSocket stubServerSocket = new StubServerSocket(PORT);
    126         StubServerSocketFactory stubServerSocketFactory = new StubServerSocketFactory(stubServerSocket);
    127         session.serverSocketFactory = stubServerSocketFactory;
    128 
    129         session.switchToPassiveMode();
    130         assertFalse("server socket closed", stubServerSocket.isClosed());
    131         assertNotNull("passiveModeDataSocket", session.passiveModeDataSocket);
    132         session.setClientDataPort(PORT);
    133 
    134         // Make sure that any passive mode connection info is cleared out
    135         assertTrue("server socket closed", stubServerSocket.isClosed());
    136         assertNull("passiveModeDataSocket should be null", session.passiveModeDataSocket);
    137     }
    138 
    139     /**
    140      * Test the setClientHost() method
    141      */
    142     public void testSetClientHost() throws Exception {
    143         StubSocket stubSocket = createTestSocket("");
    144         StubSocketFactory stubSocketFactory = new StubSocketFactory(stubSocket);
    145         session.socketFactory = stubSocketFactory;
    146         session.setClientDataHost(clientHost);
    147         session.openDataConnection();
    148         assertEquals("client host", clientHost, stubSocketFactory.requestedHost);
    149     }
    150 
    151     /**
    152      * Test the openDataConnection(), setClientDataPort() and setClientDataHost() methods
    153      */
    154     public void testOpenDataConnection() {
    155         StubSocket stubSocket = createTestSocket("");
    156         StubSocketFactory stubSocketFactory = new StubSocketFactory(stubSocket);
    157         session.socketFactory = stubSocketFactory;
    158 
    159         // Use default client data port
    160         session.setClientDataHost(clientHost);
    161         session.openDataConnection();
    162         assertEquals("data port", DefaultSession.DEFAULT_CLIENT_DATA_PORT, stubSocketFactory.requestedDataPort);
    163         assertEquals("client host", clientHost, stubSocketFactory.requestedHost);
    164 
    165         // Set client data port explicitly
    166         session.setClientDataPort(PORT);
    167         session.setClientDataHost(clientHost);
    168         session.openDataConnection();
    169         assertEquals("data port", PORT, stubSocketFactory.requestedDataPort);
    170         assertEquals("client host", clientHost, stubSocketFactory.requestedHost);
    171     }
    172 
    173     /**
    174      * Test the OpenDataConnection method, when in passive mode and no incoming connection is
    175      * initiated
    176      */
    177     public void testOpenDataConnection_PassiveMode_NoConnection() throws IOException {
    178 
    179         StubServerSocket stubServerSocket = new StubServerSocket(PORT);
    180         StubServerSocketFactory stubServerSocketFactory = new StubServerSocketFactory(stubServerSocket);
    181         session.serverSocketFactory = stubServerSocketFactory;
    182 
    183         session.switchToPassiveMode();
    184 
    185         try {
    186             session.openDataConnection();
    187             fail("Expected MockFtpServerException");
    188         }
    189         catch (MockFtpServerException expected) {
    190             LOG.info("Expected: " + expected);
    191             assertSame("cause", SocketTimeoutException.class, expected.getCause().getClass());
    192         }
    193     }
    194 
    195     /**
    196      * Test the OpenDataConnection method, when the clientHost has not been set
    197      */
    198     public void testOpenDataConnection_NullClientHost() {
    199         try {
    200             session.openDataConnection();
    201             fail("Expected AssertFailedException");
    202         }
    203         catch (AssertFailedException expected) {
    204             LOG.info("Expected: " + expected);
    205         }
    206     }
    207 
    208     /**
    209      * Test the readData() method
    210      */
    211     public void testReadData() {
    212         StubSocket stubSocket = createTestSocket(DATA);
    213         session.socketFactory = new StubSocketFactory(stubSocket);
    214         session.setClientDataHost(clientHost);
    215 
    216         session.openDataConnection();
    217         byte[] data = session.readData();
    218         LOG.info("data=[" + new String(data) + "]");
    219         assertEquals("data", DATA.getBytes(), data);
    220     }
    221 
    222     /**
    223      * Test the readData() method after switching to passive mode
    224      */
    225     public void testReadData_PassiveMode() throws IOException {
    226         StubSocket stubSocket = createTestSocket(DATA);
    227         StubServerSocket stubServerSocket = new StubServerSocket(PORT, stubSocket);
    228         StubServerSocketFactory stubServerSocketFactory = new StubServerSocketFactory(stubServerSocket);
    229         session.serverSocketFactory = stubServerSocketFactory;
    230 
    231         session.switchToPassiveMode();
    232         session.openDataConnection();
    233         byte[] data = session.readData();
    234         LOG.info("data=[" + new String(data) + "]");
    235         assertEquals("data", DATA.getBytes(), data);
    236     }
    237 
    238     /**
    239      * Test the readData(int) method
    240      */
    241     public void testReadData_NumBytes() {
    242         final int NUM_BYTES = 5;
    243         final String EXPECTED_DATA = DATA.substring(0, NUM_BYTES);
    244         StubSocket stubSocket = createTestSocket(DATA);
    245         session.socketFactory = new StubSocketFactory(stubSocket);
    246         session.setClientDataHost(clientHost);
    247 
    248         session.openDataConnection();
    249         byte[] data = session.readData(NUM_BYTES);
    250         LOG.info("data=[" + new String(data) + "]");
    251         assertEquals("data", EXPECTED_DATA.getBytes(), data);
    252     }
    253 
    254     public void testReadData_NumBytes_AskForMoreBytesThanThereAre() {
    255         StubSocket stubSocket = createTestSocket(DATA);
    256         session.socketFactory = new StubSocketFactory(stubSocket);
    257         session.setClientDataHost(clientHost);
    258 
    259         session.openDataConnection();
    260         byte[] data = session.readData(10000);
    261         LOG.info("data=[" + new String(data) + "]");
    262         assertEquals("data", DATA.getBytes(), data);
    263     }
    264 
    265     /**
    266      * Test the closeDataConnection() method
    267      */
    268     public void testCloseDataConnection() {
    269         StubSocket stubSocket = createTestSocket(DATA);
    270         session.socketFactory = new StubSocketFactory(stubSocket);
    271 
    272         session.setClientDataHost(clientHost);
    273         session.openDataConnection();
    274         session.closeDataConnection();
    275         assertTrue("client data socket should be closed", stubSocket.isClosed());
    276     }
    277 
    278     /**
    279      * Test the switchToPassiveMode() method
    280      */
    281     public void testSwitchToPassiveMode() throws IOException {
    282         StubServerSocket stubServerSocket = new StubServerSocket(PORT);
    283         StubServerSocketFactory stubServerSocketFactory = new StubServerSocketFactory(stubServerSocket);
    284         session.serverSocketFactory = stubServerSocketFactory;
    285 
    286         assertNull("passiveModeDataSocket starts out null", session.passiveModeDataSocket);
    287         int port = session.switchToPassiveMode();
    288         assertSame("passiveModeDataSocket", stubServerSocket, session.passiveModeDataSocket);
    289         assertEquals("port", PORT, port);
    290     }
    291 
    292     /**
    293      * Test the getServerHost() method
    294      */
    295     public void testGetServerHost() {
    296         assertEquals("host", DEFAULT_HOST, session.getServerHost());
    297     }
    298 
    299     /**
    300      * Test the getClientHost() method when the session is not yet started
    301      */
    302     public void testGetClientHost_NotRunning() {
    303         assertNull("null", session.getClientHost());
    304     }
    305 
    306     /**
    307      * Test the parseCommand() method
    308      */
    309     public void testParseCommand() {
    310         Command command = session.parseCommand("LIST");
    311         assertEquals("command name", "LIST", command.getName());
    312         assertEquals("command parameters", EMPTY, command.getParameters());
    313 
    314         command = session.parseCommand("USER user123");
    315         assertEquals("command name", "USER", command.getName());
    316         assertEquals("command parameters", array("user123"), command.getParameters());
    317 
    318         command = session.parseCommand("PORT 127,0,0,1,17,37");
    319         assertEquals("command name", "PORT", command.getName());
    320         assertEquals("command parameters", new String[] { "127", "0", "0", "1", "17", "37" }, command
    321                 .getParameters());
    322     }
    323 
    324     /**
    325      * Test the parseCommand() method, passing in an empty command String
    326      */
    327     public void testParseCommand_EmptyCommandString() {
    328         try {
    329             session.parseCommand("");
    330             fail("Expected AssertFailedException");
    331         }
    332         catch (AssertFailedException expected) {
    333             LOG.info("Expected: " + expected);
    334         }
    335     }
    336 
    337     /**
    338      * Test the sendData() method, as well as the openDataConnection() and closeDataConnection()
    339      */
    340     public void testSendData() {
    341         StubSocket stubSocket = createTestSocket("1234567890 abcdef");
    342         session.socketFactory = new StubSocketFactory(stubSocket);
    343 
    344         session.setClientDataHost(clientHost);
    345         session.openDataConnection();
    346         session.sendData(DATA.getBytes(), DATA.length());
    347         LOG.info("output=[" + outputStream.toString() + "]");
    348         assertEquals("output", DATA, outputStream.toString());
    349     }
    350 
    351     /**
    352      * Test the SendData() method, passing in a null byte[]
    353      */
    354     public void testSendData_Null() {
    355 
    356         try {
    357             session.sendData(null, 1);
    358             fail("Expected AssertFailedException");
    359         }
    360         catch (AssertFailedException expected) {
    361             LOG.info("Expected: " + expected);
    362         }
    363     }
    364 
    365     /**
    366      * Test the SendReply(int,String) method, passing in an invalid reply code
    367      */
    368     public void testSendReply_InvalidReplyCode() {
    369 
    370         try {
    371             session.sendReply(-66, "text");
    372             fail("Expected AssertFailedException");
    373         }
    374         catch (AssertFailedException expected) {
    375             LOG.info("Expected: " + expected);
    376         }
    377     }
    378 
    379     /**
    380      * Test the getAttribute() and setAttribute() methods
    381      */
    382     public void testGetAndSetAttribute() {
    383         assertNull("name does not exist yet", session.getAttribute(NAME1));
    384         session.setAttribute(NAME1, VALUE);
    385         session.setAttribute(NAME2, null);
    386         assertEquals("NAME1", VALUE, session.getAttribute(NAME1));
    387         assertNull("NAME2", session.getAttribute(NAME2));
    388         assertNull("no such name", session.getAttribute("noSuchName"));
    389     }
    390 
    391     /**
    392      * Test the getAttribute() method, passing in a null name
    393      */
    394     public void testGetAttribute_Null() {
    395         try {
    396             session.getAttribute(null);
    397             fail("Expected AssertFailedException");
    398         }
    399         catch (AssertFailedException expected) {
    400             LOG.info("Expected: " + expected);
    401         }
    402     }
    403 
    404     /**
    405      * Test the setAttribute() method, passing in a null name
    406      */
    407     public void testSetAttribute_NullName() {
    408         try {
    409             session.setAttribute(null, VALUE);
    410             fail("Expected AssertFailedException");
    411         }
    412         catch (AssertFailedException expected) {
    413             LOG.info("Expected: " + expected);
    414         }
    415     }
    416 
    417     /**
    418      * Test the removeAttribute()
    419      */
    420     public void testRemoveAttribute() {
    421         session.removeAttribute("noSuchName");      // do nothing
    422         session.setAttribute(NAME1, VALUE);
    423         session.removeAttribute(NAME1);
    424         assertNull("NAME1", session.getAttribute(NAME1));
    425     }
    426 
    427     /**
    428      * Test the removeAttribute() method, passing in a null name
    429      */
    430     public void testRemoveAttribute_Null() {
    431         try {
    432             session.removeAttribute(null);
    433             fail("Expected AssertFailedException");
    434         }
    435         catch (AssertFailedException expected) {
    436             LOG.info("Expected: " + expected);
    437         }
    438     }
    439 
    440     /**
    441      * Test the getAttributeNames()
    442      */
    443     public void testGetAttributeNames() {
    444         assertEquals("No names yet", Collections.EMPTY_SET, session.getAttributeNames());
    445         session.setAttribute(NAME1, VALUE);
    446         assertEquals("1", Collections.singleton(NAME1), session.getAttributeNames());
    447         session.setAttribute(NAME2, VALUE);
    448         assertEquals("2", set(NAME1, NAME2), session.getAttributeNames());
    449     }
    450 
    451     // -------------------------------------------------------------------------
    452     // Internal Helper Methods
    453     // -------------------------------------------------------------------------
    454 
    455     /**
    456      * Create and return a DefaultSession object that reads from an InputStream with the specified
    457      * contents and writes to the predefined outputStrean ByteArrayOutputStream. Also, save the
    458      * StubSocket being used in the stubSocket attribute.
    459      *
    460      * @param inputStreamContents - the contents of the input stream
    461      * @return the DefaultSession
    462      */
    463     private DefaultSession createDefaultSession(String inputStreamContents) {
    464         stubSocket = createTestSocket(inputStreamContents);
    465         return new DefaultSession(stubSocket, commandHandlerMap);
    466     }
    467 
    468     /**
    469      * Create and return a StubSocket that reads from an InputStream with the specified contents and
    470      * writes to the predefined outputStrean ByteArrayOutputStream.
    471      *
    472      * @param inputStreamContents - the contents of the input stream
    473      * @return the StubSocket
    474      */
    475     private StubSocket createTestSocket(String inputStreamContents) {
    476         InputStream inputStream = new ByteArrayInputStream(inputStreamContents.getBytes());
    477         StubSocket stubSocket = new StubSocket(inputStream, outputStream);
    478         stubSocket._setLocalAddress(DEFAULT_HOST);
    479         return stubSocket;
    480     }
    481 
    482 }
    483