BUG-5619 Enable maven parallel build for bgpcep I
[bgpcep.git] / pcep / impl / src / test / java / org / opendaylight / protocol / pcep / impl / PCEPDispatcherImplTest.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.protocol.pcep.impl;
10
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.DefaultPromise;
23 import io.netty.util.concurrent.EventExecutor;
24 import io.netty.util.concurrent.Future;
25 import io.netty.util.concurrent.GlobalEventExecutor;
26 import java.net.InetSocketAddress;
27 import java.nio.channels.Channel;
28 import java.util.ArrayList;
29 import java.util.List;
30 import java.util.concurrent.ExecutionException;
31 import org.junit.After;
32 import org.junit.Assert;
33 import org.junit.Before;
34 import org.junit.Test;
35 import org.mockito.Mock;
36 import org.mockito.Mockito;
37 import org.mockito.MockitoAnnotations;
38 import org.opendaylight.protocol.concepts.KeyMapping;
39 import org.opendaylight.protocol.pcep.PCEPCapability;
40 import org.opendaylight.protocol.pcep.PCEPSession;
41 import org.opendaylight.protocol.pcep.PCEPSessionListenerFactory;
42 import org.opendaylight.protocol.pcep.PCEPSessionNegotiatorFactory;
43 import org.opendaylight.protocol.pcep.PCEPSessionProposalFactory;
44 import org.opendaylight.protocol.pcep.impl.PCEPDispatcherImpl.ChannelPipelineInitializer;
45 import org.opendaylight.protocol.pcep.spi.MessageRegistry;
46 import org.opendaylight.protocol.pcep.spi.pojo.ServiceLoaderPCEPExtensionProviderContext;
47 import org.opendaylight.protocol.util.InetSocketAddressUtil;
48
49 public class PCEPDispatcherImplTest {
50     private static final short DEAD_TIMER = 120;
51     private static final short KEEP_ALIVE = 30;
52     private static final int RETRY_TIMER = 0;
53     private static final int CONNECT_TIMEOUT = 500;
54
55     private PCEPDispatcherImpl dispatcher;
56     private PCEPDispatcherImpl disp2Spy;
57
58     @Mock private Channel mockChannel;
59
60     private PCCMock pccMock;
61
62     @Before
63     public void setUp() {
64         MockitoAnnotations.initMocks(this);
65         final List<PCEPCapability> capList = new ArrayList<>();
66         final PCEPSessionProposalFactory sessionProposal = new BasePCEPSessionProposalFactory(DEAD_TIMER, KEEP_ALIVE, capList);
67         final EventLoopGroup eventLoopGroup;
68         if (Epoll.isAvailable()) {
69             eventLoopGroup = new EpollEventLoopGroup();
70         } else {
71             eventLoopGroup = new NioEventLoopGroup();
72         }
73         final MessageRegistry msgReg = ServiceLoaderPCEPExtensionProviderContext.getSingletonInstance()
74                 .getMessageHandlerRegistry();
75         this.dispatcher = new PCEPDispatcherImpl(msgReg, new DefaultPCEPSessionNegotiatorFactory(sessionProposal, 0),
76                 eventLoopGroup, eventLoopGroup);
77
78         Mockito.doReturn("mockChannel").when(this.mockChannel).toString();
79         final PCEPDispatcherImpl dispatcher2 = new PCEPDispatcherImpl(msgReg, new DefaultPCEPSessionNegotiatorFactory(sessionProposal, 0), eventLoopGroup, eventLoopGroup);
80         this.disp2Spy = Mockito.spy(dispatcher2);
81
82         this.pccMock = new PCCMock(new DefaultPCEPSessionNegotiatorFactory(sessionProposal, 0),
83                 new PCEPHandlerFactory(msgReg), new DefaultPromise<PCEPSessionImpl>(
84                         GlobalEventExecutor.INSTANCE));
85     }
86
87     @Test
88     public void testCreateClientServer() throws InterruptedException, ExecutionException {
89         final int port = InetSocketAddressUtil.getRandomPort();
90         final InetSocketAddress serverAddr = new InetSocketAddress("0.0.0.0", port);
91         final InetSocketAddress clientAddr1 = InetSocketAddressUtil.getRandomLoopbackInetSocketAddress(port);
92         final InetSocketAddress clientAddr2 = InetSocketAddressUtil.getRandomLoopbackInetSocketAddress(port);
93         final ChannelFuture futureChannel = this.dispatcher.createServer(serverAddr,
94                 () -> new SimpleSessionListener(), null);
95         final PCEPSessionImpl session1 = (PCEPSessionImpl) this.pccMock.createClient(clientAddr1,
96                 RETRY_TIMER, CONNECT_TIMEOUT,
97                 () -> new SimpleSessionListener()).get();
98
99         final PCEPSessionImpl session2 = (PCEPSessionImpl) this.pccMock.createClient(clientAddr2,
100                 RETRY_TIMER, CONNECT_TIMEOUT,
101                 () -> new SimpleSessionListener()).get();
102
103         Assert.assertTrue(futureChannel.channel().isActive());
104         Assert.assertEquals(clientAddr1.getAddress().getHostAddress(), session1.getPeerPref().getIpAddress());
105         Assert.assertEquals(DEAD_TIMER, session1.getDeadTimerValue().shortValue());
106         Assert.assertEquals(KEEP_ALIVE, session1.getKeepAliveTimerValue().shortValue());
107
108         Assert.assertEquals(clientAddr2.getAddress().getHostAddress(), session2.getPeerPref().getIpAddress());
109         Assert.assertEquals(DEAD_TIMER, session2.getDeadTimerValue().shortValue());
110         Assert.assertEquals(KEEP_ALIVE, session2.getKeepAliveTimerValue().shortValue());
111
112         session1.close();
113         session2.close();
114         Assert.assertTrue(futureChannel.channel().isActive());
115     }
116
117     @Test
118     public void testCreateDuplicateClient() throws InterruptedException, ExecutionException {
119         final int port = InetSocketAddressUtil.getRandomPort();
120         final InetSocketAddress serverAddr = new InetSocketAddress("0.0.0.0", port);
121         final InetSocketAddress clientAddr = InetSocketAddressUtil.getRandomLoopbackInetSocketAddress(port);
122         this.dispatcher.createServer(serverAddr,
123                 () -> new SimpleSessionListener(), null);
124         final PCEPSessionImpl session1 = (PCEPSessionImpl) this.pccMock.createClient(clientAddr,
125                 RETRY_TIMER, CONNECT_TIMEOUT,
126                 () -> new SimpleSessionListener()).get();
127
128         try {
129             this.pccMock.createClient(clientAddr,
130                     RETRY_TIMER, CONNECT_TIMEOUT,
131                     () -> new SimpleSessionListener()).get();
132             Assert.fail();
133         } catch (final ExecutionException e) {
134             Assert.assertTrue(e.getMessage().contains("A conflicting session for address"));
135         } finally {
136             session1.close();
137         }
138     }
139
140     @Test
141     public void testReconectClient() throws InterruptedException, ExecutionException {
142         final int port = InetSocketAddressUtil.getRandomPort();
143         final InetSocketAddress clientAddr = InetSocketAddressUtil.getRandomLoopbackInetSocketAddress(port);
144         this.dispatcher.createServer(new InetSocketAddress("0.0.0.0", port),
145                 () -> new SimpleSessionListener(), null);
146         final PCEPSessionImpl session1 = (PCEPSessionImpl) this.pccMock.createClient(clientAddr,
147                 RETRY_TIMER, CONNECT_TIMEOUT,
148                 () -> new SimpleSessionListener()).get();
149
150         Assert.assertEquals(clientAddr.getAddress(), session1.getRemoteAddress());
151         Assert.assertEquals(DEAD_TIMER, session1.getDeadTimerValue().shortValue());
152         Assert.assertEquals(KEEP_ALIVE, session1.getKeepAliveTimerValue().shortValue());
153         session1.close();
154
155         final PCEPSessionImpl session2 = (PCEPSessionImpl) this.pccMock.createClient(clientAddr,
156                 RETRY_TIMER, CONNECT_TIMEOUT,
157                 () -> new SimpleSessionListener()).get();
158
159         Assert.assertEquals(clientAddr.getAddress(), session1.getRemoteAddress());
160         Assert.assertEquals(DEAD_TIMER, session2.getDeadTimerValue().shortValue());
161         Assert.assertEquals(KEEP_ALIVE, session2.getKeepAliveTimerValue().shortValue());
162
163         session2.close();
164     }
165
166     @Test
167     public void testCustomizeBootstrap() {
168         final int port = InetSocketAddressUtil.getRandomPort();
169         final InetSocketAddress clientAddr1 = InetSocketAddressUtil.getRandomLoopbackInetSocketAddress(port);
170         final InetSocketAddress clientAddr2 = InetSocketAddressUtil.getRandomLoopbackInetSocketAddress(port);
171         final KeyMapping keys = KeyMapping.getKeyMapping(clientAddr1.getAddress(), new String("CLIENT1_ADDRESS"));
172         keys.put(clientAddr2.getAddress(), new String("CLIENT2_ADDRESS").getBytes() );
173
174         final ChannelFuture futureChannel = this.disp2Spy.createServer(new InetSocketAddress("0.0.0.0", port),
175                 () -> new SimpleSessionListener(), null);
176         Mockito.verify(this.disp2Spy).createServerBootstrap(Mockito.any(PCEPDispatcherImpl.ChannelPipelineInitializer.class));
177     }
178
179     @After
180     public void tearDown() {
181         this.dispatcher.close();
182         this.disp2Spy.close();
183     }
184
185     private static class PCCMock {
186
187         private final PCEPSessionNegotiatorFactory negotiatorFactory;
188         private final PCEPHandlerFactory factory;
189         private final EventExecutor executor;
190         private final EventLoopGroup workerGroup;
191         private final EventLoopGroup bossGroup;
192
193         public PCCMock(final PCEPSessionNegotiatorFactory negotiatorFactory, final PCEPHandlerFactory factory,
194                 final DefaultPromise<PCEPSessionImpl> defaultPromise) {
195             this.bossGroup = Preconditions.checkNotNull(new NioEventLoopGroup());
196             this.workerGroup = Preconditions.checkNotNull(new NioEventLoopGroup());
197             this.negotiatorFactory = Preconditions.checkNotNull(negotiatorFactory);
198             this.factory = Preconditions.checkNotNull(factory);
199             this.executor = Preconditions.checkNotNull(GlobalEventExecutor.INSTANCE);
200         }
201
202         public Future<PCEPSession> createClient(final InetSocketAddress address, final int retryTimer,
203                 final int connectTimeout, final PCEPSessionListenerFactory listenerFactory) {
204             return createClient(address, retryTimer, connectTimeout, (ChannelPipelineInitializer) (ch, promise) -> {
205                 ch.pipeline().addLast(PCCMock.this.factory.getDecoders());
206                 ch.pipeline().addLast("negotiator", PCCMock.this.negotiatorFactory.getSessionNegotiator(listenerFactory, ch, promise, null));
207                 ch.pipeline().addLast(PCCMock.this.factory.getEncoders());
208             });
209         }
210
211         Future<PCEPSession> createClient(final InetSocketAddress address, final int retryTimer, final int connectTimeout,
212                 final PCEPDispatcherImpl.ChannelPipelineInitializer initializer) {
213             final Bootstrap b = new Bootstrap();
214             final PCEPProtocolSessionPromise p = new PCEPProtocolSessionPromise(this.executor, address, retryTimer, connectTimeout, b);
215             (b.option(ChannelOption.SO_KEEPALIVE, Boolean.valueOf(true))).handler(new ChannelInitializer<SocketChannel>() {
216                 @Override
217                 protected void initChannel(final SocketChannel ch) {
218                     initializer.initializeChannel(ch, p);
219                 }
220             });
221
222             setWorkerGroup(b);
223             setChannelFactory(b);
224             p.connect();
225             return p;
226         }
227
228         private void setChannelFactory(final Bootstrap b) {
229             try {
230                 b.channel(NioSocketChannel.class);
231             } catch (final IllegalStateException ignored) {
232             }
233
234         }
235
236         private void setWorkerGroup(final Bootstrap b) {
237             if (b.group() == null) {
238                 b.group(this.workerGroup);
239             }
240         }
241     }
242
243 }