2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
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
9 package org.opendaylight.protocol.pcep.pcc.mock;
11 import static org.junit.Assert.assertEquals;
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.crabbe.initiated.rev181109.Srp1;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev181109.Srp1Builder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev181109.pcinitiate.message.pcinitiate.message.Requests;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev181109.pcinitiate.message.pcinitiate.message.RequestsBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.Pcrpt;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.PlspId;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.SrpIdNumber;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.SymbolicPathName;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.lsp.object.LspBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.lsp.object.lsp.TlvsBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.pcupd.message.pcupd.message.Updates;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.pcupd.message.pcupd.message.UpdatesBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.pcupd.message.pcupd.message.updates.PathBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.srp.object.SrpBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.symbolic.path.name.tlv.SymbolicPathNameBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev181109.Pcerr;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.explicit.route.object.Ero;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.explicit.route.object.EroBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.explicit.route.object.ero.SubobjectBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcep.error.object.ErrorObject;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.basic.explicit.route.subobjects.subobject.type.IpPrefixCaseBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.basic.explicit.route.subobjects.subobject.type.ip.prefix._case.IpPrefixBuilder;
55 import org.opendaylight.yangtools.yang.common.Uint32;
57 public class PCCTunnelManagerImplTest {
59 private static final InetAddress ADDRESS = InetAddresses.forString("1.2.4.5");
60 private static final Timer TIMER = new HashedWheelTimer();
61 private static final byte[] SYMBOLIC_NAME = "tets".getBytes(StandardCharsets.UTF_8);
62 private static final Ero ERO = new EroBuilder().setSubobject(Lists.newArrayList(new SubobjectBuilder()
63 .setSubobjectType(new IpPrefixCaseBuilder().setIpPrefix(new IpPrefixBuilder()
64 .setIpPrefix(new IpPrefix(new Ipv4Prefix("127.0.0.2/32"))).build()).build()).build())).build();
65 private final List<PCEPErrors> errorsSession1 = new ArrayList<>();
66 private final List<PCEPErrors> errorsSession2 = new ArrayList<>();
68 private PCCSession session1;
70 private PCCSession session2;
71 private final Optional<TimerHandler> timerHandler = Optional.empty();
75 MockitoAnnotations.initMocks(this);
76 Mockito.doNothing().when(this.session1).sendReport(Mockito.any(Pcrpt.class));
77 Mockito.doAnswer(invocation -> {
78 PCCTunnelManagerImplTest.this.errorsSession1.add(getError((Pcerr) invocation.getArguments()[0]));
80 }).when(this.session1).sendError(Mockito.any(Pcerr.class));
81 Mockito.doReturn(0).when(this.session1).getId();
82 Mockito.doNothing().when(this.session2).sendReport(Mockito.any(Pcrpt.class));
83 Mockito.doAnswer(invocation -> {
84 PCCTunnelManagerImplTest.this.errorsSession2.add(getError((Pcerr) invocation.getArguments()[0]));
86 }).when(this.session2).sendError(Mockito.any(Pcerr.class));
87 Mockito.doReturn(1).when(this.session2).getId();
91 public void tearDown() {
92 this.errorsSession1.clear();
93 this.errorsSession2.clear();
97 public void testOnSessionUp() {
98 final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, 0, TIMER, this.timerHandler);
99 checkSessionUp(this.session1, tunnelManager);
100 checkSessionUp(this.session2, tunnelManager);
104 public void testOnSessionDownAndDelegateBack() {
105 final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 1, 10, TIMER, this.timerHandler);
106 checkSessionUp(this.session1, tunnelManager);
107 checkSessionUp(this.session2, tunnelManager);
108 checkSessionDown(this.session1, tunnelManager);
109 tunnelManager.onSessionUp(this.session1);
110 Mockito.verify(this.session1, Mockito.times(4)).sendReport(Mockito.any(Pcrpt.class));
111 Mockito.verify(this.session2, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
114 private static void checkSessionDown(final PCCSession session, final PCCTunnelManager tunnelManager) {
115 tunnelManager.onSessionDown(session);
116 Mockito.verify(session, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
119 private static void checkSessionUp(final PCCSession session, final PCCTunnelManager tunnelManager) {
120 //1 reported LSP + 1 end-of-sync marker
121 tunnelManager.onSessionUp(session);
122 Mockito.verify(session, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
126 public void testOnSessionDownAndDelegateToOther() throws InterruptedException {
127 final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, -1, TIMER, this.timerHandler);
128 tunnelManager.onSessionUp(this.session2);
129 checkSessionUp(this.session1, tunnelManager);
130 checkSessionDown(this.session1, tunnelManager);
131 //wait for re-delegation timeout expires
133 Mockito.verify(this.session2, Mockito.times(3)).sendReport(Mockito.any(Pcrpt.class));
134 tunnelManager.onSessionUp(this.session1);
135 Mockito.verify(this.session1, Mockito.times(4)).sendReport(Mockito.any(Pcrpt.class));
139 public void testReportToAll() {
140 final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, 0, TIMER, this.timerHandler);
141 tunnelManager.onSessionUp(this.session1);
142 tunnelManager.onSessionUp(this.session2);
143 tunnelManager.onMessagePcupd(createUpdateDelegate(1), this.session1);
144 Mockito.verify(this.session1, Mockito.times(3)).sendReport(Mockito.any(Pcrpt.class));
145 Mockito.verify(this.session2, Mockito.times(3)).sendReport(Mockito.any(Pcrpt.class));
149 public void testReportToAllUnknownLsp() {
150 final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, 0, TIMER, this.timerHandler);
151 tunnelManager.onSessionUp(this.session1);
152 tunnelManager.onMessagePcupd(createUpdateDelegate(2), this.session1);
153 Mockito.verify(this.session1, Mockito.times(1)).sendError(Mockito.any(Pcerr.class));
154 assertEquals(PCEPErrors.UNKNOWN_PLSP_ID, this.errorsSession1.get(0));
158 public void testReportToAllNonDelegatedLsp() {
159 final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, 0, TIMER, this.timerHandler);
160 tunnelManager.onSessionUp(this.session1);
161 tunnelManager.onSessionUp(this.session2);
162 tunnelManager.onMessagePcupd(createUpdateDelegate(1), this.session2);
163 Mockito.verify(this.session2, Mockito.times(1)).sendError(Mockito.any(Pcerr.class));
164 assertEquals(PCEPErrors.UPDATE_REQ_FOR_NON_LSP, this.errorsSession2.get(0));
168 public void testReturnDelegationPccLsp() throws InterruptedException {
169 final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 1, -1, TIMER, this.timerHandler);
170 tunnelManager.onSessionUp(this.session1);
171 tunnelManager.onSessionUp(this.session2);
172 tunnelManager.onMessagePcupd(createUpdate(1), this.session1);
173 Mockito.verify(this.session1, Mockito.times(3)).sendReport(Mockito.any(Pcrpt.class));
174 Mockito.verify(this.session2, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
175 //wait for re-delegation timer expires
177 Mockito.verify(this.session2, Mockito.times(3)).sendReport(Mockito.any(Pcrpt.class));
181 public void testReturnDelegationUnknownLsp() {
182 final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, 0, TIMER, this.timerHandler);
183 tunnelManager.onSessionUp(this.session1);
184 tunnelManager.onMessagePcupd(createUpdate(2), this.session1);
185 Mockito.verify(this.session1, Mockito.times(1)).sendError(Mockito.any(Pcerr.class));
186 assertEquals(PCEPErrors.UNKNOWN_PLSP_ID, this.errorsSession1.get(0));
190 public void testReturnDelegationNonDelegatedLsp() {
191 final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, 0, TIMER, this.timerHandler);
192 tunnelManager.onSessionUp(this.session1);
193 tunnelManager.onSessionUp(this.session2);
194 tunnelManager.onMessagePcupd(createUpdate(1), this.session2);
195 Mockito.verify(this.session2, Mockito.times(1)).sendError(Mockito.any(Pcerr.class));
196 assertEquals(PCEPErrors.UPDATE_REQ_FOR_NON_LSP, this.errorsSession2.get(0));
200 public void testAddTunnel() {
201 final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(0, ADDRESS, 0, 0, TIMER, this.timerHandler);
202 tunnelManager.onSessionUp(this.session1);
203 tunnelManager.onSessionUp(this.session2);
204 tunnelManager.onMessagePcInitiate(createRequests(1), this.session1);
205 Mockito.verify(this.session1, Mockito.times(1)).sendReport(Mockito.any(Pcrpt.class));
206 Mockito.verify(this.session2, Mockito.times(1)).sendReport(Mockito.any(Pcrpt.class));
210 public void testRemoveTunnel() {
211 final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(0, ADDRESS, 0, 0, TIMER, this.timerHandler);
212 tunnelManager.onSessionUp(this.session1);
213 tunnelManager.onSessionUp(this.session2);
214 tunnelManager.onMessagePcInitiate(createRequests(1), this.session1);
215 tunnelManager.onMessagePcInitiate(createRequestsRemove(1), this.session1);
216 Mockito.verify(this.session1, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
217 Mockito.verify(this.session2, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
221 public void testRemoveTunnelUnknownLsp() {
222 final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(0, ADDRESS, 0, 0, TIMER, this.timerHandler);
223 tunnelManager.onSessionUp(this.session1);
224 tunnelManager.onMessagePcInitiate(createRequestsRemove(1), this.session1);
225 Mockito.verify(this.session1, Mockito.times(1)).sendError(Mockito.any(Pcerr.class));
226 assertEquals(PCEPErrors.UNKNOWN_PLSP_ID, this.errorsSession1.get(0));
230 public void testRemoveTunnelNotPceInitiatedLsp() {
231 final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, 0, TIMER, this.timerHandler);
232 tunnelManager.onSessionUp(this.session1);
233 tunnelManager.onMessagePcInitiate(createRequestsRemove(1), this.session1);
234 Mockito.verify(this.session1, Mockito.times(1)).sendError(Mockito.any(Pcerr.class));
235 assertEquals(PCEPErrors.LSP_NOT_PCE_INITIATED, this.errorsSession1.get(0));
239 public void testRemoveTunnelNotDelegated() {
240 final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(0, ADDRESS, 0, 0, TIMER, this.timerHandler);
241 tunnelManager.onSessionUp(this.session1);
242 tunnelManager.onSessionUp(this.session2);
243 tunnelManager.onMessagePcInitiate(createRequests(1), this.session1);
244 tunnelManager.onMessagePcInitiate(createRequestsRemove(1), this.session2);
245 Mockito.verify(this.session2, Mockito.times(1)).sendError(Mockito.any(Pcerr.class));
246 assertEquals(PCEPErrors.UPDATE_REQ_FOR_NON_LSP, this.errorsSession2.get(0));
250 public void testTakeDelegation() throws InterruptedException {
251 final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(0, ADDRESS, 0, -1, TIMER, this.timerHandler);
252 tunnelManager.onSessionUp(this.session1);
253 tunnelManager.onSessionUp(this.session2);
254 tunnelManager.onMessagePcInitiate(createRequests(1), this.session1); //AddTunel
255 tunnelManager.onMessagePcupd(createUpdate(1), this.session1); //returnDelegation
256 Mockito.verify(this.session1, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
257 Mockito.verify(this.session2, Mockito.times(1)).sendReport(Mockito.any(Pcrpt.class));
259 tunnelManager.onMessagePcInitiate(createRequestsDelegate(1), this.session2);//takeDelegation
260 Mockito.verify(this.session1, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
261 Mockito.verify(this.session2, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
265 public void testTakeDelegationUnknownLsp() {
266 final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(0, ADDRESS, 0, 0, TIMER, this.timerHandler);
267 tunnelManager.onSessionUp(this.session1);
268 tunnelManager.onMessagePcInitiate(createRequestsDelegate(1), this.session1);
269 Mockito.verify(this.session1, Mockito.times(1)).sendError(Mockito.any(Pcerr.class));
270 assertEquals(PCEPErrors.UNKNOWN_PLSP_ID, this.errorsSession1.get(0));
274 public void testTakeDelegationNotPceInitiatedLsp() {
275 final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(1, ADDRESS, 0, 0, TIMER, this.timerHandler);
276 tunnelManager.onSessionUp(this.session1);
277 tunnelManager.onMessagePcInitiate(createRequestsDelegate(1), this.session1);
278 Mockito.verify(this.session1, Mockito.times(1)).sendError(Mockito.any(Pcerr.class));
279 assertEquals(PCEPErrors.LSP_NOT_PCE_INITIATED, this.errorsSession1.get(0));
283 public void testReturnDelegationNoRetake() throws InterruptedException {
284 final PCCTunnelManager tunnelManager = new PCCTunnelManagerImpl(0, ADDRESS, 0, 0, TIMER, this.timerHandler);
285 tunnelManager.onSessionUp(this.session1);
286 tunnelManager.onSessionUp(this.session2);
287 tunnelManager.onMessagePcInitiate(createRequests(1), this.session1);
288 tunnelManager.onMessagePcupd(createUpdate(1), this.session1);
289 //wait for state timeout expires
291 Mockito.verify(this.session1, Mockito.times(3)).sendReport(Mockito.any(Pcrpt.class));
292 Mockito.verify(this.session2, Mockito.times(2)).sendReport(Mockito.any(Pcrpt.class));
295 private static Updates createUpdateDelegate(final long plspId) {
296 return createUpdate(plspId, Optional.of(Boolean.TRUE));
299 private static Updates createUpdate(final long plspId) {
300 return createUpdate(plspId, Optional.empty());
303 private static Updates createUpdate(final long plspId, final Optional<Boolean> delegate) {
304 final UpdatesBuilder updsBuilder = new UpdatesBuilder();
305 final LspBuilder lsp = new LspBuilder().setPlspId(new PlspId(Uint32.valueOf(plspId)));
306 if (delegate.isPresent()) {
307 lsp.setDelegate(Boolean.TRUE);
309 updsBuilder.setLsp(lsp.build());
310 final PathBuilder pathBuilder = new PathBuilder();
311 pathBuilder.setEro(ERO);
312 updsBuilder.setPath(pathBuilder.build());
313 updsBuilder.setSrp(new SrpBuilder().setOperationId(new SrpIdNumber(Uint32.ZERO)).build());
314 return updsBuilder.build();
317 private static Requests createRequests(final long plspId, final Optional<Boolean> remove,
318 final Optional<Boolean> delegate) {
319 final RequestsBuilder reqBuilder = new RequestsBuilder();
320 reqBuilder.setEro(ERO);
321 final LspBuilder lsp = new LspBuilder().setTlvs(new TlvsBuilder()
322 .setSymbolicPathName(new SymbolicPathNameBuilder().setPathName(
323 new SymbolicPathName(SYMBOLIC_NAME)).build()).build()).setPlspId(new PlspId(Uint32.valueOf(plspId)));
324 if (delegate.isPresent()) {
325 lsp.setDelegate(Boolean.TRUE);
328 reqBuilder.setLsp(lsp.build());
329 final SrpBuilder srpBuilder = new SrpBuilder();
330 if (remove.isPresent()) {
331 srpBuilder.addAugmentation(Srp1.class, new Srp1Builder().setRemove(Boolean.TRUE).build());
333 reqBuilder.setSrp(srpBuilder.setOperationId(new SrpIdNumber(Uint32.ZERO)).build());
334 return reqBuilder.build();
337 private static Requests createRequestsRemove(final long plspId) {
338 return createRequests(plspId, Optional.of(Boolean.TRUE), Optional.empty());
341 private static Requests createRequestsDelegate(final long plspId) {
342 return createRequests(plspId, Optional.empty(), Optional.of(Boolean.TRUE));
345 @SuppressWarnings("checkstyle:OverloadMethodsDeclarationOrder")
346 private static Requests createRequests(final long plspId) {
347 return createRequests(plspId, Optional.empty(), Optional.empty());
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());