8bd729c6ba92130d38094427fd4af4ad0d4fe4f5
[bgpcep.git] / pcep / pcc-mock / src / test / java / org / opendaylight / protocol / pcep / pcc / mock / PCCMockCommon.java
1 /*
2  * Copyright (c) 2015 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.pcc.mock;
10
11 import static org.junit.Assert.assertEquals;
12 import static org.junit.Assert.assertNotNull;
13 import static org.junit.Assert.assertNull;
14 import static org.junit.Assert.assertTrue;
15 import static org.opendaylight.protocol.util.CheckUtil.checkEquals;
16 import static org.opendaylight.protocol.util.CheckUtil.checkReceivedMessages;
17 import static org.opendaylight.protocol.util.CheckUtil.waitFutureSuccess;
18
19 import com.google.common.base.Optional;
20 import com.google.common.base.Stopwatch;
21 import com.google.common.net.InetAddresses;
22 import com.google.common.util.concurrent.Uninterruptibles;
23 import io.netty.channel.Channel;
24 import io.netty.channel.ChannelFuture;
25 import io.netty.channel.nio.NioEventLoopGroup;
26 import io.netty.util.HashedWheelTimer;
27 import io.netty.util.concurrent.Future;
28 import java.math.BigInteger;
29 import java.net.InetAddress;
30 import java.net.InetSocketAddress;
31 import java.util.List;
32 import java.util.concurrent.TimeUnit;
33 import org.junit.Before;
34 import org.opendaylight.protocol.concepts.KeyMapping;
35 import org.opendaylight.protocol.pcep.PCEPCapability;
36 import org.opendaylight.protocol.pcep.PCEPDispatcher;
37 import org.opendaylight.protocol.pcep.PCEPDispatcherDependencies;
38 import org.opendaylight.protocol.pcep.PCEPPeerProposal;
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.SpeakerIdMapping;
43 import org.opendaylight.protocol.pcep.ietf.stateful07.StatefulActivator;
44 import org.opendaylight.protocol.pcep.impl.BasePCEPSessionProposalFactory;
45 import org.opendaylight.protocol.pcep.impl.DefaultPCEPSessionNegotiatorFactory;
46 import org.opendaylight.protocol.pcep.impl.PCEPDispatcherImpl;
47 import org.opendaylight.protocol.pcep.impl.PCEPSessionImpl;
48 import org.opendaylight.protocol.pcep.pcc.mock.api.PCCTunnelManager;
49 import org.opendaylight.protocol.pcep.pcc.mock.protocol.PCCDispatcherImpl;
50 import org.opendaylight.protocol.pcep.pcc.mock.protocol.PCCSessionListener;
51 import org.opendaylight.protocol.pcep.spi.MessageRegistry;
52 import org.opendaylight.protocol.pcep.spi.PCEPExtensionProviderContext;
53 import org.opendaylight.protocol.pcep.spi.pojo.ServiceLoaderPCEPExtensionProviderContext;
54 import org.opendaylight.protocol.pcep.sync.optimizations.SyncOptimizationsActivator;
55 import org.opendaylight.protocol.util.InetSocketAddressUtil;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.pcep.sync.optimizations.rev171025.Tlvs3;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev171025.Stateful1;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev171025.Pcrpt;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev171025.Tlvs1;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev171025.lsp.object.Lsp;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev171025.pcrpt.message.pcrpt.message.Reports;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Message;
63
64 public abstract class PCCMockCommon {
65     private static final short KEEP_ALIVE = 30;
66     private static final short DEAD_TIMER = 120;
67     private static final long SLEEP_FOR = 50;
68     private final int port = InetSocketAddressUtil.getRandomPort();
69     final InetSocketAddress remoteAddress = InetSocketAddressUtil
70             .getRandomLoopbackInetSocketAddress(this.port);
71     final InetSocketAddress localAddress = new InetSocketAddress("127.0.0.1", this.port);
72     PCCSessionListener pccSessionListener;
73     private PCEPDispatcher pceDispatcher;
74     private PCEPExtensionProviderContext extensionProvider;
75     private MessageRegistry messageRegistry;
76
77     protected abstract List<PCEPCapability> getCapabilities();
78
79     @Before
80     public void setUp() {
81         final BasePCEPSessionProposalFactory proposal = new BasePCEPSessionProposalFactory(DEAD_TIMER, KEEP_ALIVE,
82                 getCapabilities());
83         final DefaultPCEPSessionNegotiatorFactory nf = new DefaultPCEPSessionNegotiatorFactory(proposal, 0);
84         this.extensionProvider = ServiceLoaderPCEPExtensionProviderContext.getSingletonInstance();
85         this.messageRegistry = this.extensionProvider.getMessageHandlerRegistry();
86         this.pceDispatcher = new PCEPDispatcherImpl(this.messageRegistry, nf, new NioEventLoopGroup(),
87                 new NioEventLoopGroup());
88     }
89
90     static TestingSessionListener checkSessionListener(final int numMessages, final Channel channel,
91             final TestingSessionListenerFactory factory,
92             final String localAddress) throws
93             Exception {
94         final TestingSessionListener sessionListener = checkSessionListenerNotNull(factory, localAddress);
95         assertTrue(sessionListener.isUp());
96         checkReceivedMessages(sessionListener, numMessages);
97         assertEquals(numMessages, sessionListener.messages().size());
98         channel.close().get();
99         return sessionListener;
100     }
101
102     static TestingSessionListener checkSessionListenerNotNull(final TestingSessionListenerFactory factory,
103             final String localAddress) {
104         final Stopwatch sw = Stopwatch.createStarted();
105         TestingSessionListener listener;
106         final InetAddress address = InetAddresses.forString(localAddress);
107         while (sw.elapsed(TimeUnit.SECONDS) <= 60) {
108             listener = factory.getSessionListenerByRemoteAddress(address);
109             if (listener == null) {
110                 Uninterruptibles.sleepUninterruptibly(SLEEP_FOR, TimeUnit.MILLISECONDS);
111             } else {
112                 return listener;
113             }
114         }
115         throw new NullPointerException();
116     }
117
118     Channel createServer(final TestingSessionListenerFactory factory,
119             final InetSocketAddress serverAddress2) throws InterruptedException {
120         return createServer(factory, serverAddress2, null);
121     }
122
123     Channel createServer(final TestingSessionListenerFactory factory, final InetSocketAddress
124             serverAddress2, final PCEPPeerProposal peerProposal) {
125         final StatefulActivator activator07 = new StatefulActivator();
126         final SyncOptimizationsActivator optimizationsActivator = new SyncOptimizationsActivator();
127         activator07.start(this.extensionProvider);
128         optimizationsActivator.start(this.extensionProvider);
129
130         final ChannelFuture future = this.pceDispatcher
131                 .createServer(new DispatcherDependencies(serverAddress2, factory, peerProposal));
132         waitFutureSuccess(future);
133         return future.channel();
134     }
135
136     static void checkSynchronizedSession(final int numberOfLsp,
137             final TestingSessionListener pceSessionListener, final BigInteger expectedeInitialDb) throws Exception {
138         assertTrue(pceSessionListener.isUp());
139         //Send Open with LspDBV = 1
140         final int numberOfSyncMessage = 1;
141         int numberOfLspExpected = numberOfLsp;
142         if (!expectedeInitialDb.equals(BigInteger.ZERO)) {
143             checkEquals(() -> checkSequequenceDBVersionSync(pceSessionListener, expectedeInitialDb));
144             numberOfLspExpected += numberOfSyncMessage;
145         }
146         checkReceivedMessages(pceSessionListener, numberOfLspExpected);
147         final PCEPSession session = pceSessionListener.getSession();
148         checkSession(session, DEAD_TIMER, KEEP_ALIVE);
149
150         assertTrue(session.getRemoteTlvs().getAugmentation(Tlvs1.class).getStateful()
151                 .getAugmentation(Stateful1.class).isInitiation());
152         assertNull(session.localSessionCharacteristics().getAugmentation(Tlvs3.class)
153                 .getLspDbVersion().getLspDbVersionValue());
154     }
155
156     static void checkResyncSession(final Optional<Integer> startAtNumberLsp, final int expectedNumberOfLsp,
157             final int expectedTotalMessages, final BigInteger startingDBVersion, final BigInteger expectedDBVersion,
158             final TestingSessionListener pceSessionListener) throws Exception {
159         assertNotNull(pceSessionListener.getSession());
160         assertTrue(pceSessionListener.isUp());
161         final List<Message> messages;
162         checkReceivedMessages(pceSessionListener, expectedTotalMessages);
163         if (startAtNumberLsp.isPresent()) {
164             messages = pceSessionListener.messages().subList(startAtNumberLsp.get(),
165                     startAtNumberLsp.get() + expectedNumberOfLsp);
166         } else {
167             messages = pceSessionListener.messages();
168         }
169         checkEquals(() -> checkSequequenceDBVersionSync(pceSessionListener, expectedDBVersion));
170         assertEquals(expectedNumberOfLsp, messages.size());
171         final PCEPSession session = pceSessionListener.getSession();
172
173         checkSession(session, DEAD_TIMER, KEEP_ALIVE);
174
175         assertTrue(session.getRemoteTlvs().getAugmentation(Tlvs1.class).getStateful()
176                 .getAugmentation(Stateful1.class).isInitiation());
177         final BigInteger pceDBVersion = session.localSessionCharacteristics().getAugmentation(Tlvs3.class)
178                 .getLspDbVersion().getLspDbVersionValue();
179         assertEquals(startingDBVersion, pceDBVersion);
180     }
181
182     static void checkSession(final PCEPSession session, final int expectedDeadTimer,
183             final int expectedKeepAlive) {
184         assertNotNull(session);
185         assertEquals(expectedDeadTimer, session.getPeerPref().getDeadtimer().shortValue());
186         assertEquals(expectedKeepAlive, session.getPeerPref().getKeepalive().shortValue());
187         final Stateful1 stateful = session.getRemoteTlvs().getAugmentation(Tlvs1.class)
188                 .getStateful().getAugmentation(Stateful1.class);
189         assertTrue(stateful.isInitiation());
190     }
191
192     protected static void checkSequequenceDBVersionSync(final TestingSessionListener pceSessionListener,
193             final BigInteger expectedDbVersion) {
194         for (final Message msg : pceSessionListener.messages()) {
195             final List<Reports> pcrt = ((Pcrpt) msg).getPcrptMessage().getReports();
196             for (final Reports report : pcrt) {
197                 final Lsp lsp = report.getLsp();
198                 if (lsp.getPlspId().getValue() == 0) {
199                     assertEquals(false, lsp.isSync());
200                 } else {
201                     assertEquals(true, lsp.isSync());
202                 }
203                 final BigInteger actuaLspDBVersion = lsp.getTlvs().getAugmentation(org.opendaylight.yang.gen
204                     .v1.urn.opendaylight.params.xml.ns.yang.controller.pcep.sync.optimizations.rev171025.Tlvs1.class)
205                     .getLspDbVersion().getLspDbVersionValue();
206                 assertEquals(expectedDbVersion, actuaLspDBVersion);
207             }
208         }
209     }
210
211     Future<PCEPSession> createPCCSession(final BigInteger dbVersion) {
212         final PCCDispatcherImpl pccDispatcher = new PCCDispatcherImpl(this.messageRegistry);
213         final PCEPSessionNegotiatorFactory<PCEPSessionImpl> snf = getSessionNegotiatorFactory();
214         final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(3, this.localAddress.getAddress(),
215                 0, -1, new HashedWheelTimer(), Optional.absent());
216
217         return pccDispatcher.createClient(this.remoteAddress, -1, () -> {
218             this.pccSessionListener = new PCCSessionListener(1, tunnelManager, false);
219             return this.pccSessionListener;
220         }, snf, KeyMapping.getKeyMapping(), this.localAddress, dbVersion);
221     }
222
223     private PCEPSessionNegotiatorFactory<PCEPSessionImpl> getSessionNegotiatorFactory() {
224         return new DefaultPCEPSessionNegotiatorFactory(new BasePCEPSessionProposalFactory(DEAD_TIMER, KEEP_ALIVE,
225                 getCapabilities()), 0);
226     }
227
228     TestingSessionListener getListener(final TestingSessionListenerFactory factory) {
229         return checkSessionListenerNotNull(factory, this.localAddress.getHostString());
230     }
231
232     private class DispatcherDependencies implements PCEPDispatcherDependencies {
233         final KeyMapping keys = KeyMapping.getKeyMapping();
234         final SpeakerIdMapping ids = SpeakerIdMapping.getSpeakerIdMap();
235         private final InetSocketAddress address;
236         private final TestingSessionListenerFactory listenerFactory;
237         private final PCEPPeerProposal peerProposal;
238
239         DispatcherDependencies(
240                 final InetSocketAddress address,
241                 final TestingSessionListenerFactory listenerFactory,
242                 final PCEPPeerProposal peerProposal) {
243             this.address = address;
244             this.listenerFactory = listenerFactory;
245             this.peerProposal = peerProposal;
246         }
247
248         @Override
249         public InetSocketAddress getAddress() {
250             return this.address;
251         }
252
253         @Override
254         public KeyMapping getKeys() {
255             return keys;
256         }
257
258         @Override
259         public SpeakerIdMapping getSpeakerIdMapping() {
260             return ids;
261         }
262
263         @Override
264         public PCEPSessionListenerFactory getListenerFactory() {
265             return this.listenerFactory;
266         }
267
268         @Override
269         public PCEPPeerProposal getPeerProposal() {
270             return this.peerProposal;
271         }
272     }
273 }