Update Statefuful & Initiated yang models
[bgpcep.git] / pcep / pcc-mock / src / test / java / org / opendaylight / protocol / pcep / pcc / mock / PCCTunnelManagerImplTest.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
13 import com.google.common.collect.Lists;
14 import com.google.common.net.InetAddresses;
15 import io.netty.util.HashedWheelTimer;
16 import io.netty.util.Timer;
17 import java.net.InetAddress;
18 import java.nio.charset.StandardCharsets;
19 import java.util.ArrayList;
20 import java.util.List;
21 import java.util.Optional;
22 import org.junit.After;
23 import org.junit.Before;
24 import org.junit.Test;
25 import org.mockito.Mock;
26 import org.mockito.Mockito;
27 import org.mockito.MockitoAnnotations;
28 import org.opendaylight.protocol.pcep.pcc.mock.api.PCCSession;
29 import org.opendaylight.protocol.pcep.pcc.mock.api.PCCTunnelManager;
30 import org.opendaylight.protocol.pcep.spi.PCEPErrors;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
32 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.initiated.rev200720.Srp1Builder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.initiated.rev200720.pcinitiate.message.pcinitiate.message.Requests;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.initiated.rev200720.pcinitiate.message.pcinitiate.message.RequestsBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev200720.Pcrpt;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev200720.PlspId;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev200720.SrpIdNumber;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev200720.SymbolicPathName;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev200720.lsp.object.LspBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev200720.lsp.object.lsp.TlvsBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev200720.pcupd.message.pcupd.message.Updates;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev200720.pcupd.message.pcupd.message.UpdatesBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev200720.pcupd.message.pcupd.message.updates.PathBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev200720.srp.object.SrpBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev200720.symbolic.path.name.tlv.SymbolicPathNameBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev181109.Pcerr;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.explicit.route.object.Ero;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.explicit.route.object.EroBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.explicit.route.object.ero.SubobjectBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcep.error.object.ErrorObject;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.basic.explicit.route.subobjects.subobject.type.IpPrefixCaseBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.basic.explicit.route.subobjects.subobject.type.ip.prefix._case.IpPrefixBuilder;
54 import org.opendaylight.yangtools.yang.common.Uint32;
55
56 public class PCCTunnelManagerImplTest {
57
58     private static final InetAddress ADDRESS = InetAddresses.forString("1.2.4.5");
59     private static final Timer TIMER = new HashedWheelTimer();
60     private static final byte[] SYMBOLIC_NAME = "tets".getBytes(StandardCharsets.UTF_8);
61     private static final Ero ERO = new EroBuilder().setSubobject(Lists.newArrayList(new SubobjectBuilder()
62         .setSubobjectType(new IpPrefixCaseBuilder().setIpPrefix(new IpPrefixBuilder()
63         .setIpPrefix(new IpPrefix(new Ipv4Prefix("127.0.0.2/32"))).build()).build()).build())).build();
64     private final List<PCEPErrors> errorsSession1 = new ArrayList<>();
65     private final List<PCEPErrors> errorsSession2 = new ArrayList<>();
66     @Mock
67     private PCCSession session1;
68     @Mock
69     private PCCSession session2;
70     private final Optional<TimerHandler> timerHandler = Optional.empty();
71
72     @Before
73     public void setUp() {
74         MockitoAnnotations.initMocks(this);
75         Mockito.doNothing().when(this.session1).sendReport(Mockito.any(Pcrpt.class));
76         Mockito.doAnswer(invocation -> {
77             PCCTunnelManagerImplTest.this.errorsSession1.add(getError((Pcerr) invocation.getArguments()[0]));
78             return null;
79         }).when(this.session1).sendError(Mockito.any(Pcerr.class));
80         Mockito.doReturn(0).when(this.session1).getId();
81         Mockito.doNothing().when(this.session2).sendReport(Mockito.any(Pcrpt.class));
82         Mockito.doAnswer(invocation -> {
83             PCCTunnelManagerImplTest.this.errorsSession2.add(getError((Pcerr) invocation.getArguments()[0]));
84             return null;
85         }).when(this.session2).sendError(Mockito.any(Pcerr.class));
86         Mockito.doReturn(1).when(this.session2).getId();
87     }
88
89     @After
90     public void tearDown() {
91         this.errorsSession1.clear();
92         this.errorsSession2.clear();
93     }
94
95     @Test
96     public void testOnSessionUp() {
97         final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, 0, TIMER, this.timerHandler);
98         checkSessionUp(this.session1, tunnelManager);
99         checkSessionUp(this.session2, tunnelManager);
100     }
101
102     @Test
103     public void testOnSessionDownAndDelegateBack() {
104         final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 1, 10, TIMER, this.timerHandler);
105         checkSessionUp(this.session1, tunnelManager);
106         checkSessionUp(this.session2, tunnelManager);
107         checkSessionDown(this.session1, tunnelManager);
108         tunnelManager.onSessionUp(this.session1);
109         Mockito.verify(this.session1, Mockito.times(4)).sendReport(Mockito.any(Pcrpt.class));
110         Mockito.verify(this.session2, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
111     }
112
113     private static void checkSessionDown(final PCCSession session, final PCCTunnelManager tunnelManager) {
114         tunnelManager.onSessionDown(session);
115         Mockito.verify(session, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
116     }
117
118     private static void checkSessionUp(final PCCSession session, final PCCTunnelManager tunnelManager) {
119         //1 reported LSP + 1 end-of-sync marker
120         tunnelManager.onSessionUp(session);
121         Mockito.verify(session, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
122     }
123
124     @Test
125     public void testOnSessionDownAndDelegateToOther() throws InterruptedException {
126         final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, -1, TIMER, this.timerHandler);
127         tunnelManager.onSessionUp(this.session2);
128         checkSessionUp(this.session1, tunnelManager);
129         checkSessionDown(this.session1, tunnelManager);
130         //wait for re-delegation timeout expires
131         Thread.sleep(500);
132         Mockito.verify(this.session2, Mockito.times(3)).sendReport(Mockito.any(Pcrpt.class));
133         tunnelManager.onSessionUp(this.session1);
134         Mockito.verify(this.session1, Mockito.times(4)).sendReport(Mockito.any(Pcrpt.class));
135     }
136
137     @Test
138     public void testReportToAll() {
139         final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, 0, TIMER, this.timerHandler);
140         tunnelManager.onSessionUp(this.session1);
141         tunnelManager.onSessionUp(this.session2);
142         tunnelManager.onMessagePcupd(createUpdateDelegate(1), this.session1);
143         Mockito.verify(this.session1, Mockito.times(3)).sendReport(Mockito.any(Pcrpt.class));
144         Mockito.verify(this.session2, Mockito.times(3)).sendReport(Mockito.any(Pcrpt.class));
145     }
146
147     @Test
148     public void testReportToAllUnknownLsp() {
149         final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, 0, TIMER, this.timerHandler);
150         tunnelManager.onSessionUp(this.session1);
151         tunnelManager.onMessagePcupd(createUpdateDelegate(2), this.session1);
152         Mockito.verify(this.session1, Mockito.times(1)).sendError(Mockito.any(Pcerr.class));
153         assertEquals(PCEPErrors.UNKNOWN_PLSP_ID, this.errorsSession1.get(0));
154     }
155
156     @Test
157     public void testReportToAllNonDelegatedLsp() {
158         final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, 0, TIMER, this.timerHandler);
159         tunnelManager.onSessionUp(this.session1);
160         tunnelManager.onSessionUp(this.session2);
161         tunnelManager.onMessagePcupd(createUpdateDelegate(1), this.session2);
162         Mockito.verify(this.session2, Mockito.times(1)).sendError(Mockito.any(Pcerr.class));
163         assertEquals(PCEPErrors.UPDATE_REQ_FOR_NON_LSP, this.errorsSession2.get(0));
164     }
165
166     @Test
167     public void testReturnDelegationPccLsp() throws InterruptedException {
168         final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 1, -1, TIMER, this.timerHandler);
169         tunnelManager.onSessionUp(this.session1);
170         tunnelManager.onSessionUp(this.session2);
171         tunnelManager.onMessagePcupd(createUpdate(1), this.session1);
172         Mockito.verify(this.session1, Mockito.times(3)).sendReport(Mockito.any(Pcrpt.class));
173         Mockito.verify(this.session2, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
174         //wait for re-delegation timer expires
175         Thread.sleep(1200);
176         Mockito.verify(this.session2, Mockito.times(3)).sendReport(Mockito.any(Pcrpt.class));
177     }
178
179     @Test
180     public void testReturnDelegationUnknownLsp() {
181         final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, 0, TIMER, this.timerHandler);
182         tunnelManager.onSessionUp(this.session1);
183         tunnelManager.onMessagePcupd(createUpdate(2), this.session1);
184         Mockito.verify(this.session1, Mockito.times(1)).sendError(Mockito.any(Pcerr.class));
185         assertEquals(PCEPErrors.UNKNOWN_PLSP_ID, this.errorsSession1.get(0));
186     }
187
188     @Test
189     public void testReturnDelegationNonDelegatedLsp() {
190         final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, 0, TIMER, this.timerHandler);
191         tunnelManager.onSessionUp(this.session1);
192         tunnelManager.onSessionUp(this.session2);
193         tunnelManager.onMessagePcupd(createUpdate(1), this.session2);
194         Mockito.verify(this.session2, Mockito.times(1)).sendError(Mockito.any(Pcerr.class));
195         assertEquals(PCEPErrors.UPDATE_REQ_FOR_NON_LSP, this.errorsSession2.get(0));
196     }
197
198     @Test
199     public void testAddTunnel() {
200         final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(0, ADDRESS, 0, 0, TIMER, this.timerHandler);
201         tunnelManager.onSessionUp(this.session1);
202         tunnelManager.onSessionUp(this.session2);
203         tunnelManager.onMessagePcInitiate(createRequests(1), this.session1);
204         Mockito.verify(this.session1, Mockito.times(1)).sendReport(Mockito.any(Pcrpt.class));
205         Mockito.verify(this.session2, Mockito.times(1)).sendReport(Mockito.any(Pcrpt.class));
206     }
207
208     @Test
209     public void testRemoveTunnel() {
210         final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(0, ADDRESS, 0, 0, TIMER, this.timerHandler);
211         tunnelManager.onSessionUp(this.session1);
212         tunnelManager.onSessionUp(this.session2);
213         tunnelManager.onMessagePcInitiate(createRequests(1), this.session1);
214         tunnelManager.onMessagePcInitiate(createRequestsRemove(1), this.session1);
215         Mockito.verify(this.session1, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
216         Mockito.verify(this.session2, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
217     }
218
219     @Test
220     public void testRemoveTunnelUnknownLsp() {
221         final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(0, ADDRESS, 0, 0, TIMER, this.timerHandler);
222         tunnelManager.onSessionUp(this.session1);
223         tunnelManager.onMessagePcInitiate(createRequestsRemove(1), this.session1);
224         Mockito.verify(this.session1, Mockito.times(1)).sendError(Mockito.any(Pcerr.class));
225         assertEquals(PCEPErrors.UNKNOWN_PLSP_ID, this.errorsSession1.get(0));
226     }
227
228     @Test
229     public void testRemoveTunnelNotPceInitiatedLsp() {
230         final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, 0, TIMER, this.timerHandler);
231         tunnelManager.onSessionUp(this.session1);
232         tunnelManager.onMessagePcInitiate(createRequestsRemove(1), this.session1);
233         Mockito.verify(this.session1, Mockito.times(1)).sendError(Mockito.any(Pcerr.class));
234         assertEquals(PCEPErrors.LSP_NOT_PCE_INITIATED, this.errorsSession1.get(0));
235     }
236
237     @Test
238     public void testRemoveTunnelNotDelegated() {
239         final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(0, ADDRESS, 0, 0, TIMER, this.timerHandler);
240         tunnelManager.onSessionUp(this.session1);
241         tunnelManager.onSessionUp(this.session2);
242         tunnelManager.onMessagePcInitiate(createRequests(1), this.session1);
243         tunnelManager.onMessagePcInitiate(createRequestsRemove(1), this.session2);
244         Mockito.verify(this.session2, Mockito.times(1)).sendError(Mockito.any(Pcerr.class));
245         assertEquals(PCEPErrors.UPDATE_REQ_FOR_NON_LSP, this.errorsSession2.get(0));
246     }
247
248     @Test
249     public void testTakeDelegation() throws InterruptedException {
250         final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(0, ADDRESS, 0, -1, TIMER, this.timerHandler);
251         tunnelManager.onSessionUp(this.session1);
252         tunnelManager.onSessionUp(this.session2);
253         tunnelManager.onMessagePcInitiate(createRequests(1), this.session1); //AddTunel
254         tunnelManager.onMessagePcupd(createUpdate(1), this.session1); //returnDelegation
255         Mockito.verify(this.session1, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
256         Mockito.verify(this.session2, Mockito.times(1)).sendReport(Mockito.any(Pcrpt.class));
257         Thread.sleep(500);
258         tunnelManager.onMessagePcInitiate(createRequestsDelegate(1), this.session2);//takeDelegation
259         Mockito.verify(this.session1, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
260         Mockito.verify(this.session2, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
261     }
262
263     @Test
264     public void testTakeDelegationUnknownLsp() {
265         final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(0, ADDRESS, 0, 0, TIMER, this.timerHandler);
266         tunnelManager.onSessionUp(this.session1);
267         tunnelManager.onMessagePcInitiate(createRequestsDelegate(1), this.session1);
268         Mockito.verify(this.session1, Mockito.times(1)).sendError(Mockito.any(Pcerr.class));
269         assertEquals(PCEPErrors.UNKNOWN_PLSP_ID, this.errorsSession1.get(0));
270     }
271
272     @Test
273     public void testTakeDelegationNotPceInitiatedLsp() {
274         final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, 0, TIMER, this.timerHandler);
275         tunnelManager.onSessionUp(this.session1);
276         tunnelManager.onMessagePcInitiate(createRequestsDelegate(1), this.session1);
277         Mockito.verify(this.session1, Mockito.times(1)).sendError(Mockito.any(Pcerr.class));
278         assertEquals(PCEPErrors.LSP_NOT_PCE_INITIATED, this.errorsSession1.get(0));
279     }
280
281     @Test
282     public void testReturnDelegationNoRetake() throws InterruptedException {
283         final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(0, ADDRESS, 0, 0, TIMER, this.timerHandler);
284         tunnelManager.onSessionUp(this.session1);
285         tunnelManager.onSessionUp(this.session2);
286         tunnelManager.onMessagePcInitiate(createRequests(1), this.session1);
287         tunnelManager.onMessagePcupd(createUpdate(1), this.session1);
288         //wait for state timeout expires
289         Thread.sleep(500);
290         Mockito.verify(this.session1, Mockito.times(3)).sendReport(Mockito.any(Pcrpt.class));
291         Mockito.verify(this.session2, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
292     }
293
294     private static Updates createUpdateDelegate(final long plspId) {
295         return createUpdate(plspId, Optional.of(Boolean.TRUE));
296     }
297
298     private static Updates createUpdate(final long plspId) {
299         return createUpdate(plspId, Optional.empty());
300     }
301
302     private static Updates createUpdate(final long plspId, final Optional<Boolean> delegate) {
303         final UpdatesBuilder updsBuilder = new UpdatesBuilder();
304         final LspBuilder lsp = new LspBuilder().setPlspId(new PlspId(Uint32.valueOf(plspId)));
305         if (delegate.isPresent()) {
306             lsp.setDelegate(Boolean.TRUE);
307         }
308         updsBuilder.setLsp(lsp.build());
309         final PathBuilder pathBuilder = new PathBuilder();
310         pathBuilder.setEro(ERO);
311         updsBuilder.setPath(pathBuilder.build());
312         updsBuilder.setSrp(new SrpBuilder().setOperationId(new SrpIdNumber(Uint32.ZERO)).build());
313         return updsBuilder.build();
314     }
315
316     private static Requests createRequests(final long plspId, final Optional<Boolean> remove,
317             final Optional<Boolean> delegate) {
318         final RequestsBuilder reqBuilder = new RequestsBuilder();
319         reqBuilder.setEro(ERO);
320         final LspBuilder lsp = new LspBuilder().setTlvs(new TlvsBuilder()
321             .setSymbolicPathName(new SymbolicPathNameBuilder().setPathName(
322             new SymbolicPathName(SYMBOLIC_NAME)).build()).build()).setPlspId(new PlspId(Uint32.valueOf(plspId)));
323         if (delegate.isPresent()) {
324             lsp.setDelegate(Boolean.TRUE);
325         }
326
327         reqBuilder.setLsp(lsp.build());
328         final SrpBuilder srpBuilder = new SrpBuilder();
329         if (remove.isPresent()) {
330             srpBuilder.addAugmentation(new Srp1Builder().setRemove(Boolean.TRUE).build());
331         }
332         return reqBuilder
333                 .setSrp(srpBuilder.setOperationId(new SrpIdNumber(Uint32.ZERO)).build())
334                 .build();
335     }
336
337     private static Requests createRequestsRemove(final long plspId) {
338         return createRequests(plspId, Optional.of(Boolean.TRUE), Optional.empty());
339     }
340
341     private static Requests createRequestsDelegate(final long plspId) {
342         return createRequests(plspId, Optional.empty(), Optional.of(Boolean.TRUE));
343     }
344
345     @SuppressWarnings("checkstyle:OverloadMethodsDeclarationOrder")
346     private static Requests createRequests(final long plspId) {
347         return createRequests(plspId, Optional.empty(), Optional.empty());
348     }
349
350     private static PCEPErrors getError(final Pcerr errorMessage) {
351         final ErrorObject errorObject = errorMessage.getPcerrMessage().getErrors().get(0).getErrorObject();
352         return PCEPErrors.forValue(errorObject.getType(), errorObject.getValue());
353     }
354
355 }