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