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 static org.junit.Assert.assertEquals;
023import static org.junit.Assert.assertNull;
024import static org.junit.Assert.assertSame;
025import static org.junit.Assert.assertTrue;
026
027import java.net.InetSocketAddress;
028import java.net.SocketAddress;
029
030import org.apache.mina.core.service.IoAcceptor;
031import org.apache.mina.core.service.IoConnector;
032import org.apache.mina.core.service.IoHandler;
033import org.apache.mina.core.service.IoService;
034import org.apache.mina.core.service.IoServiceListener;
035import org.apache.mina.core.service.IoServiceListenerSupport;
036import org.apache.mina.core.session.DummySession;
037import org.easymock.EasyMock;
038import org.junit.Test;
039
040/**
041 * Tests {@link IoServiceListenerSupport}.
042 *
043 * @author <a href="http://mina.apache.org">Apache MINA Project</a>
044 */
045public class IoServiceListenerSupportTest {
046    private static final SocketAddress ADDRESS = new InetSocketAddress(8080);
047
048    private final IoService mockService = EasyMock.createMock(IoService.class);
049
050    @Test
051    public void testServiceLifecycle() throws Exception {
052        IoServiceListenerSupport support = new IoServiceListenerSupport(mockService);
053
054        IoServiceListener listener = EasyMock.createStrictMock(IoServiceListener.class);
055
056        // Test activation
057        listener.serviceActivated(mockService);
058
059        EasyMock.replay(listener);
060
061        support.add(listener);
062        support.fireServiceActivated();
063
064        EasyMock.verify(listener);
065
066        // Test deactivation & other side effects
067        EasyMock.reset(listener);
068        listener.serviceDeactivated(mockService);
069
070        EasyMock.replay(listener);
071        //// Activate more than once
072        support.fireServiceActivated();
073        //// Deactivate
074        support.fireServiceDeactivated();
075        //// Deactivate more than once
076        support.fireServiceDeactivated();
077
078        EasyMock.verify(listener);
079    }
080
081    @Test
082    public void testSessionLifecycle() throws Exception {
083        IoServiceListenerSupport support = new IoServiceListenerSupport(mockService);
084
085        DummySession session = new DummySession();
086        session.setService(mockService);
087        session.setLocalAddress(ADDRESS);
088
089        IoHandler handler = EasyMock.createStrictMock(IoHandler.class);
090        session.setHandler(handler);
091
092        IoServiceListener listener = EasyMock.createStrictMock(IoServiceListener.class);
093
094        // Test creation
095        listener.sessionCreated(session);
096        handler.sessionCreated(session);
097        handler.sessionOpened(session);
098
099        EasyMock.replay(listener);
100        EasyMock.replay(handler);
101
102        support.add(listener);
103        support.fireSessionCreated(session);
104
105        EasyMock.verify(listener);
106        EasyMock.verify(handler);
107
108        assertEquals(1, support.getManagedSessions().size());
109        assertSame(session, support.getManagedSessions().get(session.getId()));
110
111        // Test destruction & other side effects
112        EasyMock.reset(listener);
113        EasyMock.reset(handler);
114        handler.sessionClosed(session);
115        listener.sessionDestroyed(session);
116
117        EasyMock.replay(listener);
118        //// Activate more than once
119        support.fireSessionCreated(session);
120        //// Deactivate
121        support.fireSessionDestroyed(session);
122        //// Deactivate more than once
123        support.fireSessionDestroyed(session);
124
125        EasyMock.verify(listener);
126
127        assertTrue(session.isClosing());
128        assertEquals(0, support.getManagedSessions().size());
129        assertNull(support.getManagedSessions().get(session.getId()));
130    }
131
132    @Test
133    public void testDisconnectOnUnbind() throws Exception {
134        IoAcceptor acceptor = EasyMock.createStrictMock(IoAcceptor.class);
135
136        final IoServiceListenerSupport support = new IoServiceListenerSupport(acceptor);
137
138        final DummySession session = new DummySession();
139        session.setService(acceptor);
140        session.setLocalAddress(ADDRESS);
141
142        IoHandler handler = EasyMock.createStrictMock(IoHandler.class);
143        session.setHandler(handler);
144
145        final IoServiceListener listener = EasyMock.createStrictMock(IoServiceListener.class);
146
147        // Activate a service and create a session.
148        listener.serviceActivated(acceptor);
149        listener.sessionCreated(session);
150        handler.sessionCreated(session);
151        handler.sessionOpened(session);
152
153        EasyMock.replay(listener);
154        EasyMock.replay(handler);
155
156        support.add(listener);
157        support.fireServiceActivated();
158        support.fireSessionCreated(session);
159
160        EasyMock.verify(listener);
161        EasyMock.verify(handler);
162
163        // Deactivate a service and make sure the session is closed & destroyed.
164        EasyMock.reset(listener);
165        EasyMock.reset(handler);
166
167        listener.serviceDeactivated(acceptor);
168        EasyMock.expect(acceptor.isCloseOnDeactivation()).andReturn(true);
169        listener.sessionDestroyed(session);
170        handler.sessionClosed(session);
171
172        EasyMock.replay(listener);
173        EasyMock.replay(acceptor);
174        EasyMock.replay(handler);
175
176        new Thread() {
177            // Emulate I/O service
178            @Override
179            public void run() {
180                try {
181                    Thread.sleep(500);
182                } catch (InterruptedException e) {
183                    // e.printStackTrace();
184                }
185                // This synchronization block is a workaround for
186                // the visibility problem of simultaneous EasyMock
187                // state update. (not sure if it fixes the failing test yet.)
188                synchronized (listener) {
189                    support.fireSessionDestroyed(session);
190                }
191            }
192        }.start();
193        support.fireServiceDeactivated();
194
195        synchronized (listener) {
196            EasyMock.verify(listener);
197        }
198        EasyMock.verify(acceptor);
199        EasyMock.verify(handler);
200
201        assertTrue(session.isClosing());
202        assertEquals(0, support.getManagedSessions().size());
203        assertNull(support.getManagedSessions().get(session.getId()));
204    }
205
206    @Test
207    public void testConnectorActivation() throws Exception {
208        IoConnector connector = EasyMock.createStrictMock(IoConnector.class);
209
210        IoServiceListenerSupport support = new IoServiceListenerSupport(connector);
211
212        final DummySession session = new DummySession();
213        session.setService(connector);
214        session.setRemoteAddress(ADDRESS);
215
216        IoHandler handler = EasyMock.createStrictMock(IoHandler.class);
217        session.setHandler(handler);
218
219        IoServiceListener listener = EasyMock.createStrictMock(IoServiceListener.class);
220
221        // Creating a session should activate a service automatically.
222        listener.serviceActivated(connector);
223        listener.sessionCreated(session);
224        handler.sessionCreated(session);
225        handler.sessionOpened(session);
226
227        EasyMock.replay(listener);
228        EasyMock.replay(handler);
229
230        support.add(listener);
231        support.fireSessionCreated(session);
232
233        EasyMock.verify(listener);
234        EasyMock.verify(handler);
235
236        // Destroying a session should deactivate a service automatically.
237        EasyMock.reset(listener);
238        EasyMock.reset(handler);
239        listener.sessionDestroyed(session);
240        handler.sessionClosed(session);
241        listener.serviceDeactivated(connector);
242
243        EasyMock.replay(listener);
244        EasyMock.replay(handler);
245
246        support.fireSessionDestroyed(session);
247
248        EasyMock.verify(listener);
249        EasyMock.verify(handler);
250
251        assertEquals(0, support.getManagedSessions().size());
252        assertNull(support.getManagedSessions().get(session.getId()));
253    }
254}