blob: 4b58fbae9f7b49aee2254d2c4277b08599a69511 [file] [log] [blame]
Pier Ventre81c47bf2016-11-04 07:26:22 -07001/*
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 */
16
17package org.onosproject.net.intent.impl.compiler;
18
19import com.google.common.collect.ImmutableSet;
20import org.junit.After;
21import org.junit.Before;
22import org.junit.Test;
23import org.onlab.packet.Ethernet;
24import org.onlab.packet.MplsLabel;
25import org.onlab.packet.VlanId;
26import org.onosproject.cfg.ComponentConfigAdapter;
27import org.onosproject.core.CoreService;
28import org.onosproject.net.FilteredConnectPoint;
29import org.onosproject.net.flow.DefaultTrafficSelector;
30import org.onosproject.net.flow.DefaultTrafficTreatment;
31import org.onosproject.net.flow.FlowRule;
32import org.onosproject.net.flow.criteria.MplsCriterion;
33import org.onosproject.net.flow.criteria.VlanIdCriterion;
34import org.onosproject.net.intent.FlowRuleIntent;
35import org.onosproject.net.intent.Intent;
36import org.onosproject.net.intent.IntentExtensionService;
37import org.onosproject.net.intent.LinkCollectionIntent;
38import org.onosproject.net.resource.MockResourceService;
39
40import java.util.Collection;
41import java.util.Collections;
42import java.util.List;
43import java.util.stream.Collectors;
44
45import static org.easymock.EasyMock.*;
46import static org.hamcrest.MatcherAssert.assertThat;
47import static org.hamcrest.Matchers.hasSize;
48import static org.hamcrest.core.Is.is;
49import static org.onlab.packet.EthType.EtherType.IPV4;
50import static org.onosproject.net.NetTestTools.*;
51import static org.onosproject.net.flow.criteria.Criterion.Type.*;
52import static org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
53
54/**
55 * This set of tests are meant to test the encapsulation
56 * in the LinkCollectionIntent.
57 */
58public class LinkCollectionOptimizationTest extends AbstractLinkCollectionTest {
59
60 @Before
61 public void setUp() {
62 sut = new LinkCollectionIntentCompiler();
63 coreService = createMock(CoreService.class);
64 expect(coreService.registerApplication("org.onosproject.net.intent"))
65 .andReturn(appId);
66 sut.coreService = coreService;
67
68 Intent.bindIdGenerator(idGenerator);
69
70 intentExtensionService = createMock(IntentExtensionService.class);
71 intentExtensionService.registerCompiler(LinkCollectionIntent.class, sut);
72 intentExtensionService.unregisterCompiler(LinkCollectionIntent.class);
73
74 registrator = new IntentConfigurableRegistrator();
75 registrator.extensionService = intentExtensionService;
76 registrator.cfgService = new ComponentConfigAdapter();
77 registrator.activate();
78
79 sut.registrator = registrator;
80 sut.resourceService = new MockResourceService();
81
82 /*
83 * We activate the optimizations.
84 */
85 LinkCollectionCompiler.optimize = true;
86 LinkCollectionCompiler.copyTtl = true;
87
88 replay(coreService, intentExtensionService);
89 }
90
91 @After
92 public void tearDown() {
93 Intent.unbindIdGenerator(idGenerator);
94 }
95
96 /**
97 * We test the proper optimization of sp2mp with dec tll
98 * and dec mpls ttl.
99 */
100 @Test
101 public void testDecTtlOptimization() {
102
103 intent = LinkCollectionIntent.builder()
104 .appId(APP_ID)
105 .selector(selector)
106 .treatment(decTllTreatment)
107 .links(linksForSp2Mp)
108 .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10)))
109 .filteredEgressPoints(ImmutableSet.of(
110 new FilteredConnectPoint(d1p10),
111 new FilteredConnectPoint(d1p11),
112 new FilteredConnectPoint(d2p10)
113 ))
114 .applyTreatmentOnEgress(true)
115 .build();
116
117 sut.activate();
118
119 List<Intent> compiled = sut.compile(intent, Collections.emptyList());
120 assertThat(compiled, hasSize(1));
121
122 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
123 assertThat(rules, hasSize(3));
124
125 Collection<FlowRule> rulesS3 = rules.stream()
126 .filter(rule -> rule.deviceId().equals(d3p0.deviceId()))
127 .collect(Collectors.toSet());
128 assertThat(rulesS3, hasSize(1));
129 FlowRule ruleS3 = rulesS3.iterator().next();
130 assertThat(ruleS3.selector(), is(
131 DefaultTrafficSelector
132 .builder()
133 .matchInPort(d3p10.port())
134 .build()
135 ));
136 assertThat(ruleS3.treatment(), is(
137 DefaultTrafficTreatment
138 .builder()
139 .setOutput(d3p0.port())
140 .build()
141 ));
142
143 Collection<FlowRule> rulesS2 = rules.stream()
144 .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
145 .collect(Collectors.toSet());
146 assertThat(rulesS2, hasSize(1));
147 FlowRule ruleS2 = rulesS2.iterator().next();
148 assertThat(ruleS2.selector(), is(
149 DefaultTrafficSelector
150 .builder()
151 .matchInPort(d2p1.port())
152 .build()
153 ));
154 assertThat(ruleS2.treatment(), is(
155 DefaultTrafficTreatment
156 .builder()
157 .setOutput(d2p0.port())
158 .decMplsTtl()
159 .decNwTtl()
160 .setOutput(d2p10.port())
161 .build()
162 ));
163
164 Collection<FlowRule> rulesS1 = rules.stream()
165 .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
166 .collect(Collectors.toSet());
167 assertThat(rulesS1, hasSize(1));
168 FlowRule ruleS1 = rulesS1.iterator().next();
169 assertThat(ruleS1.selector(), is(
170 DefaultTrafficSelector
171 .builder()
172 .matchInPort(d1p0.port())
173 .build()
174 ));
175 assertThat(ruleS1.treatment(), is(
176 DefaultTrafficTreatment
177 .builder()
178 .decMplsTtl()
179 .decNwTtl()
180 .setOutput(d1p10.port())
181 .setOutput(d1p11.port())
182 .build()
183 ));
184
185 sut.deactivate();
186
187 }
188
189 /**
190 * We test the proper optimization of sp2mp with VLAN
191 * ingress point and different egress points: 1) it is
192 * a simple ingress point; 2) it is a vlan ingress point;
193 * 3) It is a simple ingress point. 1) and 2) share the same
194 * egress switch. The outcomes of the test are the re-ordering
195 * of the actions and the proper optimization of the chain.
196 */
197 @Test
198 public void testVlanOrder() {
199
200 intent = LinkCollectionIntent.builder()
201 .appId(APP_ID)
202 .selector(selector)
203 .treatment(treatment)
204 .links(linksForSp2Mp)
205 .applyTreatmentOnEgress(true)
206 .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10, vlan100Selector)))
207 .filteredEgressPoints(ImmutableSet.of(
208 new FilteredConnectPoint(d1p10),
209 new FilteredConnectPoint(d1p11, vlan200Selector),
210 new FilteredConnectPoint(d2p10)
211 ))
212 .build();
213
214 sut.activate();
215
216 List<Intent> compiled = sut.compile(intent, Collections.emptyList());
217 assertThat(compiled, hasSize(1));
218
219 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
220 assertThat(rules, hasSize(3));
221
222 Collection<FlowRule> rulesS3 = rules.stream()
223 .filter(rule -> rule.deviceId().equals(d3p0.deviceId()))
224 .collect(Collectors.toSet());
225 assertThat(rulesS3, hasSize(1));
226 FlowRule ruleS3 = rulesS3.iterator().next();
227 assertThat(ruleS3.selector(), is(
228 DefaultTrafficSelector
229 .builder(vlan100Selector)
230 .matchInPort(d3p10.port())
231 .build()
232 ));
233 assertThat(ruleS3.treatment(), is(
234 DefaultTrafficTreatment
235 .builder()
236 .setOutput(d3p0.port())
237 .build()
238 ));
239
240 Collection<FlowRule> rulesS2 = rules.stream()
241 .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
242 .collect(Collectors.toSet());
243 assertThat(rulesS2, hasSize(1));
244 FlowRule ruleS2 = rulesS2.iterator().next();
245 assertThat(ruleS2.selector(), is(
246 DefaultTrafficSelector
247 .builder(vlan100Selector)
248 .matchInPort(d2p1.port())
249 .build()
250 ));
251 assertThat(ruleS2.treatment(), is(
252 DefaultTrafficTreatment
253 .builder()
254 .setOutput(d2p0.port())
255 .popVlan()
256 .setOutput(d2p10.port())
257 .build()
258 ));
259
260 Collection<FlowRule> rulesS1 = rules.stream()
261 .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
262 .collect(Collectors.toSet());
263 assertThat(rulesS1, hasSize(1));
264 FlowRule ruleS1 = rulesS1.iterator().next();
265 assertThat(ruleS1.selector(), is(
266 DefaultTrafficSelector
267 .builder(vlan100Selector)
268 .matchInPort(d1p0.port())
269 .build()
270 ));
271 assertThat(ruleS1.treatment(), is(
272 DefaultTrafficTreatment
273 .builder()
274 .setVlanId(((VlanIdCriterion) vlan200Selector.getCriterion(VLAN_VID)).vlanId())
275 .setOutput(d1p11.port())
276 .popVlan()
277 .setOutput(d1p10.port())
278 .build()
279 ));
280
281 sut.deactivate();
282
283 }
284
285 /**
286 * We test the proper optimization of sp2mp with MPLS
287 * ingress point and different egress points: 1) it is
288 * a vlan ingress point; 2) it is a mpls ingress point;
289 * 3) It is a simple ingress point. 1) and 2) share the same
290 * egress switch. The outcomes of the test are the re-ordering
291 * of the actions and the proper optimization of the chain.
292 */
293 @Test
294 public void testMplsOrder() {
295
296 intent = LinkCollectionIntent.builder()
297 .appId(APP_ID)
298 .selector(selector)
299 .treatment(treatment)
300 .links(linksForSp2Mp)
301 .applyTreatmentOnEgress(true)
302 .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10, mpls100Selector)))
303 .filteredEgressPoints(ImmutableSet.of(
304 new FilteredConnectPoint(d1p10, vlan100Selector),
305 new FilteredConnectPoint(d1p11, mpls200Selector),
306 new FilteredConnectPoint(d2p10)
307 ))
308 .build();
309
310 sut.activate();
311
312 List<Intent> compiled = sut.compile(intent, Collections.emptyList());
313 assertThat(compiled, hasSize(1));
314
315 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
316 assertThat(rules, hasSize(3));
317
318 Collection<FlowRule> rulesS3 = rules.stream()
319 .filter(rule -> rule.deviceId().equals(d3p0.deviceId()))
320 .collect(Collectors.toSet());
321 assertThat(rulesS3, hasSize(1));
322 FlowRule ruleS3 = rulesS3.iterator().next();
323 assertThat(ruleS3.selector(), is(
324 DefaultTrafficSelector
325 .builder(mpls100Selector)
326 .matchInPort(d3p10.port())
327 .build()
328 ));
329 assertThat(ruleS3.treatment(), is(
330 DefaultTrafficTreatment
331 .builder()
332 .setOutput(d3p0.port())
333 .build()
334 ));
335
336 Collection<FlowRule> rulesS2 = rules.stream()
337 .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
338 .collect(Collectors.toSet());
339 assertThat(rulesS2, hasSize(1));
340 FlowRule ruleS2 = rulesS2.iterator().next();
341 assertThat(ruleS2.selector(), is(
342 DefaultTrafficSelector
343 .builder(mpls100Selector)
344 .matchInPort(d2p1.port())
345 .build()
346 ));
347 assertThat(ruleS2.treatment(), is(
348 DefaultTrafficTreatment
349 .builder()
350 .setOutput(d2p0.port())
351 .copyTtlIn()
352 .popMpls(IPV4.ethType())
353 .setOutput(d2p10.port())
354 .build()
355 ));
356
357 Collection<FlowRule> rulesS1 = rules.stream()
358 .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
359 .collect(Collectors.toSet());
360 assertThat(rulesS1, hasSize(1));
361 FlowRule ruleS1 = rulesS1.iterator().next();
362 assertThat(ruleS1.selector(), is(
363 DefaultTrafficSelector
364 .builder(mpls100Selector)
365 .matchInPort(d1p0.port())
366 .build()
367 ));
368 assertThat(ruleS1.treatment(), is(
369 DefaultTrafficTreatment
370 .builder()
371 .setMpls(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
372 .setOutput(d1p11.port())
373 .copyTtlIn()
374 .popMpls(IPV4.ethType())
375 .pushVlan()
376 .setVlanId(((VlanIdCriterion) vlan100Selector.getCriterion(VLAN_VID)).vlanId())
377 .setOutput(d1p10.port())
378 .build()
379 ));
380
381 sut.deactivate();
382
383 }
384
385 /**
386 * We test the proper optimization of sp2mp with untagged
387 * ingress point and different egress points: 1) it is
388 * a vlan ingress point; 2) it is a mpls ingress point;
389 * 3) It is a simple ingress point. 1) and 2) share the same
390 * egress switch. The outcomes of the test are the re-ordering
391 * of the actions and the proper optimization of the chain.
392 */
393 @Test
394 public void testUntaggedOrder() {
395
396 intent = LinkCollectionIntent.builder()
397 .appId(APP_ID)
398 .selector(selector)
399 .treatment(treatment)
400 .links(linksForSp2Mp)
401 .applyTreatmentOnEgress(true)
402 .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10)))
403 .filteredEgressPoints(ImmutableSet.of(
404 new FilteredConnectPoint(d1p10, vlan100Selector),
405 new FilteredConnectPoint(d1p11, mpls200Selector),
406 new FilteredConnectPoint(d1p12),
407 new FilteredConnectPoint(d2p10)
408 ))
409 .build();
410
411 sut.activate();
412
413 List<Intent> compiled = sut.compile(intent, Collections.emptyList());
414 assertThat(compiled, hasSize(1));
415
416 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
417 assertThat(rules, hasSize(3));
418
419 Collection<FlowRule> rulesS3 = rules.stream()
420 .filter(rule -> rule.deviceId().equals(d3p0.deviceId()))
421 .collect(Collectors.toSet());
422 assertThat(rulesS3, hasSize(1));
423 FlowRule ruleS3 = rulesS3.iterator().next();
424 assertThat(ruleS3.selector(), is(
425 DefaultTrafficSelector
426 .builder()
427 .matchInPort(d3p10.port())
428 .build()
429 ));
430 assertThat(ruleS3.treatment(), is(
431 DefaultTrafficTreatment
432 .builder()
433 .setOutput(d3p0.port())
434 .build()
435 ));
436
437
438 Collection<FlowRule> rulesS2 = rules.stream()
439 .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
440 .collect(Collectors.toSet());
441 assertThat(rulesS2, hasSize(1));
442 FlowRule ruleS2 = rulesS2.iterator().next();
443 assertThat(ruleS2.selector(), is(
444 DefaultTrafficSelector
445 .builder()
446 .matchInPort(d2p1.port())
447 .build()
448 ));
449 assertThat(ruleS2.treatment(), is(
450 DefaultTrafficTreatment
451 .builder()
452 .setOutput(d2p0.port())
453 .setOutput(d2p10.port())
454 .build()
455 ));
456
457
458 Collection<FlowRule> rulesS1 = rules.stream()
459 .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
460 .collect(Collectors.toSet());
461 assertThat(rulesS1, hasSize(1));
462 FlowRule ruleS1 = rulesS1.iterator().next();
463 assertThat(ruleS1.selector(), is(
464 DefaultTrafficSelector
465 .builder()
466 .matchInPort(d1p0.port())
467 .build()
468 ));
469 assertThat(ruleS1.treatment(), is(
470 DefaultTrafficTreatment
471 .builder()
472 .setOutput(d1p12.port())
473 .pushVlan()
474 .setVlanId(((VlanIdCriterion) vlan100Selector.getCriterion(VLAN_VID)).vlanId())
475 .setOutput(d1p10.port())
476 .popVlan()
477 .pushMpls()
478 .copyTtlOut()
479 .setMpls(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
480 .setOutput(d1p11.port())
481 .build()
482 ));
483
484 sut.deactivate();
485
486 }
487
488 /**
489 * We test the proper optimization of sp2mp with VLAN ingress point,
490 * simple egress point, non trivial intent treatment and non trivial
491 * intent selector. The outcomes of the test are the proper optimization
492 * of the actions. It is expected that the actions related to the intent
493 * treatment and intent selector are not optimized. The optimization is
494 * performed only on the dec ttl actions and on the actions which create
495 * traffic slices. The rationale is that in the intent treatment we expect
496 * actions like set something so it is fine to perform them several times.
497 */
498 @Test
499 public void testPoPVlanOptimization() {
500
501 intent = LinkCollectionIntent.builder()
502 .appId(APP_ID)
503 .selector(ipPrefixSelector)
504 .treatment(ethDstTreatment)
505 .links(linksForSp2Mp)
506 .applyTreatmentOnEgress(true)
507 .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10, vlan100Selector)))
508 .filteredEgressPoints(ImmutableSet.of(
509 new FilteredConnectPoint(d1p10),
510 new FilteredConnectPoint(d1p11),
511 new FilteredConnectPoint(d1p12),
512 new FilteredConnectPoint(d2p10)
513 ))
514 .build();
515
516 sut.activate();
517
518 List<Intent> compiled = sut.compile(intent, Collections.emptyList());
519 assertThat(compiled, hasSize(1));
520
521 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
522 assertThat(rules, hasSize(3));
523
524 Collection<FlowRule> rulesS3 = rules.stream()
525 .filter(rule -> rule.deviceId().equals(d3p0.deviceId()))
526 .collect(Collectors.toSet());
527 assertThat(rulesS3, hasSize(1));
528 FlowRule ruleS3 = rulesS3.iterator().next();
529 assertThat(ruleS3.selector(), is(
530 DefaultTrafficSelector
531 .builder(ipPrefixSelector)
532 .matchVlanId(((VlanIdCriterion) vlan100Selector.getCriterion(VLAN_VID)).vlanId())
533 .matchInPort(d3p10.port())
534 .build()
535 ));
536 assertThat(ruleS3.treatment(), is(
537 DefaultTrafficTreatment
538 .builder()
539 .setOutput(d3p0.port())
540 .build()
541 ));
542
543 Collection<FlowRule> rulesS2 = rules.stream()
544 .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
545 .collect(Collectors.toSet());
546 assertThat(rulesS2, hasSize(1));
547 FlowRule ruleS2 = rulesS2.iterator().next();
548 assertThat(ruleS2.selector(), is(
549 DefaultTrafficSelector
550 .builder(ipPrefixSelector)
551 .matchInPort(d2p1.port())
552 .matchVlanId(((VlanIdCriterion) vlan100Selector.getCriterion(VLAN_VID)).vlanId())
553 .build()
554 ));
555 assertThat(ruleS2.treatment(), is(
556 DefaultTrafficTreatment
557 .builder()
558 .setOutput(d2p0.port())
559 .setEthDst(((ModEtherInstruction) ethDstTreatment
560 .allInstructions()
561 .stream()
562 .filter(instruction -> instruction instanceof ModEtherInstruction)
563 .findFirst().get()).mac())
564 .popVlan()
565 .setOutput(d2p10.port())
566 .build()
567 ));
568
569 Collection<FlowRule> rulesS1 = rules.stream()
570 .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
571 .collect(Collectors.toSet());
572 assertThat(rulesS1, hasSize(1));
573 FlowRule ruleS1 = rulesS1.iterator().next();
574 assertThat(ruleS1.selector(), is(
575 DefaultTrafficSelector
576 .builder(ipPrefixSelector)
577 .matchInPort(d1p0.port())
578 .matchVlanId(((VlanIdCriterion) vlan100Selector.getCriterion(VLAN_VID)).vlanId())
579 .build()
580 ));
581 assertThat(ruleS1.treatment(), is(
582 DefaultTrafficTreatment
583 .builder()
584 .setEthDst(((ModEtherInstruction) ethDstTreatment
585 .allInstructions()
586 .stream()
587 .filter(instruction -> instruction instanceof ModEtherInstruction)
588 .findFirst().get()).mac())
589 .popVlan()
590 .setOutput(d1p12.port())
591 .setEthDst(((ModEtherInstruction) ethDstTreatment
592 .allInstructions()
593 .stream()
594 .filter(instruction -> instruction instanceof ModEtherInstruction)
595 .findFirst().get()).mac())
596 .setOutput(d1p10.port())
597 .setEthDst(((ModEtherInstruction) ethDstTreatment
598 .allInstructions()
599 .stream()
600 .filter(instruction -> instruction instanceof ModEtherInstruction)
601 .findFirst().get()).mac())
602 .setOutput(d1p11.port())
603 .build()
604 ));
605
606 sut.deactivate();
607
608 }
609
610 /**
611 * We test the proper optimization of sp2mp with the VLAN
612 * encapsulation and trivial selector.
613 */
614 @Test
615 public void testOptimizationMplsEncapTrivialSelectors() {
616
617 intent = LinkCollectionIntent.builder()
618 .appId(APP_ID)
619 .selector(selector)
620 .treatment(treatment)
621 .constraints(constraintsForMPLS)
622 .links(linksForSp2Mp)
623 .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10)))
624 .filteredEgressPoints(ImmutableSet.of(
625 new FilteredConnectPoint(d1p10),
626 new FilteredConnectPoint(d1p11),
627 new FilteredConnectPoint(d2p10)
628 ))
629 .build();
630
631 sut.activate();
632 /*
633 * We use the FIRST_FIT to simplify tests.
634 */
635 LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
636
637 List<Intent> compiled = sut.compile(intent, Collections.emptyList());
638 assertThat(compiled, hasSize(1));
639
640 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
641 assertThat(rules, hasSize(3));
642
643 Collection<FlowRule> rulesS3 = rules.stream()
644 .filter(rule -> rule.deviceId().equals(d3p0.deviceId()))
645 .collect(Collectors.toSet());
646 assertThat(rulesS3, hasSize(1));
647 FlowRule ruleS3 = rulesS3.iterator().next();
648 assertThat(ruleS3.selector(), is(
649 DefaultTrafficSelector
650 .builder()
651 .matchInPort(d3p10.port())
652 .build()
653 ));
654 assertThat(ruleS3.treatment(), is(
655 DefaultTrafficTreatment
656 .builder()
657 .pushMpls()
658 .copyTtlOut()
659 .setMpls(MplsLabel.mplsLabel(LABEL))
660 .setOutput(d3p0.port())
661 .build()
662 ));
663
664 Collection<FlowRule> rulesS2 = rules.stream()
665 .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
666 .collect(Collectors.toSet());
667 assertThat(rulesS2, hasSize(1));
668 FlowRule ruleS2 = rulesS2.iterator().next();
669 assertThat(ruleS2.selector(), is(
670 DefaultTrafficSelector
671 .builder()
672 .matchInPort(d2p1.port())
673 .matchMplsLabel(MplsLabel.mplsLabel((LABEL)))
674 .matchEthType(Ethernet.MPLS_UNICAST)
675 .build()
676 ));
677 assertThat(ruleS2.treatment(), is(
678 DefaultTrafficTreatment
679 .builder()
680 .setMpls(MplsLabel.mplsLabel(LABEL))
681 .setOutput(d2p0.port())
682 .copyTtlIn()
683 .popMpls(IPV4.ethType())
684 .setOutput(d2p10.port())
685 .build()
686 ));
687
688 Collection<FlowRule> rulesS1 = rules.stream()
689 .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
690 .collect(Collectors.toSet());
691 assertThat(rulesS1, hasSize(1));
692 FlowRule ruleS1 = rulesS1.iterator().next();
693 assertThat(ruleS1.selector(), is(
694 DefaultTrafficSelector
695 .builder()
696 .matchInPort(d1p0.port())
697 .matchMplsLabel(MplsLabel.mplsLabel((LABEL)))
698 .matchEthType(Ethernet.MPLS_UNICAST)
699 .build()
700 ));
701 assertThat(ruleS1.treatment(), is(
702 DefaultTrafficTreatment
703 .builder()
704 .copyTtlIn()
705 .popMpls(IPV4.ethType())
706 .setOutput(d1p10.port())
707 .setOutput(d1p11.port())
708 .build()
709 ));
710
711 sut.deactivate();
712
713 }
714
715 /**
716 * We test the proper optimization of sp2mp with the VLAN
717 * encapsulation, filtered selectors.
718 */
719 @Test
720 public void testOptimizationVlanEncapMplsSelectors() {
721
722 intent = LinkCollectionIntent.builder()
723 .appId(APP_ID)
724 .selector(selector)
725 .treatment(treatment)
726 .constraints(constraintsForVlan)
727 .links(linksForSp2Mp)
728 .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10, mpls80Selector)))
729 .filteredEgressPoints(ImmutableSet.of(
730 new FilteredConnectPoint(d1p10, mpls100Selector),
731 new FilteredConnectPoint(d1p11, mpls200Selector),
732 new FilteredConnectPoint(d2p10, mpls69Selector)
733 ))
734 .build();
735
736 sut.activate();
737 /*
738 * We use the FIRST_FIT to simplify tests.
739 */
740 LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
741
742 List<Intent> compiled = sut.compile(intent, Collections.emptyList());
743 assertThat(compiled, hasSize(1));
744
745 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
746 assertThat(rules, hasSize(3));
747
748 Collection<FlowRule> rulesS3 = rules.stream()
749 .filter(rule -> rule.deviceId().equals(d3p0.deviceId()))
750 .collect(Collectors.toSet());
751 assertThat(rulesS3, hasSize(1));
752 FlowRule ruleS3 = rulesS3.iterator().next();
753 assertThat(ruleS3.selector(), is(
754 DefaultTrafficSelector
755 .builder(mpls80Selector)
756 .matchInPort(d3p10.port())
757 .build()
758 ));
759 assertThat(ruleS3.treatment(), is(
760 DefaultTrafficTreatment
761 .builder()
762 .copyTtlIn()
763 .popMpls(IPV4.ethType())
764 .pushVlan()
765 .setVlanId(VlanId.vlanId(LABEL))
766 .setOutput(d3p0.port())
767 .build()
768 ));
769
770 Collection<FlowRule> rulesS2 = rules.stream()
771 .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
772 .collect(Collectors.toSet());
773 assertThat(rulesS2, hasSize(1));
774 FlowRule ruleS2 = rulesS2.iterator().next();
775 assertThat(ruleS2.selector(), is(
776 DefaultTrafficSelector
777 .builder()
778 .matchInPort(d2p1.port())
779 .matchVlanId(VlanId.vlanId(LABEL))
780 .build()
781 ));
782 assertThat(ruleS2.treatment(), is(
783 DefaultTrafficTreatment
784 .builder()
785 .setVlanId(VlanId.vlanId(LABEL))
786 .setOutput(d2p0.port())
787 .popVlan()
788 .pushMpls()
789 .copyTtlOut()
790 .setMpls(((MplsCriterion) mpls69Selector.getCriterion(MPLS_LABEL)).label())
791 .setOutput(d2p10.port())
792 .build()
793 ));
794
795 Collection<FlowRule> rulesS1 = rules.stream()
796 .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
797 .collect(Collectors.toSet());
798 assertThat(rulesS1, hasSize(1));
799 FlowRule ruleS1 = rulesS1.iterator().next();
800 assertThat(ruleS1.selector(), is(
801 DefaultTrafficSelector
802 .builder()
803 .matchInPort(d1p0.port())
804 .matchVlanId(VlanId.vlanId(LABEL))
805 .build()
806 ));
807 assertThat(ruleS1.treatment(), is(
808 DefaultTrafficTreatment
809 .builder()
810 .popVlan()
811 .pushMpls()
812 .copyTtlOut()
813 .setMpls(((MplsCriterion) mpls100Selector.getCriterion(MPLS_LABEL)).label())
814 .setOutput(d1p10.port())
815 .setMpls(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
816 .setOutput(d1p11.port())
817 .build()
818 ));
819
820 sut.deactivate();
821
822 }
823
824 /**
825 * We test the proper optimization of sp2mp with the MPLS
826 * encapsulation, filtered selectors, intent selector, and
827 * intent treatment.
828 */
829 @Test
830 public void testOptimizationMplsEncapNonTrivial() {
831
832 intent = LinkCollectionIntent.builder()
833 .appId(APP_ID)
834 .selector(ipPrefixSelector)
835 .treatment(ethDstTreatment)
836 .constraints(constraintsForMPLS)
837 .links(linksForSp2Mp)
838 .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10, vlan69Selector)))
839 .filteredEgressPoints(ImmutableSet.of(
840 new FilteredConnectPoint(d1p10, vlan100Selector),
841 new FilteredConnectPoint(d1p11, vlan200Selector),
842 new FilteredConnectPoint(d2p10, vlan300Selector)
843 ))
844 .build();
845
846 sut.activate();
847 /*
848 * We use the FIRST_FIT to simplify tests.
849 */
850 LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
851
852 List<Intent> compiled = sut.compile(intent, Collections.emptyList());
853 assertThat(compiled, hasSize(1));
854
855 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
856 assertThat(rules, hasSize(3));
857
858 Collection<FlowRule> rulesS3 = rules.stream()
859 .filter(rule -> rule.deviceId().equals(d3p0.deviceId()))
860 .collect(Collectors.toSet());
861 assertThat(rulesS3, hasSize(1));
862 FlowRule ruleS3 = rulesS3.iterator().next();
863 assertThat(ruleS3.selector(), is(
864 DefaultTrafficSelector
865 .builder(ipPrefixSelector)
866 .matchInPort(d3p10.port())
867 .matchVlanId(((VlanIdCriterion) vlan69Selector.getCriterion(VLAN_VID)).vlanId())
868 .build()
869 ));
870 assertThat(ruleS3.treatment(), is(
871 DefaultTrafficTreatment
872 .builder()
873 .popVlan()
874 .pushMpls()
875 .copyTtlOut()
876 .setMpls(MplsLabel.mplsLabel(LABEL))
877 .setOutput(d3p0.port())
878 .build()
879 ));
880
881 Collection<FlowRule> rulesS2 = rules.stream()
882 .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
883 .collect(Collectors.toSet());
884 assertThat(rulesS2, hasSize(1));
885 FlowRule ruleS2 = rulesS2.iterator().next();
886 assertThat(ruleS2.selector(), is(
887 DefaultTrafficSelector
888 .builder()
889 .matchInPort(d2p1.port())
890 .matchMplsLabel(MplsLabel.mplsLabel(LABEL))
891 .matchEthType(Ethernet.MPLS_UNICAST)
892 .build()
893 ));
894 assertThat(ruleS2.treatment(), is(
895 DefaultTrafficTreatment
896 .builder()
897 .setMpls(MplsLabel.mplsLabel(LABEL))
898 .setOutput(d2p0.port())
899 .setEthDst(((ModEtherInstruction) ethDstTreatment
900 .allInstructions()
901 .stream()
902 .filter(instruction -> instruction instanceof ModEtherInstruction)
903 .findFirst().get()).mac())
904 .copyTtlIn()
905 .popMpls(IPV4.ethType())
906 .pushVlan()
907 .setVlanId(((VlanIdCriterion) vlan300Selector.getCriterion(VLAN_VID)).vlanId())
908 .setOutput(d2p10.port())
909 .build()
910 ));
911
912 Collection<FlowRule> rulesS1 = rules.stream()
913 .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
914 .collect(Collectors.toSet());
915 assertThat(rulesS1, hasSize(1));
916 FlowRule ruleS1 = rulesS1.iterator().next();
917 assertThat(ruleS1.selector(), is(
918 DefaultTrafficSelector
919 .builder()
920 .matchInPort(d1p0.port())
921 .matchMplsLabel(MplsLabel.mplsLabel(LABEL))
922 .matchEthType(Ethernet.MPLS_UNICAST)
923 .build()
924 ));
925 assertThat(ruleS1.treatment(), is(
926 DefaultTrafficTreatment
927 .builder()
928 .setEthDst(((ModEtherInstruction) ethDstTreatment
929 .allInstructions()
930 .stream()
931 .filter(instruction -> instruction instanceof ModEtherInstruction)
932 .findFirst().get()).mac())
933 .copyTtlIn()
934 .popMpls(IPV4.ethType())
935 .pushVlan()
936 .setVlanId(((VlanIdCriterion) vlan100Selector.getCriterion(VLAN_VID)).vlanId())
937 .setOutput(d1p10.port())
938 .setEthDst(((ModEtherInstruction) ethDstTreatment
939 .allInstructions()
940 .stream()
941 .filter(instruction -> instruction instanceof ModEtherInstruction)
942 .findFirst().get()).mac())
943 .setVlanId(((VlanIdCriterion) vlan200Selector.getCriterion(VLAN_VID)).vlanId())
944 .setOutput(d1p11.port())
945 .build()
946 ));
947
948 sut.deactivate();
949
950 }
951
952 /**
953 * We test the proper compilation of sp2mp with the VLAN
954 * encapsulation and filtered selectors of different type.
955 */
956 @Test
957 public void testOptimizationVlanEncapDifferentSelectors() {
958
959 intent = LinkCollectionIntent.builder()
960 .appId(APP_ID)
961 .selector(selector)
962 .treatment(treatment)
963 .constraints(constraintsForVlan)
964 .links(linksForSp2Mp)
965 .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10, vlan69Selector)))
966 .filteredEgressPoints(ImmutableSet.of(
967 new FilteredConnectPoint(d1p10, mpls100Selector),
968 new FilteredConnectPoint(d1p11, vlan200Selector),
969 new FilteredConnectPoint(d1p12),
970 new FilteredConnectPoint(d2p10, mpls200Selector)
971 ))
972 .build();
973
974 sut.activate();
975 /*
976 * We use the FIRST_FIT to simplify tests.
977 */
978 LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
979
980 List<Intent> compiled = sut.compile(intent, Collections.emptyList());
981 assertThat(compiled, hasSize(1));
982
983 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
984 assertThat(rules, hasSize(3));
985
986 Collection<FlowRule> rulesS3 = rules.stream()
987 .filter(rule -> rule.deviceId().equals(d3p0.deviceId()))
988 .collect(Collectors.toSet());
989 assertThat(rulesS3, hasSize(1));
990 FlowRule ruleS3 = rulesS3.iterator().next();
991 assertThat(ruleS3.selector(), is(
992 DefaultTrafficSelector
993 .builder(vlan69Selector)
994 .matchInPort(d3p10.port())
995 .build()
996 ));
997 assertThat(ruleS3.treatment(), is(
998 DefaultTrafficTreatment
999 .builder()
1000 .setVlanId(VlanId.vlanId(LABEL))
1001 .setOutput(d3p0.port())
1002 .build()
1003 ));
1004
1005 Collection<FlowRule> rulesS2 = rules.stream()
1006 .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
1007 .collect(Collectors.toSet());
1008 assertThat(rulesS2, hasSize(1));
1009 FlowRule ruleS2 = rulesS2.iterator().next();
1010 assertThat(ruleS2.selector(), is(
1011 DefaultTrafficSelector
1012 .builder()
1013 .matchInPort(d2p1.port())
1014 .matchVlanId(VlanId.vlanId(LABEL))
1015 .build()
1016 ));
1017 assertThat(ruleS2.treatment(), is(
1018 DefaultTrafficTreatment
1019 .builder()
1020 .setVlanId(VlanId.vlanId(LABEL))
1021 .setOutput(d2p0.port())
1022 .popVlan()
1023 .pushMpls()
1024 .copyTtlOut()
1025 .setMpls(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
1026 .setOutput(d2p10.port())
1027 .build()
1028 ));
1029
1030 Collection<FlowRule> rulesS1 = rules.stream()
1031 .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
1032 .collect(Collectors.toSet());
1033 assertThat(rulesS1, hasSize(1));
1034 FlowRule ruleS1 = rulesS1.iterator().next();
1035 assertThat(ruleS1.selector(), is(
1036 DefaultTrafficSelector
1037 .builder()
1038 .matchInPort(d1p0.port())
1039 .matchVlanId(VlanId.vlanId(LABEL))
1040 .build()
1041 ));
1042 assertThat(ruleS1.treatment(), is(
1043 DefaultTrafficTreatment
1044 .builder()
1045 .setVlanId(((VlanIdCriterion) vlan200Selector.getCriterion(VLAN_VID)).vlanId())
1046 .setOutput(d1p11.port())
1047 .popVlan()
1048 .setOutput(d1p12.port())
1049 .pushMpls()
1050 .copyTtlOut()
1051 .setMpls(((MplsCriterion) mpls100Selector.getCriterion(MPLS_LABEL)).label())
1052 .setOutput(d1p10.port())
1053 .build()
1054 ));
1055
1056 sut.deactivate();
1057
1058 }
1059
1060}