2 * Copyright (c) 2014 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.bgpcep.pcep.topology.provider;
11 import static org.junit.Assert.assertEquals;
12 import static org.junit.Assert.assertFalse;
13 import static org.junit.Assert.assertNotNull;
14 import static org.junit.Assert.assertNull;
15 import static org.junit.Assert.assertTrue;
16 import static org.junit.Assert.fail;
17 import static org.opendaylight.protocol.pcep.pcc.mock.spi.MsgBuilderUtil.createLspTlvs;
18 import static org.opendaylight.protocol.util.CheckTestUtil.checkEquals;
19 import static org.opendaylight.protocol.util.CheckTestUtil.checkNotPresentOperational;
20 import static org.opendaylight.protocol.util.CheckTestUtil.readDataOperational;
22 import com.google.common.collect.Lists;
23 import java.util.Collections;
24 import java.util.List;
25 import java.util.Optional;
26 import java.util.concurrent.ExecutionException;
27 import java.util.concurrent.Future;
28 import java.util.concurrent.TimeUnit;
29 import java.util.concurrent.TimeoutException;
30 import org.junit.Before;
31 import org.junit.Test;
32 import org.opendaylight.protocol.pcep.PCEPCloseTermination;
33 import org.opendaylight.protocol.pcep.TerminationReason;
34 import org.opendaylight.protocol.pcep.impl.PCEPSessionImpl;
35 import org.opendaylight.protocol.pcep.pcc.mock.spi.MsgBuilderUtil;
36 import org.opendaylight.protocol.pcep.spi.AbstractMessageParser;
37 import org.opendaylight.protocol.pcep.spi.PCEPErrors;
38 import org.opendaylight.protocol.util.CheckTestUtil;
39 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.topology.rev140113.NetworkTopologyRef;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev181109.Pcinitiate;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev181109.Stateful1;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev181109.Stateful1Builder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev181109.pcinitiate.message.pcinitiate.message.Requests;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.Arguments1;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.Arguments1Builder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.Arguments2;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.Arguments2Builder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.Arguments3;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.Arguments3Builder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.OperationalStatus;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.Pcrpt;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.PcrptBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.Pcupd;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.PlspId;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.SymbolicPathName;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.Tlvs1;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.Tlvs1Builder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.lsp.identifiers.tlv.LspIdentifiersBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.lsp.object.LspBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.lsp.object.lsp.Tlvs;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.pcrpt.message.PcrptMessageBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.pcrpt.message.pcrpt.message.Reports;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.pcrpt.message.pcrpt.message.ReportsBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.pcrpt.message.pcrpt.message.reports.PathBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.pcupd.message.pcupd.message.Updates;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.stateful.capability.tlv.StatefulBuilder;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.symbolic.path.name.tlv.SymbolicPathNameBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev181109.Close;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stateful.stats.rev181109.StatefulCapabilitiesStatsAug;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stateful.stats.rev181109.StatefulMessagesStatsAug;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.PcepSessionState;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.LocalPref;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.PeerPref;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.reply.time.grouping.ReplyTime;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.Message;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.endpoints.address.family.Ipv4CaseBuilder;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.endpoints.address.family.ipv4._case.Ipv4Builder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.endpoints.object.EndpointsObjBuilder;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.explicit.route.object.EroBuilder;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.open.object.Open;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.open.object.OpenBuilder;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.open.object.open.TlvsBuilder;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcep.error.object.ErrorObject;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.LspId;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev181109.AddLspInput;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev181109.AddLspInputBuilder;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev181109.AddLspOutput;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev181109.EnsureLspOperationalInput;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev181109.EnsureLspOperationalInputBuilder;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev181109.FailureType;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev181109.OperationResult;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev181109.RemoveLspInput;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev181109.RemoveLspInputBuilder;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev181109.UpdateLspInput;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev181109.UpdateLspInputBuilder;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev181109.UpdateLspOutput;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev181109.add.lsp.args.ArgumentsBuilder;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev181109.pcep.client.attributes.path.computation.client.ReportedLsp;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev181109.pcep.client.attributes.path.computation.client.reported.lsp.Path;
101 import org.opendaylight.yangtools.yang.common.RpcResult;
103 public class Stateful07TopologySessionListenerTest
104 extends AbstractPCEPSessionTest<Stateful07TopologySessionListenerFactory> {
106 private final String tunnelName = "pcc_" + this.testAddress + "_tunnel_0";
108 private Stateful07TopologySessionListener listener;
110 private PCEPSessionImpl session;
114 public void setUp() throws Exception {
116 this.listener = (Stateful07TopologySessionListener) getSessionListener();
117 this.session = getPCEPSession(getLocalPref(), getRemotePref());
121 public void testStateful07TopologySessionListener() throws Exception {
122 this.listener.onSessionUp(this.session);
123 final PcepSessionState listenerState = this.listener.listenerState;
124 assertEquals(this.testAddress, listenerState.getPeerPref().getIpAddress());
125 final LocalPref state = this.listener.listenerState.getLocalPref();
126 assertNotNull(state);
127 assertEquals(DEAD_TIMER, state.getDeadtimer().shortValue());
128 assertEquals(KEEP_ALIVE, state.getKeepalive().shortValue());
129 assertEquals(0, state.getSessionId().intValue());
130 assertEquals(this.testAddress, state.getIpAddress());
132 final PeerPref peerState = listenerState.getPeerPref();
134 assertEquals(DEAD_TIMER, peerState.getDeadtimer().shortValue());
135 assertEquals(KEEP_ALIVE, peerState.getKeepalive().shortValue());
136 assertEquals(0, peerState.getSessionId().intValue());
137 assertEquals(this.testAddress, peerState.getIpAddress());
140 this.topologyRpcs.addLsp(createAddLspInput());
141 assertEquals(1, this.receivedMsgs.size());
142 assertTrue(this.receivedMsgs.get(0) instanceof Pcinitiate);
143 final Pcinitiate pcinitiate = (Pcinitiate) this.receivedMsgs.get(0);
144 final Requests req = pcinitiate.getPcinitiateMessage().getRequests().get(0);
145 final long srpId = req.getSrp().getOperationId().getValue();
146 final Tlvs tlvs = createLspTlvs(req.getLsp().getPlspId().getValue(), true,
147 this.testAddress, this.testAddress, this.testAddress, Optional.empty());
148 final Pcrpt pcRpt = MsgBuilderUtil.createPcRtpMessage(new LspBuilder(req.getLsp())
149 .setTlvs(tlvs).setPlspId(new PlspId(1L)).setSync(false).setRemove(false)
150 .setOperational(OperationalStatus.Active).build(), Optional.of(MsgBuilderUtil.createSrp(srpId)),
151 MsgBuilderUtil.createPath(req.getEro().getSubobject()));
152 final Pcrpt esm = MsgBuilderUtil.createPcRtpMessage(new LspBuilder().setSync(false).build(),
153 Optional.of(MsgBuilderUtil.createSrp(0L)), null);
154 this.listener.onMessage(this.session, esm);
155 readDataOperational(getDataBroker(), this.pathComputationClientIId, pcc -> {
156 assertEquals(this.testAddress, pcc.getIpAddress().getIpv4Address().getValue());
157 // reported lsp so far empty, has not received response (PcRpt) yet
158 assertTrue(pcc.getReportedLsp().isEmpty());
162 this.listener.onMessage(this.session, pcRpt);
164 readDataOperational(getDataBroker(), this.pathComputationClientIId, pcc -> {
165 assertEquals(1, pcc.getReportedLsp().size());
166 final ReportedLsp reportedLsp = pcc.getReportedLsp().get(0);
167 assertEquals(this.tunnelName, reportedLsp.getName());
168 assertEquals(1, reportedLsp.getPath().size());
169 final Path path = reportedLsp.getPath().get(0);
170 assertEquals(1, path.getEro().getSubobject().size());
171 assertEquals(this.eroIpPrefix, getLastEroIpPrefix(path.getEro()));
176 checkEquals(() -> assertEquals(1, listenerState.getDelegatedLspsCount().intValue()));
177 checkEquals(() -> assertTrue(this.listener.isSessionSynchronized()));
178 checkEquals(() -> assertTrue(listenerState.getMessages()
179 .augmentation(StatefulMessagesStatsAug.class).getLastReceivedRptMsgTimestamp() > 0));
180 checkEquals(() -> assertEquals(2, listenerState.getMessages()
181 .augmentation(StatefulMessagesStatsAug.class).getReceivedRptMsgCount().intValue()));
182 checkEquals(() -> assertEquals(1, listenerState.getMessages()
183 .augmentation(StatefulMessagesStatsAug.class).getSentInitMsgCount().intValue()));
184 checkEquals(() -> assertEquals(0, listenerState.getMessages()
185 .augmentation(StatefulMessagesStatsAug.class).getSentUpdMsgCount().intValue()));
188 final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev181109.update.lsp.args
189 .ArgumentsBuilder updArgsBuilder = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang
190 .topology.pcep.rev181109.update.lsp.args.ArgumentsBuilder();
191 updArgsBuilder.setEro(createEroWithIpPrefixes(Lists.newArrayList(this.eroIpPrefix, this.dstIpPrefix)));
192 updArgsBuilder.addAugmentation(Arguments3.class, new Arguments3Builder().setLsp(new LspBuilder()
193 .setDelegate(true).setAdministrative(true).build()).build());
194 final UpdateLspInput update = new UpdateLspInputBuilder().setArguments(updArgsBuilder.build())
195 .setName(this.tunnelName).setNetworkTopologyRef(new NetworkTopologyRef(TOPO_IID))
196 .setNode(this.nodeId).build();
197 this.topologyRpcs.updateLsp(update);
198 assertEquals(2, this.receivedMsgs.size());
199 assertTrue(this.receivedMsgs.get(1) instanceof Pcupd);
200 final Pcupd updateMsg = (Pcupd) this.receivedMsgs.get(1);
201 final Updates upd = updateMsg.getPcupdMessage().getUpdates().get(0);
202 final long srpId2 = upd.getSrp().getOperationId().getValue();
203 final Tlvs tlvs2 = createLspTlvs(upd.getLsp().getPlspId().getValue(), false,
204 this.newDestinationAddress, this.testAddress, this.testAddress, Optional.empty());
205 final Pcrpt pcRpt2 = MsgBuilderUtil.createPcRtpMessage(new LspBuilder(upd.getLsp()).setTlvs(tlvs2)
206 .setSync(true).setRemove(false).setOperational(OperationalStatus.Active).build(),
207 Optional.of(MsgBuilderUtil.createSrp(srpId2)), MsgBuilderUtil.createPath(upd.getPath()
208 .getEro().getSubobject()));
209 this.listener.onMessage(this.session, pcRpt2);
212 readDataOperational(getDataBroker(), this.pathComputationClientIId, pcc -> {
213 assertEquals(1, pcc.getReportedLsp().size());
214 final ReportedLsp reportedLsp = pcc.getReportedLsp().get(0);
215 assertEquals(this.tunnelName, reportedLsp.getName());
216 assertEquals(1, reportedLsp.getPath().size());
217 final Path path = reportedLsp.getPath().get(0);
218 assertEquals(2, path.getEro().getSubobject().size());
219 assertEquals(this.dstIpPrefix, getLastEroIpPrefix(path.getEro()));
220 assertEquals(1, listenerState.getDelegatedLspsCount().intValue());
221 assertTrue(this.listener.isSessionSynchronized());
222 final StatefulMessagesStatsAug statefulstate = listenerState.getMessages()
223 .augmentation(StatefulMessagesStatsAug.class);
224 assertTrue(statefulstate.getLastReceivedRptMsgTimestamp() > 0);
225 assertEquals(3, statefulstate.getReceivedRptMsgCount().intValue());
226 assertEquals(1, statefulstate.getSentInitMsgCount().intValue());
227 assertEquals(1, statefulstate.getSentUpdMsgCount().intValue());
228 final ReplyTime replyTime = listenerState.getMessages().getReplyTime();
229 assertTrue(replyTime.getAverageTime() > 0);
230 assertTrue(replyTime.getMaxTime() > 0);
231 final StatefulCapabilitiesStatsAug statefulCapabilities = listenerState
232 .getPeerCapabilities().augmentation(StatefulCapabilitiesStatsAug.class);
233 assertFalse(statefulCapabilities.isActive());
234 assertTrue(statefulCapabilities.isInstantiation());
235 assertTrue(statefulCapabilities.isStateful());
239 // ensure-operational
240 final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev181109.ensure.lsp
241 .operational.args.ArgumentsBuilder ensureArgs = new org.opendaylight.yang.gen.v1.urn.opendaylight.params
242 .xml.ns.yang.topology.pcep.rev181109.ensure.lsp.operational.args.ArgumentsBuilder();
243 ensureArgs.addAugmentation(Arguments1.class, new Arguments1Builder().setOperational(OperationalStatus.Active)
245 final EnsureLspOperationalInput ensure = new EnsureLspOperationalInputBuilder().setArguments(ensureArgs.build())
246 .setName(this.tunnelName).setNetworkTopologyRef(new NetworkTopologyRef(TOPO_IID))
247 .setNode(this.nodeId).build();
248 final OperationResult result = this.topologyRpcs.ensureLspOperational(ensure).get().getResult();
250 assertNull(result.getFailure());
253 final RemoveLspInput remove = new RemoveLspInputBuilder().setName(this.tunnelName)
254 .setNetworkTopologyRef(new NetworkTopologyRef(TOPO_IID)).setNode(this.nodeId).build();
255 this.topologyRpcs.removeLsp(remove);
256 assertEquals(3, this.receivedMsgs.size());
257 assertTrue(this.receivedMsgs.get(2) instanceof Pcinitiate);
258 final Pcinitiate pcinitiate2 = (Pcinitiate) this.receivedMsgs.get(2);
259 final Requests req2 = pcinitiate2.getPcinitiateMessage().getRequests().get(0);
260 final long srpId3 = req2.getSrp().getOperationId().getValue();
261 final Tlvs tlvs3 = createLspTlvs(req2.getLsp().getPlspId().getValue(), false,
262 this.testAddress, this.testAddress, this.testAddress, Optional.empty());
263 final Pcrpt pcRpt3 = MsgBuilderUtil.createPcRtpMessage(new LspBuilder(req2.getLsp()).setTlvs(tlvs3)
264 .setRemove(true).setSync(true).setOperational(OperationalStatus.Down).build(),
265 Optional.of(MsgBuilderUtil.createSrp(srpId3)), MsgBuilderUtil.createPath(Collections.emptyList()));
266 this.listener.onMessage(this.session, pcRpt3);
268 // check if lsp was removed
269 readDataOperational(getDataBroker(), this.pathComputationClientIId, pcc -> {
270 assertNull(pcc.getReportedLsp());
274 checkEquals(() -> assertEquals(0, listenerState.getDelegatedLspsCount().intValue()));
275 checkEquals(() -> assertTrue(this.listener.isSessionSynchronized()));
276 checkEquals(() -> assertTrue(listenerState.getMessages()
277 .augmentation(StatefulMessagesStatsAug.class).getLastReceivedRptMsgTimestamp() > 0));
278 checkEquals(() -> assertEquals(4, listenerState.getMessages()
279 .augmentation(StatefulMessagesStatsAug.class).getReceivedRptMsgCount().intValue()));
280 checkEquals(() -> assertEquals(2, listenerState.getMessages()
281 .augmentation(StatefulMessagesStatsAug.class).getSentInitMsgCount().intValue()));
282 checkEquals(() -> assertEquals(1, listenerState.getMessages()
283 .augmentation(StatefulMessagesStatsAug.class).getSentUpdMsgCount().intValue()));
287 public void testOnUnhandledErrorMessage() {
288 final Message errorMsg = AbstractMessageParser.createErrorMsg(PCEPErrors.NON_ZERO_PLSPID, Optional.empty());
289 this.listener.onSessionUp(this.session);
290 assertTrue(this.listener.onMessage(Optional.<AbstractTopologySessionListener.MessageContext>empty()
296 public void testOnErrorMessage() throws InterruptedException, ExecutionException {
297 final Message errorMsg = MsgBuilderUtil.createErrorMsg(PCEPErrors.NON_ZERO_PLSPID, 1L);
298 this.listener.onSessionUp(this.session);
299 final Future<RpcResult<AddLspOutput>> futureOutput = this.topologyRpcs.addLsp(createAddLspInput());
300 this.listener.onMessage(this.session, errorMsg);
302 final AddLspOutput output = futureOutput.get().getResult();
303 assertEquals(FailureType.Failed, output.getFailure());
304 assertEquals(1, output.getError().size());
305 final ErrorObject err = output.getError().get(0).getErrorObject();
306 assertEquals(PCEPErrors.NON_ZERO_PLSPID.getErrorType(), err.getType().shortValue());
307 assertEquals(PCEPErrors.NON_ZERO_PLSPID.getErrorValue(), err.getValue().shortValue());
311 public void testOnSessionDown() throws InterruptedException, ExecutionException {
312 this.listener.onSessionUp(this.session);
314 final Future<RpcResult<AddLspOutput>> futureOutput = this.topologyRpcs.addLsp(createAddLspInput());
315 assertFalse(this.session.isClosed());
316 this.listener.onSessionDown(this.session, new IllegalArgumentException());
317 assertTrue(this.session.isClosed());
318 final AddLspOutput output = futureOutput.get().getResult();
319 // deal with unsent request after session down
320 assertEquals(FailureType.Unsent, output.getFailure());
324 * All the pcep session registration should be closed when the session manager is closed.
327 public void testOnServerSessionManagerDown() throws InterruptedException, ExecutionException {
328 this.listener.onSessionUp(this.session);
329 // the session should not be closed when session manager is up
330 assertFalse(this.session.isClosed());
332 final Future<RpcResult<AddLspOutput>> futureOutput = this.topologyRpcs.addLsp(createAddLspInput());
333 stopSessionManager();
334 final AddLspOutput output = futureOutput.get().getResult();
335 // deal with unsent request after session down
336 assertEquals(FailureType.Unsent, output.getFailure());
337 // verify the session is closed after server session manager is closed
338 assertTrue(this.session.isClosed());
342 * Verify the PCEP session should not be up when server session manager is down,
343 * otherwise it would be a problem when the session is up while it's not registered with session manager.
346 public void testOnServerSessionManagerUnstarted() throws InterruptedException, ExecutionException {
347 stopSessionManager();
348 assertFalse(this.session.isClosed());
349 this.listener.onSessionUp(this.session);
350 // verify the session was NOT added to topology
351 checkNotPresentOperational(getDataBroker(), TOPO_IID);
352 // verify the session is closed due to server session manager is closed
353 assertTrue(this.session.isClosed());
355 final Future<RpcResult<AddLspOutput>> futureOutput = this.topologyRpcs.addLsp(createAddLspInput());
356 final AddLspOutput output = futureOutput.get().getResult();
357 // deal with unsent request after session down
358 assertEquals(FailureType.Unsent, output.getFailure());
362 public void testOnServerSessionManagerRestartAndSessionRecovery() throws Exception {
363 // close server session manager first
364 stopSessionManager();
365 assertFalse(this.session.isClosed());
366 this.listener.onSessionUp(this.session);
367 // verify the session was NOT added to topology
368 checkNotPresentOperational(getDataBroker(), TOPO_IID);
369 // verify the session is closed due to server session manager is closed
370 assertTrue(this.session.isClosed());
372 final Future<RpcResult<AddLspOutput>> futureOutput = this.topologyRpcs.addLsp(createAddLspInput());
373 final AddLspOutput output = futureOutput.get().getResult();
374 // deal with unsent request after session down
375 assertEquals(FailureType.Unsent, output.getFailure());
376 // PCC client is not there
377 checkNotPresentOperational(getDataBroker(), this.pathComputationClientIId);
379 // reset received message queue
380 this.receivedMsgs.clear();
381 // now we restart the session manager
382 startSessionManager();
383 // try to start the session again
384 // notice since the session was terminated before, it is not usable anymore.
385 // we need to get a new session instance. the new session will have the same local / remote preference
386 this.session = getPCEPSession(getLocalPref(), getRemotePref());
387 assertFalse(this.session.isClosed());
388 this.listener.onSessionUp(this.session);
389 assertFalse(this.session.isClosed());
392 this.topologyRpcs.addLsp(createAddLspInput());
393 final Pcinitiate pcinitiate = (Pcinitiate) this.receivedMsgs.get(0);
394 final Requests req = pcinitiate.getPcinitiateMessage().getRequests().get(0);
395 final long srpId = req.getSrp().getOperationId().getValue();
396 final Tlvs tlvs = createLspTlvs(req.getLsp().getPlspId().getValue(), true,
397 this.testAddress, this.testAddress, this.testAddress, Optional.empty());
398 final Pcrpt pcRpt = MsgBuilderUtil.createPcRtpMessage(new LspBuilder(req.getLsp()).setTlvs(tlvs).setSync(true)
399 .setRemove(false).setOperational(OperationalStatus.Active).build(),
400 Optional.of(MsgBuilderUtil.createSrp(srpId)), MsgBuilderUtil.createPath(req.getEro().getSubobject()));
401 this.listener.onMessage(this.session, pcRpt);
402 readDataOperational(getDataBroker(), TOPO_IID, topology -> {
403 assertEquals(1, topology.getNode().size());
409 * When a session is somehow duplicated in controller, the controller should drop existing session.
412 public void testDuplicatedSession() throws ExecutionException, InterruptedException {
413 this.listener.onSessionUp(this.session);
416 this.topologyRpcs.addLsp(createAddLspInput());
417 final Pcinitiate pcinitiate = (Pcinitiate) this.receivedMsgs.get(0);
418 final Requests req = pcinitiate.getPcinitiateMessage().getRequests().get(0);
419 final long srpId = req.getSrp().getOperationId().getValue();
420 final Tlvs tlvs = createLspTlvs(req.getLsp().getPlspId().getValue(), true,
421 this.testAddress, this.testAddress, this.testAddress, Optional.empty());
422 final Pcrpt pcRpt = MsgBuilderUtil.createPcRtpMessage(new LspBuilder(req.getLsp()).setTlvs(tlvs).setSync(true)
423 .setRemove(false).setOperational(OperationalStatus.Active).build(),
424 Optional.of(MsgBuilderUtil.createSrp(srpId)), MsgBuilderUtil.createPath(req.getEro().getSubobject()));
425 this.listener.onMessage(this.session, pcRpt);
426 readDataOperational(getDataBroker(), TOPO_IID, topology -> {
427 assertEquals(1, topology.getNode().size());
431 // now we do session up again
432 this.listener.onSessionUp(this.session);
433 assertTrue(this.session.isClosed());
434 // node should be removed after termination
435 checkNotPresentOperational(getDataBroker(), this.pathComputationClientIId);
436 assertFalse(this.receivedMsgs.isEmpty());
437 // the last message should be a Close message
438 assertTrue(this.receivedMsgs.get(this.receivedMsgs.size() - 1) instanceof Close);
442 public void testConflictingListeners() {
443 this.listener.onSessionUp(this.session);
444 assertFalse(this.session.isClosed());
445 Stateful07TopologySessionListener conflictingListener =
446 (Stateful07TopologySessionListener) getSessionListener();
447 conflictingListener.onSessionUp(this.session);
448 assertTrue(this.session.isClosed());
452 public void testOnSessionTermination() throws Exception {
453 this.listener.onSessionUp(this.session);
455 this.topologyRpcs.addLsp(createAddLspInput());
456 final Pcinitiate pcinitiate = (Pcinitiate) this.receivedMsgs.get(0);
457 final Requests req = pcinitiate.getPcinitiateMessage().getRequests().get(0);
458 final long srpId = req.getSrp().getOperationId().getValue();
459 final Tlvs tlvs = createLspTlvs(req.getLsp().getPlspId().getValue(), true,
460 this.testAddress, this.testAddress, this.testAddress, Optional.empty());
461 final Pcrpt pcRpt = MsgBuilderUtil.createPcRtpMessage(new LspBuilder(req.getLsp()).setTlvs(tlvs).setSync(true)
462 .setRemove(false).setOperational(OperationalStatus.Active).build(),
463 Optional.of(MsgBuilderUtil.createSrp(srpId)), MsgBuilderUtil.createPath(req.getEro().getSubobject()));
464 this.listener.onMessage(this.session, pcRpt);
465 readDataOperational(getDataBroker(), TOPO_IID, topology -> {
466 assertEquals(1, topology.getNode().size());
470 assertFalse(this.session.isClosed());
471 // node should be removed after termination
472 this.listener.onSessionTerminated(this.session, new PCEPCloseTermination(TerminationReason.UNKNOWN));
473 assertTrue(this.session.isClosed());
474 checkNotPresentOperational(getDataBroker(), this.pathComputationClientIId);
478 public void testUnknownLsp() throws Exception {
479 final List<Reports> reports = Lists.newArrayList(new ReportsBuilder().setPath(new PathBuilder()
480 .setEro(new EroBuilder().build()).build()).setLsp(new LspBuilder().setPlspId(new PlspId(5L))
481 .setSync(false).setRemove(false).setTlvs(new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml
482 .ns.yang.pcep.ietf.stateful.rev181109.lsp.object.lsp.TlvsBuilder().setLspIdentifiers(
483 new LspIdentifiersBuilder().setLspId(new LspId(1L)).build()).setSymbolicPathName(
484 new SymbolicPathNameBuilder().setPathName(new SymbolicPathName(new byte[]{22, 34}))
485 .build()).build()).build()).build());
486 final Pcrpt rptmsg = new PcrptBuilder().setPcrptMessage(new PcrptMessageBuilder().setReports(reports).build())
488 this.listener.onSessionUp(this.session);
489 this.listener.onMessage(this.session, rptmsg);
490 readDataOperational(getDataBroker(), TOPO_IID, node -> {
491 assertFalse(node.getNode().isEmpty());
497 public void testUpdateUnknownLsp() throws InterruptedException, ExecutionException {
498 this.listener.onSessionUp(this.session);
499 final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev181109.update.lsp.args
500 .ArgumentsBuilder updArgsBuilder = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang
501 .topology.pcep.rev181109.update.lsp.args.ArgumentsBuilder();
502 updArgsBuilder.setEro(createEroWithIpPrefixes(Lists.newArrayList(this.eroIpPrefix, this.dstIpPrefix)));
503 updArgsBuilder.addAugmentation(Arguments3.class, new Arguments3Builder().setLsp(new LspBuilder()
504 .setDelegate(true).setAdministrative(true).build()).build());
505 final UpdateLspInput update = new UpdateLspInputBuilder().setArguments(updArgsBuilder.build())
506 .setName(this.tunnelName).setNetworkTopologyRef(new NetworkTopologyRef(TOPO_IID)).setNode(this.nodeId)
508 final UpdateLspOutput result = this.topologyRpcs.updateLsp(update).get().getResult();
509 assertEquals(FailureType.Unsent, result.getFailure());
510 assertEquals(1, result.getError().size());
511 final ErrorObject errorObject = result.getError().get(0).getErrorObject();
512 assertNotNull(errorObject);
513 assertEquals(PCEPErrors.UNKNOWN_PLSP_ID, PCEPErrors.forValue(errorObject.getType(), errorObject.getValue()));
517 public void testRemoveUnknownLsp() throws InterruptedException, ExecutionException {
518 this.listener.onSessionUp(this.session);
519 final RemoveLspInput remove = new RemoveLspInputBuilder().setName(this.tunnelName).setNetworkTopologyRef(
520 new NetworkTopologyRef(TOPO_IID)).setNode(this.nodeId).build();
521 final OperationResult result = this.topologyRpcs.removeLsp(remove).get().getResult();
522 assertEquals(FailureType.Unsent, result.getFailure());
523 assertEquals(1, result.getError().size());
524 final ErrorObject errorObject = result.getError().get(0).getErrorObject();
525 assertNotNull(errorObject);
526 assertEquals(PCEPErrors.UNKNOWN_PLSP_ID, PCEPErrors.forValue(errorObject.getType(), errorObject.getValue()));
530 public void testAddAlreadyExistingLsp() throws InterruptedException, ExecutionException {
531 this.listener.onSessionUp(this.session);
532 this.topologyRpcs.addLsp(createAddLspInput());
533 assertEquals(1, this.receivedMsgs.size());
534 assertTrue(this.receivedMsgs.get(0) instanceof Pcinitiate);
535 final Pcinitiate pcinitiate = (Pcinitiate) this.receivedMsgs.get(0);
536 final Requests req = pcinitiate.getPcinitiateMessage().getRequests().get(0);
537 final long srpId = req.getSrp().getOperationId().getValue();
538 final Tlvs tlvs = createLspTlvs(req.getLsp().getPlspId().getValue(), true,
539 this.testAddress, this.testAddress, this.testAddress, Optional.empty());
540 final Pcrpt pcRpt = MsgBuilderUtil.createPcRtpMessage(new LspBuilder(req.getLsp()).setTlvs(tlvs)
541 .setPlspId(new PlspId(1L))
544 .setOperational(OperationalStatus.Active)
545 .build(), Optional.of(MsgBuilderUtil.createSrp(srpId)), MsgBuilderUtil.createPath(req.getEro()
547 this.listener.onMessage(this.session, pcRpt);
549 //try to add already existing LSP
550 final AddLspOutput result = this.topologyRpcs.addLsp(createAddLspInput()).get().getResult();
551 assertEquals(FailureType.Unsent, result.getFailure());
552 assertEquals(1, result.getError().size());
553 final ErrorObject errorObject = result.getError().get(0).getErrorObject();
554 assertNotNull(errorObject);
555 assertEquals(PCEPErrors.USED_SYMBOLIC_PATH_NAME, PCEPErrors.forValue(errorObject.getType(),
556 errorObject.getValue()));
560 @SuppressWarnings("checkstyle:IllegalCatch")
561 public void testPccResponseTimeout() throws Exception {
562 this.listener.onSessionUp(this.session);
563 final Future<RpcResult<AddLspOutput>> addLspResult = this.topologyRpcs.addLsp(createAddLspInput());
565 addLspResult.get(2, TimeUnit.SECONDS);
567 } catch (final Exception e) {
568 assertTrue(e instanceof TimeoutException);
570 Thread.sleep(AbstractPCEPSessionTest.RPC_TIMEOUT);
571 CheckTestUtil.checkEquals(() -> {
572 final RpcResult<AddLspOutput> rpcResult = addLspResult.get();
573 assertNotNull(rpcResult);
574 assertEquals(rpcResult.getResult().getFailure(), FailureType.Unsent);
579 public void testDelegatedLspsCountWithDelegation() throws Exception {
580 this.listener.onSessionUp(this.session);
581 this.topologyRpcs.addLsp(createAddLspInput());
582 assertEquals(1, this.receivedMsgs.size());
583 assertTrue(this.receivedMsgs.get(0) instanceof Pcinitiate);
584 final Pcinitiate pcinitiate = (Pcinitiate) this.receivedMsgs.get(0);
585 final Requests req = pcinitiate.getPcinitiateMessage().getRequests().get(0);
586 final long srpId = req.getSrp().getOperationId().getValue();
587 final Tlvs tlvs = createLspTlvs(req.getLsp().getPlspId().getValue(), true,
588 this.testAddress, this.testAddress, this.testAddress, Optional.empty());
589 //delegate set to true
590 final Pcrpt pcRpt = MsgBuilderUtil.createPcRtpMessage(new LspBuilder(req.getLsp()).setTlvs(tlvs)
591 .setPlspId(new PlspId(1L))
594 .setOperational(OperationalStatus.Active)
596 .build(), Optional.of(MsgBuilderUtil.createSrp(srpId)), MsgBuilderUtil.createPath(
597 req.getEro().getSubobject()));
598 this.listener.onMessage(this.session, pcRpt);
599 checkEquals(() -> assertEquals(1, this.listener.listenerState.getDelegatedLspsCount().intValue()));
603 public void testDelegatedLspsCountWithoutDelegation() throws Exception {
604 this.listener.onSessionUp(this.session);
605 this.topologyRpcs.addLsp(createAddLspInput());
606 assertEquals(1, this.receivedMsgs.size());
607 assertTrue(this.receivedMsgs.get(0) instanceof Pcinitiate);
608 final Pcinitiate pcinitiate = (Pcinitiate) this.receivedMsgs.get(0);
609 final Requests req = pcinitiate.getPcinitiateMessage().getRequests().get(0);
610 final long srpId = req.getSrp().getOperationId().getValue();
611 final Tlvs tlvs = createLspTlvs(req.getLsp().getPlspId().getValue(), true,
612 this.testAddress, this.testAddress, this.testAddress, Optional.empty());
613 //delegate set to false
614 final Pcrpt pcRpt = MsgBuilderUtil.createPcRtpMessage(new LspBuilder(req.getLsp()).setTlvs(tlvs)
619 .setOperational(OperationalStatus.Active)
621 .build(), Optional.of(MsgBuilderUtil.createSrp(srpId)),
622 MsgBuilderUtil.createPath(req.getEro().getSubobject()));
623 this.listener.onMessage(this.session, pcRpt);
624 checkEquals(() -> assertEquals(0, this.listener.listenerState.getDelegatedLspsCount().intValue()));
628 protected Open getLocalPref() {
629 return new OpenBuilder(super.getLocalPref()).setTlvs(new TlvsBuilder().addAugmentation(Tlvs1.class,
630 new Tlvs1Builder().setStateful(new StatefulBuilder()
631 .addAugmentation(Stateful1.class, new Stateful1Builder().setInitiation(Boolean.TRUE).build())
632 .addAugmentation(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller
633 .pcep.sync.optimizations.rev181109.Stateful1.class, new org.opendaylight.yang.gen.v1
634 .urn.opendaylight.params.xml.ns.yang.controller.pcep.sync.optimizations.rev181109
635 .Stateful1Builder().setTriggeredInitialSync(Boolean.TRUE).build())
636 .build()).build()).build()).build();
640 protected Open getRemotePref() {
641 return getLocalPref();
644 private AddLspInput createAddLspInput() {
645 final ArgumentsBuilder argsBuilder = new ArgumentsBuilder();
646 final Ipv4CaseBuilder ipv4Builder = new Ipv4CaseBuilder();
647 ipv4Builder.setIpv4(new Ipv4Builder().setSourceIpv4Address(new Ipv4AddressNoZone(this.testAddress))
648 .setDestinationIpv4Address(new Ipv4AddressNoZone(this.testAddress)).build());
649 argsBuilder.setEndpointsObj(new EndpointsObjBuilder().setAddressFamily(ipv4Builder.build()).build());
650 argsBuilder.setEro(createEroWithIpPrefixes(Lists.newArrayList(this.eroIpPrefix)));
651 argsBuilder.addAugmentation(Arguments2.class, new Arguments2Builder().setLsp(new LspBuilder()
652 .setDelegate(true).setAdministrative(true).build()).build());
653 return new AddLspInputBuilder().setName(this.tunnelName).setArguments(argsBuilder.build())
654 .setNetworkTopologyRef(new NetworkTopologyRef(TOPO_IID)).setNode(this.nodeId).build();