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