a1b462031cd1b9fd8d4ba3c2801c4969e91a1ef8
[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(session1).sendReport(Mockito.any(Pcrpt.class));
79         Mockito.doAnswer(new Answer<Void>() {
80             @Override
81             public Void answer(final InvocationOnMock invocation) throws Throwable {
82                 errorsSession1.add(getError((Pcerr) invocation.getArguments()[0]));
83                 return null;
84             }
85         }).when(session1).sendError(Mockito.any(Pcerr.class));
86         Mockito.doReturn(0).when(session1).getId();
87         Mockito.doNothing().when(session2).sendReport(Mockito.any(Pcrpt.class));
88         Mockito.doAnswer(new Answer<Void>() {
89             @Override
90             public Void answer(final InvocationOnMock invocation) throws Throwable {
91                 errorsSession2.add(getError((Pcerr) invocation.getArguments()[0]));
92                 return null;
93             }
94         }).when(session2).sendError(Mockito.any(Pcerr.class));
95         Mockito.doReturn(1).when(session2).getId();
96     }
97
98     @After
99     public void tearDown() {
100         this.errorsSession1.clear();
101         this.errorsSession2.clear();
102     }
103
104     @Test
105     public void testOnSessionUp() {
106         final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, 0, TIMER, this.timerHandler);
107         checkSessionUp(session1, tunnelManager);
108         checkSessionUp(session2, tunnelManager);
109     }
110
111     @Test
112     public void testOnSessionDownAndDelegateBack() throws InterruptedException {
113         final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 1, 10, TIMER, this.timerHandler);
114         checkSessionUp(session1, tunnelManager);
115         checkSessionUp(session2, tunnelManager);
116         checkSessionDown(session1, tunnelManager);
117         tunnelManager.onSessionUp(session1);
118         Mockito.verify(session1, Mockito.times(4)).sendReport(Mockito.any(Pcrpt.class));
119         Mockito.verify(session2, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
120     }
121
122     private static void checkSessionDown(final PCCSession session, final PCCTunnelManager tunnelManager) {
123         tunnelManager.onSessionDown(session);
124         Mockito.verify(session, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
125     }
126
127     private static void checkSessionUp(final PCCSession session, final PCCTunnelManager tunnelManager) {
128         //1 reported LSP + 1 end-of-sync marker
129         tunnelManager.onSessionUp(session);
130         Mockito.verify(session, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
131     }
132
133     @Test
134     public void testOnSessionDownAndDelegateToOther() throws InterruptedException {
135         final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, -1, TIMER, this.timerHandler);
136         tunnelManager.onSessionUp(session2);
137         checkSessionUp(session1, tunnelManager);
138         checkSessionDown(session1, tunnelManager);
139         //wait for re-delegation timeout expires
140         Thread.sleep(500);
141         Mockito.verify(session2, Mockito.times(3)).sendReport(Mockito.any(Pcrpt.class));
142         tunnelManager.onSessionUp(session1);
143         Mockito.verify(session1, Mockito.times(4)).sendReport(Mockito.any(Pcrpt.class));
144     }
145
146     @Test
147     public void testReportToAll() throws InterruptedException {
148         final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, 0, TIMER, this.timerHandler);
149         tunnelManager.onSessionUp(session1);
150         tunnelManager.onSessionUp(session2);
151         tunnelManager.onMessagePcupd(createUpdateDelegate(1), session1);
152         Mockito.verify(session1, Mockito.times(3)).sendReport(Mockito.any(Pcrpt.class));
153         Mockito.verify(session2, Mockito.times(3)).sendReport(Mockito.any(Pcrpt.class));
154     }
155
156     @Test
157     public void testReportToAllUnknownLsp() {
158         final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, 0, TIMER, this.timerHandler);
159         tunnelManager.onSessionUp(session1);
160         tunnelManager.onMessagePcupd(createUpdateDelegate(2), session1);
161         Mockito.verify(session1, Mockito.times(1)).sendError(Mockito.any(Pcerr.class));
162         assertEquals(PCEPErrors.UNKNOWN_PLSP_ID, errorsSession1.get(0));
163     }
164
165     @Test
166     public void testReportToAllNonDelegatedLsp() {
167         final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, 0, TIMER, this.timerHandler);
168         tunnelManager.onSessionUp(session1);
169         tunnelManager.onSessionUp(session2);
170         tunnelManager.onMessagePcupd(createUpdateDelegate(1), session2);
171         Mockito.verify(session2, Mockito.times(1)).sendError(Mockito.any(Pcerr.class));
172         assertEquals(PCEPErrors.UPDATE_REQ_FOR_NON_LSP, errorsSession2.get(0));
173     }
174
175     @Test
176     public void testReturnDelegationPccLsp() throws InterruptedException {
177         final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 1, -1, TIMER, this.timerHandler);
178         tunnelManager.onSessionUp(session1);
179         tunnelManager.onSessionUp(session2);
180         tunnelManager.onMessagePcupd(createUpdate(1), session1);
181         Mockito.verify(session1, Mockito.times(3)).sendReport(Mockito.any(Pcrpt.class));
182         Mockito.verify(session2, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
183         //wait for re-delegation timer expires
184         Thread.sleep(1200);
185         Mockito.verify(session2, Mockito.times(3)).sendReport(Mockito.any(Pcrpt.class));
186     }
187
188     @Test
189     public void testReturnDelegationUnknownLsp() {
190         final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, 0, TIMER, this.timerHandler);
191         tunnelManager.onSessionUp(session1);
192         tunnelManager.onMessagePcupd(createUpdate(2), session1);
193         Mockito.verify(session1, Mockito.times(1)).sendError(Mockito.any(Pcerr.class));
194         assertEquals(PCEPErrors.UNKNOWN_PLSP_ID, errorsSession1.get(0));
195     }
196
197     @Test
198     public void testReturnDelegationNonDelegatedLsp() {
199         final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, 0, TIMER, this.timerHandler);
200         tunnelManager.onSessionUp(session1);
201         tunnelManager.onSessionUp(session2);
202         tunnelManager.onMessagePcupd(createUpdate(1), session2);
203         Mockito.verify(session2, Mockito.times(1)).sendError(Mockito.any(Pcerr.class));
204         assertEquals(PCEPErrors.UPDATE_REQ_FOR_NON_LSP, errorsSession2.get(0));
205     }
206
207     @Test
208     public void testAddTunnel() {
209         final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(0, ADDRESS, 0, 0, TIMER, this.timerHandler);
210         tunnelManager.onSessionUp(session1);
211         tunnelManager.onSessionUp(session2);
212         tunnelManager.onMessagePcInitiate(createRequests(1), session1);
213         Mockito.verify(session1, Mockito.times(1)).sendReport(Mockito.any(Pcrpt.class));
214         Mockito.verify(session2, Mockito.times(1)).sendReport(Mockito.any(Pcrpt.class));
215     }
216
217     @Test
218     public void testRemoveTunnel() {
219         final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(0, ADDRESS, 0, 0, TIMER, this.timerHandler);
220         tunnelManager.onSessionUp(session1);
221         tunnelManager.onSessionUp(session2);
222         tunnelManager.onMessagePcInitiate(createRequests(1), session1);
223         tunnelManager.onMessagePcInitiate(createRequestsRemove(1), session1);
224         Mockito.verify(session1, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
225         Mockito.verify(session2, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
226     }
227
228     @Test
229     public void testRemoveTunnelUnknownLsp() {
230         final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(0, ADDRESS, 0, 0, TIMER, this.timerHandler);
231         tunnelManager.onSessionUp(session1);
232         tunnelManager.onMessagePcInitiate(createRequestsRemove(1), session1);
233         Mockito.verify(session1, Mockito.times(1)).sendError(Mockito.any(Pcerr.class));
234         assertEquals(PCEPErrors.UNKNOWN_PLSP_ID, errorsSession1.get(0));
235     }
236
237     @Test
238     public void testRemoveTunnelNotPceInitiatedLsp() {
239         final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, 0, TIMER, this.timerHandler);
240         tunnelManager.onSessionUp(session1);
241         tunnelManager.onMessagePcInitiate(createRequestsRemove(1), session1);
242         Mockito.verify(session1, Mockito.times(1)).sendError(Mockito.any(Pcerr.class));
243         assertEquals(PCEPErrors.LSP_NOT_PCE_INITIATED, errorsSession1.get(0));
244     }
245
246     @Test
247     public void testRemoveTunnelNotDelegated() {
248         final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(0, ADDRESS, 0, 0, TIMER, this.timerHandler);
249         tunnelManager.onSessionUp(session1);
250         tunnelManager.onSessionUp(session2);
251         tunnelManager.onMessagePcInitiate(createRequests(1), session1);
252         tunnelManager.onMessagePcInitiate(createRequestsRemove(1), session2);
253         Mockito.verify(session2, Mockito.times(1)).sendError(Mockito.any(Pcerr.class));
254         assertEquals(PCEPErrors.UPDATE_REQ_FOR_NON_LSP, errorsSession2.get(0));
255     }
256
257     @Test
258     public void testTakeDelegation() throws InterruptedException {
259         final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(0, ADDRESS, 0, -1, TIMER, this.timerHandler);
260         tunnelManager.onSessionUp(session1);
261         tunnelManager.onSessionUp(session2);
262         tunnelManager.onMessagePcInitiate(createRequests(1), session1); //AddTunel
263         tunnelManager.onMessagePcupd(createUpdate(1), session1); //returnDelegation
264         Mockito.verify(session1, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
265         Mockito.verify(session2, Mockito.times(1)).sendReport(Mockito.any(Pcrpt.class));
266         Thread.sleep(500);
267         tunnelManager.onMessagePcInitiate(createRequestsDelegate(1), session2);//takeDelegation
268         Mockito.verify(session1, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
269         Mockito.verify(session2, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
270     }
271
272     @Test
273     public void testTakeDelegationUnknownLsp() {
274         final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(0, ADDRESS, 0, 0, TIMER, this.timerHandler);
275         tunnelManager.onSessionUp(session1);
276         tunnelManager.onMessagePcInitiate(createRequestsDelegate(1), session1);
277         Mockito.verify(session1, Mockito.times(1)).sendError(Mockito.any(Pcerr.class));
278         assertEquals(PCEPErrors.UNKNOWN_PLSP_ID, errorsSession1.get(0));
279     }
280
281     @Test
282     public void testTakeDelegationNotPceInitiatedLsp() {
283         final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, 0, TIMER, this.timerHandler);
284         tunnelManager.onSessionUp(session1);
285         tunnelManager.onMessagePcInitiate(createRequestsDelegate(1), session1);
286         Mockito.verify(session1, Mockito.times(1)).sendError(Mockito.any(Pcerr.class));
287         assertEquals(PCEPErrors.LSP_NOT_PCE_INITIATED, errorsSession1.get(0));
288     }
289
290     @Test
291     public void testReturnDelegationNoRetake() throws InterruptedException {
292         final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(0, ADDRESS, 0, 0, TIMER, this.timerHandler);
293         tunnelManager.onSessionUp(session1);
294         tunnelManager.onSessionUp(session2);
295         tunnelManager.onMessagePcInitiate(createRequests(1), session1);
296         tunnelManager.onMessagePcupd(createUpdate(1), session1);
297         //wait for state timeout expires
298         Thread.sleep(500);
299         Mockito.verify(session1, Mockito.times(3)).sendReport(Mockito.any(Pcrpt.class));
300         Mockito.verify(session2, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
301     }
302     private Updates createUpdateDelegate(final long plspId) {
303         return createUpdate(plspId, Optional.of(true));
304     }
305
306     private Updates createUpdate(final long plspId) {
307         return createUpdate(plspId, Optional.<Boolean>absent());
308     }
309
310     private static Updates createUpdate(final long plspId, final Optional<Boolean> delegate) {
311         final UpdatesBuilder updsBuilder = new UpdatesBuilder();
312         final LspBuilder lsp = new LspBuilder().setPlspId(new PlspId(plspId));
313         if (delegate.isPresent()) {
314             lsp.setDelegate(true);
315         }
316         updsBuilder.setLsp(lsp.build());
317         final PathBuilder pathBuilder = new PathBuilder();
318         pathBuilder.setEro(ERO);
319         updsBuilder.setPath(pathBuilder.build());
320         updsBuilder.setSrp(new SrpBuilder().setOperationId(new SrpIdNumber(0L)).build());
321         return updsBuilder.build();
322     }
323
324     private static Requests createRequests(final long plspId, final Optional<Boolean> remove, final Optional<Boolean> delegate) {
325         final RequestsBuilder reqBuilder = new RequestsBuilder();
326         reqBuilder.setEro(ERO);
327         final LspBuilder lsp = new LspBuilder().setTlvs(new TlvsBuilder().setSymbolicPathName(new SymbolicPathNameBuilder().setPathName(
328             new SymbolicPathName(SYMBOLIC_NAME)).build()).build()).setPlspId(new PlspId(plspId));
329         if (delegate.isPresent()) {
330             lsp.setDelegate(true);
331         }
332
333         reqBuilder.setLsp(lsp.build());
334         final SrpBuilder srpBuilder = new SrpBuilder();
335         if (remove.isPresent()) {
336             srpBuilder.addAugmentation(Srp1.class, new Srp1Builder().setRemove(true).build());
337         }
338         reqBuilder.setSrp(srpBuilder.setOperationId(new SrpIdNumber(0L)).build());
339         return reqBuilder.build();
340     }
341
342     private static Requests createRequestsRemove(final long plspId) {
343         return createRequests(plspId, Optional.of(true), Optional.<Boolean>absent());
344     }
345
346     private static Requests createRequestsDelegate(final long plspId) {
347         return createRequests(plspId, Optional.<Boolean>absent(), Optional.of(true));
348     }
349
350     private static Requests createRequests(final long plspId) {
351         return createRequests(plspId, Optional.<Boolean>absent(), Optional.<Boolean>absent());
352     }
353
354     private static PCEPErrors getError(final Pcerr errorMessage) {
355         final ErrorObject errorObject = errorMessage.getPcerrMessage().getErrors().get(0).getErrorObject();
356         return PCEPErrors.forValue(errorObject.getType(), errorObject.getValue());
357     }
358
359 }