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.transport.socket.nio;
021
022import static org.junit.Assert.assertEquals;
023
024import java.net.InetSocketAddress;
025import java.net.PortUnreachableException;
026
027import org.apache.mina.core.buffer.IoBuffer;
028import org.apache.mina.core.future.ConnectFuture;
029import org.apache.mina.core.service.IoConnector;
030import org.apache.mina.core.service.IoHandlerAdapter;
031import org.apache.mina.core.session.IoSession;
032import org.apache.mina.transport.socket.DatagramSessionConfig;
033import org.apache.mina.util.AvailablePortFinder;
034import org.junit.Test;
035
036/**
037 * Tests {@link DatagramSessionConfig#setCloseOnPortUnreachable(boolean)}.
038 *
039 * @author <a href="http://mina.apache.org">Apache MINA Project</a>
040 */
041public class DatagramPortUnreachableTest {
042
043    Object mutex = new Object();
044
045    private void runTest(boolean closeOnPortUnreachable) throws Exception {
046        IoConnector connector = new NioDatagramConnector();
047        connector.setHandler(new IoHandlerAdapter() {
048
049            @Override
050            public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
051                if (cause instanceof PortUnreachableException) {
052                    synchronized (mutex) {
053                        mutex.notify();
054                    }
055                }
056            }
057
058        });
059        ConnectFuture future = connector.connect(new InetSocketAddress("localhost", AvailablePortFinder
060                .getNextAvailable(20000)));
061        future.awaitUninterruptibly();
062        IoSession session = future.getSession();
063
064        DatagramSessionConfig cfg = ((DatagramSessionConfig) session.getConfig());
065        cfg.setUseReadOperation(true);
066        cfg.setCloseOnPortUnreachable(closeOnPortUnreachable);
067
068        synchronized (mutex) {
069            session.write(IoBuffer.allocate(1)).awaitUninterruptibly().isWritten();
070            session.read();
071            mutex.wait();
072        }
073
074        Thread.sleep(500);
075
076        assertEquals(closeOnPortUnreachable, session.isClosing());
077        connector.dispose();
078    }
079
080    @Test
081    public void testPortUnreachableClosesSession() throws Exception {
082        // session should be closing
083        runTest(true);
084    }
085
086    @Test
087    public void testNormal() throws Exception {
088        // test that session is not closed on port unreachable exception
089        runTest(false);
090    }
091}