blob: 5b0d86988f78cf36b8e39c86ba85f8d298b40797 [file] [log] [blame]
Avantika-Huaweidbdf7722016-05-21 14:20:31 +05301package org.onosproject.pce.pceservice;
2
3import static org.hamcrest.MatcherAssert.assertThat;
4import static org.hamcrest.core.Is.is;
5import static org.onlab.graph.GraphPathSearch.ALL_PATHS;
6import static org.onosproject.net.Link.State.ACTIVE;
7import static org.onosproject.net.Link.Type.DIRECT;
8import static org.onosproject.pce.pceservice.constraint.CostConstraint.Type.COST;
9import static org.onosproject.pce.pceservice.constraint.CostConstraint.Type.TE_COST;
10import static org.onosproject.net.resource.Resources.continuous;
11import static org.onosproject.pce.pceservice.LspType.SR_WITHOUT_SIGNALLING;
12import static org.onosproject.pce.pceservice.LspType.WITHOUT_SIGNALLING_AND_WITHOUT_SR;
13import static org.onosproject.pce.pceservice.LspType.WITH_SIGNALLING;
14import static org.onosproject.pce.pceservice.PathComputationTest.D1;
15import static org.onosproject.pce.pceservice.PathComputationTest.D2;
16import static org.onosproject.pce.pceservice.PathComputationTest.D3;
17import static org.onosproject.pce.pceservice.PathComputationTest.D4;
18import static org.onosproject.pce.pceservice.PcepAnnotationKeys.LOCAL_LSP_ID;
19import static org.onosproject.pce.pceservice.PcepAnnotationKeys.PLSP_ID;
20import static org.onosproject.incubator.net.tunnel.Tunnel.State.UNSTABLE;
21import static org.onosproject.incubator.net.tunnel.Tunnel.State.ESTABLISHED;
22
23import java.net.URISyntaxException;
24import java.nio.ByteBuffer;
25import java.util.Collection;
26import java.util.Collections;
27import java.util.HashMap;
28import java.util.HashSet;
29import java.util.LinkedList;
30import java.util.List;
31import java.util.Set;
32import java.util.concurrent.atomic.AtomicLong;
33
34import org.junit.After;
35import org.junit.Before;
36import org.junit.Test;
37import org.onlab.graph.GraphPathSearch;
38import org.onlab.packet.Ethernet;
39import org.onlab.packet.IPv4;
40import org.onlab.util.Bandwidth;
41import org.onosproject.common.DefaultTopologyGraph;
42import org.onosproject.core.ApplicationId;
43import org.onosproject.core.CoreServiceAdapter;
44import org.onosproject.core.DefaultApplicationId;
45import org.onosproject.core.IdGenerator;
46import org.onosproject.incubator.net.resource.label.LabelResourceId;
47import org.onosproject.incubator.net.resource.label.LabelResourceService;
48import org.onosproject.incubator.net.tunnel.DefaultTunnel;
49import org.onosproject.incubator.net.tunnel.Tunnel;
50import org.onosproject.incubator.net.tunnel.Tunnel.State;
51import org.onosproject.incubator.net.tunnel.TunnelEndPoint;
52import org.onosproject.incubator.net.tunnel.TunnelEvent;
53import org.onosproject.incubator.net.tunnel.TunnelId;
54import org.onosproject.incubator.net.tunnel.TunnelListener;
55import org.onosproject.net.AnnotationKeys;
56import org.onosproject.net.Annotations;
57import org.onosproject.net.ConnectPoint;
58import org.onosproject.net.DefaultAnnotations;
59import org.onosproject.net.DefaultDevice;
60import org.onosproject.net.DefaultLink;
61import org.onosproject.net.Device;
62import org.onosproject.net.DefaultAnnotations.Builder;
63import org.onosproject.net.device.DeviceServiceAdapter;
64import org.onosproject.net.flowobjective.ForwardingObjective;
65import org.onosproject.net.DeviceId;
66import org.onosproject.net.ElementId;
67import org.onosproject.net.Link;
68import org.onosproject.net.Path;
69import org.onosproject.net.PortNumber;
70import org.onosproject.net.SparseAnnotations;
71import org.onosproject.net.intent.Constraint;
72import org.onosproject.net.intent.IntentId;
73import org.onosproject.net.intent.constraint.BandwidthConstraint;
74import org.onosproject.net.packet.DefaultInboundPacket;
75import org.onosproject.net.packet.DefaultPacketContext;
76import org.onosproject.net.packet.InboundPacket;
77import org.onosproject.net.packet.OutboundPacket;
78import org.onosproject.net.packet.PacketProcessor;
79import org.onosproject.net.packet.PacketService;
80import org.onosproject.net.packet.PacketServiceAdapter;
81import org.onosproject.net.provider.ProviderId;
82import org.onosproject.net.resource.Resource;
83import org.onosproject.net.topology.DefaultTopologyEdge;
84import org.onosproject.net.topology.DefaultTopologyVertex;
85import org.onosproject.net.topology.LinkWeight;
86import org.onosproject.net.topology.PathServiceAdapter;
87import org.onosproject.net.topology.Topology;
88import org.onosproject.net.topology.TopologyEdge;
89import org.onosproject.net.topology.TopologyGraph;
90import org.onosproject.net.topology.TopologyServiceAdapter;
91import org.onosproject.net.topology.TopologyVertex;
92import org.onosproject.pce.pceservice.PathComputationTest.MockPathResourceService;
93import org.onosproject.pce.pceservice.constraint.CostConstraint;
94import org.onosproject.pce.pcestore.api.PceStore;
95import org.onosproject.pce.util.LabelResourceAdapter;
96import org.onosproject.pce.util.PceStoreAdapter;
97import org.onosproject.pce.util.TunnelServiceAdapter;
98import org.onosproject.pce.util.FlowObjServiceAdapter;
99import org.onosproject.store.service.TestStorageService;
100import com.google.common.collect.ImmutableSet;
101
102/**
103 * Tests the functions of PceManager.
104 */
105public class PceManagerTest {
106
107 private PathComputationTest pathCompTest = new PathComputationTest();
108 private MockPathResourceService resourceService = pathCompTest.new MockPathResourceService();
109 private MockTopologyService topologyService = new MockTopologyService();
110 private MockPathService pathService = new MockPathService();
111 private PceManager pceManager = new PceManager();
112 private MockCoreService coreService = new MockCoreService();
113 private MockTunnelServiceAdapter tunnelService = new MockTunnelServiceAdapter();
114 private TestStorageService storageService = new TestStorageService();
115 private PacketService packetService = new MockPacketService();
116 private MockDeviceService deviceService = new MockDeviceService();
117 private MockFlowObjService flowObjectiveService = new MockFlowObjService();
118 private PceStore pceStore = new PceStoreAdapter();
119 private LabelResourceService labelResourceService = new LabelResourceAdapter();
120
121 public static ProviderId providerId = new ProviderId("pce", "foo");
122 private static final String L3 = "L3";
123 private static final String LSRID = "lsrId";
124 private static final String PCECC_CAPABILITY = "pceccCapability";
125 private static final String SR_CAPABILITY = "srCapability";
126 private static final String LABEL_STACK_CAPABILITY = "labelStackCapability";
127
128 private TopologyGraph graph = null;
129 private Device deviceD1, deviceD2, deviceD3, deviceD4;
130 private Device pcepDeviceD1, pcepDeviceD2, pcepDeviceD3, pcepDeviceD4;
131 private Link link1, link2, link3, link4;
132 private static int flowsDownloaded;
133 private TunnelListener tunnelListener;
134
135 @Before
136 public void startUp() {
137 pceManager.pathService = pathService;
138 pceManager.resourceService = resourceService;
139 pceManager.tunnelService = tunnelService;
140 pceManager.coreService = coreService;
141 pceManager.storageService = storageService;
142 pceManager.packetService = packetService;
143 pceManager.deviceService = deviceService;
144 pceManager.labelRsrcService = labelResourceService;
145 pceManager.flowObjectiveService = flowObjectiveService;
146 pceManager.pceStore = pceStore;
147 pceManager.activate();
148 }
149
150 private void build4RouterTopo(boolean setCost, boolean setPceccCap, boolean setSrCap,
151 boolean setLabelStackCap, int bandwidth) {
152 Set<TopologyVertex> vertexes = new HashSet<TopologyVertex>();
153 vertexes.add(D1);
154 vertexes.add(D2);
155 vertexes.add(D3);
156 vertexes.add(D4);
157
158 Set<TopologyEdge> edges = new HashSet<TopologyEdge>();
159 link1 = PathComputationTest.addLink(D1.deviceId().toString(), 10, D2.deviceId().toString(), 20, setCost, 50);
160 TopologyEdge edge1 = new DefaultTopologyEdge(D1, D2, link1);
161 edges.add(edge1);
162
163 link2 = PathComputationTest.addLink(D2.deviceId().toString(), 30, D4.deviceId().toString(), 40, setCost, 20);
164 TopologyEdge edge2 = new DefaultTopologyEdge(D2, D4, link2);
165 edges.add(edge2);
166
167 link3 = PathComputationTest.addLink(D1.deviceId().toString(), 80, D3.deviceId().toString(), 70, setCost, 100);
168 TopologyEdge edge3 = new DefaultTopologyEdge(D1, D3, link3);
169 edges.add(edge3);
170
171 link4 = PathComputationTest.addLink(D3.deviceId().toString(), 60, D4.deviceId().toString(), 50, setCost, 80);
172 TopologyEdge edge4 = new DefaultTopologyEdge(D3, D4, link4);
173 edges.add(edge4);
174
175 graph = new DefaultTopologyGraph(vertexes, edges);
176
177 DefaultAnnotations.Builder builderDev1 = DefaultAnnotations.builder();
178 DefaultAnnotations.Builder builderDev2 = DefaultAnnotations.builder();
179 DefaultAnnotations.Builder builderDev3 = DefaultAnnotations.builder();
180 DefaultAnnotations.Builder builderDev4 = DefaultAnnotations.builder();
181
182 builderDev1.set(AnnotationKeys.TYPE, L3);
183 builderDev1.set(LSRID, "1.1.1.1");
184
185 builderDev2.set(AnnotationKeys.TYPE, L3);
186 builderDev2.set(LSRID, "2.2.2.2");
187
188 builderDev3.set(AnnotationKeys.TYPE, L3);
189 builderDev3.set(LSRID, "3.3.3.3");
190
191 builderDev4.set(AnnotationKeys.TYPE, L3);
192 builderDev4.set(LSRID, "4.4.4.4");
193
194 if (setSrCap) {
195 builderDev1.set(SR_CAPABILITY, "true");
196 builderDev2.set(SR_CAPABILITY, "true");
197 builderDev3.set(SR_CAPABILITY, "true");
198 builderDev4.set(SR_CAPABILITY, "true");
199 }
200
201 if (setPceccCap) {
202 builderDev1.set(PCECC_CAPABILITY, "true");
203 builderDev2.set(PCECC_CAPABILITY, "true");
204 builderDev3.set(PCECC_CAPABILITY, "true");
205 builderDev4.set(PCECC_CAPABILITY, "true");
206 }
207
208 if (setLabelStackCap) {
209 builderDev1.set(LABEL_STACK_CAPABILITY, "true");
210 builderDev2.set(LABEL_STACK_CAPABILITY, "true");
211 builderDev3.set(LABEL_STACK_CAPABILITY, "true");
212 builderDev4.set(LABEL_STACK_CAPABILITY, "true");
213 }
214
215 deviceD1 = new MockDevice(D1.deviceId(), builderDev1.build());
216 deviceD2 = new MockDevice(D2.deviceId(), builderDev2.build());
217 deviceD3 = new MockDevice(D3.deviceId(), builderDev3.build());
218 deviceD4 = new MockDevice(D4.deviceId(), builderDev4.build());
219
220 deviceService.addDevice(deviceD1);
221 deviceService.addDevice(deviceD2);
222 deviceService.addDevice(deviceD3);
223 deviceService.addDevice(deviceD4);
224
225 pcepDeviceD1 = new MockDevice(DeviceId.deviceId(PathComputationTest.PCEPDEVICE1), builderDev1.build());
226 deviceService.addDevice(pcepDeviceD1);
227
228 pcepDeviceD2 = new MockDevice(DeviceId.deviceId(PathComputationTest.PCEPDEVICE2), builderDev1.build());
229 deviceService.addDevice(pcepDeviceD2);
230
231 pcepDeviceD3 = new MockDevice(DeviceId.deviceId(PathComputationTest.PCEPDEVICE3), builderDev1.build());
232 deviceService.addDevice(pcepDeviceD3);
233
234 pcepDeviceD4 = new MockDevice(DeviceId.deviceId(PathComputationTest.PCEPDEVICE4), builderDev1.build());
235 deviceService.addDevice(pcepDeviceD4);
236
237 if (bandwidth != 0) {
238 List<Resource> resources = new LinkedList<>();
239 resources.add(continuous(link1.src().deviceId(), link1.src().port(), Bandwidth.class).resource(bandwidth));
240 resources.add(continuous(link2.src().deviceId(), link2.src().port(), Bandwidth.class).resource(bandwidth));
241 resources.add(continuous(link3.src().deviceId(), link3.src().port(), Bandwidth.class).resource(bandwidth));
242 resources.add(continuous(link4.src().deviceId(), link4.src().port(), Bandwidth.class).resource(bandwidth));
243
244 resources.add(continuous(link1.dst().deviceId(), link1.dst().port(), Bandwidth.class).resource(bandwidth));
245 resources.add(continuous(link2.dst().deviceId(), link2.dst().port(), Bandwidth.class).resource(bandwidth));
246 resources.add(continuous(link3.dst().deviceId(), link3.dst().port(), Bandwidth.class).resource(bandwidth));
247 resources.add(continuous(link4.dst().deviceId(), link4.dst().port(), Bandwidth.class).resource(bandwidth));
248
249 resourceService.allocate(IntentId.valueOf(bandwidth), resources);
250 }
251 }
252
253 /**
254 * Tests path success with (IGP) cost constraint for signalled LSP.
255 */
256 @Test
257 public void setupPathTest1() {
258 build4RouterTopo(true, false, false, false, 0); // IGP cost is set here.
259 List<Constraint> constraints = new LinkedList<Constraint>();
260 CostConstraint costConstraint = new CostConstraint(COST);
261 constraints.add(costConstraint);
262
263 boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, WITH_SIGNALLING);
264 assertThat(result, is(true));
265 }
266
267 /**
268 * Tests path failure with (IGP) cost constraint for signalled LSP.
269 */
270 @Test
271 public void setupPathTest2() {
272 build4RouterTopo(false, false, false, false, 0); // TE cost is set here, not IGP.
273 List<Constraint> constraints = new LinkedList<Constraint>();
274 CostConstraint costConstraint = new CostConstraint(COST);
275 constraints.add(costConstraint);
276
277 boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, WITH_SIGNALLING);
278 assertThat(result, is(false));
279 }
280
281 /**
282 * Tests path success with TE-cost constraint for signalled LSP.
283 */
284 @Test
285 public void setupPathTest3() {
286 build4RouterTopo(false, false, false, false, 0); // TE cost is set here.
287
288 List<Constraint> constraints = new LinkedList<Constraint>();
289 CostConstraint costConstraint = new CostConstraint(TE_COST);
290 constraints.add(costConstraint);
291
292 boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, WITH_SIGNALLING);
293 assertThat(result, is(true));
294 }
295
296 /**
297 * Tests path failure with TE-cost constraint for signalled LSP.
298 */
299 @Test
300 public void setupPathTest4() {
301 build4RouterTopo(true, false, false, false, 0); // IGP cost is set here, not TE.
302
303 List<Constraint> constraints = new LinkedList<Constraint>();
304 CostConstraint costConstraint = new CostConstraint(TE_COST);
305 constraints.add(costConstraint);
306
307 boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, WITH_SIGNALLING);
308 assertThat(result, is(false));
309 }
310
311 /**
312 * Tests path success with (IGP) cost constraint for non-SR non-signalled LSP.
313 */
314 @Test
315 public void setupPathTest5() {
316 build4RouterTopo(true, true, false, false, 0);
317
318 List<Constraint> constraints = new LinkedList<Constraint>();
319 CostConstraint costConstraint = new CostConstraint(COST);
320 constraints.add(costConstraint);
321
322 boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints,
323 WITHOUT_SIGNALLING_AND_WITHOUT_SR);
324 assertThat(result, is(true));
325 }
326
327 /**
328 * Tests path success with TE-cost constraint for non-SR non-sgnalled LSP.
329 */
330 @Test
331 public void setupPathTest6() {
332 build4RouterTopo(false, true, false, false, 0);
333
334 List<Constraint> constraints = new LinkedList<Constraint>();
335 CostConstraint costConstraint = new CostConstraint(TE_COST);
336 constraints.add(costConstraint);
337
338 boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints,
339 WITHOUT_SIGNALLING_AND_WITHOUT_SR);
340 assertThat(result, is(true));
341 }
342
343 /**
344 * Tests path failure with TE-cost constraint for non-SR non-signalled LSP(CR). Label capability not registered.
345 */
346 @Test
347 public void setupPathTest7() {
348 build4RouterTopo(true, false, false, false, 0);
349
350 List<Constraint> constraints = new LinkedList<Constraint>();
351 CostConstraint costConstraint = new CostConstraint(TE_COST);
352 constraints.add(costConstraint);
353
354 boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints,
355 WITHOUT_SIGNALLING_AND_WITHOUT_SR);
356 assertThat(result, is(false));
357 }
358
359 /**
360 * Tests path failure as bandwidth is requested but is not registered.
361 */
362 @Test
363 public void setupPathTest8() {
364 build4RouterTopo(true, false, false, false, 0);
365 List<Constraint> constraints = new LinkedList<Constraint>();
366 BandwidthConstraint bwConstraint = new BandwidthConstraint(Bandwidth.bps(10.0));
367 CostConstraint costConstraint = new CostConstraint(TE_COST);
368
369 constraints.add(costConstraint);
370 constraints.add(bwConstraint);
371
372 boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, WITH_SIGNALLING);
373 assertThat(result, is(false));
374 }
375
376 /**
377 * Tests path failure as bandwidth requested is more than registered.
378 */
379 @Test
380 public void setupPathTest9() {
381 build4RouterTopo(false, false, false, false, 5);
382 List<Constraint> constraints = new LinkedList<Constraint>();
383 BandwidthConstraint bwConstraint = new BandwidthConstraint(Bandwidth.bps(10.0));
384 CostConstraint costConstraint = new CostConstraint(TE_COST);
385
386 constraints.add(costConstraint);
387 constraints.add(bwConstraint);
388
389 boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, WITH_SIGNALLING);
390 assertThat(result, is(false));
391 }
392
393 /**
394 * Tests path setup failure(without signalling). Label capability is not present.
395 */
396 @Test
397 public void setupPathTest10() {
398 build4RouterTopo(false, false, false, false, 0);
399 List<Constraint> constraints = new LinkedList<Constraint>();
400 CostConstraint costConstraint = new CostConstraint(TE_COST);
401 constraints.add(costConstraint);
402
403 boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, SR_WITHOUT_SIGNALLING);
404 assertThat(result, is(false));
405 }
406
407 /**
408 * Tests path setup without failure for LSP with signalling and with bandwidth reservation.
409 */
410 @Test
411 public void setupPathTest11() {
412 build4RouterTopo(false, true, true, true, 15);
413 List<Constraint> constraints = new LinkedList<Constraint>();
414 BandwidthConstraint bwConstraint = new BandwidthConstraint(Bandwidth.bps(10.0));
415 CostConstraint costConstraint = new CostConstraint(TE_COST);
416
417 constraints.add(costConstraint);
418 constraints.add(bwConstraint);
419
420 LabelResourceId node1Label = LabelResourceId.labelResourceId(5200);
421 LabelResourceId node2Label = LabelResourceId.labelResourceId(5201);
422
423 pceManager.pceStore.addGlobalNodeLabel(D1.deviceId(), node1Label);
424 pceManager.pceStore.addGlobalNodeLabel(D2.deviceId(), node2Label);
425
426 boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, SR_WITHOUT_SIGNALLING);
427 assertThat(result, is(false));
428 }
429
430 /**
431 * Tests path setup without signalling and with bandwidth reservation.
432 */
433 @Test
434 public void setupPathTest12() {
435 build4RouterTopo(false, true, true, true, 15);
436 List<Constraint> constraints = new LinkedList<Constraint>();
437 BandwidthConstraint bwConstraint = new BandwidthConstraint(Bandwidth.bps(10.0));
438 CostConstraint costConstraint = new CostConstraint(TE_COST);
439
440 constraints.add(costConstraint);
441 constraints.add(bwConstraint);
442
443 LabelResourceId node1Label = LabelResourceId.labelResourceId(5200);
444 LabelResourceId node2Label = LabelResourceId.labelResourceId(5201);
445
446 pceManager.pceStore.addGlobalNodeLabel(D1.deviceId(), node1Label);
447 pceManager.pceStore.addGlobalNodeLabel(D2.deviceId(), node2Label);
448
449 LabelResourceId link1Label = LabelResourceId.labelResourceId(5202);
450 pceManager.pceStore.addAdjLabel(link1, link1Label);
451
452 LabelResourceId link2Label = LabelResourceId.labelResourceId(5203);
453 pceManager.pceStore.addAdjLabel(link2, link2Label);
454
455 LabelResourceId link3Label = LabelResourceId.labelResourceId(5204);
456 pceManager.pceStore.addAdjLabel(link3, link3Label);
457
458 LabelResourceId link4Label = LabelResourceId.labelResourceId(5205);
459 pceManager.pceStore.addAdjLabel(link4, link4Label);
460
461 boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, SR_WITHOUT_SIGNALLING);
462 assertThat(result, is(true));
463 }
464
465 /**
466 * Tests path setup without cost/bandwidth constraints.
467 */
468 @Test
469 public void setupPathTest13() {
470 build4RouterTopo(false, false, false, false, 0);
471
472 boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", null, WITH_SIGNALLING);
473 assertThat(result, is(true));
474 }
475
476 /**
477 * Tests path update with increase in bandwidth.
478 */
479 @Test
480 public void updatePathTest1() {
481 build4RouterTopo(false, true, true, true, 100);
482
483 // Setup tunnel.
484 List<Constraint> constraints = new LinkedList<>();
485 BandwidthConstraint bwConstraint = new BandwidthConstraint(Bandwidth.bps(60.0));
486 constraints.add(bwConstraint);
487 CostConstraint costConstraint = new CostConstraint(TE_COST);
488 constraints.add(costConstraint);
489
490 boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123", constraints, WITH_SIGNALLING);
491 assertThat(result, is(true));
492
493 // Change constraint and update it.
494 constraints = new LinkedList<>();
495 bwConstraint = new BandwidthConstraint(Bandwidth.bps(50.0));
496 constraints.add(bwConstraint);
497 constraints.add(costConstraint);
498
499 Collection<Tunnel> tunnels = (Collection<Tunnel>) pceManager.queryAllPath();
500 assertThat(tunnels.size(), is(1));
501
502 Tunnel tunnel = tunnels.iterator().next();
503
504 // Stimulate the effect of LSP ids from protocol msg.
505 tunnelService.updateTunnelWithLspIds(tunnel, "123", "1", State.ACTIVE);
506
507 result = pceManager.updatePath(tunnel.tunnelId(), constraints);
508 assertThat(result, is(true));
509
510 tunnels = (Collection<Tunnel>) pceManager.queryAllPath();
511 assertThat(tunnels.size(), is(2));
512 }
513
514 /**
515 * Tests path update with decrease in bandwidth.
516 */
517 @Test
518 public void updatePathTest2() {
519 build4RouterTopo(false, true, true, true, 100);
520
521 // Setup tunnel.
522 List<Constraint> constraints = new LinkedList<Constraint>();
523 BandwidthConstraint bwConstraint = new BandwidthConstraint(Bandwidth.bps(60.0));
524 constraints.add(bwConstraint);
525 CostConstraint costConstraint = new CostConstraint(TE_COST);
526 constraints.add(costConstraint);
527
528 LabelResourceId node1Label = LabelResourceId.labelResourceId(5200);
529 LabelResourceId node2Label = LabelResourceId.labelResourceId(5201);
530
531 pceManager.pceStore.addGlobalNodeLabel(D1.deviceId(), node1Label);
532 pceManager.pceStore.addGlobalNodeLabel(D2.deviceId(), node2Label);
533
534 LabelResourceId link1Label = LabelResourceId.labelResourceId(5202);
535 pceManager.pceStore.addAdjLabel(link1, link1Label);
536
537 LabelResourceId link2Label = LabelResourceId.labelResourceId(5203);
538 pceManager.pceStore.addAdjLabel(link2, link2Label);
539
540 LabelResourceId link3Label = LabelResourceId.labelResourceId(5204);
541 pceManager.pceStore.addAdjLabel(link3, link3Label);
542
543 LabelResourceId link4Label = LabelResourceId.labelResourceId(5205);
544 pceManager.pceStore.addAdjLabel(link4, link4Label);
545
546 boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, SR_WITHOUT_SIGNALLING);
547 assertThat(result, is(true));
548
549 // Change constraint and update it.
550 constraints.remove(bwConstraint);
551 bwConstraint = new BandwidthConstraint(Bandwidth.bps(70.0));
552 constraints.add(bwConstraint);
553
554 Collection<Tunnel> tunnels = (Collection<Tunnel>) pceManager.queryAllPath();
555 assertThat(tunnels.size(), is(1));
556
557 for (Tunnel tunnel : tunnels) {
558 result = pceManager.updatePath(tunnel.tunnelId(), constraints);
559 assertThat(result, is(true));
560 }
561
562 tunnels = (Collection<Tunnel>) pceManager.queryAllPath();
563 assertThat(tunnels.size(), is(2));
564 }
565
566 /**
567 * Tests path update without cost/bandwidth constraints.
568 */
569 @Test
570 public void updatePathTest3() {
571 build4RouterTopo(false, true, true, true, 100);
572
573 // Setup tunnel.
574 boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", null, WITH_SIGNALLING);
575 assertThat(result, is(true));
576
577 Collection<Tunnel> tunnels = (Collection<Tunnel>) pceManager.queryAllPath();
578 assertThat(tunnels.size(), is(1));
579
580 for (Tunnel tunnel : tunnels) {
581 result = pceManager.updatePath(tunnel.tunnelId(), null);
582 assertThat(result, is(true));
583 }
584
585 Iterable<Tunnel> queryTunnelResult = pceManager.queryAllPath();
586 assertThat((int) queryTunnelResult.spliterator().getExactSizeIfKnown(), is(2));
587 }
588
589 /**
590 * Tests path release.
591 */
592 @Test
593 public void releasePathTest1() {
594 build4RouterTopo(false, false, false, false, 5);
595 List<Constraint> constraints = new LinkedList<Constraint>();
596 CostConstraint costConstraint = new CostConstraint(TE_COST);
597 constraints.add(costConstraint);
598
599 pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, WITH_SIGNALLING);
600
601 Collection<Tunnel> tunnels = (Collection<Tunnel>) pceManager.queryAllPath();
602 assertThat(tunnels.size(), is(1));
603 boolean result;
604 for (Tunnel tunnel : tunnels) {
605 result = pceManager.releasePath(tunnel.tunnelId());
606 assertThat(result, is(true));
607 }
608 tunnels = (Collection<Tunnel>) pceManager.queryAllPath();
609 assertThat(tunnels.size(), is(0));
610 }
611
612 /**
613 * Tests path release failure.
614 */
615 @Test
616 public void releasePathTest2() {
617 build4RouterTopo(false, false, false, false, 5);
618 List<Constraint> constraints = new LinkedList<Constraint>();
619 CostConstraint costConstraint = new CostConstraint(TE_COST);
620 constraints.add(costConstraint);
621
622 pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, WITH_SIGNALLING);
623
624 Collection<Tunnel> tunnels = (Collection<Tunnel>) pceManager.queryAllPath();
625 assertThat(tunnels.size(), is(1));
626
627 // Random tunnel id.
628 boolean result = pceManager.releasePath(TunnelId.valueOf("111"));
629 assertThat(result, is(false));
630
631 tunnels = (Collection<Tunnel>) pceManager.queryAllPath();
632 assertThat(tunnels.size(), is(1));
633 }
634
635 /**
636 * Tests packet in to trigger label DB sync.
637 */
638 @Test
639 public void packetProcessingTest() throws URISyntaxException {
640
641 build4RouterTopo(false, true, true, true, 0); // This also initializes devices etc.
642
643 final int srcHost = 2;
644 final int dstHost = 5;
645
646 LabelResourceId node1Label = LabelResourceId.labelResourceId(5200);
647 LabelResourceId node2Label = LabelResourceId.labelResourceId(5201);
648
649 pceManager.pceStore.addGlobalNodeLabel(D1.deviceId(), node1Label);
650 pceManager.pceStore.addGlobalNodeLabel(D2.deviceId(), node2Label);
651
652 ConnectPoint src = new ConnectPoint(D1.deviceId(), PortNumber.portNumber(srcHost));
653 ConnectPoint dst = new ConnectPoint(D2.deviceId(), PortNumber.portNumber(dstHost));
654
655 Link link1 = DefaultLink.builder().src(src).dst(dst).state(ACTIVE).type(DIRECT)
656 .providerId(new ProviderId("eth", "1")).build();
657
658 LabelResourceId link1Label = LabelResourceId.labelResourceId(5204);
659 pceManager.pceStore.addAdjLabel(link1, link1Label);
660
661 Ethernet eth;
662 IPv4 ipv4;
663
664 ipv4 = new IPv4();
665 eth = new Ethernet();
666 eth.setEtherType(Ethernet.TYPE_IPV4);
667 eth.setPayload(ipv4);
668
669 eth.setSourceMACAddress("00:00:00:10:00:0" + srcHost).setDestinationMACAddress("00:00:00:10:00:0" + dstHost);
670
671 InboundPacket inPkt = new DefaultInboundPacket(new ConnectPoint(D1.deviceId(), PortNumber.portNumber(srcHost)),
672 eth, ByteBuffer.wrap(eth.serialize()));
673
674 pktProcessor.process(new MockPcepPacketContext(inPkt, null));
675 assertThat(flowsDownloaded, is(4));
676 }
677
678 /**
679 * Tests tunnel events added and removed.
680 */
681 @Test
682 public void tunnelEventTest1() {
683 build4RouterTopo(false, true, true, true, 15);
684 List<Constraint> constraints = new LinkedList<Constraint>();
685 BandwidthConstraint bwConstraint = new BandwidthConstraint(Bandwidth.bps(10.0));
686 CostConstraint costConstraint = new CostConstraint(TE_COST);
687
688 constraints.add(costConstraint);
689 constraints.add(bwConstraint);
690
691 LabelResourceId node1Label = LabelResourceId.labelResourceId(5200);
692 LabelResourceId node2Label = LabelResourceId.labelResourceId(5201);
693
694 pceManager.pceStore.addGlobalNodeLabel(D1.deviceId(), node1Label);
695 pceManager.pceStore.addGlobalNodeLabel(D2.deviceId(), node2Label);
696
697 LabelResourceId link1Label = LabelResourceId.labelResourceId(5202);
698 pceManager.pceStore.addAdjLabel(link1, link1Label);
699
700 LabelResourceId link2Label = LabelResourceId.labelResourceId(5203);
701 pceManager.pceStore.addAdjLabel(link2, link2Label);
702
703 LabelResourceId link3Label = LabelResourceId.labelResourceId(5204);
704 pceManager.pceStore.addAdjLabel(link3, link3Label);
705
706 LabelResourceId link4Label = LabelResourceId.labelResourceId(5205);
707 pceManager.pceStore.addAdjLabel(link4, link4Label);
708
709 pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T1", constraints, SR_WITHOUT_SIGNALLING);
710 assertThat(pceStore.getTunnelInfoCount(), is(1));
711
712 Collection<Tunnel> tunnels = (Collection<Tunnel>) pceManager.queryAllPath();
713
714 for (Tunnel tunnel : tunnels) {
715 TunnelEvent event = new TunnelEvent(TunnelEvent.Type.TUNNEL_ADDED, tunnel);
716 tunnelListener.event(event);
717
718 pceManager.releasePath(tunnel.tunnelId());
719
720 event = new TunnelEvent(TunnelEvent.Type.TUNNEL_REMOVED, tunnel);
721 tunnelListener.event(event);
722 }
723
724 assertThat(pceStore.getTunnelInfoCount(), is(0));
725 }
726
727 /**
728 * Tests label allocation/removal in CR case based on tunnel event.
729 */
730 @Test
731 public void tunnelEventTest2() {
732 build4RouterTopo(false, true, true, true, 15);
733 List<Constraint> constraints = new LinkedList<Constraint>();
734 BandwidthConstraint bwConstraint = new BandwidthConstraint(Bandwidth.bps(10.0));
735 CostConstraint costConstraint = new CostConstraint(TE_COST);
736
737 constraints.add(costConstraint);
738 constraints.add(bwConstraint);
739
740 pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T2", constraints, WITHOUT_SIGNALLING_AND_WITHOUT_SR);
741 assertThat(pceStore.getTunnelInfoCount(), is(1));
742
743 TunnelEvent event;
744 Collection<Tunnel> tunnels = (Collection<Tunnel>) pceManager.queryAllPath();
745 for (Tunnel tunnel : tunnels) {
746 event = new TunnelEvent(TunnelEvent.Type.TUNNEL_ADDED, tunnel);
747 tunnelListener.event(event);
748
749 // Stimulate the effect of LSP ids from protocol msg.
750 tunnelService.updateTunnelWithLspIds(tunnel, "123", "1", ESTABLISHED);
751 }
752
753 tunnels = (Collection<Tunnel>) pceManager.queryAllPath();
754 for (Tunnel tunnel : tunnels) {
755 event = new TunnelEvent(TunnelEvent.Type.TUNNEL_UPDATED, tunnel);
756 tunnelListener.event(event);
757
758 pceManager.releasePath(tunnel.tunnelId());
759
760 event = new TunnelEvent(TunnelEvent.Type.TUNNEL_REMOVED, tunnel);
761 tunnelListener.event(event);
762 }
763
764 assertThat(pceStore.getTunnelInfoCount(), is(0));
765 }
766
767 /**
768 * Tests handling UNSTABLE state based on tunnel event.
769 */
770 @Test
771 public void tunnelEventTest3() {
772 build4RouterTopo(false, true, true, true, 15);
773 List<Constraint> constraints = new LinkedList<Constraint>();
774 BandwidthConstraint bwConstraint = new BandwidthConstraint(Bandwidth.bps(10.0));
775 CostConstraint costConstraint = new CostConstraint(TE_COST);
776
777 constraints.add(costConstraint);
778 constraints.add(bwConstraint);
779
780 pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T2", constraints, WITHOUT_SIGNALLING_AND_WITHOUT_SR);
781 assertThat(pceStore.getTunnelInfoCount(), is(1));
782 assertThat(pceStore.getFailedPathInfoCount(), is(0));
783
784 TunnelEvent event;
785 Collection<Tunnel> tunnels = (Collection<Tunnel>) pceManager.queryAllPath();
786 for (Tunnel tunnel : tunnels) {
787 event = new TunnelEvent(TunnelEvent.Type.TUNNEL_ADDED, tunnel);
788 tunnelListener.event(event);
789
790 // Stimulate the effect of LSP ids from protocol msg.
791 tunnelService.updateTunnelWithLspIds(tunnel, "123", "1", UNSTABLE);
792 }
793
794 tunnels = (Collection<Tunnel>) pceManager.queryAllPath();
795 for (Tunnel tunnel : tunnels) {
796 event = new TunnelEvent(TunnelEvent.Type.TUNNEL_UPDATED, tunnel);
797 tunnelListener.event(event);
798 }
799 assertThat(pceStore.getTunnelInfoCount(), is(1));
800 assertThat(pceStore.getFailedPathInfoCount(), is(1));
801 }
802
803 @After
804 public void tearDown() {
805 pceManager.deactivate();
806 pceManager.pathService = null;
807 pceManager.resourceService = null;
808 pceManager.tunnelService = null;
809 pceManager.coreService = null;
810 pceManager.storageService = null;
811 pceManager.packetService = null;
812 pceManager.deviceService = null;
813 pceManager.labelRsrcService = null;
814 pceManager.flowObjectiveService = null;
815 pceManager.pceStore = null;
816 flowsDownloaded = 0;
817 }
818
819 private class MockTopologyService extends TopologyServiceAdapter {
820 @Override
821 public Set<Path> getPaths(Topology topology, DeviceId src, DeviceId dst, LinkWeight weight) {
822 DefaultTopologyVertex srcV = new DefaultTopologyVertex(src);
823 DefaultTopologyVertex dstV = new DefaultTopologyVertex(dst);
824 Set<TopologyVertex> vertices = graph.getVertexes();
825 if (!vertices.contains(srcV) || !vertices.contains(dstV)) {
826 // src or dst not part of the current graph
827 return ImmutableSet.of();
828 }
829
830 GraphPathSearch.Result<TopologyVertex, TopologyEdge> result = PathComputationTest.graphSearch()
831 .search(graph, srcV, dstV, weight, ALL_PATHS);
832 ImmutableSet.Builder<Path> builder = ImmutableSet.builder();
833 for (org.onlab.graph.Path<TopologyVertex, TopologyEdge> path : result.paths()) {
834 builder.add(PathComputationTest.networkPath(path));
835 }
836 return builder.build();
837 }
838 }
839
840 private class MockPathService extends PathServiceAdapter {
841
842 @Override
843 public Set<Path> getPaths(ElementId src, ElementId dst, LinkWeight weight) {
844 // If either edge is null, bail with no paths.
845 if (src == null || dst == null) {
846 return ImmutableSet.of();
847 }
848
849 // Otherwise get all paths between the source and destination edge
850 // devices.
851 return topologyService.getPaths(null, (DeviceId) src, (DeviceId) dst, weight);
852 }
853 }
854
855 private class MockTunnelServiceAdapter extends TunnelServiceAdapter {
856 private HashMap<TunnelId, Tunnel> tunnelIdAsKeyStore = new HashMap<TunnelId, Tunnel>();
857 private int tunnelIdCounter = 0;
858
859 @Override
860 public TunnelId setupTunnel(ApplicationId producerId, ElementId srcElementId, Tunnel tunnel, Path path) {
861 TunnelId tunnelId = TunnelId.valueOf(String.valueOf(++tunnelIdCounter));
862 Tunnel tunnelToInsert = new DefaultTunnel(tunnel.providerId(), tunnel.src(), tunnel.dst(), tunnel.type(),
863 tunnel.state(), tunnel.groupId(), tunnelId, tunnel.tunnelName(),
864 path, tunnel.annotations());
865 tunnelIdAsKeyStore.put(tunnelId, tunnelToInsert);
866 return tunnelId;
867 }
868
869 @Override
870 public void addListener(TunnelListener listener) {
871 tunnelListener = listener;
872 }
873
874 /**
875 * Stimulates the effect of receiving PLSP id and LSP id from protocol PCRpt msg.
876 */
877 public TunnelId updateTunnelWithLspIds(Tunnel tunnel, String pLspId, String localLspId, State state) {
878 TunnelId tunnelId = tunnel.tunnelId();
879 Builder annotationBuilder = DefaultAnnotations.builder();
880 annotationBuilder.putAll(tunnel.annotations());
881
882 // PCRpt in response to PCInitate msg will carry PLSP id allocated by PCC.
883 if (tunnel.annotations().value(PLSP_ID) == null) {
884 annotationBuilder.set(PLSP_ID, pLspId);
885 }
886
887 // Signalled LSPs will carry local LSP id allocated by signalling protocol(PCC).
888 if (tunnel.annotations().value(LOCAL_LSP_ID) == null) {
889 annotationBuilder.set(LOCAL_LSP_ID, localLspId);
890 }
891 SparseAnnotations annotations = annotationBuilder.build();
892 tunnelIdAsKeyStore.remove(tunnelId, tunnel);
893
894 Tunnel tunnelToInsert = new DefaultTunnel(tunnel.providerId(), tunnel.src(), tunnel.dst(), tunnel.type(),
895 state, tunnel.groupId(), tunnelId, tunnel.tunnelName(),
896 tunnel.path(), annotations);
897
898 tunnelIdAsKeyStore.put(tunnelId, tunnelToInsert);
899
900 return tunnelId;
901 }
902
903 @Override
904 public boolean downTunnel(ApplicationId producerId, TunnelId tunnelId) {
905 for (TunnelId tunnelIdKey : tunnelIdAsKeyStore.keySet()) {
906 if (tunnelIdKey.equals(tunnelId)) {
907 tunnelIdAsKeyStore.remove(tunnelId);
908 return true;
909 }
910 }
911 return false;
912 }
913
914 @Override
915 public Tunnel queryTunnel(TunnelId tunnelId) {
916 for (TunnelId tunnelIdKey : tunnelIdAsKeyStore.keySet()) {
917 if (tunnelIdKey.equals(tunnelId)) {
918 return tunnelIdAsKeyStore.get(tunnelId);
919 }
920 }
921 return null;
922 }
923
924 @Override
925 public Collection<Tunnel> queryTunnel(TunnelEndPoint src, TunnelEndPoint dst) {
926 Collection<Tunnel> result = new HashSet<Tunnel>();
927 Tunnel tunnel = null;
928 for (TunnelId tunnelId : tunnelIdAsKeyStore.keySet()) {
929 tunnel = tunnelIdAsKeyStore.get(tunnelId);
930
931 if ((null != tunnel) && (src.equals(tunnel.src())) && (dst.equals(tunnel.dst()))) {
932 result.add(tunnel);
933 }
934 }
935
936 return result.size() == 0 ? Collections.emptySet() : ImmutableSet.copyOf(result);
937 }
938
939 @Override
940 public Collection<Tunnel> queryTunnel(Tunnel.Type type) {
941 Collection<Tunnel> result = new HashSet<Tunnel>();
942
943 for (TunnelId tunnelId : tunnelIdAsKeyStore.keySet()) {
944 result.add(tunnelIdAsKeyStore.get(tunnelId));
945 }
946
947 return result.size() == 0 ? Collections.emptySet() : ImmutableSet.copyOf(result);
948 }
949 }
950
951 public static class MockCoreService extends CoreServiceAdapter {
952
953 @Override
954 public ApplicationId registerApplication(String name) {
955 return new DefaultApplicationId(1, name);
956 }
957
958 @Override
959 public IdGenerator getIdGenerator(String topic) {
960 return new IdGenerator() {
961 private AtomicLong counter = new AtomicLong(0);
962
963 @Override
964 public long getNewId() {
965 return counter.getAndIncrement();
966 }
967 };
968 }
969 }
970
971 private class MockDevice extends DefaultDevice {
972 MockDevice(DeviceId id, Annotations annotations) {
973 super(null, id, null, null, null, null, null, null, annotations);
974 }
975 }
976
977 private class MockDeviceService extends DeviceServiceAdapter {
978 List<Device> devices = new LinkedList<>();
979
980 private void addDevice(Device dev) {
981 devices.add(dev);
982 }
983
984 @Override
985 public Device getDevice(DeviceId deviceId) {
986 for (Device dev : devices) {
987 if (dev.id().equals(deviceId)) {
988 return dev;
989 }
990 }
991 return null;
992 }
993
994 @Override
995 public Iterable<Device> getAvailableDevices() {
996 return devices;
997 }
998 }
999
1000 private PacketProcessor pktProcessor = null;
1001
1002 private class MockPacketService extends PacketServiceAdapter {
1003 @Override
1004 public void addProcessor(PacketProcessor processor, int priority) {
1005 pktProcessor = processor;
1006 }
1007 }
1008
1009 // Minimal PacketContext to make core and applications happy.
1010 final class MockPcepPacketContext extends DefaultPacketContext {
1011 private MockPcepPacketContext(InboundPacket inPkt, OutboundPacket outPkt) {
1012 super(System.currentTimeMillis(), inPkt, outPkt, false);
1013 }
1014
1015 @Override
1016 public void send() {
1017 }
1018 }
1019
1020 public static class MockFlowObjService extends FlowObjServiceAdapter {
1021 @Override
1022 public void forward(DeviceId deviceId, ForwardingObjective forwardingObjective) {
1023 ++flowsDownloaded;
1024 }
1025 }
1026}