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.support;
21  
22  import java.net.InetSocketAddress;
23  import java.net.SocketAddress;
24  
25  import junit.framework.Assert;
26  import junit.framework.TestCase;
27  
28  import org.apache.mina.common.IoAcceptor;
29  import org.apache.mina.common.IoAcceptorConfig;
30  import org.apache.mina.common.IoConnector;
31  import org.apache.mina.common.IoFilterChain;
32  import org.apache.mina.common.IoHandler;
33  import org.apache.mina.common.IoService;
34  import org.apache.mina.common.IoServiceConfig;
35  import org.apache.mina.common.IoServiceListener;
36  import org.apache.mina.common.IoSessionConfig;
37  import org.apache.mina.common.TransportType;
38  import org.easymock.MockControl;
39  
40  /**
41   * Tests {@link IoServiceListenerSupport}.
42   *
43   * @author The Apache Directory Project (mina-dev@directory.apache.org)
44   * @version $Rev: 555855 $, $Date: 2007-07-13 12:19:00 +0900 (금, 13  7월 2007) $
45   */
46  public class IoServiceListenerSupportTest extends TestCase {
47      private static final SocketAddress ADDRESS = new InetSocketAddress(8080);
48  
49      public void testServiceLifecycle() throws Exception {
50          IoServiceListenerSupport support = new IoServiceListenerSupport();
51  
52          MockControl listenerControl = MockControl
53                  .createStrictControl(IoServiceListener.class);
54          IoServiceListener listener = (IoServiceListener) listenerControl
55                  .getMock();
56  
57          // Test activation
58          listener.serviceActivated(null, ADDRESS, null, null);
59  
60          listenerControl.replay();
61  
62          support.add(listener);
63          support.fireServiceActivated(null, ADDRESS, null, null);
64  
65          listenerControl.verify();
66  
67          Assert.assertEquals(1, support.getManagedServiceAddresses().size());
68          Assert.assertTrue(support.getManagedServiceAddresses()
69                  .contains(ADDRESS));
70  
71          // Test deactivation & other side effects
72          listenerControl.reset();
73          listener.serviceDeactivated(null, ADDRESS, null, null);
74  
75          listenerControl.replay();
76          //// Activate more than once
77          support.fireServiceActivated(null, ADDRESS, null, null);
78          //// Deactivate
79          support.fireServiceDeactivated(null, ADDRESS, null, null);
80          //// Deactivate more than once
81          support.fireServiceDeactivated(null, ADDRESS, null, null);
82  
83          listenerControl.verify();
84  
85          Assert.assertEquals(0, support.getManagedServiceAddresses().size());
86          Assert.assertFalse(support.getManagedServiceAddresses().contains(
87                  ADDRESS));
88      }
89  
90      public void testSessionLifecycle() throws Exception {
91          IoServiceListenerSupport support = new IoServiceListenerSupport();
92  
93          TestSession session = new TestSession(ADDRESS);
94  
95          MockControl chainControl = MockControl
96                  .createStrictControl(IoFilterChain.class);
97          IoFilterChain chain = (IoFilterChain) chainControl.getMock();
98          session.setFilterChain(chain);
99  
100         MockControl listenerControl = MockControl
101                 .createStrictControl(IoServiceListener.class);
102         IoServiceListener listener = (IoServiceListener) listenerControl
103                 .getMock();
104 
105         // Test creation
106         listener.sessionCreated(session);
107         chain.fireSessionCreated(session);
108         chain.fireSessionOpened(session);
109 
110         listenerControl.replay();
111         chainControl.replay();
112 
113         support.add(listener);
114         support.fireSessionCreated(session);
115 
116         listenerControl.verify();
117         chainControl.verify();
118 
119         Assert.assertEquals(1, support.getManagedSessions(ADDRESS).size());
120         Assert
121                 .assertTrue(support.getManagedSessions(ADDRESS).contains(
122                         session));
123 
124         // Test destruction & other side effects
125         listenerControl.reset();
126         chainControl.reset();
127         chain.fireSessionClosed(session);
128         listener.sessionDestroyed(session);
129 
130         listenerControl.replay();
131         //// Activate more than once
132         support.fireSessionCreated(session);
133         //// Deactivate
134         support.fireSessionDestroyed(session);
135         //// Deactivate more than once
136         support.fireSessionDestroyed(session);
137 
138         listenerControl.verify();
139 
140         Assert.assertFalse(session.isClosing());
141         Assert.assertEquals(0, support.getManagedSessions(ADDRESS).size());
142         Assert.assertFalse(support.getManagedSessions(ADDRESS)
143                 .contains(session));
144     }
145 
146     public void testDisconnectOnUnbind() throws Exception {
147         final IoServiceListenerSupport support = new IoServiceListenerSupport();
148 
149         MockControl acceptorControl = MockControl
150                 .createStrictControl(IoAcceptor.class);
151         IoAcceptor acceptor = (IoAcceptor) acceptorControl.getMock();
152 
153         final TestSession session = new TestSession(acceptor, ADDRESS);
154 
155         MockControl configControl = MockControl
156                 .createStrictControl(IoAcceptorConfig.class);
157         IoAcceptorConfig config = (IoAcceptorConfig) configControl.getMock();
158 
159         MockControl chainControl = MockControl
160                 .createStrictControl(IoFilterChain.class);
161         IoFilterChain chain = (IoFilterChain) chainControl.getMock();
162         session.setFilterChain(chain);
163 
164         MockControl listenerControl = MockControl
165                 .createStrictControl(IoServiceListener.class);
166         IoServiceListener listener = (IoServiceListener) listenerControl
167                 .getMock();
168 
169         // Activate a service and create a session.
170         listener.serviceActivated(acceptor, ADDRESS, null, config);
171         listener.sessionCreated(session);
172         chain.fireSessionCreated(session);
173         chain.fireSessionOpened(session);
174 
175         listenerControl.replay();
176         chainControl.replay();
177 
178         support.add(listener);
179         support.fireServiceActivated(acceptor, ADDRESS, null, config);
180         support.fireSessionCreated(session);
181 
182         listenerControl.verify();
183         chainControl.verify();
184 
185         // Deactivate a service and make sure the session is closed & destroyed.
186         listenerControl.reset();
187         chainControl.reset();
188 
189         listener.serviceDeactivated(acceptor, ADDRESS, null, config);
190         configControl.expectAndReturn(config.isDisconnectOnUnbind(), true);
191         listener.sessionDestroyed(session);
192         chain.fireSessionClosed(session);
193 
194         listenerControl.replay();
195         configControl.replay();
196         chainControl.replay();
197 
198         new Thread() {
199             // Emulate I/O service
200             @Override
201             public void run() {
202                 try {
203                     Thread.sleep(500);
204                 } catch (InterruptedException e) {
205                     //noinspection CallToPrintStackTrace
206                     e.printStackTrace();
207                 }
208                 support.fireSessionDestroyed(session);
209             }
210         }.start();
211 
212         support.fireServiceDeactivated(acceptor, ADDRESS, null, config);
213 
214         Thread.sleep(1000);
215 
216         listenerControl.verify();
217         configControl.verify();
218         chainControl.verify();
219 
220         Assert.assertTrue(session.isClosing());
221         Assert.assertEquals(0, support.getManagedSessions(ADDRESS).size());
222         Assert.assertFalse(support.getManagedSessions(ADDRESS)
223                 .contains(session));
224     }
225 
226     public void testConnectorActivation() throws Exception {
227         IoServiceListenerSupport support = new IoServiceListenerSupport();
228 
229         MockControl connectorControl = MockControl
230                 .createStrictControl(IoConnector.class);
231         IoConnector connector = (IoConnector) connectorControl.getMock();
232 
233         final TestSession session = new TestSession(connector, ADDRESS);
234 
235         MockControl chainControl = MockControl
236                 .createStrictControl(IoFilterChain.class);
237         IoFilterChain chain = (IoFilterChain) chainControl.getMock();
238         session.setFilterChain(chain);
239 
240         MockControl listenerControl = MockControl
241                 .createStrictControl(IoServiceListener.class);
242         IoServiceListener listener = (IoServiceListener) listenerControl
243                 .getMock();
244 
245         // Creating a session should activate a service automatically.
246         listener.serviceActivated(connector, ADDRESS, null, null);
247         listener.sessionCreated(session);
248         chain.fireSessionCreated(session);
249         chain.fireSessionOpened(session);
250 
251         listenerControl.replay();
252         chainControl.replay();
253 
254         support.add(listener);
255         support.fireSessionCreated(session);
256 
257         listenerControl.verify();
258         chainControl.verify();
259 
260         // Destroying a session should deactivate a service automatically.
261         listenerControl.reset();
262         chainControl.reset();
263         listener.sessionDestroyed(session);
264         chain.fireSessionClosed(session);
265         listener.serviceDeactivated(connector, ADDRESS, null, null);
266 
267         listenerControl.replay();
268         chainControl.replay();
269 
270         support.fireSessionDestroyed(session);
271 
272         listenerControl.verify();
273         chainControl.verify();
274 
275         Assert.assertEquals(0, support.getManagedSessions(ADDRESS).size());
276         Assert.assertFalse(support.getManagedSessions(ADDRESS)
277                 .contains(session));
278     }
279 
280     private static class TestSession extends BaseIoSession {
281         private final IoService service;
282 
283         private final SocketAddress serviceAddress;
284 
285         private IoFilterChain filterChain;
286 
287         TestSession(SocketAddress serviceAddress) {
288             this(null, serviceAddress);
289         }
290 
291         TestSession(IoService service, SocketAddress serviceAddress) {
292             this.service = service;
293             this.serviceAddress = serviceAddress;
294         }
295 
296         @Override
297         protected void updateTrafficMask() {
298         }
299 
300         public IoSessionConfig getConfig() {
301             return null;
302         }
303 
304         public IoFilterChain getFilterChain() {
305             return filterChain;
306         }
307 
308         public void setFilterChain(IoFilterChain filterChain) {
309             this.filterChain = filterChain;
310         }
311 
312         public IoHandler getHandler() {
313             return null;
314         }
315 
316         public SocketAddress getLocalAddress() {
317             return null;
318         }
319 
320         public SocketAddress getRemoteAddress() {
321             return null;
322         }
323 
324         public int getScheduledWriteBytes() {
325             return 0;
326         }
327 
328         public int getScheduledWriteRequests() {
329             return 0;
330         }
331 
332         public IoService getService() {
333             return service;
334         }
335 
336         public SocketAddress getServiceAddress() {
337             return serviceAddress;
338         }
339 
340         public IoServiceConfig getServiceConfig() {
341             return null;
342         }
343 
344         public TransportType getTransportType() {
345             return null;
346         }
347     }
348 }