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.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;
58 public class PCCTunnelManagerImplTest {
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<>();
69 private PCCSession session1;
71 private PCCSession session2;
73 private Optional<TimerHandler> timerHandler;
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]));
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]));
88 }).when(this.session2).sendError(Mockito.any(Pcerr.class));
89 Mockito.doReturn(1).when(this.session2).getId();
93 public void tearDown() {
94 this.errorsSession1.clear();
95 this.errorsSession2.clear();
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);
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));
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));
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));
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
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));
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));
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));
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));
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
179 Mockito.verify(this.session2, Mockito.times(3)).sendReport(Mockito.any(Pcrpt.class));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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
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));
296 private Updates createUpdateDelegate(final long plspId) {
297 return createUpdate(plspId, Optional.of(true));
300 private Updates createUpdate(final long plspId) {
301 return createUpdate(plspId, Optional.absent());
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);
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();
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);
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());
332 reqBuilder.setSrp(srpBuilder.setOperationId(new SrpIdNumber(0L)).build());
333 return reqBuilder.build();
336 private static Requests createRequestsRemove(final long plspId) {
337 return createRequests(plspId, Optional.of(true), Optional.absent());
340 private static Requests createRequestsDelegate(final long plspId) {
341 return createRequests(plspId, Optional.absent(), Optional.of(true));
344 private static Requests createRequests(final long plspId) {
345 return createRequests(plspId, Optional.absent(), Optional.absent());
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());