Replace Preconditions.CheckNotNull per RequireNonNull
[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.Matchers.any;
14 import static org.opendaylight.protocol.util.CheckUtil.waitFutureSuccess;
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.PCEPSession;
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
63     private PCCMock pccMock;
64
65     @Before
66     public void setUp() {
67         MockitoAnnotations.initMocks(this);
68         final List<PCEPCapability> capList = new ArrayList<>();
69         final PCEPSessionProposalFactory sessionProposal = new BasePCEPSessionProposalFactory(DEAD_TIMER, KEEP_ALIVE,
70             capList);
71         final EventLoopGroup eventLoopGroup;
72         if (Epoll.isAvailable()) {
73             eventLoopGroup = new EpollEventLoopGroup();
74         } else {
75             eventLoopGroup = new NioEventLoopGroup();
76         }
77         final MessageRegistry msgReg = ServiceLoaderPCEPExtensionProviderContext.getSingletonInstance()
78             .getMessageHandlerRegistry();
79         this.dispatcher = new PCEPDispatcherImpl(msgReg, new DefaultPCEPSessionNegotiatorFactory(sessionProposal, 0),
80             eventLoopGroup, eventLoopGroup);
81
82         Mockito.doReturn("mockChannel").when(this.mockChannel).toString();
83         final PCEPDispatcherImpl dispatcher2 = new PCEPDispatcherImpl(msgReg,
84             new DefaultPCEPSessionNegotiatorFactory(sessionProposal, 0),
85             eventLoopGroup, eventLoopGroup);
86         this.disp2Spy = Mockito.spy(dispatcher2);
87
88         this.pccMock = new PCCMock(new DefaultPCEPSessionNegotiatorFactory(sessionProposal, 0),
89             new PCEPHandlerFactory(msgReg));
90     }
91
92     @Test
93     public void testCreateClientServer() throws InterruptedException, ExecutionException {
94         final int port = InetSocketAddressUtil.getRandomPort();
95         final InetSocketAddress serverAddr = new InetSocketAddress("0.0.0.0", port);
96         final InetSocketAddress clientAddr1 = InetSocketAddressUtil.getRandomLoopbackInetSocketAddress(port);
97         final InetSocketAddress clientAddr2 = InetSocketAddressUtil.getRandomLoopbackInetSocketAddress(port);
98         final ChannelFuture futureChannel = this.dispatcher.createServer(serverAddr,
99             SimpleSessionListener::new, null);
100         waitFutureSuccess(futureChannel);
101         final PCEPSessionImpl session1 = (PCEPSessionImpl) this.pccMock.createClient(clientAddr1,
102             RETRY_TIMER, CONNECT_TIMEOUT, SimpleSessionListener::new).get();
103
104         final PCEPSessionImpl session2 = (PCEPSessionImpl) this.pccMock.createClient(clientAddr2,
105             RETRY_TIMER, CONNECT_TIMEOUT, SimpleSessionListener::new).get();
106
107         Assert.assertTrue(futureChannel.channel().isActive());
108         assertEquals(clientAddr1.getAddress().getHostAddress(), session1.getPeerPref().getIpAddress());
109         assertEquals(DEAD_TIMER, session1.getDeadTimerValue().shortValue());
110         assertEquals(KEEP_ALIVE, session1.getKeepAliveTimerValue().shortValue());
111
112         assertEquals(clientAddr2.getAddress().getHostAddress(), session2.getPeerPref().getIpAddress());
113         assertEquals(DEAD_TIMER, session2.getDeadTimerValue().shortValue());
114         assertEquals(KEEP_ALIVE, session2.getKeepAliveTimerValue().shortValue());
115
116         session1.close();
117         session2.close();
118         Assert.assertTrue(futureChannel.channel().isActive());
119     }
120
121     @Test
122     public void testCreateDuplicateClient() throws InterruptedException, ExecutionException {
123         final int port = InetSocketAddressUtil.getRandomPort();
124         final InetSocketAddress serverAddr = new InetSocketAddress("0.0.0.0", port);
125         final InetSocketAddress clientAddr = InetSocketAddressUtil.getRandomLoopbackInetSocketAddress(port);
126         waitFutureSuccess(this.dispatcher.createServer(serverAddr, SimpleSessionListener::new, null));
127         final Future<PCEPSession> futureClient = this.pccMock.createClient(clientAddr, RETRY_TIMER, CONNECT_TIMEOUT,
128             SimpleSessionListener::new);
129         waitFutureSuccess(futureClient);
130         final PCEPSessionImpl session1 = (PCEPSessionImpl) futureClient.get();
131
132         try {
133             this.pccMock.createClient(clientAddr, RETRY_TIMER, CONNECT_TIMEOUT,
134                 SimpleSessionListener::new).get();
135             Assert.fail();
136         } catch (final ExecutionException e) {
137             Assert.assertTrue(e.getMessage().contains("A conflicting session for address"));
138         } finally {
139             session1.close();
140         }
141     }
142
143     @Test
144     public void testReconectClient() throws InterruptedException, ExecutionException {
145         final int port = InetSocketAddressUtil.getRandomPort();
146         final InetSocketAddress clientAddr = InetSocketAddressUtil.getRandomLoopbackInetSocketAddress(port);
147         waitFutureSuccess(this.dispatcher.createServer(new InetSocketAddress("0.0.0.0", port),
148             SimpleSessionListener::new, null));
149         final PCEPSessionImpl session1 = (PCEPSessionImpl) this.pccMock.createClient(clientAddr,
150             RETRY_TIMER, CONNECT_TIMEOUT, SimpleSessionListener::new).get();
151
152         assertEquals(clientAddr.getAddress(), session1.getRemoteAddress());
153         assertEquals(DEAD_TIMER, session1.getDeadTimerValue().shortValue());
154         assertEquals(KEEP_ALIVE, session1.getKeepAliveTimerValue().shortValue());
155         waitFutureSuccess(session1.closeChannel());
156
157         final PCEPSessionImpl session2 = (PCEPSessionImpl) this.pccMock.createClient(clientAddr,
158             RETRY_TIMER, CONNECT_TIMEOUT, SimpleSessionListener::new).get();
159
160         assertEquals(clientAddr.getAddress(), session1.getRemoteAddress());
161         assertEquals(DEAD_TIMER, session2.getDeadTimerValue().shortValue());
162         assertEquals(KEEP_ALIVE, session2.getKeepAliveTimerValue().shortValue());
163
164         session2.close();
165     }
166
167     @Test
168     public void testCustomizeBootstrap() {
169         final int port = InetSocketAddressUtil.getRandomPort();
170         final InetSocketAddress clientAddr1 = InetSocketAddressUtil.getRandomLoopbackInetSocketAddress(port);
171         final InetSocketAddress clientAddr2 = InetSocketAddressUtil.getRandomLoopbackInetSocketAddress(port);
172         final KeyMapping keys = KeyMapping.getKeyMapping(clientAddr1.getAddress(), "CLIENT1_ADDRESS");
173         keys.put(clientAddr2.getAddress(), "CLIENT2_ADDRESS".getBytes());
174
175         final ChannelFuture futureChannel = this.disp2Spy.createServer(new InetSocketAddress("0.0.0.0", port),
176             SimpleSessionListener::new, null);
177         waitFutureSuccess(futureChannel);
178         Mockito.verify(this.disp2Spy).createServerBootstrap(any(PCEPDispatcherImpl.ChannelPipelineInitializer.class));
179     }
180
181     @After
182     public void tearDown() {
183         this.dispatcher.close();
184         this.disp2Spy.close();
185     }
186
187     private static class PCCMock {
188         private final PCEPSessionNegotiatorFactory negotiatorFactory;
189         private final PCEPHandlerFactory factory;
190         private final EventExecutor executor;
191         private final EventLoopGroup workerGroup;
192
193         PCCMock(final PCEPSessionNegotiatorFactory<?> negotiatorFactory, final PCEPHandlerFactory factory) {
194             this.workerGroup = requireNonNull(new NioEventLoopGroup());
195             this.negotiatorFactory = requireNonNull(negotiatorFactory);
196             this.factory = requireNonNull(factory);
197             this.executor = requireNonNull(GlobalEventExecutor.INSTANCE);
198         }
199
200         Future<PCEPSession> createClient(final InetSocketAddress address, final int retryTimer,
201             final int connectTimeout, final PCEPSessionListenerFactory listenerFactory) {
202             return createClient(address, retryTimer, connectTimeout, (ch, promise) -> {
203                 ch.pipeline().addLast(this.factory.getDecoders());
204                 ch.pipeline().addLast("negotiator", this.negotiatorFactory.getSessionNegotiator(listenerFactory, ch,
205                     promise, null));
206                 ch.pipeline().addLast(this.factory.getEncoders());
207             });
208         }
209
210         Future<PCEPSession> createClient(final InetSocketAddress address, final int retryTimer,
211             final int connectTimeout, final PCEPDispatcherImpl.ChannelPipelineInitializer initializer) {
212             final Bootstrap b = new Bootstrap();
213             final PCEPProtocolSessionPromise p = new PCEPProtocolSessionPromise<>(this.executor, address, retryTimer,
214                 connectTimeout, b);
215             b.option(ChannelOption.SO_KEEPALIVE, Boolean.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 static void setChannelFactory(final Bootstrap b) {
229             try {
230                 b.channel(NioSocketChannel.class);
231             } catch (final IllegalStateException ignored) {
232             }
233         }
234
235         private void setWorkerGroup(final Bootstrap b) {
236             if (b.group() == null) {
237                 b.group(this.workerGroup);
238             }
239         }
240     }
241
242 }