2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.protocol.pcep.impl;
11 import com.google.common.base.Preconditions;
12 import io.netty.bootstrap.Bootstrap;
13 import io.netty.channel.ChannelFuture;
14 import io.netty.channel.ChannelInitializer;
15 import io.netty.channel.ChannelOption;
16 import io.netty.channel.EventLoopGroup;
17 import io.netty.channel.epoll.Epoll;
18 import io.netty.channel.epoll.EpollEventLoopGroup;
19 import io.netty.channel.nio.NioEventLoopGroup;
20 import io.netty.channel.socket.SocketChannel;
21 import io.netty.channel.socket.nio.NioSocketChannel;
22 import io.netty.util.concurrent.EventExecutor;
23 import io.netty.util.concurrent.Future;
24 import io.netty.util.concurrent.GlobalEventExecutor;
25 import java.net.InetSocketAddress;
26 import java.nio.channels.Channel;
27 import java.util.ArrayList;
28 import java.util.List;
29 import java.util.concurrent.ExecutionException;
30 import org.junit.After;
31 import org.junit.Assert;
32 import org.junit.Before;
33 import org.junit.Test;
34 import org.mockito.Mock;
35 import org.mockito.Mockito;
36 import org.mockito.MockitoAnnotations;
37 import org.opendaylight.protocol.concepts.KeyMapping;
38 import org.opendaylight.protocol.pcep.PCEPCapability;
39 import org.opendaylight.protocol.pcep.PCEPSession;
40 import org.opendaylight.protocol.pcep.PCEPSessionListenerFactory;
41 import org.opendaylight.protocol.pcep.PCEPSessionNegotiatorFactory;
42 import org.opendaylight.protocol.pcep.PCEPSessionProposalFactory;
43 import org.opendaylight.protocol.pcep.impl.PCEPDispatcherImpl.ChannelPipelineInitializer;
44 import org.opendaylight.protocol.pcep.spi.MessageRegistry;
45 import org.opendaylight.protocol.pcep.spi.pojo.ServiceLoaderPCEPExtensionProviderContext;
46 import org.opendaylight.protocol.util.InetSocketAddressUtil;
48 public class PCEPDispatcherImplTest {
49 private static final short DEAD_TIMER = 120;
50 private static final short KEEP_ALIVE = 30;
51 private static final int RETRY_TIMER = 0;
52 private static final int CONNECT_TIMEOUT = 500;
54 private PCEPDispatcherImpl dispatcher;
55 private PCEPDispatcherImpl disp2Spy;
57 @Mock private Channel mockChannel;
59 private PCCMock pccMock;
63 MockitoAnnotations.initMocks(this);
64 final List<PCEPCapability> capList = new ArrayList<>();
65 final PCEPSessionProposalFactory sessionProposal = new BasePCEPSessionProposalFactory(DEAD_TIMER, KEEP_ALIVE, capList);
66 final EventLoopGroup eventLoopGroup;
67 if (Epoll.isAvailable()) {
68 eventLoopGroup = new EpollEventLoopGroup();
70 eventLoopGroup = new NioEventLoopGroup();
72 final MessageRegistry msgReg = ServiceLoaderPCEPExtensionProviderContext.getSingletonInstance()
73 .getMessageHandlerRegistry();
74 this.dispatcher = new PCEPDispatcherImpl(msgReg, new DefaultPCEPSessionNegotiatorFactory(sessionProposal, 0),
75 eventLoopGroup, eventLoopGroup);
77 Mockito.doReturn("mockChannel").when(this.mockChannel).toString();
78 final PCEPDispatcherImpl dispatcher2 = new PCEPDispatcherImpl(msgReg, new DefaultPCEPSessionNegotiatorFactory(sessionProposal, 0), eventLoopGroup, eventLoopGroup);
79 this.disp2Spy = Mockito.spy(dispatcher2);
81 this.pccMock = new PCCMock(new DefaultPCEPSessionNegotiatorFactory(sessionProposal, 0),
82 new PCEPHandlerFactory(msgReg));
86 public void testCreateClientServer() throws InterruptedException, ExecutionException {
87 final int port = InetSocketAddressUtil.getRandomPort();
88 final InetSocketAddress serverAddr = new InetSocketAddress("0.0.0.0", port);
89 final InetSocketAddress clientAddr1 = InetSocketAddressUtil.getRandomLoopbackInetSocketAddress(port);
90 final InetSocketAddress clientAddr2 = InetSocketAddressUtil.getRandomLoopbackInetSocketAddress(port);
91 final ChannelFuture futureChannel = this.dispatcher.createServer(serverAddr,
92 () -> new SimpleSessionListener(), null);
93 final PCEPSessionImpl session1 = (PCEPSessionImpl) this.pccMock.createClient(clientAddr1,
94 RETRY_TIMER, CONNECT_TIMEOUT,
95 () -> new SimpleSessionListener()).get();
97 final PCEPSessionImpl session2 = (PCEPSessionImpl) this.pccMock.createClient(clientAddr2,
98 RETRY_TIMER, CONNECT_TIMEOUT,
99 () -> new SimpleSessionListener()).get();
101 Assert.assertTrue(futureChannel.channel().isActive());
102 Assert.assertEquals(clientAddr1.getAddress().getHostAddress(), session1.getPeerPref().getIpAddress());
103 Assert.assertEquals(DEAD_TIMER, session1.getDeadTimerValue().shortValue());
104 Assert.assertEquals(KEEP_ALIVE, session1.getKeepAliveTimerValue().shortValue());
106 Assert.assertEquals(clientAddr2.getAddress().getHostAddress(), session2.getPeerPref().getIpAddress());
107 Assert.assertEquals(DEAD_TIMER, session2.getDeadTimerValue().shortValue());
108 Assert.assertEquals(KEEP_ALIVE, session2.getKeepAliveTimerValue().shortValue());
112 Assert.assertTrue(futureChannel.channel().isActive());
116 public void testCreateDuplicateClient() throws InterruptedException, ExecutionException {
117 final int port = InetSocketAddressUtil.getRandomPort();
118 final InetSocketAddress serverAddr = new InetSocketAddress("0.0.0.0", port);
119 final InetSocketAddress clientAddr = InetSocketAddressUtil.getRandomLoopbackInetSocketAddress(port);
120 this.dispatcher.createServer(serverAddr,
121 () -> new SimpleSessionListener(), null);
122 final PCEPSessionImpl session1 = (PCEPSessionImpl) this.pccMock.createClient(clientAddr,
123 RETRY_TIMER, CONNECT_TIMEOUT,
124 () -> new SimpleSessionListener()).get();
127 this.pccMock.createClient(clientAddr,
128 RETRY_TIMER, CONNECT_TIMEOUT,
129 () -> new SimpleSessionListener()).get();
131 } catch (final ExecutionException e) {
132 Assert.assertTrue(e.getMessage().contains("A conflicting session for address"));
139 public void testReconectClient() throws InterruptedException, ExecutionException {
140 final int port = InetSocketAddressUtil.getRandomPort();
141 final InetSocketAddress clientAddr = InetSocketAddressUtil.getRandomLoopbackInetSocketAddress(port);
142 this.dispatcher.createServer(new InetSocketAddress("0.0.0.0", port),
143 () -> new SimpleSessionListener(), null);
144 final PCEPSessionImpl session1 = (PCEPSessionImpl) this.pccMock.createClient(clientAddr,
145 RETRY_TIMER, CONNECT_TIMEOUT,
146 () -> new SimpleSessionListener()).get();
148 Assert.assertEquals(clientAddr.getAddress(), session1.getRemoteAddress());
149 Assert.assertEquals(DEAD_TIMER, session1.getDeadTimerValue().shortValue());
150 Assert.assertEquals(KEEP_ALIVE, session1.getKeepAliveTimerValue().shortValue());
153 final PCEPSessionImpl session2 = (PCEPSessionImpl) this.pccMock.createClient(clientAddr,
154 RETRY_TIMER, CONNECT_TIMEOUT,
155 () -> new SimpleSessionListener()).get();
157 Assert.assertEquals(clientAddr.getAddress(), session1.getRemoteAddress());
158 Assert.assertEquals(DEAD_TIMER, session2.getDeadTimerValue().shortValue());
159 Assert.assertEquals(KEEP_ALIVE, session2.getKeepAliveTimerValue().shortValue());
165 public void testCustomizeBootstrap() {
166 final int port = InetSocketAddressUtil.getRandomPort();
167 final InetSocketAddress clientAddr1 = InetSocketAddressUtil.getRandomLoopbackInetSocketAddress(port);
168 final InetSocketAddress clientAddr2 = InetSocketAddressUtil.getRandomLoopbackInetSocketAddress(port);
169 final KeyMapping keys = KeyMapping.getKeyMapping(clientAddr1.getAddress(), new String("CLIENT1_ADDRESS"));
170 keys.put(clientAddr2.getAddress(), new String("CLIENT2_ADDRESS").getBytes() );
172 final ChannelFuture futureChannel = this.disp2Spy.createServer(new InetSocketAddress("0.0.0.0", port),
173 () -> new SimpleSessionListener(), null);
174 Mockito.verify(this.disp2Spy).createServerBootstrap(Mockito.any(PCEPDispatcherImpl.ChannelPipelineInitializer.class));
178 public void tearDown() {
179 this.dispatcher.close();
180 this.disp2Spy.close();
183 private static class PCCMock {
185 private final PCEPSessionNegotiatorFactory negotiatorFactory;
186 private final PCEPHandlerFactory factory;
187 private final EventExecutor executor;
188 private final EventLoopGroup workerGroup;
190 public PCCMock(final PCEPSessionNegotiatorFactory negotiatorFactory, final PCEPHandlerFactory factory) {
191 this.workerGroup = Preconditions.checkNotNull(new NioEventLoopGroup());
192 this.negotiatorFactory = Preconditions.checkNotNull(negotiatorFactory);
193 this.factory = Preconditions.checkNotNull(factory);
194 this.executor = Preconditions.checkNotNull(GlobalEventExecutor.INSTANCE);
197 public Future<PCEPSession> createClient(final InetSocketAddress address, final int retryTimer,
198 final int connectTimeout, final PCEPSessionListenerFactory listenerFactory) {
199 return createClient(address, retryTimer, connectTimeout, (ChannelPipelineInitializer) (ch, promise) -> {
200 ch.pipeline().addLast(PCCMock.this.factory.getDecoders());
201 ch.pipeline().addLast("negotiator", PCCMock.this.negotiatorFactory.getSessionNegotiator(listenerFactory, ch, promise, null));
202 ch.pipeline().addLast(PCCMock.this.factory.getEncoders());
206 Future<PCEPSession> createClient(final InetSocketAddress address, final int retryTimer, final int connectTimeout,
207 final PCEPDispatcherImpl.ChannelPipelineInitializer initializer) {
208 final Bootstrap b = new Bootstrap();
209 final PCEPProtocolSessionPromise p = new PCEPProtocolSessionPromise(this.executor, address, retryTimer, connectTimeout, b);
210 (b.option(ChannelOption.SO_KEEPALIVE, Boolean.valueOf(true))).handler(new ChannelInitializer<SocketChannel>() {
212 protected void initChannel(final SocketChannel ch) {
213 initializer.initializeChannel(ch, p);
218 setChannelFactory(b);
223 private void setChannelFactory(final Bootstrap b) {
225 b.channel(NioSocketChannel.class);
226 } catch (final IllegalStateException ignored) {
231 private void setWorkerGroup(final Bootstrap b) {
232 if (b.group() == null) {
233 b.group(this.workerGroup);