    1   /*
    2    *  Licensed to the Apache Software Foundation (ASF) under one
    3    *  or more contributor license agreements.  See the NOTICE file
    4    *  distributed with this work for additional information
    5    *  regarding copyright ownership.  The ASF licenses this file
    6    *  to you under the Apache License, Version 2.0 (the
    7    *  "License"); you may not use this file except in compliance
    8    *  with the License.  You may obtain a copy of the License at
    9    *
    10   *    http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   *  Unless required by applicable law or agreed to in writing,
    13   *  software distributed under the License is distributed on an
    14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    15   *  KIND, either express or implied.  See the License for the
    16   *  specific language governing permissions and limitations
    17   *  under the License.
    18   *
    19   */
    20  package org.apache.mina.common;
    21
    22  import java.net.SocketAddress;
    23  import java.util.Iterator;
    24
    25  import junit.framework.Assert;
    26  import junit.framework.TestCase;
    27
    28  import org.apache.mina.common.IoFilter.WriteRequest;
    29  import org.apache.mina.common.IoFilterChain.Entry;
    30  import org.apache.mina.common.support.AbstractIoFilterChain;
    31  import org.apache.mina.common.support.BaseIoSession;
    32
    33  /**
    34   * Tests {@link AbstractIoFilterChain}.
    35   *
    36   * @author The Apache Directory Project (mina-dev@directory.apache.org)
    37   * @version $Rev: 555855 $, $Date: 2007-07-13 12:19:00 +0900 (Fri, 13 Jul 2007) $
    38   */
    39  public class IoFilterChainTest extends TestCase {
    40      private IoFilterChainImpl chain;
    41
    42      private IoSession session;
    43
    44      private String result;
    45
    46      public void setUp() {
    47          chain = new IoFilterChainImpl();
    48          session = new TestSession();
    49          result = "";
    50      }
    51
    52      public void tearDown() {
    53      }
    54
    55      public void testAdd() throws Exception {
    56          chain.addFirst("A", new EventOrderTestFilter('A'));
    57          chain.addLast("B", new EventOrderTestFilter('A'));
    58          chain.addFirst("C", new EventOrderTestFilter('A'));
    59          chain.addLast("D", new EventOrderTestFilter('A'));
    60          chain.addBefore("B", "E", new EventOrderTestFilter('A'));
    61          chain.addBefore("C", "F", new EventOrderTestFilter('A'));
    62          chain.addAfter("B", "G", new EventOrderTestFilter('A'));
    63          chain.addAfter("D", "H", new EventOrderTestFilter('A'));
    64
    65          String actual = "";
    66          for (Iterator i = chain.getAll().iterator(); i.hasNext();) {
    67              Entry e = (Entry) i.next();
    68              actual += e.getName();
    69          }
    70
    71          Assert.assertEquals("FCAEBGDH", actual);
    72      }
    73
    74      public void testGet() throws Exception {
    75          IoFilter filterA = new IoFilterAdapter();
    76          IoFilter filterB = new IoFilterAdapter();
    77          IoFilter filterC = new IoFilterAdapter();
    78          IoFilter filterD = new IoFilterAdapter();
    79
    80          chain.addFirst("A", filterA);
    81          chain.addLast("B", filterB);
    82          chain.addBefore("B", "C", filterC);
    83          chain.addAfter("A", "D", filterD);
    84
    85          Assert.assertSame(filterA, chain.get("A"));
    86          Assert.assertSame(filterB, chain.get("B"));
    87          Assert.assertSame(filterC, chain.get("C"));
    88          Assert.assertSame(filterD, chain.get("D"));
    89      }
    90
    91      public void testRemove() throws Exception {
    92          chain.addLast("A", new EventOrderTestFilter('A'));
    93          chain.addLast("B", new EventOrderTestFilter('A'));
    94          chain.addLast("C", new EventOrderTestFilter('A'));
    95          chain.addLast("D", new EventOrderTestFilter('A'));
    96          chain.addLast("E", new EventOrderTestFilter('A'));
    97
    98          chain.remove("A");
    99          chain.remove("E");
    100         chain.remove("C");
    101         chain.remove("B");
    102         chain.remove("D");
    103
    104         Assert.assertEquals(0, chain.getAll().size());
    105     }
    106
    107     public void testClear() throws Exception {
    108         chain.addLast("A", new EventOrderTestFilter('A'));
    109         chain.addLast("B", new EventOrderTestFilter('A'));
    110         chain.addLast("C", new EventOrderTestFilter('A'));
    111         chain.addLast("D", new EventOrderTestFilter('A'));
    112         chain.addLast("E", new EventOrderTestFilter('A'));
    113
    114         chain.clear();
    115
    116         Assert.assertEquals(0, chain.getAll().size());
    117     }
    118
    119     public void testToString() throws Exception {
    120         // When the chain is empty
    121         Assert.assertEquals("{ empty }", chain.toString());
    122
    123         // When there's one filter
    124         chain.addLast("A", new IoFilterAdapter() {
    125             public String toString() {
    126                 return "B";
    127             }
    128         });
    129         Assert.assertEquals("{ (A:B) }", chain.toString());
    130
    131         // When there are two
    132         chain.addLast("C", new IoFilterAdapter() {
    133             public String toString() {
    134                 return "D";
    135             }
    136         });
    137         Assert.assertEquals("{ (A:B), (C:D) }", chain.toString());
    138     }
    139
    140     public void testDefault() {
    141         run("HS0 HSO HMR HMS HSI HEC HSC");
    142     }
    143
    144     public void testChained() throws Exception {
    145         chain.addLast("A", new EventOrderTestFilter('A'));
    146         chain.addLast("B", new EventOrderTestFilter('B'));
    147         run("AS0 BS0 HS0" + "ASO BSO HSO" + "AMR BMR HMR"
    148                 + "BFW AFW AMS BMS HMS" + "ASI BSI HSI" + "AEC BEC HEC"
    149                 + "ASC BSC HSC");
    150     }
    151
    152     public void testAddRemove() throws Exception {
    153         IoFilter filter = new AddRemoveTestFilter();
    154
    155         chain.addFirst("A", filter);
    156         assertEquals("ADDED", result);
    157
    158         chain.remove("A");
    159         assertEquals("ADDEDREMOVED", result);
    160     }
    161
    162     private void run(String expectedResult) {
    163         chain.fireSessionCreated(session);
    164         chain.fireSessionOpened(session);
    165         chain.fireMessageReceived(session, new Object());
    166         chain.fireFilterWrite(session, new WriteRequest(new Object()));
    167         chain.fireSessionIdle(session, IdleStatus.READER_IDLE);
    168         chain.fireExceptionCaught(session, new Exception());
    169         chain.fireSessionClosed(session);
    170
    171         result = formatResult(result);
    172         expectedResult = formatResult(expectedResult);
    173
    174         System.out.println("Expected: " + expectedResult);
    175         System.out.println("Actual:   " + result);
    176         Assert.assertEquals(expectedResult, result);
    177     }
    178
    179     private String formatResult(String result) {
    180         result = result.replaceAll("\\s", "");
    181         StringBuffer buf = new StringBuffer(result.length() * 4 / 3);
    182         for (int i = 0; i < result.length(); i++) {
    183             buf.append(result.charAt(i));
    184             if (i % 3 == 2) {
    185                 buf.append(' ');
    186             }
    187         }
    188
    189         return buf.toString();
    190     }
    191
    192     private class TestSession extends BaseIoSession implements IoSession {
    193         private IoHandler handler = new IoHandlerAdapter() {
    194             public void sessionCreated(IoSession session) {
    195                 result += "HS0";
    196             }
    197
    198             public void sessionOpened(IoSession session) {
    199                 result += "HSO";
    200             }
    201
    202             public void sessionClosed(IoSession session) {
    203                 result += "HSC";
    204             }
    205
    206             public void sessionIdle(IoSession session, IdleStatus status) {
    207                 result += "HSI";
    208             }
    209
    210             public void exceptionCaught(IoSession session, Throwable cause) {
    211                 result += "HEC";
    212                 if (cause.getClass() != Exception.class) {
    213                     cause.printStackTrace(System.out);
    214                 }
    215             }
    216
    217             public void messageReceived(IoSession session, Object message) {
    218                 result += "HMR";
    219             }
    220
    221             public void messageSent(IoSession session, Object message) {
    222                 result += "HMS";
    223             }
    224         };
    225
    226         public IoHandler getHandler() {
    227             return handler;
    228         }
    229
    230         public CloseFuture close() {
    231             return null;
    232         }
    233
    234         public TransportType getTransportType() {
    235             return TransportType.VM_PIPE;
    236         }
    237
    238         public SocketAddress getRemoteAddress() {
    239             return null;
    240         }
    241
    242         public SocketAddress getLocalAddress() {
    243             return null;
    244         }
    245
    246         public IoFilterChain getFilterChain() {
    247             return new AbstractIoFilterChain(this) {
    248                 protected void doWrite(IoSession session,
    249                         WriteRequest writeRequest) {
    250                 }
    251
    252                 protected void doClose(IoSession session) {
    253                 }
    254             };
    255         }
    256
    257         public int getScheduledWriteRequests() {
    258             return 0;
    259         }
    260
    261         protected void updateTrafficMask() {
    262         }
    263
    264         public boolean isClosing() {
    265             return false;
    266         }
    267
    268         public IoService getService() {
    269             return null;
    270         }
    271
    272         public IoSessionConfig getConfig() {
    273             return null;
    274         }
    275
    276         public SocketAddress getServiceAddress() {
    277             return null;
    278         }
    279
    280         public int getScheduledWriteBytes() {
    281             return 0;
    282         }
    283
    284         public IoServiceConfig getServiceConfig() {
    285             return null;
    286         }
    287     }
    288
    289     private class EventOrderTestFilter extends IoFilterAdapter {
    290         private final char id;
    291
    292         private EventOrderTestFilter(char id) {
    293             this.id = id;
    294         }
    295
    296         public void sessionCreated(NextFilter nextFilter, IoSession session) {
    297             result += id + "S0";
    298             nextFilter.sessionCreated(session);
    299         }
    300
    301         public void sessionOpened(NextFilter nextFilter, IoSession session) {
    302             result += id + "SO";
    303             nextFilter.sessionOpened(session);
    304         }
    305
    306         public void sessionClosed(NextFilter nextFilter, IoSession session) {
    307             result += id + "SC";
    308             nextFilter.sessionClosed(session);
    309         }
    310
    311         public void sessionIdle(NextFilter nextFilter, IoSession session,
    312                 IdleStatus status) {
    313             result += id + "SI";
    314             nextFilter.sessionIdle(session, status);
    315         }
    316
    317         public void exceptionCaught(NextFilter nextFilter, IoSession session,
    318                 Throwable cause) {
    319             result += id + "EC";
    320             nextFilter.exceptionCaught(session, cause);
    321         }
    322
    323         public void filterWrite(NextFilter nextFilter, IoSession session,
    324                 WriteRequest writeRequest) {
    325             result += id + "FW";
    326             nextFilter.filterWrite(session, writeRequest);
    327         }
    328
    329         public void messageReceived(NextFilter nextFilter, IoSession session,
    330                 Object message) {
    331             result += id + "MR";
    332             nextFilter.messageReceived(session, message);
    333         }
    334
    335         public void messageSent(NextFilter nextFilter, IoSession session,
    336                 Object message) {
    337             result += id + "MS";
    338             nextFilter.messageSent(session, message);
    339         }
    340
    341         public void filterClose(NextFilter nextFilter, IoSession session)
    342                 throws Exception {
    343             nextFilter.filterClose(session);
    344         }
    345     }
    346
    347     private class AddRemoveTestFilter extends IoFilterAdapter {
    348         public void onPostAdd(IoFilterChain parent, String name,
    349                 NextFilter nextFilter) {
    350             result += "ADDED";
    351         }
    352
    353         public void onPostRemove(IoFilterChain parent, String name,
    354                 NextFilter nextFilter) {
    355             result += "REMOVED";
    356         }
    357     }
    358
    359     private static class IoFilterChainImpl extends AbstractIoFilterChain {
    360         protected IoFilterChainImpl() {
    361             super(new BaseIoSession() {
    362                 protected void updateTrafficMask() {
    363                 }
    364
    365                 public IoService getService() {
    366                     return null;
    367                 }
    368
    369                 public IoHandler getHandler() {
    370                     return null;
    371                 }
    372
    373                 public IoFilterChain getFilterChain() {
    374                     return null;
    375                 }
    376
    377                 public TransportType getTransportType() {
    378                     return null;
    379                 }
    380
    381                 public SocketAddress getRemoteAddress() {
    382                     return null;
    383                 }
    384
    385                 public SocketAddress getLocalAddress() {
    386                     return null;
    387                 }
    388
    389                 public int getScheduledWriteRequests() {
    390                     return 0;
    391                 }
    392
    393                 public IoSessionConfig getConfig() {
    394                     return null;
    395                 }
    396
    397                 public SocketAddress getServiceAddress() {
    398                     return null;
    399                 }
    400
    401                 public int getScheduledWriteBytes() {
    402                     return 0;
    403                 }
    404
    405                 public IoServiceConfig getServiceConfig() {
    406                     return null;
    407                 }
    408             });
    409         }
    410
    411         protected void doWrite(IoSession session, WriteRequest writeRequest) {
    412             fireMessageSent(session, writeRequest);
    413         }
    414
    415         protected void doClose(IoSession session) {
    416         }
    417     }
    418
    419 }