2 * Copyright © 2020 Orange, 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.transportpce.pce.networkanalyzer;
12 import static org.junit.jupiter.api.Assertions.assertEquals;
13 import static org.junit.jupiter.api.Assertions.assertNotNull;
14 import static org.junit.jupiter.api.Assertions.assertNull;
15 import static org.junit.jupiter.api.Assertions.assertTrue;
17 import java.math.RoundingMode;
18 import java.util.HashMap;
20 import org.junit.jupiter.api.BeforeEach;
21 import org.junit.jupiter.api.Test;
22 import org.mockito.Mock;
23 import org.mockito.MockitoAnnotations;
24 import org.opendaylight.transportpce.common.NetworkUtils;
25 import org.opendaylight.transportpce.common.StringConstants;
26 import org.opendaylight.transportpce.common.fixedflex.GridConstant;
27 import org.opendaylight.transportpce.common.mapping.PortMapping;
28 import org.opendaylight.transportpce.test.AbstractTest;
29 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.link.types.rev191129.FiberPmd;
30 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.link.types.rev191129.RatioDB;
31 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210.Link1Builder;
32 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210.TerminationPoint1Builder;
33 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.state.types.rev191129.State;
34 import org.opendaylight.yang.gen.v1.http.org.openroadm.equipment.states.types.rev191129.AdminStates;
35 import org.opendaylight.yang.gen.v1.http.org.openroadm.link.rev211210.span.attributes.LinkConcatenation1.FiberType;
36 import org.opendaylight.yang.gen.v1.http.org.openroadm.link.rev211210.span.attributes.LinkConcatenation1Builder;
37 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210.networks.network.link.OMSAttributesBuilder;
38 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210.networks.network.link.oms.attributes.SpanBuilder;
39 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev211210.OpenroadmLinkType;
40 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev211210.OpenroadmNodeType;
41 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev211210.OpenroadmTpType;
42 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev211210.link.concatenation.LinkConcatenation;
43 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev211210.link.concatenation.LinkConcatenationBuilder;
44 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev211210.link.concatenation.LinkConcatenationKey;
45 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NetworkId;
46 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NodeId;
47 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.Node;
48 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.NodeBuilder;
49 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.NodeKey;
50 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.node.SupportingNode;
51 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.node.SupportingNodeBuilder;
52 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.node.SupportingNodeKey;
53 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.LinkId;
54 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1Builder;
55 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.TpId;
56 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.Link;
57 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.LinkBuilder;
58 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.LinkKey;
59 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.link.DestinationBuilder;
60 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.link.SourceBuilder;
61 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.TerminationPoint;
62 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.TerminationPointBuilder;
63 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.TerminationPointKey;
64 import org.opendaylight.yangtools.yang.common.Decimal64;
65 import org.opendaylight.yangtools.yang.common.Uint32;
67 public class PceLinkTest extends AbstractTest {
69 private static final String LINK_ID_FORMAT = "%1$s-%2$sto%3$s-%4$s";
70 private PceLink pceLink = null;
71 private String deviceNodeId = "device node";
72 private String deviceNodeId2 = "device node 2";
73 private String serviceType = "100GE";
75 private PortMapping portMapping;
79 MockitoAnnotations.openMocks(this);
83 void testBuildPceLinkRoadmToRoadm() {
84 Node node = getNodeBuilder(geSupportingNodes()).setNodeId(new NodeId("test")).build();
85 pceLink = new PceLink(
86 createRoadmToRoadm("srcNode", "destNode", "srcTp", "destTp").build(),
87 new PceOpticalNode(deviceNodeId, serviceType, portMapping, node,
88 OpenroadmNodeType.DEGREE, StringConstants.OPENROADM_DEVICE_VERSION_2_2_1,
89 GridConstant.SLOT_WIDTH_50, GridConstant.SLOT_WIDTH_50),
90 new PceOpticalNode(deviceNodeId2, serviceType, portMapping, node,
91 OpenroadmNodeType.DEGREE, StringConstants.OPENROADM_DEVICE_VERSION_2_2_1,
92 GridConstant.SLOT_WIDTH_50, GridConstant.SLOT_WIDTH_50));
96 void testBuildPceLinkRoadmToRoadmWithoutPMD() {
97 Link link = createRoadmToRoadmWithoutPMD("srcNode", "destNode", "srcTp", "destTp").build();
98 Node node = getNodeBuilder(geSupportingNodes()).setNodeId(new NodeId("test")).build();
99 pceLink = new PceLink(
101 new PceOpticalNode(deviceNodeId, serviceType, portMapping, node,
102 OpenroadmNodeType.DEGREE, StringConstants.OPENROADM_DEVICE_VERSION_2_2_1,
103 GridConstant.SLOT_WIDTH_50, GridConstant.SLOT_WIDTH_50),
104 new PceOpticalNode(deviceNodeId2, serviceType, portMapping, node,
105 OpenroadmNodeType.DEGREE, StringConstants.OPENROADM_DEVICE_VERSION_2_2_1,
106 GridConstant.SLOT_WIDTH_50, GridConstant.SLOT_WIDTH_50));
107 assertNotNull(MapUtils.getOmsAttributesSpan(link));
108 assertEquals(1, pceLink.getsrlgList().size());
109 assertEquals(20.0, pceLink.getspanLoss(), 0.005, "Checking length loss");
110 assertEquals(825.0, pceLink.getcd(), 0.005, "Checking length loss");
111 assertEquals(4.0, pceLink.getpmd2(), 0.005, "Checking PMDvalue of link");
115 void testBuildPceLinkRoadmToRoadmWithoutLinkLatency() {
116 Node node = getNodeBuilder(geSupportingNodes()).setNodeId(new NodeId("test")).build();
117 pceLink = new PceLink(
118 createRoadmToRoadmWithoutLinkLatency("srcNode", "destNode", "srcTp", "destTp").build(),
119 new PceOpticalNode(deviceNodeId, serviceType, portMapping, node,
120 OpenroadmNodeType.DEGREE, StringConstants.OPENROADM_DEVICE_VERSION_2_2_1,
121 GridConstant.SLOT_WIDTH_50, GridConstant.SLOT_WIDTH_50),
122 new PceOpticalNode(deviceNodeId2, serviceType, portMapping, node,
123 OpenroadmNodeType.DEGREE, StringConstants.OPENROADM_DEVICE_VERSION_2_2_1,
124 GridConstant.SLOT_WIDTH_50, GridConstant.SLOT_WIDTH_50));
128 void testBuildPceLinkOTN() {
129 // TODO: Modify with OTN node not PceOpticalNode
130 Node node = getNodeBuilder(geSupportingNodes()).setNodeId(new NodeId("test")).build();
131 pceLink = new PceLink(
132 createOTNLink("srcNode", "destNode", "srcTp", "destTp").build(),
133 new PceOpticalNode(deviceNodeId, serviceType, portMapping, node,
134 OpenroadmNodeType.SWITCH, StringConstants.OPENROADM_DEVICE_VERSION_2_2_1,
135 GridConstant.SLOT_WIDTH_50, GridConstant.SLOT_WIDTH_50),
136 new PceOpticalNode(deviceNodeId2, serviceType, portMapping, node,
137 OpenroadmNodeType.SWITCH, StringConstants.OPENROADM_DEVICE_VERSION_2_2_1,
138 GridConstant.SLOT_WIDTH_50, GridConstant.SLOT_WIDTH_50));
142 void testBuildPceLinkExponder() {
143 Node node = getNodeBuilder(geSupportingNodes()).setNodeId(new NodeId("test")).build();
144 pceLink = new PceLink(
145 createXponderLink("srcNode", "destNode", "srcTp", "destTp").build(),
146 new PceOpticalNode(deviceNodeId, serviceType, portMapping, node,
147 OpenroadmNodeType.XPONDER, StringConstants.OPENROADM_DEVICE_VERSION_2_2_1,
148 GridConstant.SLOT_WIDTH_50, GridConstant.SLOT_WIDTH_50),
149 new PceOpticalNode(deviceNodeId2, serviceType, portMapping, node,
150 OpenroadmNodeType.SRG, StringConstants.OPENROADM_DEVICE_VERSION_2_2_1,
151 GridConstant.SLOT_WIDTH_50, GridConstant.SLOT_WIDTH_50));
155 void testCalcSpanOSNR() {
156 Link link = createRoadmToRoadm("srcNode", "destNode", "srcTp", "destTp").build();
157 Node node = getNodeBuilder(geSupportingNodes()).setNodeId(new NodeId("test")).build();
158 pceLink = new PceLink(
160 new PceOpticalNode(deviceNodeId, serviceType, portMapping, node,
161 OpenroadmNodeType.DEGREE, StringConstants.OPENROADM_DEVICE_VERSION_2_2_1,
162 GridConstant.SLOT_WIDTH_50, GridConstant.SLOT_WIDTH_50),
163 new PceOpticalNode(deviceNodeId, serviceType, portMapping, node,
164 OpenroadmNodeType.DEGREE, StringConstants.OPENROADM_DEVICE_VERSION_2_2_1,
165 GridConstant.SLOT_WIDTH_50, GridConstant.SLOT_WIDTH_50));
166 assertNotNull(MapUtils.getOmsAttributesSpan(link));
167 // assertNotNull(pceLink.getosnr());
168 assertEquals(1, pceLink.getsrlgList().size());
169 assertEquals(0.25, pceLink.getpmd2(), 0.005, "Checking PMDvalue of link");
170 assertEquals(825, pceLink.getcd(), 0.005, "Checking CDvalue of link");
171 // assertTrue(7.857119000000001 == pceLink.getosnr());
172 assertNull(pceLink.getOppositeLink());
173 assertNull(pceLink.getOppositeLink());
174 assertNotNull(pceLink.getDestTP());
175 assertNotNull(pceLink.getlinkType());
176 assertNotNull(pceLink.getLinkId());
177 assertNotNull(pceLink.getSourceId());
178 assertNotNull(pceLink.getDestId());
179 pceLink.setClient("specific_client");
180 assertTrue(pceLink.getClient().equals("specific_client"));
181 assertNotNull(pceLink.getClient());
182 assertNotNull(pceLink.getLatency());
183 assertNotNull(pceLink.getAvailableBandwidth());
184 assertNotNull(pceLink.getUsedBandwidth());
185 assertNotNull(pceLink.getsourceNetworkSupNodeId());
186 assertNotNull(pceLink.getdestNetworkSupNodeId());
187 assertNotNull(pceLink.getSourceTP());
188 assertNotNull(pceLink.getsourceCLLI());
189 assertNotNull(pceLink.getdestCLLI());
190 assertTrue(pceLink.toString().equals("PceLink type=" + pceLink.getlinkType()
191 + " ID=" + pceLink.getLinkId().getValue() + " latency=" + pceLink.getLatency().intValue()));
195 void testWrongSpanLoss() {
196 Link link = createInvalidRoadmToRoadm("srcNode", "destNode", "srcTp", "destTp").build();
197 Node node = getNodeBuilder(geSupportingNodes()).setNodeId(new NodeId("test")).build();
198 pceLink = new PceLink(
200 new PceOpticalNode(deviceNodeId, serviceType, portMapping, node,
201 OpenroadmNodeType.DEGREE, StringConstants.OPENROADM_DEVICE_VERSION_2_2_1,
202 GridConstant.SLOT_WIDTH_50, GridConstant.SLOT_WIDTH_50),
203 new PceOpticalNode(deviceNodeId, serviceType, portMapping, node,
204 OpenroadmNodeType.DEGREE, StringConstants.OPENROADM_DEVICE_VERSION_2_2_1,
205 GridConstant.SLOT_WIDTH_50, GridConstant.SLOT_WIDTH_50));
206 assertNull(MapUtils.getOmsAttributesSpan(link));
207 assertNull(pceLink.getpmd2());
208 assertNull(pceLink.getpowerCorrection());
209 assertNull(pceLink.getcd());
213 void testExtrapolatedPMD() {
214 Link link = createRoadmToRoadmWithoutPMD("srcNode", "destNode", "srcTp", "destTp").build();
215 Node node = getNodeBuilder(geSupportingNodes()).setNodeId(new NodeId("test")).build();
216 pceLink = new PceLink(
218 new PceOpticalNode(deviceNodeId, serviceType, portMapping, node,
219 OpenroadmNodeType.DEGREE, StringConstants.OPENROADM_DEVICE_VERSION_2_2_1,
220 GridConstant.SLOT_WIDTH_50, GridConstant.SLOT_WIDTH_50),
221 new PceOpticalNode(deviceNodeId, serviceType, portMapping, node,
222 OpenroadmNodeType.DEGREE, StringConstants.OPENROADM_DEVICE_VERSION_2_2_1,
223 GridConstant.SLOT_WIDTH_50, GridConstant.SLOT_WIDTH_50));
224 assertNotNull(MapUtils.getOmsAttributesSpan(link));
225 assertEquals(1, pceLink.getsrlgList().size());
226 assertEquals(4.0, pceLink.getpmd2(), 0.005, "Checking PMDvalue of link");
229 private static LinkBuilder createOTNLink(String srcNode, String destNode, String srcTp, String destTp) {
230 return createLinkBuilder(false, false, 10000.0, srcNode, destNode, srcTp, destTp,
232 .setLinkType(OpenroadmLinkType.OTNLINK)
233 .setOperationalState(State.InService)
234 .setAdministrativeState(AdminStates.InService));
237 private static LinkBuilder createXponderLink(String srcNode, String destNode, String srcTp, String destTp) {
238 // create source link
239 return createLinkBuilder(false, false, 10.0, srcNode, destNode, srcTp, destTp,
241 .setLinkType(OpenroadmLinkType.XPONDERINPUT)
242 .setAdministrativeState(AdminStates.InService)
243 .setOperationalState(State.InService));
246 private static LinkBuilder createLinkBuilder(boolean pmdpresent, boolean omspresent, double length,
247 String srcNode, String destNode, String srcTp, String destTp, Link1Builder link1Builder) {
248 LinkId linkId = new LinkId(String.format(LINK_ID_FORMAT, srcNode, srcTp, destNode, destTp));
249 LinkBuilder linkBuilder = new LinkBuilder()
251 new SourceBuilder().setSourceNode(new NodeId(srcNode)).setSourceTp(new TpId(srcTp)).build())
253 new DestinationBuilder().setDestNode(new NodeId(destNode)).setDestTp(new TpId(destTp)).build())
255 .withKey(new LinkKey(linkId))
256 .addAugmentation(link1Builder.build());
258 LinkConcatenation linkConcatenation = new LinkConcatenationBuilder()
259 .withKey(new LinkConcatenationKey(Uint32.valueOf(1)))
260 .setSRLGLength(Decimal64.valueOf(length, RoundingMode.FLOOR))
263 ? new LinkConcatenation1Builder().setFiberType(FiberType.Smf)
264 .setPmd(FiberPmd.getDefaultInstance("0.500")).build()
265 : new LinkConcatenation1Builder().setFiberType(FiberType.Smf).build())
267 linkBuilder.addAugmentation(
268 new org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev211210.Link1Builder()
270 new OMSAttributesBuilder()
271 .setSpan(new SpanBuilder()
272 // .setSpanlossCurrent(new RatioDB(Decimal64.valueOf("55")))
273 .setSpanlossCurrent(new RatioDB(Decimal64.valueOf("20")))
274 .setLinkConcatenation(Map.of(linkConcatenation.key(), linkConcatenation))
282 private static LinkBuilder createRoadmToRoadm(String srcNode, String destNode, String srcTp, String destTp) {
283 return createLinkBuilder(true, true, 50000.0, srcNode, destNode, srcTp, destTp, new Link1Builder()
284 .setLinkLatency(Uint32.valueOf(100))
285 .setAdministrativeState(AdminStates.InService)
286 .setOperationalState(State.InService)
287 .setLinkType(OpenroadmLinkType.ROADMTOROADM)
288 .setLinkLength(Decimal64.valueOf(50.0, RoundingMode.FLOOR)));
291 private static LinkBuilder createRoadmToRoadmWithoutPMD(String srcNode, String destNode, String srcTp,
293 return createLinkBuilder(false, true, 50000.0, srcNode, destNode, srcTp, destTp, new Link1Builder()
294 .setLinkLatency(Uint32.valueOf(100))
295 .setAdministrativeState(AdminStates.InService)
296 .setOperationalState(State.InService)
297 .setLinkType(OpenroadmLinkType.ROADMTOROADM)
298 .setLinkLength(Decimal64.valueOf(50.0, RoundingMode.FLOOR)));
301 private static LinkBuilder createInvalidRoadmToRoadm(String srcNode, String destNode,
302 String srcTp, String destTp) {
303 return createLinkBuilder(false, false, 0.0, srcNode, destNode, srcTp, destTp, new Link1Builder()
304 .setLinkLatency(Uint32.valueOf(100))
305 .setAdministrativeState(AdminStates.InService)
306 .setOperationalState(State.InService)
307 .setLinkType(OpenroadmLinkType.ROADMTOROADM));
310 private static LinkBuilder createRoadmToRoadmWithoutLinkLatency(
311 String srcNode, String destNode, String srcTp, String destTp) {
312 return createLinkBuilder(true, true, 50000.0, srcNode, destNode, srcTp, destTp, new Link1Builder()
313 .setLinkType(OpenroadmLinkType.ROADMTOROADM));
316 private Map<SupportingNodeKey, SupportingNode> geSupportingNodes() {
317 SupportingNode supportingNode1 = new SupportingNodeBuilder()
318 .setNodeRef(new NodeId("node 1"))
319 .setNetworkRef(new NetworkId(NetworkUtils.CLLI_NETWORK_ID))
321 SupportingNode supportingNode2 = new SupportingNodeBuilder()
322 .setNodeRef(new NodeId("node 2"))
323 .setNetworkRef(new NetworkId(NetworkUtils.UNDERLAY_NETWORK_ID))
325 return new HashMap<>(Map.of(
326 supportingNode1.key(), supportingNode1,
327 supportingNode2.key(), supportingNode2));
330 private NodeBuilder getNodeBuilder(Map<SupportingNodeKey, SupportingNode> supportingNodes1) {
331 // update tp of nodes
332 TerminationPoint xpdr = new TerminationPointBuilder()
333 .withKey(new TerminationPointKey(new TpId("xpdr")))
335 new TerminationPoint1Builder()
336 .setTpType(OpenroadmTpType.XPONDERNETWORK)
337 .setAdministrativeState(AdminStates.InService)
338 .setOperationalState(State.InService)
341 return new NodeBuilder()
342 .setNodeId(new NodeId("node 1"))
343 .withKey(new NodeKey(new NodeId("node 1")))
344 .addAugmentation(new Node1Builder().setTerminationPoint(Map.of(xpdr.key(), xpdr)).build())
346 new org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev211210.Node1Builder()
347 .setOperationalState(State.InService).setAdministrativeState(AdminStates.InService).build())
348 .setSupportingNode(supportingNodes1);