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 (금, 13  7월 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 }