X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=pcep%2Fimpl%2Fsrc%2Ftest%2Fjava%2Forg%2Fopendaylight%2Fprotocol%2Fpcep%2Fimpl%2FPCEPDispatcherImplTest.java;h=2be37f019b3abafdf445d8d4ebd7df633c4a10a9;hb=5ddbbec3193f9dfcbb980379a5454b70fe4847ea;hp=fc52bcdee92d43381c077ab868a0a7b15d608427;hpb=4405ee3abce8391fa32188be6c50ee5d20ba4b32;p=bgpcep.git diff --git a/pcep/impl/src/test/java/org/opendaylight/protocol/pcep/impl/PCEPDispatcherImplTest.java b/pcep/impl/src/test/java/org/opendaylight/protocol/pcep/impl/PCEPDispatcherImplTest.java old mode 100644 new mode 100755 index fc52bcdee9..2be37f019b --- a/pcep/impl/src/test/java/org/opendaylight/protocol/pcep/impl/PCEPDispatcherImplTest.java +++ b/pcep/impl/src/test/java/org/opendaylight/protocol/pcep/impl/PCEPDispatcherImplTest.java @@ -8,134 +8,235 @@ package org.opendaylight.protocol.pcep.impl; -import com.google.common.base.Preconditions; +import static java.util.Objects.requireNonNull; +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.any; +import static org.opendaylight.protocol.util.CheckUtil.waitFutureSuccess; + +import io.netty.bootstrap.Bootstrap; import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; +import io.netty.channel.epoll.Epoll; +import io.netty.channel.epoll.EpollEventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; -import io.netty.util.concurrent.DefaultPromise; +import io.netty.channel.socket.nio.NioSocketChannel; +import io.netty.util.concurrent.EventExecutor; import io.netty.util.concurrent.Future; import io.netty.util.concurrent.GlobalEventExecutor; -import io.netty.util.concurrent.Promise; import java.net.InetSocketAddress; +import java.nio.channels.Channel; +import java.util.ArrayList; +import java.util.List; import java.util.concurrent.ExecutionException; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.opendaylight.protocol.framework.AbstractDispatcher; -import org.opendaylight.protocol.framework.NeverReconnectStrategy; -import org.opendaylight.protocol.framework.ProtocolSession; -import org.opendaylight.protocol.framework.ReconnectStrategy; -import org.opendaylight.protocol.framework.SessionListener; -import org.opendaylight.protocol.framework.SessionListenerFactory; -import org.opendaylight.protocol.framework.SessionNegotiatorFactory; -import org.opendaylight.protocol.pcep.PCEPSessionListener; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.opendaylight.protocol.concepts.KeyMapping; +import org.opendaylight.protocol.pcep.PCEPCapability; +import org.opendaylight.protocol.pcep.PCEPSession; +import org.opendaylight.protocol.pcep.PCEPSessionListenerFactory; +import org.opendaylight.protocol.pcep.PCEPSessionNegotiatorFactory; +import org.opendaylight.protocol.pcep.PCEPSessionProposalFactory; import org.opendaylight.protocol.pcep.spi.MessageRegistry; import org.opendaylight.protocol.pcep.spi.pojo.ServiceLoaderPCEPExtensionProviderContext; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Message; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.object.Open; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.object.OpenBuilder; +import org.opendaylight.protocol.util.InetSocketAddressUtil; public class PCEPDispatcherImplTest { - - private static final int PORT = 4189; - private static final InetSocketAddress CLIENT1_ADDRESS = new InetSocketAddress("127.0.0.10", PORT); - private static final InetSocketAddress CLIENT2_ADDRESS = new InetSocketAddress("127.0.0.11", PORT); private static final short DEAD_TIMER = 120; private static final short KEEP_ALIVE = 30; + private static final int RETRY_TIMER = 0; + private static final int CONNECT_TIMEOUT = 500; private PCEPDispatcherImpl dispatcher; + private PCEPDispatcherImpl disp2Spy; + + @Mock + private Channel mockChannel; - private PCCMock pccMock; + private PCCMock pccMock; @Before public void setUp() { - final Open open = new OpenBuilder().setSessionId((short) 0).setDeadTimer(DEAD_TIMER).setKeepalive(KEEP_ALIVE) - .build(); - final SessionNegotiatorFactory snf = new DefaultPCEPSessionNegotiatorFactory( - open, 0); - final EventLoopGroup eventLoopGroup = new NioEventLoopGroup(); + MockitoAnnotations.initMocks(this); + final List capList = new ArrayList<>(); + final PCEPSessionProposalFactory sessionProposal = new BasePCEPSessionProposalFactory(DEAD_TIMER, KEEP_ALIVE, + capList); + final EventLoopGroup eventLoopGroup; + if (Epoll.isAvailable()) { + eventLoopGroup = new EpollEventLoopGroup(); + } else { + eventLoopGroup = new NioEventLoopGroup(); + } final MessageRegistry msgReg = ServiceLoaderPCEPExtensionProviderContext.getSingletonInstance() - .getMessageHandlerRegistry(); - this.dispatcher = new PCEPDispatcherImpl(msgReg, snf, eventLoopGroup, eventLoopGroup); - this.pccMock = new PCCMock<>(snf, new PCEPHandlerFactory(msgReg), new DefaultPromise( - GlobalEventExecutor.INSTANCE)); + .getMessageHandlerRegistry(); + this.dispatcher = new PCEPDispatcherImpl(msgReg, new DefaultPCEPSessionNegotiatorFactory(sessionProposal, 0), + eventLoopGroup, eventLoopGroup); + + Mockito.doReturn("mockChannel").when(this.mockChannel).toString(); + final PCEPDispatcherImpl dispatcher2 = new PCEPDispatcherImpl(msgReg, + new DefaultPCEPSessionNegotiatorFactory(sessionProposal, 0), + eventLoopGroup, eventLoopGroup); + this.disp2Spy = Mockito.spy(dispatcher2); + + this.pccMock = new PCCMock(new DefaultPCEPSessionNegotiatorFactory(sessionProposal, 0), + new PCEPHandlerFactory(msgReg)); } @Test public void testCreateClientServer() throws InterruptedException, ExecutionException { - final ChannelFuture futureChannel = this.dispatcher.createServer(new InetSocketAddress("0.0.0.0", PORT), - new SessionListenerFactory() { - @Override - public PCEPSessionListener getSessionListener() { - return new SimpleSessionListener(); - } - }); - final PCEPSessionImpl session1 = pccMock.createClient(CLIENT1_ADDRESS, - new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE, 500), - new SessionListenerFactory() { - @Override - public PCEPSessionListener getSessionListener() { - return new SimpleSessionListener(); - } - }).get(); - - final PCEPSessionImpl session2 = pccMock.createClient(CLIENT2_ADDRESS, - new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE, 500), - new SessionListenerFactory() { - @Override - public PCEPSessionListener getSessionListener() { - return new SimpleSessionListener(); - } - }).get(); + final int port = InetSocketAddressUtil.getRandomPort(); + final InetSocketAddress serverAddr = new InetSocketAddress("0.0.0.0", port); + final InetSocketAddress clientAddr1 = InetSocketAddressUtil.getRandomLoopbackInetSocketAddress(port); + final InetSocketAddress clientAddr2 = InetSocketAddressUtil.getRandomLoopbackInetSocketAddress(port); + final ChannelFuture futureChannel = this.dispatcher.createServer(serverAddr, + SimpleSessionListener::new, null); + waitFutureSuccess(futureChannel); + final PCEPSessionImpl session1 = (PCEPSessionImpl) this.pccMock.createClient(clientAddr1, + RETRY_TIMER, CONNECT_TIMEOUT, SimpleSessionListener::new).get(); + + final PCEPSessionImpl session2 = (PCEPSessionImpl) this.pccMock.createClient(clientAddr2, + RETRY_TIMER, CONNECT_TIMEOUT, SimpleSessionListener::new).get(); Assert.assertTrue(futureChannel.channel().isActive()); - Assert.assertEquals(CLIENT1_ADDRESS.getAddress().getHostAddress(), session1.getPeerAddress()); - Assert.assertEquals(DEAD_TIMER, session1.getDeadTimerValue().shortValue()); - Assert.assertEquals(KEEP_ALIVE, session1.getKeepAliveTimerValue().shortValue()); + assertEquals(clientAddr1.getAddress().getHostAddress(), session1.getPeerPref().getIpAddress()); + assertEquals(DEAD_TIMER, session1.getDeadTimerValue().shortValue()); + assertEquals(KEEP_ALIVE, session1.getKeepAliveTimerValue().shortValue()); - Assert.assertEquals(CLIENT2_ADDRESS.getAddress().getHostAddress(), session2.getPeerAddress()); - Assert.assertEquals(DEAD_TIMER, session2.getDeadTimerValue().shortValue()); - Assert.assertEquals(KEEP_ALIVE, session2.getKeepAliveTimerValue().shortValue()); + assertEquals(clientAddr2.getAddress().getHostAddress(), session2.getPeerPref().getIpAddress()); + assertEquals(DEAD_TIMER, session2.getDeadTimerValue().shortValue()); + assertEquals(KEEP_ALIVE, session2.getKeepAliveTimerValue().shortValue()); session1.close(); session2.close(); Assert.assertTrue(futureChannel.channel().isActive()); + } + + @Test + public void testCreateDuplicateClient() throws InterruptedException, ExecutionException { + final int port = InetSocketAddressUtil.getRandomPort(); + final InetSocketAddress serverAddr = new InetSocketAddress("0.0.0.0", port); + final InetSocketAddress clientAddr = InetSocketAddressUtil.getRandomLoopbackInetSocketAddress(port); + waitFutureSuccess(this.dispatcher.createServer(serverAddr, SimpleSessionListener::new, null)); + final Future futureClient = this.pccMock.createClient(clientAddr, RETRY_TIMER, CONNECT_TIMEOUT, + SimpleSessionListener::new); + waitFutureSuccess(futureClient); + final PCEPSessionImpl session1 = (PCEPSessionImpl) futureClient.get(); + + try { + this.pccMock.createClient(clientAddr, RETRY_TIMER, CONNECT_TIMEOUT, + SimpleSessionListener::new).get(); + Assert.fail(); + } catch (final ExecutionException e) { + Assert.assertTrue(e.getMessage().contains("A conflicting session for address")); + } finally { + session1.close(); + } + } - futureChannel.channel().close(); + @Test + public void testReconectClient() throws InterruptedException, ExecutionException { + final int port = InetSocketAddressUtil.getRandomPort(); + final InetSocketAddress clientAddr = InetSocketAddressUtil.getRandomLoopbackInetSocketAddress(port); + waitFutureSuccess(this.dispatcher.createServer(new InetSocketAddress("0.0.0.0", port), + SimpleSessionListener::new, null)); + final PCEPSessionImpl session1 = (PCEPSessionImpl) this.pccMock.createClient(clientAddr, + RETRY_TIMER, CONNECT_TIMEOUT, SimpleSessionListener::new).get(); + + assertEquals(clientAddr.getAddress(), session1.getRemoteAddress()); + assertEquals(DEAD_TIMER, session1.getDeadTimerValue().shortValue()); + assertEquals(KEEP_ALIVE, session1.getKeepAliveTimerValue().shortValue()); + waitFutureSuccess(session1.closeChannel()); + + final PCEPSessionImpl session2 = (PCEPSessionImpl) this.pccMock.createClient(clientAddr, + RETRY_TIMER, CONNECT_TIMEOUT, SimpleSessionListener::new).get(); + + assertEquals(clientAddr.getAddress(), session1.getRemoteAddress()); + assertEquals(DEAD_TIMER, session2.getDeadTimerValue().shortValue()); + assertEquals(KEEP_ALIVE, session2.getKeepAliveTimerValue().shortValue()); + + session2.close(); + } + + @Test + public void testCustomizeBootstrap() { + final int port = InetSocketAddressUtil.getRandomPort(); + final InetSocketAddress clientAddr1 = InetSocketAddressUtil.getRandomLoopbackInetSocketAddress(port); + final InetSocketAddress clientAddr2 = InetSocketAddressUtil.getRandomLoopbackInetSocketAddress(port); + final KeyMapping keys = KeyMapping.getKeyMapping(clientAddr1.getAddress(), "CLIENT1_ADDRESS"); + keys.put(clientAddr2.getAddress(), "CLIENT2_ADDRESS".getBytes()); + + final ChannelFuture futureChannel = this.disp2Spy.createServer(new InetSocketAddress("0.0.0.0", port), + SimpleSessionListener::new, null); + waitFutureSuccess(futureChannel); + Mockito.verify(this.disp2Spy).createServerBootstrap(any(PCEPDispatcherImpl.ChannelPipelineInitializer.class)); } @After public void tearDown() { this.dispatcher.close(); + this.disp2Spy.close(); } - private static class PCCMock, L extends SessionListener> extends - AbstractDispatcher { - - private final SessionNegotiatorFactory negotiatorFactory; + private static class PCCMock { + private final PCEPSessionNegotiatorFactory negotiatorFactory; private final PCEPHandlerFactory factory; + private final EventExecutor executor; + private final EventLoopGroup workerGroup; + + PCCMock(final PCEPSessionNegotiatorFactory negotiatorFactory, final PCEPHandlerFactory factory) { + this.workerGroup = requireNonNull(new NioEventLoopGroup()); + this.negotiatorFactory = requireNonNull(negotiatorFactory); + this.factory = requireNonNull(factory); + this.executor = requireNonNull(GlobalEventExecutor.INSTANCE); + } - public PCCMock(final SessionNegotiatorFactory negotiatorFactory, final PCEPHandlerFactory factory, - final DefaultPromise defaultPromise) { - super(GlobalEventExecutor.INSTANCE, new NioEventLoopGroup(), new NioEventLoopGroup()); - this.negotiatorFactory = Preconditions.checkNotNull(negotiatorFactory); - this.factory = Preconditions.checkNotNull(factory); + Future createClient(final InetSocketAddress address, final int retryTimer, + final int connectTimeout, final PCEPSessionListenerFactory listenerFactory) { + return createClient(address, retryTimer, connectTimeout, (ch, promise) -> { + ch.pipeline().addLast(this.factory.getDecoders()); + ch.pipeline().addLast("negotiator", this.negotiatorFactory.getSessionNegotiator(listenerFactory, ch, + promise, null)); + ch.pipeline().addLast(this.factory.getEncoders()); + }); } - public Future createClient(final InetSocketAddress address, final ReconnectStrategy strategy, - final SessionListenerFactory listenerFactory) { - return super.createClient(address, strategy, new PipelineInitializer() { + Future createClient(final InetSocketAddress address, final int retryTimer, + final int connectTimeout, final PCEPDispatcherImpl.ChannelPipelineInitializer initializer) { + final Bootstrap b = new Bootstrap(); + final PCEPProtocolSessionPromise p = new PCEPProtocolSessionPromise<>(this.executor, address, retryTimer, + connectTimeout, b); + b.option(ChannelOption.SO_KEEPALIVE, Boolean.TRUE).handler(new ChannelInitializer() { @Override - public void initializeChannel(final SocketChannel ch, final Promise promise) { - ch.pipeline().addLast(PCCMock.this.factory.getDecoders()); - ch.pipeline().addLast("negotiator", - PCCMock.this.negotiatorFactory.getSessionNegotiator(listenerFactory, ch, promise)); - ch.pipeline().addLast(PCCMock.this.factory.getEncoders()); + protected void initChannel(final SocketChannel ch) { + initializer.initializeChannel(ch, p); } }); + + setWorkerGroup(b); + setChannelFactory(b); + p.connect(); + return p; + } + + private static void setChannelFactory(final Bootstrap b) { + try { + b.channel(NioSocketChannel.class); + } catch (final IllegalStateException ignored) { + } + } + + private void setWorkerGroup(final Bootstrap b) { + if (b.group() == null) { + b.group(this.workerGroup); + } } } -} +} \ No newline at end of file