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