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