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 junit.framework.Assert;
23  import junit.framework.TestCase;
24  
25  import org.apache.mina.common.IoFilterChain.Entry;
26  
27  /**
28   * Tests {@link DefaultIoFilterChain}.
29   *
30   * @author The Apache MINA Project (dev@mina.apache.org)
31   * @version $Rev: 576271 $, $Date: 2007-09-17 00:43:04 -0600 (Mon, 17 Sep 2007) $
32   */
33  public class IoFilterChainTest extends TestCase {
34      private DummySession session;
35      private IoFilterChain chain;
36      private String result;
37  
38      private final IoHandler handler = new IoHandlerAdapter() {
39          @Override
40          public void sessionCreated(IoSession session) {
41              result += "HS0";
42          }
43  
44          @Override
45          public void sessionOpened(IoSession session) {
46              result += "HSO";
47          }
48  
49          @Override
50          public void sessionClosed(IoSession session) {
51              result += "HSC";
52          }
53  
54          @Override
55          public void sessionIdle(IoSession session, IdleStatus status) {
56              result += "HSI";
57          }
58  
59          @Override
60          public void exceptionCaught(IoSession session, Throwable cause) {
61              result += "HEC";
62              if (cause.getClass() != Exception.class) {
63                  cause.printStackTrace(System.out);
64              }
65          }
66  
67          @Override
68          public void messageReceived(IoSession session, Object message) {
69              result += "HMR";
70          }
71  
72          @Override
73          public void messageSent(IoSession session, Object message) {
74              result += "HMS";
75          }
76      };
77  
78      @Override
79      public void setUp() {
80          session = new DummySession();
81          session.setHandler(handler);
82          chain = session.getFilterChain();
83          result = "";
84      }
85  
86      @Override
87      public void tearDown() {
88      }
89  
90      public void testAdd() throws Exception {
91          chain.addFirst("A", new EventOrderTestFilter('A'));
92          chain.addLast("B", new EventOrderTestFilter('A'));
93          chain.addFirst("C", new EventOrderTestFilter('A'));
94          chain.addLast("D", new EventOrderTestFilter('A'));
95          chain.addBefore("B", "E", new EventOrderTestFilter('A'));
96          chain.addBefore("C", "F", new EventOrderTestFilter('A'));
97          chain.addAfter("B", "G", new EventOrderTestFilter('A'));
98          chain.addAfter("D", "H", new EventOrderTestFilter('A'));
99  
100         String actual = "";
101         for (Entry e : chain.getAll()) {
102             actual += e.getName();
103         }
104 
105         Assert.assertEquals("FCAEBGDH", actual);
106     }
107 
108     public void testGet() throws Exception {
109         IoFilter filterA = new IoFilterAdapter();
110         IoFilter filterB = new IoFilterAdapter();
111         IoFilter filterC = new IoFilterAdapter();
112         IoFilter filterD = new IoFilterAdapter();
113 
114         chain.addFirst("A", filterA);
115         chain.addLast("B", filterB);
116         chain.addBefore("B", "C", filterC);
117         chain.addAfter("A", "D", filterD);
118 
119         Assert.assertSame(filterA, chain.get("A"));
120         Assert.assertSame(filterB, chain.get("B"));
121         Assert.assertSame(filterC, chain.get("C"));
122         Assert.assertSame(filterD, chain.get("D"));
123     }
124 
125     public void testRemove() throws Exception {
126         chain.addLast("A", new EventOrderTestFilter('A'));
127         chain.addLast("B", new EventOrderTestFilter('A'));
128         chain.addLast("C", new EventOrderTestFilter('A'));
129         chain.addLast("D", new EventOrderTestFilter('A'));
130         chain.addLast("E", new EventOrderTestFilter('A'));
131 
132         chain.remove("A");
133         chain.remove("E");
134         chain.remove("C");
135         chain.remove("B");
136         chain.remove("D");
137 
138         Assert.assertEquals(0, chain.getAll().size());
139     }
140 
141     public void testClear() throws Exception {
142         chain.addLast("A", new EventOrderTestFilter('A'));
143         chain.addLast("B", new EventOrderTestFilter('A'));
144         chain.addLast("C", new EventOrderTestFilter('A'));
145         chain.addLast("D", new EventOrderTestFilter('A'));
146         chain.addLast("E", new EventOrderTestFilter('A'));
147 
148         chain.clear();
149 
150         Assert.assertEquals(0, chain.getAll().size());
151     }
152 
153     public void testToString() throws Exception {
154         // When the chain is empty
155         Assert.assertEquals("{ empty }", chain.toString());
156 
157         // When there's one filter
158         chain.addLast("A", new IoFilterAdapter() {
159             @Override
160             public String toString() {
161                 return "B";
162             }
163         });
164         Assert.assertEquals("{ (A:B) }", chain.toString());
165 
166         // When there are two
167         chain.addLast("C", new IoFilterAdapter() {
168             @Override
169             public String toString() {
170                 return "D";
171             }
172         });
173         Assert.assertEquals("{ (A:B), (C:D) }", chain.toString());
174     }
175 
176     public void testDefault() {
177         run("HS0 HSO HMR HMS HSI HEC HSC");
178     }
179 
180     public void testChained() throws Exception {
181         chain.addLast("A", new EventOrderTestFilter('A'));
182         chain.addLast("B", new EventOrderTestFilter('B'));
183         run("AS0 BS0 HS0" + "ASO BSO HSO" + "AMR BMR HMR"
184                 + "BFW AFW AMS BMS HMS" + "ASI BSI HSI" + "AEC BEC HEC"
185                 + "ASC BSC HSC");
186     }
187 
188     public void testAddRemove() throws Exception {
189         IoFilter filter = new AddRemoveTestFilter();
190 
191         chain.addFirst("A", filter);
192         assertEquals("ADDED", result);
193 
194         chain.remove("A");
195         assertEquals("ADDEDREMOVED", result);
196     }
197 
198     private void run(String expectedResult) {
199         chain.fireSessionCreated();
200         chain.fireSessionOpened();
201         chain.fireMessageReceived(new Object());
202         chain.fireFilterWrite(new DefaultWriteRequest(new Object()));
203         chain.fireSessionIdle(IdleStatus.READER_IDLE);
204         chain.fireExceptionCaught(new Exception());
205         chain.fireSessionClosed();
206 
207         result = formatResult(result);
208         expectedResult = formatResult(expectedResult);
209 
210         System.out.println("Expected: " + expectedResult);
211         System.out.println("Actual:   " + result);
212         Assert.assertEquals(expectedResult, result);
213     }
214 
215     private String formatResult(String result) {
216         result = result.replaceAll("\\s", "");
217         StringBuffer buf = new StringBuffer(result.length() * 4 / 3);
218         for (int i = 0; i < result.length(); i++) {
219             buf.append(result.charAt(i));
220             if (i % 3 == 2) {
221                 buf.append(' ');
222             }
223         }
224 
225         return buf.toString();
226     }
227 
228     private class EventOrderTestFilter extends IoFilterAdapter {
229         private final char id;
230 
231         private EventOrderTestFilter(char id) {
232             this.id = id;
233         }
234 
235         @Override
236         public void sessionCreated(NextFilter nextFilter, IoSession session) {
237             result += id + "S0";
238             nextFilter.sessionCreated(session);
239         }
240 
241         @Override
242         public void sessionOpened(NextFilter nextFilter, IoSession session) {
243             result += id + "SO";
244             nextFilter.sessionOpened(session);
245         }
246 
247         @Override
248         public void sessionClosed(NextFilter nextFilter, IoSession session) {
249             result += id + "SC";
250             nextFilter.sessionClosed(session);
251         }
252 
253         @Override
254         public void sessionIdle(NextFilter nextFilter, IoSession session,
255                 IdleStatus status) {
256             result += id + "SI";
257             nextFilter.sessionIdle(session, status);
258         }
259 
260         @Override
261         public void exceptionCaught(NextFilter nextFilter, IoSession session,
262                 Throwable cause) {
263             result += id + "EC";
264             nextFilter.exceptionCaught(session, cause);
265         }
266 
267         @Override
268         public void filterWrite(NextFilter nextFilter, IoSession session,
269                 WriteRequest writeRequest) {
270             result += id + "FW";
271             nextFilter.filterWrite(session, writeRequest);
272         }
273 
274         @Override
275         public void messageReceived(NextFilter nextFilter, IoSession session,
276                 Object message) {
277             result += id + "MR";
278             nextFilter.messageReceived(session, message);
279         }
280 
281         @Override
282         public void messageSent(NextFilter nextFilter, IoSession session,
283                 WriteRequest writeRequest) {
284             result += id + "MS";
285             nextFilter.messageSent(session, writeRequest);
286         }
287 
288         @Override
289         public void filterClose(NextFilter nextFilter, IoSession session)
290                 throws Exception {
291             nextFilter.filterClose(session);
292         }
293     }
294 
295     private class AddRemoveTestFilter extends IoFilterAdapter {
296         @Override
297         public void onPostAdd(IoFilterChain parent, String name,
298                 NextFilter nextFilter) {
299             result += "ADDED";
300         }
301 
302         @Override
303         public void onPostRemove(IoFilterChain parent, String name,
304                 NextFilter nextFilter) {
305             result += "REMOVED";
306         }
307     }
308 }