blob: 446aea2e3c57c85009866c561c0bb1cac7ececd5 [file] [log] [blame]
Priyanka Bb6963582016-05-20 20:21:20 +05301/*
2 * Copyright 2016-present Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.pce.pceservice;
17
18import org.junit.After;
19import org.junit.Before;
20import org.junit.Test;
21import org.onlab.graph.AbstractGraphPathSearch;
22import org.onlab.graph.AdjacencyListsGraph;
23import org.onlab.graph.DijkstraGraphSearch;
24import org.onlab.graph.Graph;
25import org.onlab.graph.GraphPathSearch;
26import org.onlab.packet.ChassisId;
27import org.onlab.util.Bandwidth;
28import org.onlab.util.Tools;
29import org.onosproject.net.AnnotationKeys;
30import org.onosproject.net.ConnectPoint;
31import org.onosproject.net.DefaultAnnotations;
32import org.onosproject.net.DefaultDevice;
33import org.onosproject.net.DefaultLink;
34import org.onosproject.net.DefaultPath;
35import org.onosproject.net.Device;
36import org.onosproject.net.DeviceId;
37import org.onosproject.net.Link;
38import org.onosproject.net.Path;
39import org.onosproject.net.PortNumber;
40import org.onosproject.net.intent.Constraint;
41import org.onosproject.net.intent.IntentId;
42import org.onosproject.net.Device.Type;
43import org.onosproject.net.intent.constraint.BandwidthConstraint;
44import org.onosproject.net.device.DeviceServiceAdapter;
45import org.onosproject.net.resource.ContinuousResource;
46import org.onosproject.net.resource.ContinuousResourceId;
47import org.onosproject.net.resource.DiscreteResource;
48import org.onosproject.net.resource.DiscreteResourceId;
49import org.onosproject.net.resource.Resource;
50import org.onosproject.net.resource.ResourceAllocation;
51import org.onosproject.net.resource.ResourceConsumer;
52import org.onosproject.net.resource.ResourceId;
53import org.onosproject.net.resource.Resources;
54import org.onosproject.net.provider.ProviderId;
55import org.onosproject.net.topology.DefaultTopologyEdge;
56import org.onosproject.net.topology.DefaultTopologyVertex;
57import org.onosproject.net.topology.LinkWeight;
58import org.onosproject.net.topology.TopologyEdge;
59import org.onosproject.net.topology.TopologyVertex;
60import org.onosproject.pce.pceservice.constraint.CapabilityConstraint;
61import org.onosproject.pce.pceservice.constraint.CostConstraint;
62import org.onosproject.pce.pceservice.constraint.SharedBandwidthConstraint;
63
64import com.google.common.collect.ImmutableList;
65import com.google.common.collect.ImmutableSet;
66
67import java.util.Collections;
68import java.util.HashMap;
69import java.util.HashSet;
70import java.util.Iterator;
71import java.util.LinkedList;
72import java.util.List;
73import java.util.Map;
74import java.util.Optional;
75import java.util.Set;
76import java.util.stream.Collectors;
77
78import static org.hamcrest.MatcherAssert.assertThat;
79import static org.hamcrest.core.Is.is;
80import static org.onlab.graph.GraphPathSearch.ALL_PATHS;
81import static org.onosproject.core.CoreService.CORE_PROVIDER_ID;
82import static com.google.common.collect.ImmutableSet.of;
83import static org.onosproject.net.resource.Resources.continuous;
84import static org.onosproject.net.Link.Type.DIRECT;
85import static org.onosproject.net.Link.State.ACTIVE;
86import static org.onosproject.net.DeviceId.deviceId;
87import static org.onosproject.pce.pceservice.constraint.CostConstraint.Type.COST;
88import static org.onosproject.pce.pceservice.constraint.CostConstraint.Type.TE_COST;
89
90/**
91 * Test for CSPF path computation.
92 */
93public class PathComputationTest {
94
95 private final MockPathResourceService resourceService = new MockPathResourceService();
96 private final MockDeviceService deviceService = new MockDeviceService();
97 private PceManager pceManager = new PceManager();
98 public static ProviderId providerId = new ProviderId("pce", "foo");
99 private static final String DEVICE1 = "D001";
100 private static final String DEVICE2 = "D002";
101 private static final String DEVICE3 = "D003";
102 private static final String DEVICE4 = "D004";
103 private static final String DEVICE5 = "D005";
104 public static final String PCEPDEVICE1 = "PD001";
105 public static final String PCEPDEVICE2 = "PD002";
106 public static final String PCEPDEVICE3 = "PD003";
107 public static final String PCEPDEVICE4 = "PD004";
108 private static final TopologyVertex D1 = new DefaultTopologyVertex(DeviceId.deviceId("D001"));
109 private static final TopologyVertex D2 = new DefaultTopologyVertex(DeviceId.deviceId("D002"));
110 private static final TopologyVertex D3 = new DefaultTopologyVertex(DeviceId.deviceId("D003"));
111 private static final TopologyVertex D4 = new DefaultTopologyVertex(DeviceId.deviceId("D004"));
112 private static final TopologyVertex D5 = new DefaultTopologyVertex(DeviceId.deviceId("D005"));
113 private static final String ANNOTATION_COST = "cost";
114 private static final String ANNOTATION_TE_COST = "teCost";
115 private static final String UNKNOWN = "unknown";
116 public static final String LSRID = "lsrId";
117 public static final String L3 = "L3";
118 public static final String PCECC_CAPABILITY = "pceccCapability";
119 public static final String SR_CAPABILITY = "srCapability";
120 public static final String LABEL_STACK_CAPABILITY = "labelStackCapability";
121
122 @Before
123 public void startUp() {
124 pceManager.resourceService = resourceService;
125 pceManager.deviceService = deviceService;
126 }
127
128 /**
129 * Selects path computation algorithm.
130 *
131 * @return graph path search algorithm
132 */
133 private AbstractGraphPathSearch<TopologyVertex, TopologyEdge> graphSearch() {
134 return new DijkstraGraphSearch<>();
135 }
136
137 /**
138 * Returns link for two devices.
139 *
140 * @param device source device
141 * @param port source port
142 * @param device2 destination device
143 * @param port2 destination port
144 * @return link
145 */
146 private Link addLink(String device, long port, String device2, long port2, boolean setCost, int value) {
147 ConnectPoint src = new ConnectPoint(DeviceId.deviceId(device), PortNumber.portNumber(port));
148 ConnectPoint dst = new ConnectPoint(DeviceId.deviceId(device2), PortNumber.portNumber(port2));
149 Link curLink;
150 DefaultAnnotations.Builder annotationBuilder = DefaultAnnotations.builder();
151 if (setCost) {
152 annotationBuilder.set(ANNOTATION_COST, String.valueOf(value));
153 } else {
154 annotationBuilder.set(ANNOTATION_TE_COST, String.valueOf(value));
155 }
156
157 //TODO:If cost not set cost : default value case
158 curLink = DefaultLink.builder().src(src).dst(dst).state(ACTIVE).type(DIRECT)
159 .providerId(PathComputationTest.providerId).annotations(annotationBuilder.build()).build();
160 return curLink;
161 }
162
163 @After
164 public void tearDown() {
165 pceManager.resourceService = null;
166 pceManager.deviceService = null;
167 }
168
169 /**
170 * Returns an edge-weight capable of evaluating links on the basis of the
171 * specified constraints.
172 *
173 * @param constraints path constraints
174 * @return edge-weight function
175 */
176 private LinkWeight weight(List<Constraint> constraints) {
177 return new MockTeConstraintBasedLinkWeight(constraints);
178 }
179
180 private Set<Path> computePath(Link link1, Link link2, Link link3, Link link4, List<Constraint> constraints) {
181 Graph<TopologyVertex, TopologyEdge> graph = new AdjacencyListsGraph<>(of(D1, D2, D3, D4),
182 of(new DefaultTopologyEdge(D1, D2, link1),
183 new DefaultTopologyEdge(D2, D4, link2),
184 new DefaultTopologyEdge(D1, D3, link3),
185 new DefaultTopologyEdge(D3, D4, link4)));
186
187 GraphPathSearch.Result<TopologyVertex, TopologyEdge> result =
188 graphSearch().search(graph, D1, D4, weight(constraints), ALL_PATHS);
189 ImmutableSet.Builder<Path> builder = ImmutableSet.builder();
190 for (org.onlab.graph.Path<TopologyVertex, TopologyEdge> path : result.paths()) {
191 builder.add(networkPath(path));
192 }
193 return builder.build();
194 }
195
196 private class MockDeviceService extends DeviceServiceAdapter {
197 List<Device> devices = new LinkedList<>();
198
199 private void addDevice(Device dev) {
200 devices.add(dev);
201 }
202
203 @Override
204 public Device getDevice(DeviceId deviceId) {
205 for (Device dev : devices) {
206 if (dev.id().equals(deviceId)) {
207 return dev;
208 }
209 }
210 return null;
211 }
212
213 @Override
214 public Iterable<Device> getAvailableDevices() {
215 return devices;
216 }
217 }
218
219 private class MockTeConstraintBasedLinkWeight implements LinkWeight {
220
221 private final List<Constraint> constraints;
222
223 /**
224 * Creates a new edge-weight function capable of evaluating links
225 * on the basis of the specified constraints.
226 *
227 * @param constraints path constraints
228 */
229 MockTeConstraintBasedLinkWeight(List<Constraint> constraints) {
230 if (constraints == null) {
231 this.constraints = Collections.emptyList();
232 } else {
233 this.constraints = ImmutableList.copyOf(constraints);
234 }
235 }
236
237 public double weight(TopologyEdge edge) {
238 if (!constraints.iterator().hasNext()) {
239 //Takes default cost/hopcount as 1 if no constraints specified
240 return 1.0;
241 }
242
243 Iterator<Constraint> it = constraints.iterator();
244 double cost = 1;
245
246 //If any constraint fails return -1 also value of cost returned from cost constraint can't be negative
247 while (it.hasNext() && cost > 0) {
248 Constraint constraint = it.next();
249 if (constraint instanceof CapabilityConstraint) {
250 cost = ((CapabilityConstraint) constraint).isValidLink(edge.link(), deviceService) ? 1 : -1;
251 } else {
252 cost = constraint.cost(edge.link(), resourceService::isAvailable);
253 }
254 }
255 return cost;
256 }
257 }
258
259 private Path networkPath(org.onlab.graph.Path<TopologyVertex, TopologyEdge> path) {
260 List<Link> links = path.edges().stream().map(TopologyEdge::link).collect(Collectors.toList());
261 return new DefaultPath(CORE_PROVIDER_ID, links, path.cost());
262 }
263
264 /**
265 * Test Resource service for path computation.
266 */
267 private class MockPathResourceService extends ResourceServiceAdapter {
268 private final Map<Resource, ResourceConsumer> assignment = new HashMap<>();
269 private Map<ResourceId, List<ResourceAllocation>> resourcesAllocations = new HashMap<>();
270
271 @Override
272 public List<ResourceAllocation> allocate(ResourceConsumer consumer, List<Resource> resources) {
273 for (Resource resource: resources) {
274 if (resource instanceof ContinuousResource) {
275 List<ResourceAllocation> allocs = new LinkedList<>();
276 allocs.add(new ResourceAllocation(resource, consumer));
277 resourcesAllocations.put(resource.id(), allocs);
278 }
279 }
280 return resources.stream()
281 .map(x -> new ResourceAllocation(x, consumer))
282 .collect(Collectors.toList());
283 }
284
285 @Override
286 public List<ResourceAllocation> getResourceAllocations(ResourceId id) {
287 if (id instanceof ContinuousResourceId) {
288 return resourcesAllocations.get(id);
289 }
290 DiscreteResource discrete = Resources.discrete((DiscreteResourceId) id).resource();
291 return Optional.ofNullable(assignment.get(discrete))
292 .map(x -> ImmutableList.of(new ResourceAllocation(discrete, x)))
293 .orElse(ImmutableList.of());
294 }
295
296 @Override
297 public <T> Set<Resource> getAvailableResources(DiscreteResourceId parent, Class<T> cls) {
298 return getAvailableResources(parent).stream()
299 .filter(x -> x.isTypeOf(cls))
300 .collect(Collectors.toSet());
301 }
302
303 @Override
304 public <T> Set<T> getAvailableResourceValues(DiscreteResourceId parent, Class<T> cls) {
305 return getAvailableResources(parent).stream()
306 .filter(x -> x.isTypeOf(cls))
307 .flatMap(x -> Tools.stream(x.valueAs(cls)))
308 .collect(Collectors.toSet());
309 }
310
311 @Override
312 public boolean isAvailable(Resource resource) {
313 if (resource instanceof DiscreteResource) {
314 return true;
315 }
316
317 if (resource instanceof ContinuousResource) {
318 List<ResourceAllocation> resalloc = resourcesAllocations.get(resource.id());
319
320 if ((resalloc != null) && (!resalloc.isEmpty())) {
321 if (((ContinuousResource) resalloc.iterator().next().resource()).value()
322 >= ((ContinuousResource) resource).value()) {
323 return true;
324 }
325 }
326 }
327 return false;
328 }
329 }
330
331 /**
332 * All links with different costs with L1-L2 as least cost path.
333 */
334 @Test
335 public void testpathComputationCase1() {
336 Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 50);
337 Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, true, 20);
338 Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 100);
339 Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 50);
340
341 CostConstraint costConst = CostConstraint.of(COST);
342 List<Constraint> constraints = new LinkedList<>();
343 constraints.add(costConst);
344
345 Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
346
347 List<Link> links = new LinkedList<>();
348
349 links.add(link1);
350 links.add(link2);
351
352 assertThat(paths.iterator().next().links(), is(links));
353 assertThat(paths.iterator().next().cost(), is((double) 70));
354 }
355
356 /**
357 * Links with same cost 100 except link3.
358 */
359 @Test
360 public void testpathComputationCase2() {
361 Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 100);
362 Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, true, 100);
363 Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 1000);
364 Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 100);
365
366 CostConstraint costConst = CostConstraint.of(COST);
367 List<Constraint> constraints = new LinkedList<>();
368 constraints.add(costConst);
369 Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
370
371 List<Link> links = new LinkedList<>();
372 links.add(link1);
373 links.add(link2);
374
375 assertThat(paths.iterator().next().links(), is(links));
376 assertThat(paths.iterator().next().cost(), is((double) 200));
377 }
378
379 /**
380 * Path which satisfy bandwidth as a constraint with 10bps.
381 */
382 @Test
383 public void testpathComputationCase3() {
384 Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 50);
385 Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, true, 20);
386 Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 100);
387 Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 50);
388
389 List<Resource> resources = new LinkedList<>();
390
391 resources.add(continuous(link1.src().deviceId(), link1.src().port(), Bandwidth.class)
392 .resource(50));
393 resources.add(continuous(link2.src().deviceId(), link2.src().port(), Bandwidth.class)
394 .resource(50));
395 resources.add(continuous(link3.src().deviceId(), link3.src().port(), Bandwidth.class)
396 .resource(100));
397 resources.add(continuous(link4.src().deviceId(), link4.src().port(), Bandwidth.class)
398 .resource(100));
399
400 resources.add(continuous(link1.dst().deviceId(), link1.dst().port(), Bandwidth.class)
401 .resource(50));
402 resources.add(continuous(link2.dst().deviceId(), link2.dst().port(), Bandwidth.class)
403 .resource(50));
404 resources.add(continuous(link3.dst().deviceId(), link3.src().port(), Bandwidth.class)
405 .resource(100));
406 resources.add(continuous(link4.dst().deviceId(), link4.dst().port(), Bandwidth.class)
407 .resource(100));
408
409 resourceService.allocate(IntentId.valueOf(70), resources);
410
411 BandwidthConstraint bandwidthConst = new BandwidthConstraint(Bandwidth.bps(10.0));
412
413 List<Constraint> constraints = new LinkedList<>();
414 constraints.add(bandwidthConst);
415
416 Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
417
418 assertThat(paths.iterator().next().cost(), is((double) 2));
419 }
420
421 /**
422 * Path which satisfy bandwidth as a constraint with 60bps.
423 */
424 @Test
425 public void testpathComputationCase4() {
426 Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 50);
427 Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, true, 50);
428 Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 100);
429 Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 100);
430
431 List<Resource> resources = new LinkedList<>();
432
433 resources.add(continuous(link1.src().deviceId(), link1.src().port(), Bandwidth.class).resource(50));
434 resources.add(continuous(link2.src().deviceId(), link2.src().port(), Bandwidth.class).resource(50));
435 resources.add(continuous(link3.src().deviceId(), link3.src().port(), Bandwidth.class).resource(100));
436 resources.add(continuous(link4.src().deviceId(), link4.src().port(), Bandwidth.class).resource(100));
437
438 resources.add(continuous(link1.dst().deviceId(), link1.dst().port(), Bandwidth.class).resource(50));
439 resources.add(continuous(link2.dst().deviceId(), link2.dst().port(), Bandwidth.class).resource(50));
440 resources.add(continuous(link3.dst().deviceId(), link3.dst().port(), Bandwidth.class).resource(100));
441 resources.add(continuous(link4.dst().deviceId(), link4.dst().port(), Bandwidth.class).resource(100));
442
443 resourceService.allocate(IntentId.valueOf(70), resources);
444
445 BandwidthConstraint bandwidthConst = new BandwidthConstraint(Bandwidth.bps(60.0));
446
447 List<Constraint> constraints = new LinkedList<>();
448 constraints.add(bandwidthConst);
449 Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
450
451 assertThat(paths.iterator().next().cost(), is((double) 2));
452 }
453
454 /**
455 * Shared bandwidth as L1, L2 with its value 10 bps and bandwidth constraint as 20 bps.
456 */
457 @Test
458 public void testpathComputationCase5() {
459 Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 50);
460 Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, true, 20);
461 Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 100);
462 Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 80);
463
464 List<Resource> resources = new LinkedList<>();
465
466 resources.add(continuous(link1.src().deviceId(), link1.src().port(), Bandwidth.class).resource(50));
467 resources.add(continuous(link2.src().deviceId(), link2.src().port(), Bandwidth.class).resource(50));
468 resources.add(continuous(link3.src().deviceId(), link3.src().port(), Bandwidth.class).resource(100));
469 resources.add(continuous(link4.src().deviceId(), link4.src().port(), Bandwidth.class).resource(100));
470
471 resources.add(continuous(link1.dst().deviceId(), link1.dst().port(), Bandwidth.class).resource(50));
472 resources.add(continuous(link2.dst().deviceId(), link2.dst().port(), Bandwidth.class).resource(50));
473 resources.add(continuous(link3.dst().deviceId(), link3.dst().port(), Bandwidth.class).resource(100));
474 resources.add(continuous(link4.dst().deviceId(), link4.dst().port(), Bandwidth.class).resource(100));
475 resourceService.allocate(IntentId.valueOf(70), resources);
476
477 List<Constraint> constraints = new LinkedList<>();
478
479 List<Link> sharedLinks = new LinkedList<>();
480
481 List<Link> links = new LinkedList<>();
482 links.add(link1);
483 links.add(link2);
484
485 CostConstraint costConst = CostConstraint.of(COST);
486 sharedLinks.addAll(links);
487 SharedBandwidthConstraint sharedBw = new SharedBandwidthConstraint(sharedLinks, Bandwidth.bps(10),
488 Bandwidth.bps(20.0));
489 constraints.add(sharedBw);
490 constraints.add(costConst);
491 Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
492 assertThat(paths.iterator().next().links(), is(links));
493 assertThat(paths.iterator().next().cost(), is((double) 70));
494 }
495
496 /**
497 * Shared bandwidth as L1, L2 with its value 20 bps and bandwidth constraint as 10 bps.
498 */
499 @Test
500 public void testpathComputationCase6() {
501 Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 50);
502 Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, true, 20);
503 Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 100);
504 Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 80);
505
506 List<Resource> resources = new LinkedList<>();
507
508 resources.add(continuous(link1.src().deviceId(), link1.src().port(), Bandwidth.class).resource(50));
509 resources.add(continuous(link2.src().deviceId(), link2.src().port(), Bandwidth.class).resource(50));
510 resources.add(continuous(link3.src().deviceId(), link3.src().port(), Bandwidth.class).resource(100));
511 resources.add(continuous(link4.src().deviceId(), link4.src().port(), Bandwidth.class).resource(100));
512
513 resources.add(continuous(link1.dst().deviceId(), link1.dst().port(), Bandwidth.class).resource(50));
514 resources.add(continuous(link2.dst().deviceId(), link2.dst().port(), Bandwidth.class).resource(50));
515 resources.add(continuous(link3.dst().deviceId(), link3.dst().port(), Bandwidth.class).resource(100));
516 resources.add(continuous(link4.dst().deviceId(), link4.dst().port(), Bandwidth.class).resource(100));
517 resourceService.allocate(IntentId.valueOf(70), resources);
518
519 List<Constraint> constraints = new LinkedList<>();
520
521 List<Link> sharedLinks = new LinkedList<>();
522
523 List<Link> links = new LinkedList<>();
524 links.add(link1);
525 links.add(link2);
526 CostConstraint costConst = CostConstraint.of(COST);
527 sharedLinks.addAll(links);
528 SharedBandwidthConstraint sharedBwConst = new SharedBandwidthConstraint(sharedLinks, Bandwidth.bps(20),
529 Bandwidth.bps(10.0));
530 constraints.add(sharedBwConst);
531 constraints.add(costConst);
532 Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
533
534 assertThat(paths.iterator().next().links(), is(links));
535 assertThat(paths.iterator().next().cost(), is((double) 70));
536 }
537
538 /**
539 * Path without constraints.
540 */
541 @Test
542 public void testpathComputationCase7() {
543 Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 50);
544 Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, true, 20);
545 Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 100);
546 Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 80);
547 List<Constraint> constraints = new LinkedList<>();
548 Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
549
550 assertThat(paths.iterator().next().cost(), is((double) 2));
551 }
552
553 /**
554 * With TeCost as a constraints.
555 */
556 @Test
557 public void testpathComputationCase8() {
558 Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, false, 50);
559 Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, false, 20);
560 Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, false, 100);
561 Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, false, 80);
562
563 CostConstraint tecostConst = CostConstraint.of(TE_COST);
564
565 List<Constraint> constraints = new LinkedList<>();
566 constraints.add(tecostConst);
567 Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
568
569 List<Link> links = new LinkedList<>();
570 links.add(link1);
571 links.add(link2);
572 assertThat(paths.iterator().next().links(), is(links));
573 assertThat(paths.iterator().next().cost(), is((double) 70));
574 }
575
576 /**
577 * With device supporting RSVP capability as a constraints.
578 */
579 @Test
580 public void testpathComputationCase9() {
581 Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, false, 50);
582 Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, false, 20);
583 Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, false, 100);
584 Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, false, 80);
585
586 CostConstraint tecostConst = CostConstraint.of(TE_COST);
587 CapabilityConstraint capabilityConst = CapabilityConstraint
588 .of(CapabilityConstraint.CapabilityType.WITH_SIGNALLING);
589
590 List<Constraint> constraints = new LinkedList<>();
591 constraints.add(capabilityConst);
592 constraints.add(tecostConst);
593 //Device1
594 DefaultAnnotations.Builder builder = DefaultAnnotations.builder();
595 builder.set(AnnotationKeys.TYPE, L3);
596 builder.set(LSRID, "1.1.1.1");
597 addDevice(DEVICE1, builder);
598
599 //Device2
600 builder = DefaultAnnotations.builder();
601 builder.set(AnnotationKeys.TYPE, L3);
602 builder.set(LSRID, "2.2.2.2");
603 addDevice(DEVICE2, builder);
604
605 //Device3
606 builder = DefaultAnnotations.builder();
607 builder.set(AnnotationKeys.TYPE, L3);
608 builder.set(LSRID, "3.3.3.3");
609 addDevice(DEVICE3, builder);
610
611 //Device4
612 builder = DefaultAnnotations.builder();
613 builder.set(AnnotationKeys.TYPE, L3);
614 builder.set(LSRID, "4.4.4.4");
615 addDevice(DEVICE4, builder);
616
617 Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
618
619 List<Link> links = new LinkedList<>();
620 links.add(link1);
621 links.add(link2);
622 assertThat(paths.iterator().next().links(), is(links));
623 assertThat(paths.iterator().next().cost(), is((double) 70));
624 }
625
626 /**
627 * Devices supporting CR capability.
628 */
629 @Test
630 public void testpathComputationCase10() {
631 Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 50);
632 Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, true, 20);
633 Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 100);
634 Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 80);
635
636 CapabilityConstraint capabilityConst = CapabilityConstraint
637 .of(CapabilityConstraint.CapabilityType.WITHOUT_SIGNALLING_AND_WITHOUT_SR);
638
639 List<Constraint> constraints = new LinkedList<>();
640 constraints.add(capabilityConst);
641 CostConstraint costConst = CostConstraint.of(COST);
642 constraints.add(costConst);
643 //Device1
644 DefaultAnnotations.Builder builder = DefaultAnnotations.builder();
645 builder.set(AnnotationKeys.TYPE, L3);
646 builder.set(LSRID, "1.1.1.1");
647 addDevice(DEVICE1, builder);
648 builder.set(PCECC_CAPABILITY, "true");
649 addDevice(PCEPDEVICE1, builder);
650
651 //Device2
652 builder = DefaultAnnotations.builder();
653 builder.set(AnnotationKeys.TYPE, L3);
654 builder.set(LSRID, "2.2.2.2");
655 addDevice(DEVICE2, builder);
656 builder.set(PCECC_CAPABILITY, "true");
657 addDevice(PCEPDEVICE2, builder);
658
659 //Device3
660 builder = DefaultAnnotations.builder();
661 builder.set(AnnotationKeys.TYPE, L3);
662 builder.set(LSRID, "3.3.3.3");
663 addDevice(DEVICE3, builder);
664 builder.set(PCECC_CAPABILITY, "true");
665 addDevice(PCEPDEVICE3, builder);
666
667 //Device4
668 builder = DefaultAnnotations.builder();
669 builder.set(AnnotationKeys.TYPE, L3);
670 builder.set(LSRID, "4.4.4.4");
671 addDevice(DEVICE4, builder);
672 builder.set(PCECC_CAPABILITY, "true");
673 addDevice(PCEPDEVICE4, builder);
674
675 Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
676
677 List<Link> links = new LinkedList<>();
678 links.add(link1);
679 links.add(link2);
680 assertThat(paths.iterator().next().links(), is(links));
681 assertThat(paths.iterator().next().cost(), is((double) 70));
682 }
683
684 /**
685 * Device supporting SR capability.
686 */
687 @Test
688 public void testpathComputationCase11() {
689 Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 50);
690 Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, true, 20);
691 Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 100);
692 Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 80);
693
694 CapabilityConstraint capabilityConst = CapabilityConstraint
695 .of(CapabilityConstraint.CapabilityType.SR_WITHOUT_SIGNALLING);
696
697 List<Constraint> constraints = new LinkedList<>();
698 constraints.add(capabilityConst);
699 CostConstraint costConst = CostConstraint.of(COST);
700 constraints.add(costConst);
701 //Device1
702 DefaultAnnotations.Builder builder = DefaultAnnotations.builder();
703 builder.set(AnnotationKeys.TYPE, L3);
704 builder.set(LSRID, "1.1.1.1");
705 addDevice(DEVICE1, builder);
706 builder.set(SR_CAPABILITY, "true");
707 builder.set(LABEL_STACK_CAPABILITY, "true");
708 addDevice(PCEPDEVICE1, builder);
709
710 //Device2
711 builder = DefaultAnnotations.builder();
712 builder.set(AnnotationKeys.TYPE, L3);
713 builder.set(LSRID, "2.2.2.2");
714 addDevice(DEVICE2, builder);
715 builder.set(SR_CAPABILITY, "true");
716 builder.set(LABEL_STACK_CAPABILITY, "true");
717 addDevice(PCEPDEVICE2, builder);
718
719 //Device3
720 builder = DefaultAnnotations.builder();
721 builder.set(AnnotationKeys.TYPE, L3);
722 builder.set(LSRID, "3.3.3.3");
723 addDevice(DEVICE3, builder);
724 builder.set(SR_CAPABILITY, "true");
725 builder.set(LABEL_STACK_CAPABILITY, "true");
726 addDevice(PCEPDEVICE3, builder);
727
728 //Device4
729 builder = DefaultAnnotations.builder();
730 builder.set(AnnotationKeys.TYPE, L3);
731 builder.set(LSRID, "4.4.4.4");
732 addDevice(DEVICE4, builder);
733 builder.set(SR_CAPABILITY, "true");
734 builder.set(LABEL_STACK_CAPABILITY, "true");
735 addDevice(PCEPDEVICE4, builder);
736 Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
737
738 List<Link> links = new LinkedList<>();
739 links.add(link1);
740 links.add(link2);
741 assertThat(paths.iterator().next().links(), is(links));
742 assertThat(paths.iterator().next().cost(), is((double) 70));
743 }
744
745 /**
746 * Path with TE and SR capability constraint.
747 */
748 @Test
749 public void testpathComputationCase12() {
750 Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, false, 50);
751 Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, false, 20);
752 Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, false, 100);
753 Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, false, 80);
754
755 CostConstraint tecostConst = CostConstraint.of(TE_COST);
756 CapabilityConstraint capabilityConst = CapabilityConstraint
757 .of(CapabilityConstraint.CapabilityType.SR_WITHOUT_SIGNALLING);
758
759 List<Constraint> constraints = new LinkedList<>();
760
761 constraints.add(capabilityConst);
762 constraints.add(tecostConst);
763 //Device1
764 DefaultAnnotations.Builder builder = DefaultAnnotations.builder();
765 builder.set(AnnotationKeys.TYPE, L3);
766 builder.set(LSRID, "1.1.1.1");
767 addDevice(DEVICE1, builder);
768 builder.set(SR_CAPABILITY, "true");
769 builder.set(LABEL_STACK_CAPABILITY, "true");
770 addDevice(PCEPDEVICE1, builder);
771
772 //Device2
773 builder = DefaultAnnotations.builder();
774 builder.set(AnnotationKeys.TYPE, L3);
775 builder.set(LSRID, "2.2.2.2");
776 addDevice(DEVICE2, builder);
777 builder.set(SR_CAPABILITY, "true");
778 builder.set(LABEL_STACK_CAPABILITY, "true");
779 addDevice(PCEPDEVICE2, builder);
780
781 //Device3
782 builder = DefaultAnnotations.builder();
783 builder.set(AnnotationKeys.TYPE, L3);
784 builder.set(LSRID, "3.3.3.3");
785 addDevice(DEVICE3, builder);
786 builder.set(SR_CAPABILITY, "true");
787 builder.set(LABEL_STACK_CAPABILITY, "true");
788 addDevice(PCEPDEVICE3, builder);
789
790 //Device4
791 builder = DefaultAnnotations.builder();
792 builder.set(AnnotationKeys.TYPE, L3);
793 builder.set(LSRID, "4.4.4.4");
794 addDevice(DEVICE4, builder);
795 builder.set(SR_CAPABILITY, "true");
796 builder.set(LABEL_STACK_CAPABILITY, "true");
797 addDevice(PCEPDEVICE4, builder);
798 Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
799
800 List<Link> links = new LinkedList<>();
801 links.add(link1);
802 links.add(link2);
803 assertThat(paths.iterator().next().links(), is(links));
804 assertThat(paths.iterator().next().cost(), is((double) 70));
805 }
806
807 /**
808 * Path with capability constraint and with default cost.
809 */
810 @Test
811 public void testpathComputationCase13() {
812 Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, false, 50);
813 Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, false, 20);
814 Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, false, 100);
815 Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, false, 80);
816
817 CapabilityConstraint capabilityConst = CapabilityConstraint
818 .of(CapabilityConstraint.CapabilityType.SR_WITHOUT_SIGNALLING);
819
820 List<Constraint> constraints = new LinkedList<>();
821 constraints.add(capabilityConst);
822 //Device1
823 DefaultAnnotations.Builder builder = DefaultAnnotations.builder();
824 builder.set(AnnotationKeys.TYPE, L3);
825 builder.set(LSRID, "1.1.1.1");
826 addDevice(DEVICE1, builder);
827 builder.set(SR_CAPABILITY, "true");
828 builder.set(LABEL_STACK_CAPABILITY, "true");
829 addDevice(PCEPDEVICE1, builder);
830
831 //Device2
832 builder = DefaultAnnotations.builder();
833 builder.set(AnnotationKeys.TYPE, L3);
834 builder.set(LSRID, "2.2.2.2");
835 addDevice(DEVICE2, builder);
836 builder.set(SR_CAPABILITY, "true");
837 builder.set(LABEL_STACK_CAPABILITY, "true");
838 addDevice(PCEPDEVICE2, builder);
839
840 //Device3
841 builder = DefaultAnnotations.builder();
842 builder.set(AnnotationKeys.TYPE, L3);
843 builder.set(LSRID, "3.3.3.3");
844 addDevice(DEVICE3, builder);
845 builder.set(SR_CAPABILITY, "true");
846 builder.set(LABEL_STACK_CAPABILITY, "true");
847 addDevice(PCEPDEVICE3, builder);
848
849 //Device4
850 builder = DefaultAnnotations.builder();
851 builder.set(AnnotationKeys.TYPE, L3);
852 builder.set(LSRID, "4.4.4.4");
853 addDevice(DEVICE4, builder);
854 builder.set(SR_CAPABILITY, "true");
855 builder.set(LABEL_STACK_CAPABILITY, "true");
856 addDevice(PCEPDEVICE4, builder);
857 Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
858
859 List<Link> links = new LinkedList<>();
860 links.add(link1);
861 links.add(link2);
862 assertThat(paths.iterator().next().cost(), is((double) 2));
863 }
864
865 /**
866 * Test case with empty constraints.
867 */
868 @Test
869 public void testpathComputationCase14() {
870 Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, false, 50);
871 Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, false, 20);
872 Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, false, 100);
873 Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, false, 80);
874
875 List<Constraint> constraints = new LinkedList<>();
876 Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
877
878 assertThat(paths.iterator().next().cost(), is((double) 2));
879 }
880
881 /**
882 * Test case with constraints as null.
883 */
884 @Test
885 public void testpathComputationCase15() {
886 Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, false, 50);
887 Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, false, 20);
888 Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, false, 100);
889 Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, false, 80);
890
891 List<Constraint> constraints = null;
892 Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
893
894 assertThat(paths.iterator().next().cost(), is((double) 2));
895 }
896
897 /**
898 * Path with cost constraint.
899 */
900 @Test
901 public void testpathComputationCase16() {
902 Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 50);
903 Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, true, 100);
904 Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 10);
905 Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 10);
906 Link link5 = addLink(DEVICE4, 90, DEVICE5, 100, true, 20);
907
908 CostConstraint costConst = CostConstraint.of(COST);
909
910 List<Constraint> constraints = new LinkedList<>();
911 constraints.add(costConst);
912 Graph<TopologyVertex, TopologyEdge> graph = new AdjacencyListsGraph<>(of(D1, D2, D3, D4, D5),
913 of(new DefaultTopologyEdge(D1, D2, link1),
914 new DefaultTopologyEdge(D2, D4, link2),
915 new DefaultTopologyEdge(D1, D3, link3),
916 new DefaultTopologyEdge(D3, D4, link4),
917 new DefaultTopologyEdge(D4, D5, link5)));
918
919 GraphPathSearch.Result<TopologyVertex, TopologyEdge> result =
920 graphSearch().search(graph, D1, D5, weight(constraints), ALL_PATHS);
921 ImmutableSet.Builder<Path> builder = ImmutableSet.builder();
922 for (org.onlab.graph.Path<TopologyVertex, TopologyEdge> path : result.paths()) {
923 builder.add(networkPath(path));
924 }
925
926 List<Link> links = new LinkedList<>();
927 links.add(link3);
928 links.add(link4);
929 links.add(link5);
930 assertThat(builder.build().iterator().next().links(), is(links));
931 assertThat(builder.build().iterator().next().cost(), is((double) 40));
932 }
933
934 /**
935 * D3 doesn't support capability constraint, so path is L1-L2.
936 */
937 @Test
938 public void testpathComputationCase17() {
939 Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, false, 50);
940 Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, false, 20);
941 Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, false, 100);
942 Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, false, 80);
943
944 CapabilityConstraint capabilityConst = CapabilityConstraint
945 .of(CapabilityConstraint.CapabilityType.WITHOUT_SIGNALLING_AND_WITHOUT_SR);
946
947 List<Constraint> constraints = new LinkedList<>();
948 constraints.add(capabilityConst);
949 //Device1
950 DefaultAnnotations.Builder builder = DefaultAnnotations.builder();
951 builder.set(AnnotationKeys.TYPE, L3);
952 builder.set(LSRID, "1.1.1.1");
953 addDevice(DEVICE1, builder);
954 builder.set(PCECC_CAPABILITY, "true");
955 addDevice(PCEPDEVICE1, builder);
956
957 //Device2
958 builder = DefaultAnnotations.builder();
959 builder.set(AnnotationKeys.TYPE, L3);
960 builder.set(LSRID, "2.2.2.2");
961 addDevice(DEVICE2, builder);
962 builder.set(PCECC_CAPABILITY, "true");
963 addDevice(PCEPDEVICE2, builder);
964
965 //Device4
966 builder = DefaultAnnotations.builder();
967 builder.set(AnnotationKeys.TYPE, L3);
968 builder.set(LSRID, "4.4.4.4");
969 addDevice(DEVICE4, builder);
970 builder.set(PCECC_CAPABILITY, "true");
971 addDevice(PCEPDEVICE4, builder);
972 Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
973
974 List<Link> links = new LinkedList<>();
975 links.add(link1);
976 links.add(link2);
977
978 assertThat(paths.iterator().next().links(), is(links));
979 assertThat(paths.iterator().next().cost(), is((double) 2));
980 }
981
982 /**
983 * L2 doesn't support cost constraint and D3 doesn't support capability constraint, both constraint fails hence no
984 * path.
985 */
986 @Test
987 public void testpathComputationCase18() {
988 Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 50);
989 Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, false, 20);
990 Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 10);
991 Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 10);
992
993 CapabilityConstraint capabilityConst = CapabilityConstraint
994 .of(CapabilityConstraint.CapabilityType.WITHOUT_SIGNALLING_AND_WITHOUT_SR);
995 CostConstraint costConst = CostConstraint.of(COST);
996 List<Constraint> constraints = new LinkedList<>();
997 constraints.add(capabilityConst);
998 constraints.add(costConst);
999 //Device1
1000 DefaultAnnotations.Builder builder = DefaultAnnotations.builder();
1001 builder.set(AnnotationKeys.TYPE, L3);
1002 builder.set(LSRID, "1.1.1.1");
1003 addDevice(DEVICE2, builder);
1004 builder.set(PCECC_CAPABILITY, "true");
1005 addDevice(PCEPDEVICE1, builder);
1006
1007 //Device2
1008 builder = DefaultAnnotations.builder();
1009 builder.set(AnnotationKeys.TYPE, L3);
1010 builder.set(LSRID, "2.2.2.2");
1011 addDevice(DEVICE2, builder);
1012 builder.set(PCECC_CAPABILITY, "true");
1013 addDevice(PCEPDEVICE2, builder);
1014
1015 //Device4
1016 builder = DefaultAnnotations.builder();
1017 builder.set(AnnotationKeys.TYPE, L3);
1018 builder.set(LSRID, "4.4.4.4");
1019 addDevice(DEVICE4, builder);
1020 builder.set(PCECC_CAPABILITY, "true");
1021 addDevice(PCEPDEVICE4, builder);
1022 Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
1023
1024 assertThat(paths, is(new HashSet<>()));
1025 }
1026
1027 private void addDevice(String device, DefaultAnnotations.Builder builder) {
1028 deviceService.addDevice(new DefaultDevice(ProviderId.NONE, deviceId(device), Type.ROUTER,
1029 UNKNOWN, UNKNOWN, UNKNOWN,
1030 UNKNOWN, new ChassisId(), builder.build()));
1031 }
1032}