001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 * 019 */ 020package org.apache.mina.core; 021 022import org.apache.mina.core.filterchain.DefaultIoFilterChain; 023import org.apache.mina.core.filterchain.IoFilter; 024import org.apache.mina.core.filterchain.IoFilterAdapter; 025import org.apache.mina.core.filterchain.IoFilterChain; 026import org.apache.mina.core.filterchain.IoFilterChain.Entry; 027import org.apache.mina.core.service.IoHandler; 028import org.apache.mina.core.service.IoHandlerAdapter; 029import org.apache.mina.core.session.DummySession; 030import org.apache.mina.core.session.IdleStatus; 031import org.apache.mina.core.session.IoSession; 032import org.apache.mina.core.write.DefaultWriteRequest; 033import org.apache.mina.core.write.WriteRequest; 034import org.apache.mina.filter.util.NoopFilter; 035import org.junit.After; 036import org.junit.Before; 037import org.junit.Test; 038 039import static org.junit.Assert.assertEquals; 040import static org.junit.Assert.assertSame; 041 042/** 043 * Tests {@link DefaultIoFilterChain}. 044 * 045 * @author <a href="http://mina.apache.org">Apache MINA Project</a> 046 */ 047public class IoFilterChainTest { 048 private DummySession dummySession; 049 050 private IoFilterChain chain; 051 052 String testResult; 053 054 private final IoHandler handler = new IoHandlerAdapter() { 055 @Override 056 public void sessionCreated(IoSession session) { 057 testResult += "HS0"; 058 } 059 060 @Override 061 public void sessionOpened(IoSession session) { 062 testResult += "HSO"; 063 } 064 065 @Override 066 public void sessionClosed(IoSession session) { 067 testResult += "HSC"; 068 } 069 070 @Override 071 public void sessionIdle(IoSession session, IdleStatus status) { 072 testResult += "HSI"; 073 } 074 075 @Override 076 public void exceptionCaught(IoSession session, Throwable cause) { 077 testResult += "HEC"; 078 if (cause.getClass() != Exception.class) { 079 //cause.printStackTrace(System.out); 080 } 081 } 082 083 @Override 084 public void messageReceived(IoSession session, Object message) { 085 testResult += "HMR"; 086 } 087 088 @Override 089 public void messageSent(IoSession session, Object message) { 090 testResult += "HMS"; 091 } 092 }; 093 094 @Before 095 public void setUp() { 096 dummySession = new DummySession(); 097 dummySession.setHandler(handler); 098 chain = dummySession.getFilterChain(); 099 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}