Fixes LinkCollection compiler
Changes:
- adds the ability to handle co-located ingress/egress points;
- adds new unit tests to test the proper handling;
Change-Id: I63da5057e716cc94fcca8f13debafc44633b6820
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionCompiler.java b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionCompiler.java
index 2176a20..df87844 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionCompiler.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionCompiler.java
@@ -260,6 +260,103 @@
}
/**
+ * Helper method which handles the proper generation of the ouput actions.
+ *
+ * @param outPorts the output ports
+ * @param deviceId the current device
+ * @param intent the intent to compile
+ * @param outLabels the output labels
+ * @param type the encapsulation type
+ * @param preCondition the previous state
+ * @param treatmentBuilder the builder to update with the ouput actions
+ */
+ private void manageOutputPorts(Set<PortNumber> outPorts,
+ DeviceId deviceId,
+ LinkCollectionIntent intent,
+ Map<ConnectPoint, Identifier<?>> outLabels,
+ EncapsulationType type,
+ TrafficSelector.Builder preCondition,
+ TrafficTreatment.Builder treatmentBuilder) {
+ /*
+ * We need to order the actions. First the actions
+ * related to the not-egress points. At the same time we collect
+ * also the egress points.
+ */
+ List<FilteredConnectPoint> egressPoints = Lists.newArrayList();
+ for (PortNumber outPort : outPorts) {
+ Optional<FilteredConnectPoint> filteredEgressPoint =
+ getFilteredConnectPointFromIntent(deviceId, outPort, intent);
+ if (!filteredEgressPoint.isPresent()) {
+ /*
+ * We build a temporary selector for the encapsulation.
+ */
+ TrafficSelector.Builder encapBuilder = DefaultTrafficSelector.builder();
+ /*
+ * We retrieve the associated label to the output port.
+ */
+ ConnectPoint cp = new ConnectPoint(deviceId, outPort);
+ Identifier<?> outLabel = outLabels.get(cp);
+ /*
+ * If there are not labels, we cannot handle.
+ */
+ if (outLabel == null) {
+ throw new IntentCompilationException(String.format(NO_LABELS, cp));
+ }
+ /*
+ * In the core we match using encapsulation.
+ */
+ updateSelectorFromEncapsulation(
+ encapBuilder,
+ type,
+ outLabel
+ );
+ /*
+ * We generate the transition.
+ */
+ TrafficTreatment forwardingTreatment =
+ forwardingTreatment(preCondition.build(),
+ encapBuilder.build(),
+ getEthType(intent.selector()));
+ /*
+ * We add the instruction necessary to the transition.
+ */
+ forwardingTreatment.allInstructions().stream()
+ .filter(inst -> inst.type() != Instruction.Type.NOACTION)
+ .forEach(treatmentBuilder::add);
+ /*
+ * Finally we set the output action.
+ */
+ treatmentBuilder.setOutput(outPort);
+ /*
+ * The encapsulation modifies the packet. If we are optimizing
+ * we have to update the state.
+ */
+ if (optimize) {
+ preCondition = encapBuilder;
+ }
+ } else {
+ egressPoints.add(filteredEgressPoint.get());
+ }
+ }
+ /*
+ * The idea is to order the egress points. Before we deal
+ * with the egress points which looks like similar to the
+ * selector derived from the previous state then the
+ * the others.
+ */
+ TrafficSelector prevState = preCondition.build();
+ if (optimize) {
+ egressPoints = orderedEgressPoints(prevState, egressPoints);
+ }
+ /*
+ * In this case, we have to transit to the final
+ * state.
+ */
+ generateEgressActions(treatmentBuilder, egressPoints, prevState, intent);
+
+ }
+
+ /**
* Helper method to generate the egress actions.
*
* @param treatmentBuilder the treatment builder to update
@@ -654,60 +751,23 @@
.criteria()
.forEach(selectorBuilder::add);
/*
- * In this scenario, we can have several output ports.
+ * In this case the precondition is the selector of the filtered
+ * ingress point.
*/
- outPorts.forEach(outPort -> {
- Optional<FilteredConnectPoint> filteredEgressPoint =
- getFilteredConnectPointFromIntent(deviceId, outPort, intent);
- /*
- * If we are at the egress, we don't handle
- * with encapsulation. Error scenario
- */
- if (filteredEgressPoint.isPresent()) {
- throw new IntentCompilationException(WRONG_ENCAPSULATION);
- }
- /*
- * Transit/core, we have to transit to the intermediate
- * state. We build a temporary selector for the encapsulation.
- */
- TrafficSelector.Builder encapBuilder = DefaultTrafficSelector.builder();
- /*
- * We retrieve the associated label to the output port.
- */
- ConnectPoint cp = new ConnectPoint(deviceId, outPort);
- Identifier<?> outLabel = outLabels.get(cp);
- /*
- * If there aren't labels, we cannot handle.
- */
- if (outLabel == null) {
- throw new IntentCompilationException(String.format(NO_LABELS, cp));
- }
- /*
- * In the core we match using encapsulation.
- */
- updateSelectorFromEncapsulation(
- encapBuilder,
- type,
- outLabel
- );
- /*
- * We generate the transition.
- */
- TrafficTreatment forwardingTreatment =
- forwardingTreatment(filteredIngressPoint.get().trafficSelector(),
- encapBuilder.build(),
- getEthType(intent.selector()));
- /*
- * We add the instruction necessary to the transition.
- */
- forwardingTreatment.allInstructions().stream()
- .filter(inst -> inst.type() != Instruction.Type.NOACTION)
- .forEach(treatmentBuilder::add);
- /*
- * Finally we set the output action.
- */
- treatmentBuilder.setOutput(outPort);
- });
+ TrafficSelector.Builder preCondition = DefaultTrafficSelector
+ .builder(filteredIngressPoint.get().trafficSelector());
+ /*
+ * Generate the output actions.
+ */
+ manageOutputPorts(
+ outPorts,
+ deviceId,
+ intent,
+ outLabels,
+ type,
+ preCondition,
+ treatmentBuilder
+ );
}
@@ -751,74 +811,18 @@
inLabel
);
/*
- * We need to order the actions. First the actions
- * related to the not-egress points. At the same time we collect
- * also the egress points.
+ * Generate the output actions.
*/
- List<FilteredConnectPoint> egressPoints = Lists.newArrayList();
- for (PortNumber outPort : outPorts) {
- Optional<FilteredConnectPoint> filteredEgressPoint =
- getFilteredConnectPointFromIntent(deviceId, outPort, intent);
- if (!filteredEgressPoint.isPresent()) {
- /*
- * We build a temporary selector for the encapsulation.
- */
- TrafficSelector.Builder encapBuilder = DefaultTrafficSelector.builder();
- /*
- * We retrieve the associated label to the output port.
- */
- ConnectPoint cp = new ConnectPoint(deviceId, outPort);
- Identifier<?> outLabel = outLabels.get(cp);
- /*
- * If there are not labels, we cannot handle.
- */
- if (outLabel == null) {
- throw new IntentCompilationException(String.format(NO_LABELS, cp));
- }
- /*
- * In the core we match using encapsulation.
- */
- updateSelectorFromEncapsulation(
- encapBuilder,
- type,
- outLabel
- );
- /*
- * We generate the transition.
- */
- TrafficTreatment forwardingTreatment =
- forwardingTreatment(selectorBuilder.build(),
- encapBuilder.build(),
- getEthType(intent.selector()));
- /*
- * We add the instruction necessary to the transition.
- */
- forwardingTreatment.allInstructions().stream()
- .filter(inst -> inst.type() != Instruction.Type.NOACTION)
- .forEach(treatmentBuilder::add);
- /*
- * Finally we set the output action.
- */
- treatmentBuilder.setOutput(outPort);
- } else {
- egressPoints.add(filteredEgressPoint.get());
- }
- }
- /*
- * The idea is to order the egress points. Before we deal
- * with the egress points which looks like similar to the
- * selector derived from the encpsulation constraint then
- * the others.
- */
- TrafficSelector prevState = selectorBuilder.build();
- if (optimize) {
- egressPoints = orderedEgressPoints(prevState, egressPoints);
- }
- /*
- * In this case, we have to transit to the final
- * state.
- */
- generateEgressActions(treatmentBuilder, egressPoints, prevState, intent);
+ manageOutputPorts(
+ outPorts,
+ deviceId,
+ intent,
+ outLabels,
+ type,
+ selectorBuilder,
+ treatmentBuilder
+ );
+
}
/**
diff --git a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/AbstractLinkCollectionTest.java b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/AbstractLinkCollectionTest.java
index 38aad30..bd2c7c7 100644
--- a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/AbstractLinkCollectionTest.java
+++ b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/AbstractLinkCollectionTest.java
@@ -91,8 +91,6 @@
link(d2p1, d3p0)
);
-
-
final Set<Link> linksForSp2Mp = ImmutableSet.of(
link(d3p0, d2p1),
link(d2p0, d1p0)
@@ -103,6 +101,15 @@
link(d2p1, d3p1)
);
+ final Set<Link> linksForSp2MpCoLoc = ImmutableSet.of(
+ link(d1p0, d2p0),
+ link(d2p1, d3p0)
+ );
+
+ final Set<Link> linksForMp2SpCoLoc = ImmutableSet.of(
+ link(d2p0, d1p0)
+ );
+
final TrafficTreatment treatment = emptyTreatment();
final TrafficTreatment ethDstTreatment = macDstTreatment("C0:FF:EE:C0:FF:EE");
final TrafficTreatment decTllTreatment = decTtlTreatment();
diff --git a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/LinkCollectionEncapIntentCompilerTest.java b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/LinkCollectionEncapIntentCompilerTest.java
index eb58cce..27ef08b 100644
--- a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/LinkCollectionEncapIntentCompilerTest.java
+++ b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/LinkCollectionEncapIntentCompilerTest.java
@@ -43,14 +43,12 @@
import java.util.List;
import java.util.stream.Collectors;
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.core.Is.is;
import static org.onlab.packet.EthType.EtherType.IPV4;
-import static org.onosproject.net.NetTestTools.*;
+import static org.onosproject.net.NetTestTools.APP_ID;
import static org.onosproject.net.flow.criteria.Criterion.Type.*;
import static org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
@@ -64,8 +62,7 @@
public void setUp() {
sut = new LinkCollectionIntentCompiler();
coreService = createMock(CoreService.class);
- expect(coreService.registerApplication("org.onosproject.net.intent"))
- .andReturn(appId);
+ expect(coreService.registerApplication("org.onosproject.net.intent")).andReturn(appId);
sut.coreService = coreService;
Intent.bindIdGenerator(idGenerator);
@@ -101,11 +98,8 @@
public void testVlanEncapsulationForMp() {
intent = LinkCollectionIntent.builder()
- .appId(APP_ID)
- .selector(selector)
- .treatment(treatment)
- .constraints(constraintsForVlan)
- .links(linksForMp2Sp)
+ .appId(APP_ID).selector(selector).treatment(treatment)
+ .constraints(constraintsForVlan).links(linksForMp2Sp)
.filteredIngressPoints(ImmutableSet.of(
new FilteredConnectPoint(d1p10),
new FilteredConnectPoint(d1p11),
@@ -134,9 +128,7 @@
.filter(rule -> {
PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
return inPort.port().equals(d1p10.port());
- })
- .findFirst()
- .get();
+ }).findFirst().get();
assertThat(ruleS1.selector(), is(
DefaultTrafficSelector
.builder(intent.selector())
@@ -253,23 +245,17 @@
public void testMplsEncapsulationForSp() {
intent = LinkCollectionIntent.builder()
- .appId(APP_ID)
- .selector(selector)
- .treatment(treatment)
- .constraints(constraintsForMPLS)
- .links(linksForSp2Mp)
+ .appId(APP_ID).selector(selector).treatment(treatment)
+ .constraints(constraintsForMPLS).links(linksForSp2Mp)
.filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10)))
.filteredEgressPoints(ImmutableSet.of(
new FilteredConnectPoint(d1p10),
new FilteredConnectPoint(d1p11),
new FilteredConnectPoint(d2p10)
- ))
- .build();
+ )).build();
sut.activate();
- /*
- * We use the FIRST_FIT to simplify tests.
- */
+
LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
List<Intent> compiled = sut.compile(intent, Collections.emptyList());
@@ -356,23 +342,17 @@
public void testMplsEncapsulationFilteredForMp() {
intent = LinkCollectionIntent.builder()
- .appId(APP_ID)
- .selector(selector)
- .treatment(treatment)
- .constraints(constraintsForMPLS)
- .links(linksForMp2Sp)
+ .appId(APP_ID).selector(selector).treatment(treatment)
+ .constraints(constraintsForMPLS).links(linksForMp2Sp)
.filteredEgressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10, vlan69Selector)))
.filteredIngressPoints(ImmutableSet.of(
new FilteredConnectPoint(d1p10, vlan100Selector),
new FilteredConnectPoint(d1p11, vlan200Selector),
new FilteredConnectPoint(d2p10, vlan300Selector)
- ))
- .build();
+ )).build();
sut.activate();
- /*
- * We use the FIRST_FIT to simplify tests.
- */
+
LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
List<Intent> compiled = sut.compile(intent, Collections.emptyList());
@@ -516,23 +496,17 @@
public void testVlanEncapsulationFilteredForSp() {
intent = LinkCollectionIntent.builder()
- .appId(APP_ID)
- .selector(selector)
- .treatment(treatment)
- .constraints(constraintsForVlan)
- .links(linksForSp2Mp)
+ .appId(APP_ID).selector(selector).treatment(treatment)
+ .constraints(constraintsForVlan).links(linksForSp2Mp)
.filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10, mpls69Selector)))
.filteredEgressPoints(ImmutableSet.of(
new FilteredConnectPoint(d1p10, mpls100Selector),
new FilteredConnectPoint(d1p11, mpls200Selector),
new FilteredConnectPoint(d2p10, mpls80Selector)
- ))
- .build();
+ )).build();
sut.activate();
- /*
- * We use the FIRST_FIT to simplify tests.
- */
+
LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
List<Intent> compiled = sut.compile(intent, Collections.emptyList());
@@ -624,23 +598,17 @@
public void testVlanEncapsulationNonTrivialForMp() {
intent = LinkCollectionIntent.builder()
- .appId(APP_ID)
- .selector(ipPrefixSelector)
- .treatment(ethDstTreatment)
- .constraints(constraintsForVlan)
- .links(linksForMp2Sp)
+ .appId(APP_ID).selector(ipPrefixSelector).treatment(ethDstTreatment)
+ .constraints(constraintsForVlan).links(linksForMp2Sp)
.filteredEgressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10, mpls69Selector)))
.filteredIngressPoints(ImmutableSet.of(
new FilteredConnectPoint(d1p10, mpls80Selector),
new FilteredConnectPoint(d1p11, mpls100Selector),
new FilteredConnectPoint(d2p10, mpls200Selector)
- ))
- .build();
+ )).build();
sut.activate();
- /*
- * We use the FIRST_FIT to simplify tests.
- */
+
LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
List<Intent> compiled = sut.compile(intent, Collections.emptyList());
@@ -786,23 +754,17 @@
public void testMplsEncapsulationNonTrivialForSp() {
intent = LinkCollectionIntent.builder()
- .appId(APP_ID)
- .selector(ipPrefixSelector)
- .treatment(ethDstTreatment)
- .constraints(constraintsForMPLS)
- .links(linksForSp2Mp)
+ .appId(APP_ID).selector(ipPrefixSelector).treatment(ethDstTreatment)
+ .constraints(constraintsForMPLS).links(linksForSp2Mp)
.filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10, vlan69Selector)))
.filteredEgressPoints(ImmutableSet.of(
new FilteredConnectPoint(d1p10, vlan100Selector),
new FilteredConnectPoint(d1p11, vlan200Selector),
new FilteredConnectPoint(d2p10, vlan300Selector)
- ))
- .build();
+ )).build();
sut.activate();
- /*
- * We use the FIRST_FIT to simplify tests.
- */
+
LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
List<Intent> compiled = sut.compile(intent, Collections.emptyList());
@@ -912,23 +874,17 @@
public void testMplsEncapsulationDifferentFilterForMp() {
intent = LinkCollectionIntent.builder()
- .appId(APP_ID)
- .selector(selector)
- .treatment(treatment)
- .constraints(constraintsForMPLS)
- .links(linksForMp2Sp)
+ .appId(APP_ID).selector(selector).treatment(treatment)
+ .constraints(constraintsForMPLS).links(linksForMp2Sp)
.filteredEgressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10, mpls100Selector)))
.filteredIngressPoints(ImmutableSet.of(
new FilteredConnectPoint(d1p10, vlan100Selector),
new FilteredConnectPoint(d1p11, mpls200Selector),
new FilteredConnectPoint(d2p10, vlan200Selector)
- ))
- .build();
+ )).build();
sut.activate();
- /*
- * We use the FIRST_FIT to simplify tests.
- */
+
LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
List<Intent> compiled = sut.compile(intent, Collections.emptyList());
@@ -1065,26 +1021,20 @@
* encapsulation and filtered selectors of different type.
*/
@Test
- public void testVlanEncapsulationDifferentFilter() {
+ public void testVlanEncapsulationDifferentFilterForSp() {
intent = LinkCollectionIntent.builder()
- .appId(APP_ID)
- .selector(selector)
- .treatment(treatment)
- .constraints(constraintsForVlan)
- .links(linksForSp2Mp)
+ .appId(APP_ID).selector(selector).treatment(treatment)
+ .constraints(constraintsForVlan).links(linksForSp2Mp)
.filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10, vlan200Selector)))
.filteredEgressPoints(ImmutableSet.of(
new FilteredConnectPoint(d1p10, mpls100Selector),
new FilteredConnectPoint(d1p11, vlan100Selector),
new FilteredConnectPoint(d2p10, mpls200Selector)
- ))
- .build();
+ )).build();
sut.activate();
- /*
- * We use the FIRST_FIT to simplify tests.
- */
+
LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
List<Intent> compiled = sut.compile(intent, Collections.emptyList());
@@ -1165,26 +1115,26 @@
}
/**
- * We test the proper compilation of p2p with the VLAN
- * encapsulation and trivial filtered points.
+ * We test the proper compilation of sp2mp with trivial selector,
+ * trivial treatment, vlan encapsulation and co-located
+ * ingress/egress points.
*/
@Test
- public void testVlanEncapsulationForP2P() {
+ public void testCoLocatedPointsTrivialForSp() {
intent = LinkCollectionIntent.builder()
- .appId(APP_ID)
- .selector(selector)
- .treatment(treatment)
+ .appId(APP_ID).selector(selector).treatment(treatment)
+ .applyTreatmentOnEgress(true).links(linksForSp2MpCoLoc)
.constraints(constraintsForVlan)
- .links(linksForMp2Sp)
- .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d1p10, vlan100Selector)))
- .filteredEgressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10, mpls200Selector)))
- .build();
+ .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d1p10)))
+ .filteredEgressPoints(ImmutableSet.of(
+ new FilteredConnectPoint(d1p11),
+ new FilteredConnectPoint(d2p10),
+ new FilteredConnectPoint(d3p10)
+ )).build();
sut.activate();
- /*
- * We use the FIRST_FIT to simplify tests.
- */
+
LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
List<Intent> compiled = sut.compile(intent, Collections.emptyList());
@@ -1197,18 +1147,21 @@
.filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
.collect(Collectors.toSet());
assertThat(rulesS1, hasSize(1));
+
FlowRule ruleS1 = rulesS1.iterator().next();
assertThat(ruleS1.selector(), is(
DefaultTrafficSelector
- .builder(vlan100Selector)
+ .builder(selector)
.matchInPort(d1p10.port())
.build()
));
assertThat(ruleS1.treatment(), is(
DefaultTrafficTreatment
.builder()
+ .pushVlan()
.setVlanId(VlanId.vlanId(LABEL))
.setOutput(d1p0.port())
+ .setOutput(d1p11.port())
.build()
));
@@ -1216,6 +1169,7 @@
.filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
.collect(Collectors.toSet());
assertThat(rulesS2, hasSize(1));
+
FlowRule ruleS2 = rulesS2.iterator().next();
assertThat(ruleS2.selector(), is(
DefaultTrafficSelector
@@ -1229,13 +1183,16 @@
.builder()
.setVlanId(VlanId.vlanId(LABEL))
.setOutput(d2p1.port())
+ .popVlan()
+ .setOutput(d2p10.port())
.build()
));
Collection<FlowRule> rulesS3 = rules.stream()
- .filter(rule -> rule.deviceId().equals(d3p0.deviceId()))
+ .filter(rule -> rule.deviceId().equals(d3p1.deviceId()))
.collect(Collectors.toSet());
assertThat(rulesS3, hasSize(1));
+
FlowRule ruleS3 = rulesS3.iterator().next();
assertThat(ruleS3.selector(), is(
DefaultTrafficSelector
@@ -1248,8 +1205,6 @@
DefaultTrafficTreatment
.builder()
.popVlan()
- .pushMpls()
- .setMpls(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
.setOutput(d3p10.port())
.build()
));
@@ -1259,26 +1214,127 @@
}
/**
- * We test the proper compilation of p2p with the MPLS
- * encapsulation and trivial filtered points.
+ * We test the proper compilation of mp2sp with trivial selector,
+ * trivial treatment, mpls encapsulation and co-located
+ * ingress/egress points.
*/
@Test
- public void testMplsEncapsulationForP2P() {
+ public void testCoLocatedPointsTrivialForMp() {
intent = LinkCollectionIntent.builder()
- .appId(APP_ID)
- .selector(selector)
- .treatment(treatment)
+ .appId(APP_ID).selector(selector).treatment(treatment)
+ .links(linksForMp2SpCoLoc).constraints(constraintsForMPLS)
+ .filteredIngressPoints(ImmutableSet.of(
+ new FilteredConnectPoint(d1p10),
+ new FilteredConnectPoint(d2p10)
+ ))
+ .filteredEgressPoints(ImmutableSet.of(new FilteredConnectPoint(d1p11)))
+ .build();
+
+ sut.activate();
+
+ LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
+
+ List<Intent> compiled = sut.compile(intent, Collections.emptyList());
+ assertThat(compiled, hasSize(1));
+
+ Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
+ assertThat(rules, hasSize(3));
+
+ Collection<FlowRule> rulesS1 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS1, hasSize(2));
+
+ FlowRule ruleS1 = rulesS1.stream()
+ .filter(rule -> {
+ PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+ return inPort.port().equals(d1p10.port());
+ })
+ .findFirst()
+ .get();
+ assertThat(ruleS1.selector(), is(
+ DefaultTrafficSelector
+ .builder()
+ .matchInPort(d1p10.port())
+ .build()
+ ));
+ assertThat(ruleS1.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .setOutput(d1p11.port())
+ .build()
+ ));
+
+ ruleS1 = rulesS1.stream()
+ .filter(rule -> {
+ PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+ return inPort.port().equals(d1p0.port());
+ })
+ .findFirst()
+ .get();
+ assertThat(ruleS1.selector(), is(
+ DefaultTrafficSelector
+ .builder()
+ .matchEthType(Ethernet.MPLS_UNICAST)
+ .matchMplsLabel(MplsLabel.mplsLabel(LABEL))
+ .matchInPort(d1p0.port())
+ .build()
+ ));
+ assertThat(ruleS1.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .popMpls(IPV4.ethType())
+ .setOutput(d1p11.port())
+ .build()
+ ));
+
+ Collection<FlowRule> rulesS2 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS2, hasSize(1));
+
+ FlowRule ruleS2 = rulesS2.iterator().next();
+ assertThat(ruleS2.selector(), is(
+ DefaultTrafficSelector
+ .builder()
+ .matchInPort(d2p10.port())
+ .build()
+ ));
+ assertThat(ruleS2.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .pushMpls()
+ .setMpls(MplsLabel.mplsLabel(LABEL))
+ .setOutput(d2p0.port())
+ .build()
+ ));
+
+ sut.deactivate();
+
+ }
+
+ /**
+ * We test the proper compilation of sp2mp with trivial selector,
+ * trivial treatment, mpls encapsulation and co-located
+ * filtered ingress/egress points.
+ */
+ @Test
+ public void testCoLocatedFilteredPointsTrivialForSp() {
+
+ intent = LinkCollectionIntent.builder()
+ .appId(APP_ID).selector(selector).treatment(treatment)
+ .applyTreatmentOnEgress(true).links(linksForSp2MpCoLoc)
.constraints(constraintsForMPLS)
- .links(linksForMp2Sp)
.filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d1p10, vlan100Selector)))
- .filteredEgressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10, mpls200Selector)))
- .build();
+ .filteredEgressPoints(ImmutableSet.of(
+ new FilteredConnectPoint(d1p11, vlan200Selector),
+ new FilteredConnectPoint(d2p10, vlan300Selector),
+ new FilteredConnectPoint(d3p10, vlan69Selector)
+ )).build();
sut.activate();
- /*
- * We use the FIRST_FIT to simplify tests.
- */
+
LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
List<Intent> compiled = sut.compile(intent, Collections.emptyList());
@@ -1291,6 +1347,7 @@
.filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
.collect(Collectors.toSet());
assertThat(rulesS1, hasSize(1));
+
FlowRule ruleS1 = rulesS1.iterator().next();
assertThat(ruleS1.selector(), is(
DefaultTrafficSelector
@@ -1305,20 +1362,24 @@
.pushMpls()
.setMpls(MplsLabel.mplsLabel(LABEL))
.setOutput(d1p0.port())
+ .setVlanId(((VlanIdCriterion) vlan200Selector.getCriterion(VLAN_VID)).vlanId())
+ .setOutput(d1p11.port())
.build()
));
+
Collection<FlowRule> rulesS2 = rules.stream()
.filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
.collect(Collectors.toSet());
assertThat(rulesS2, hasSize(1));
+
FlowRule ruleS2 = rulesS2.iterator().next();
assertThat(ruleS2.selector(), is(
DefaultTrafficSelector
.builder()
.matchInPort(d2p0.port())
- .matchMplsLabel(MplsLabel.mplsLabel(LABEL))
.matchEthType(Ethernet.MPLS_UNICAST)
+ .matchMplsLabel(MplsLabel.mplsLabel(LABEL))
.build()
));
assertThat(ruleS2.treatment(), is(
@@ -1326,26 +1387,34 @@
.builder()
.setMpls(MplsLabel.mplsLabel(LABEL))
.setOutput(d2p1.port())
+ .popMpls(IPV4.ethType())
+ .pushVlan()
+ .setVlanId(((VlanIdCriterion) vlan300Selector.getCriterion(VLAN_VID)).vlanId())
+ .setOutput(d2p10.port())
.build()
));
+
Collection<FlowRule> rulesS3 = rules.stream()
- .filter(rule -> rule.deviceId().equals(d3p0.deviceId()))
+ .filter(rule -> rule.deviceId().equals(d3p1.deviceId()))
.collect(Collectors.toSet());
assertThat(rulesS3, hasSize(1));
+
FlowRule ruleS3 = rulesS3.iterator().next();
assertThat(ruleS3.selector(), is(
DefaultTrafficSelector
.builder()
.matchInPort(d3p0.port())
- .matchMplsLabel(MplsLabel.mplsLabel(LABEL))
.matchEthType(Ethernet.MPLS_UNICAST)
+ .matchMplsLabel(MplsLabel.mplsLabel(LABEL))
.build()
));
assertThat(ruleS3.treatment(), is(
DefaultTrafficTreatment
.builder()
- .setMpls(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
+ .popMpls(IPV4.ethType())
+ .pushVlan()
+ .setVlanId(((VlanIdCriterion) vlan69Selector.getCriterion(VLAN_VID)).vlanId())
.setOutput(d3p10.port())
.build()
));
@@ -1355,26 +1424,25 @@
}
/**
- * We test the proper compilation of p2p with the VLAN
- * encapsulation, filtered points, selector and treatment.
+ * We test the proper compilation of mp2sp with trivial selector,
+ * trivial treatment, vlan encapsulation and co-located
+ * filtered ingress/egress points.
*/
@Test
- public void testVlanEncapsulationNonTrivialForP2P() {
+ public void testCoLocatedFilteredPointsTrivialForMp() {
intent = LinkCollectionIntent.builder()
- .appId(APP_ID)
- .selector(ipPrefixSelector)
- .treatment(ethDstTreatment)
+ .appId(APP_ID).selector(selector).treatment(treatment).links(linksForMp2SpCoLoc)
.constraints(constraintsForVlan)
- .links(linksForMp2Sp)
- .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d1p10, vlan100Selector)))
- .filteredEgressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10, mpls69Selector)))
+ .filteredIngressPoints(ImmutableSet.of(
+ new FilteredConnectPoint(d1p10, mpls100Selector),
+ new FilteredConnectPoint(d2p10, mpls200Selector)
+ ))
+ .filteredEgressPoints(ImmutableSet.of(new FilteredConnectPoint(d1p11, mpls69Selector)))
.build();
sut.activate();
- /*
- * We use the FIRST_FIT to simplify tests.
- */
+
LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
List<Intent> compiled = sut.compile(intent, Collections.emptyList());
@@ -1386,66 +1454,170 @@
Collection<FlowRule> rulesS1 = rules.stream()
.filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
.collect(Collectors.toSet());
- assertThat(rulesS1, hasSize(1));
- FlowRule ruleS1 = rulesS1.iterator().next();
+ assertThat(rulesS1, hasSize(2));
+
+ FlowRule ruleS1 = rulesS1.stream()
+ .filter(rule -> {
+ PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+ return inPort.port().equals(d1p10.port());
+ })
+ .findFirst()
+ .get();
assertThat(ruleS1.selector(), is(
DefaultTrafficSelector
- .builder(ipPrefixSelector)
+ .builder(mpls100Selector)
.matchInPort(d1p10.port())
- .matchVlanId(((VlanIdCriterion) vlan100Selector.getCriterion(VLAN_VID)).vlanId())
.build()
));
assertThat(ruleS1.treatment(), is(
DefaultTrafficTreatment
.builder()
- .setVlanId(VlanId.vlanId(LABEL))
- .setOutput(d1p0.port())
+ .setMpls(((MplsCriterion) mpls69Selector.getCriterion(MPLS_LABEL)).label())
+ .setOutput(d1p11.port())
.build()
));
- Collection<FlowRule> rulesS2 = rules.stream()
- .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
- .collect(Collectors.toSet());
- assertThat(rulesS2, hasSize(1));
- FlowRule ruleS2 = rulesS2.iterator().next();
- assertThat(ruleS2.selector(), is(
+ ruleS1 = rulesS1.stream()
+ .filter(rule -> {
+ PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+ return inPort.port().equals(d1p0.port());
+ })
+ .findFirst()
+ .get();
+ assertThat(ruleS1.selector(), is(
DefaultTrafficSelector
.builder()
- .matchInPort(d2p0.port())
.matchVlanId(VlanId.vlanId(LABEL))
+ .matchInPort(d1p0.port())
.build()
));
- assertThat(ruleS2.treatment(), is(
+ assertThat(ruleS1.treatment(), is(
DefaultTrafficTreatment
.builder()
- .setVlanId(VlanId.vlanId(LABEL))
- .setOutput(d2p1.port())
- .build()
- ));
-
- Collection<FlowRule> rulesS3 = rules.stream()
- .filter(rule -> rule.deviceId().equals(d3p0.deviceId()))
- .collect(Collectors.toSet());
- assertThat(rulesS3, hasSize(1));
- FlowRule ruleS3 = rulesS3.iterator().next();
- assertThat(ruleS3.selector(), is(
- DefaultTrafficSelector
- .builder()
- .matchInPort(d3p0.port())
- .matchVlanId(VlanId.vlanId(LABEL))
- .build()
- ));
- assertThat(ruleS3.treatment(), is(
- DefaultTrafficTreatment
- .builder()
- .setEthDst(((ModEtherInstruction) ethDstTreatment
- .allInstructions()
- .stream()
- .filter(instruction -> instruction instanceof ModEtherInstruction)
- .findFirst().get()).mac())
.popVlan()
.pushMpls()
.setMpls(((MplsCriterion) mpls69Selector.getCriterion(MPLS_LABEL)).label())
+ .setOutput(d1p11.port())
+ .build()
+ ));
+
+ Collection<FlowRule> rulesS2 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS2, hasSize(1));
+ FlowRule ruleS2 = rulesS2.iterator().next();
+ assertThat(ruleS2.selector(), is(
+ DefaultTrafficSelector
+ .builder(mpls200Selector)
+ .matchInPort(d2p10.port())
+ .build()
+ ));
+ assertThat(ruleS2.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .popMpls(IPV4.ethType())
+ .pushVlan()
+ .setVlanId(VlanId.vlanId(LABEL))
+ .setOutput(d2p0.port())
+ .build()
+ ));
+
+ sut.deactivate();
+
+ }
+
+ /**
+ * We test the proper compilation of sp2mp with trivial selector,
+ * trivial treatment, vlan encapsulation and co-located
+ * different filtered ingress/egress points.
+ */
+ @Test
+ public void testCoLocatedDifferentFilteredPointsTrivialForSp() {
+
+ intent = LinkCollectionIntent.builder()
+ .appId(APP_ID).selector(selector).treatment(treatment)
+ .applyTreatmentOnEgress(true).links(linksForSp2MpCoLoc)
+ .constraints(constraintsForVlan)
+ .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d1p10, vlan100Selector)))
+ .filteredEgressPoints(ImmutableSet.of(
+ new FilteredConnectPoint(d1p11, mpls100Selector),
+ new FilteredConnectPoint(d2p10, vlan200Selector),
+ new FilteredConnectPoint(d3p10, mpls200Selector)
+ )).build();
+
+ sut.activate();
+
+ LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
+
+ List<Intent> compiled = sut.compile(intent, Collections.emptyList());
+ assertThat(compiled, hasSize(1));
+
+ Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
+ assertThat(rules, hasSize(3));
+
+ Collection<FlowRule> rulesS1 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS1, hasSize(1));
+ FlowRule ruleS1 = rulesS1.iterator().next();
+ assertThat(ruleS1.selector(), is(
+ DefaultTrafficSelector
+ .builder(vlan100Selector)
+ .matchInPort(d1p10.port())
+ .build()
+ ));
+ assertThat(ruleS1.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .setVlanId(VlanId.vlanId(LABEL))
+ .setOutput(d1p0.port())
+ .popVlan()
+ .pushMpls()
+ .setMpls(((MplsCriterion) mpls100Selector.getCriterion(MPLS_LABEL)).label())
+ .setOutput(d1p11.port())
+ .build()
+ ));
+
+ Collection<FlowRule> rulesS2 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS2, hasSize(1));
+ FlowRule ruleS2 = rulesS2.iterator().next();
+ assertThat(ruleS2.selector(), is(
+ DefaultTrafficSelector
+ .builder()
+ .matchInPort(d2p0.port())
+ .matchVlanId(VlanId.vlanId(LABEL))
+ .build()
+ ));
+ assertThat(ruleS2.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .setVlanId(VlanId.vlanId(LABEL))
+ .setOutput(d2p1.port())
+ .setVlanId(((VlanIdCriterion) vlan200Selector.getCriterion(VLAN_VID)).vlanId())
+ .setOutput(d2p10.port())
+ .build()
+ ));
+
+ Collection<FlowRule> rulesS3 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d3p1.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS3, hasSize(1));
+ FlowRule ruleS3 = rulesS3.iterator().next();
+ assertThat(ruleS3.selector(), is(
+ DefaultTrafficSelector
+ .builder()
+ .matchVlanId(VlanId.vlanId(LABEL))
+ .matchInPort(d3p0.port())
+ .build()
+ ));
+ assertThat(ruleS3.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .popVlan()
+ .pushMpls()
+ .setMpls(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
.setOutput(d3p10.port())
.build()
));
@@ -1455,26 +1627,126 @@
}
/**
- * We test the proper compilation of p2p with the MPLS
- * encapsulation, filtered points, selector and treatment.
+ * We test the proper compilation of mp2sp with trivial selector,
+ * trivial treatment, mpls encapsulation and co-located
+ * filtered ingress/egress points.
*/
@Test
- public void testMplsEncapsulationNonTrivialForP2P() {
+ public void testCoLocatedDifferentFilteredPointsTrivialForMp() {
intent = LinkCollectionIntent.builder()
- .appId(APP_ID)
- .selector(ipPrefixSelector)
- .treatment(ethDstTreatment)
- .constraints(constraintsForMPLS)
- .links(linksForMp2Sp)
- .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d1p10, vlan100Selector)))
- .filteredEgressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10, mpls69Selector)))
+ .appId(APP_ID).selector(selector).treatment(treatment)
+ .links(linksForMp2SpCoLoc).constraints(constraintsForMPLS)
+ .filteredIngressPoints(ImmutableSet.of(
+ new FilteredConnectPoint(d1p10, mpls100Selector),
+ new FilteredConnectPoint(d2p10, vlan100Selector)
+ ))
+ .filteredEgressPoints(ImmutableSet.of(new FilteredConnectPoint(d1p11, mpls200Selector)))
.build();
sut.activate();
- /*
- * We use the FIRST_FIT to simplify tests.
- */
+
+ LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
+
+ List<Intent> compiled = sut.compile(intent, Collections.emptyList());
+ assertThat(compiled, hasSize(1));
+
+ Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
+ assertThat(rules, hasSize(3));
+
+ Collection<FlowRule> rulesS1 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS1, hasSize(2));
+ FlowRule ruleS1 = rulesS1.stream()
+ .filter(rule -> {
+ PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+ return inPort.port().equals(d1p10.port());
+ })
+ .findFirst()
+ .get();
+ assertThat(ruleS1.selector(), is(
+ DefaultTrafficSelector
+ .builder(mpls100Selector)
+ .matchInPort(d1p10.port())
+ .build()
+ ));
+ assertThat(ruleS1.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .setMpls(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
+ .setOutput(d1p11.port())
+ .build()
+ ));
+ ruleS1 = rulesS1.stream()
+ .filter(rule -> {
+ PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+ return inPort.port().equals(d1p0.port());
+ })
+ .findFirst()
+ .get();
+ assertThat(ruleS1.selector(), is(
+ DefaultTrafficSelector
+ .builder()
+ .matchEthType(Ethernet.MPLS_UNICAST)
+ .matchMplsLabel(MplsLabel.mplsLabel(LABEL))
+ .matchInPort(d1p0.port())
+ .build()
+ ));
+ assertThat(ruleS1.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .setMpls(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
+ .setOutput(d1p11.port())
+ .build()
+ ));
+
+ Collection<FlowRule> rulesS2 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS2, hasSize(1));
+ FlowRule ruleS2 = rulesS2.iterator().next();
+ assertThat(ruleS2.selector(), is(
+ DefaultTrafficSelector
+ .builder(vlan100Selector)
+ .matchInPort(d2p10.port())
+ .build()
+ ));
+ assertThat(ruleS2.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .popVlan()
+ .pushMpls()
+ .setMpls(MplsLabel.mplsLabel(LABEL))
+ .setOutput(d2p0.port())
+ .build()
+ ));
+
+ sut.deactivate();
+
+ }
+
+ /**
+ * We test the proper compilation of sp2mp with selector,
+ * treatment, mpls encapsulation and co-located
+ * different filtered ingress/egress points.
+ */
+ @Test
+ public void testCoLocatedDifferentFilteredPointsNonTrivialForSp() {
+
+ intent = LinkCollectionIntent.builder()
+ .appId(APP_ID).selector(ipPrefixSelector).treatment(ethDstTreatment)
+ .applyTreatmentOnEgress(true).links(linksForSp2MpCoLoc)
+ .constraints(constraintsForMPLS)
+ .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d1p10, vlan100Selector)))
+ .filteredEgressPoints(ImmutableSet.of(
+ new FilteredConnectPoint(d1p11, mpls100Selector),
+ new FilteredConnectPoint(d2p10, vlan200Selector),
+ new FilteredConnectPoint(d3p10, mpls200Selector)
+ )).build();
+
+ sut.activate();
+
LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
List<Intent> compiled = sut.compile(intent, Collections.emptyList());
@@ -1502,6 +1774,15 @@
.pushMpls()
.setMpls(MplsLabel.mplsLabel(LABEL))
.setOutput(d1p0.port())
+ .setEthDst(((ModEtherInstruction) ethDstTreatment
+ .allInstructions()
+ .stream()
+ .filter(instruction -> instruction instanceof ModEtherInstruction)
+ .findFirst().get()).mac())
+ .popVlan()
+ .pushMpls()
+ .setMpls(((MplsCriterion) mpls100Selector.getCriterion(MPLS_LABEL)).label())
+ .setOutput(d1p11.port())
.build()
));
@@ -1514,8 +1795,8 @@
DefaultTrafficSelector
.builder()
.matchInPort(d2p0.port())
- .matchMplsLabel(MplsLabel.mplsLabel(LABEL))
.matchEthType(Ethernet.MPLS_UNICAST)
+ .matchMplsLabel(MplsLabel.mplsLabel(LABEL))
.build()
));
assertThat(ruleS2.treatment(), is(
@@ -1523,20 +1804,29 @@
.builder()
.setMpls(MplsLabel.mplsLabel(LABEL))
.setOutput(d2p1.port())
+ .setEthDst(((ModEtherInstruction) ethDstTreatment
+ .allInstructions()
+ .stream()
+ .filter(instruction -> instruction instanceof ModEtherInstruction)
+ .findFirst().get()).mac())
+ .popMpls(IPV4.ethType())
+ .pushVlan()
+ .setVlanId(((VlanIdCriterion) vlan200Selector.getCriterion(VLAN_VID)).vlanId())
+ .setOutput(d2p10.port())
.build()
));
Collection<FlowRule> rulesS3 = rules.stream()
- .filter(rule -> rule.deviceId().equals(d3p0.deviceId()))
+ .filter(rule -> rule.deviceId().equals(d3p1.deviceId()))
.collect(Collectors.toSet());
assertThat(rulesS3, hasSize(1));
FlowRule ruleS3 = rulesS3.iterator().next();
assertThat(ruleS3.selector(), is(
DefaultTrafficSelector
.builder()
- .matchInPort(d3p0.port())
- .matchMplsLabel(MplsLabel.mplsLabel(LABEL))
.matchEthType(Ethernet.MPLS_UNICAST)
+ .matchMplsLabel(MplsLabel.mplsLabel(LABEL))
+ .matchInPort(d3p0.port())
.build()
));
assertThat(ruleS3.treatment(), is(
@@ -1547,7 +1837,7 @@
.stream()
.filter(instruction -> instruction instanceof ModEtherInstruction)
.findFirst().get()).mac())
- .setMpls(((MplsCriterion) mpls69Selector.getCriterion(MPLS_LABEL)).label())
+ .setMpls(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
.setOutput(d3p10.port())
.build()
));
@@ -1556,4 +1846,116 @@
}
+ /**
+ * We test the proper compilation of mp2sp with selector,
+ * treatment, vlan encapsulation and co-located
+ * filtered ingress/egress points.
+ */
+ @Test
+ public void testCoLocatedDifferentFilteredPointsNonTrivialForMp() {
+
+ intent = LinkCollectionIntent.builder()
+ .appId(APP_ID).selector(ipPrefixSelector).treatment(ethDstTreatment)
+ .links(linksForMp2SpCoLoc).constraints(constraintsForVlan)
+ .filteredIngressPoints(ImmutableSet.of(
+ new FilteredConnectPoint(d1p10, mpls100Selector),
+ new FilteredConnectPoint(d2p10, vlan100Selector)
+ ))
+ .filteredEgressPoints(ImmutableSet.of(new FilteredConnectPoint(d1p11, mpls200Selector)))
+ .build();
+
+ sut.activate();
+
+ LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
+
+ List<Intent> compiled = sut.compile(intent, Collections.emptyList());
+ assertThat(compiled, hasSize(1));
+
+ Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
+ assertThat(rules, hasSize(3));
+
+ Collection<FlowRule> rulesS1 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS1, hasSize(2));
+ FlowRule ruleS1 = rulesS1.stream()
+ .filter(rule -> {
+ PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+ return inPort.port().equals(d1p10.port());
+ })
+ .findFirst()
+ .get();
+ assertThat(ruleS1.selector(), is(
+ DefaultTrafficSelector
+ .builder(ipPrefixSelector)
+ .matchInPort(d1p10.port())
+ .matchMplsLabel(((MplsCriterion) mpls100Selector.getCriterion(MPLS_LABEL)).label())
+ .build()
+ ));
+ assertThat(ruleS1.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .setEthDst(((ModEtherInstruction) ethDstTreatment
+ .allInstructions()
+ .stream()
+ .filter(instruction -> instruction instanceof ModEtherInstruction)
+ .findFirst().get()).mac())
+ .setMpls(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
+ .setOutput(d1p11.port())
+ .build()
+ ));
+
+ ruleS1 = rulesS1.stream()
+ .filter(rule -> {
+ PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+ return inPort.port().equals(d1p0.port());
+ })
+ .findFirst()
+ .get();
+ assertThat(ruleS1.selector(), is(
+ DefaultTrafficSelector
+ .builder()
+ .matchVlanId(VlanId.vlanId(LABEL))
+ .matchInPort(d1p0.port())
+ .build()
+ ));
+ assertThat(ruleS1.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .setEthDst(((ModEtherInstruction) ethDstTreatment
+ .allInstructions()
+ .stream()
+ .filter(instruction -> instruction instanceof ModEtherInstruction)
+ .findFirst().get()).mac())
+ .popVlan()
+ .pushMpls()
+ .setMpls(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
+ .setOutput(d1p11.port())
+ .build()
+ ));
+
+ Collection<FlowRule> rulesS2 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS2, hasSize(1));
+ FlowRule ruleS2 = rulesS2.iterator().next();
+ assertThat(ruleS2.selector(), is(
+ DefaultTrafficSelector
+ .builder(ipPrefixSelector)
+ .matchInPort(d2p10.port())
+ .matchVlanId(((VlanIdCriterion) vlan100Selector.getCriterion(VLAN_VID)).vlanId())
+ .build()
+ ));
+ assertThat(ruleS2.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .setVlanId(VlanId.vlanId(LABEL))
+ .setOutput(d2p0.port())
+ .build()
+ ));
+
+ sut.deactivate();
+
+ }
+
}
diff --git a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentCompilerP2PTest.java b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentCompilerP2PTest.java
new file mode 100644
index 0000000..84720b5
--- /dev/null
+++ b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentCompilerP2PTest.java
@@ -0,0 +1,768 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.intent.impl.compiler;
+
+import com.google.common.collect.ImmutableSet;
+import org.hamcrest.core.Is;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.MplsLabel;
+import org.onlab.packet.VlanId;
+import org.onosproject.cfg.ComponentConfigAdapter;
+import org.onosproject.core.CoreService;
+import org.onosproject.net.FilteredConnectPoint;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.criteria.MplsCriterion;
+import org.onosproject.net.flow.criteria.VlanIdCriterion;
+import org.onosproject.net.intent.FlowRuleIntent;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentExtensionService;
+import org.onosproject.net.intent.LinkCollectionIntent;
+import org.onosproject.net.resource.MockResourceService;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.core.Is.is;
+import static org.onosproject.net.NetTestTools.APP_ID;
+import static org.onosproject.net.flow.criteria.Criterion.Type.MPLS_LABEL;
+import static org.onosproject.net.flow.criteria.Criterion.Type.VLAN_VID;
+import static org.onosproject.net.flow.instructions.L2ModificationInstruction.*;
+
+/**
+ * This set of tests are meant to test the proper compilation
+ * of p2p intents.
+ */
+public class LinkCollectionIntentCompilerP2PTest extends AbstractLinkCollectionTest {
+
+ @Before
+ public void setUp() {
+ sut = new LinkCollectionIntentCompiler();
+ coreService = createMock(CoreService.class);
+ expect(coreService.registerApplication("org.onosproject.net.intent"))
+ .andReturn(appId);
+ sut.coreService = coreService;
+
+ Intent.bindIdGenerator(idGenerator);
+
+ intentExtensionService = createMock(IntentExtensionService.class);
+ intentExtensionService.registerCompiler(LinkCollectionIntent.class, sut);
+ intentExtensionService.unregisterCompiler(LinkCollectionIntent.class);
+
+ registrator = new IntentConfigurableRegistrator();
+ registrator.extensionService = intentExtensionService;
+ registrator.cfgService = new ComponentConfigAdapter();
+ registrator.activate();
+
+ sut.registrator = registrator;
+ sut.resourceService = new MockResourceService();
+
+ LinkCollectionCompiler.optimize = false;
+ LinkCollectionCompiler.copyTtl = false;
+
+ replay(coreService, intentExtensionService);
+ }
+
+ @After
+ public void tearDown() {
+ Intent.unbindIdGenerator(idGenerator);
+ }
+
+ /**
+ * We test the proper compilation of p2p with
+ * trivial selector and trivial treatment.
+ */
+ @Test
+ public void testCompilationTrivialForP2P() {
+
+ intent = LinkCollectionIntent.builder()
+ .appId(APP_ID)
+ .selector(selector)
+ .treatment(treatment)
+ .applyTreatmentOnEgress(true)
+ .links(p2pLinks)
+ .filteredIngressPoints(ImmutableSet.of(
+ new FilteredConnectPoint(d1p10)
+ ))
+ .filteredEgressPoints(ImmutableSet.of(
+ new FilteredConnectPoint(d3p0)
+ ))
+ .build();
+
+ sut.activate();
+
+ List<Intent> compiled = sut.compile(intent, Collections.emptyList());
+ assertThat(compiled, hasSize(1));
+
+ Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
+ assertThat(rules, hasSize(3));
+
+ Collection<FlowRule> rulesS1 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS1, hasSize(1));
+ FlowRule ruleS1 = rulesS1.iterator().next();
+ assertThat(ruleS1.selector(), Is.is(
+ DefaultTrafficSelector
+ .builder()
+ .matchInPort(d1p10.port())
+ .build()
+ ));
+ assertThat(ruleS1.treatment(), Is.is(
+ DefaultTrafficTreatment
+ .builder()
+ .setOutput(d1p0.port())
+ .build()
+ ));
+
+ Collection<FlowRule> rulesS2 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS2, hasSize(1));
+ FlowRule ruleS2 = rulesS2.iterator().next();
+ assertThat(ruleS2.selector(), Is.is(
+ DefaultTrafficSelector
+ .builder()
+ .matchInPort(d2p0.port())
+ .build()
+ ));
+ assertThat(ruleS2.treatment(), Is.is(
+ DefaultTrafficTreatment
+ .builder()
+ .setOutput(d2p1.port())
+ .build()
+ ));
+
+
+ Collection<FlowRule> rulesS3 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d3p1.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS3, hasSize(1));
+ FlowRule ruleS3 = rulesS3.iterator().next();
+ assertThat(ruleS3.selector(), Is.is(
+ DefaultTrafficSelector
+ .builder()
+ .matchInPort(d3p1.port())
+ .build()
+ ));
+ assertThat(ruleS3.treatment(), Is.is(
+ DefaultTrafficTreatment
+ .builder()
+ .setOutput(d3p0.port())
+ .build()
+ ));
+
+ sut.deactivate();
+
+ }
+
+ /**
+ * We test the proper compilation of p2p with
+ * trivial selector, trivial treatment and
+ * filtered points.
+ */
+ @Test
+ public void testCompilationFilteredPointForP2P() {
+
+ intent = LinkCollectionIntent.builder()
+ .appId(APP_ID)
+ .selector(selector)
+ .treatment(treatment)
+ .applyTreatmentOnEgress(true)
+ .links(p2pLinks)
+ .filteredIngressPoints(ImmutableSet.of(
+ new FilteredConnectPoint(d1p10, vlan100Selector)
+ ))
+ .filteredEgressPoints(ImmutableSet.of(
+ new FilteredConnectPoint(d3p0, mpls200Selector)
+ ))
+ .build();
+
+ sut.activate();
+
+ List<Intent> compiled = sut.compile(intent, Collections.emptyList());
+ assertThat(compiled, hasSize(1));
+
+ Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
+ assertThat(rules, hasSize(3));
+
+ Collection<FlowRule> rulesS1 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS1, hasSize(1));
+ FlowRule ruleS1 = rulesS1.iterator().next();
+ assertThat(ruleS1.selector(), Is.is(
+ DefaultTrafficSelector
+ .builder(vlan100Selector)
+ .matchInPort(d1p10.port())
+ .build()
+ ));
+ assertThat(ruleS1.treatment(), Is.is(
+ DefaultTrafficTreatment
+ .builder()
+ .setOutput(d1p0.port())
+ .build()
+ ));
+
+ Collection<FlowRule> rulesS2 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS2, hasSize(1));
+ FlowRule ruleS2 = rulesS2.iterator().next();
+ assertThat(ruleS2.selector(), Is.is(
+ DefaultTrafficSelector
+ .builder(vlan100Selector)
+ .matchInPort(d2p0.port())
+ .build()
+ ));
+ assertThat(ruleS2.treatment(), Is.is(
+ DefaultTrafficTreatment
+ .builder()
+ .setOutput(d2p1.port())
+ .build()
+ ));
+
+
+ Collection<FlowRule> rulesS3 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d3p1.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS3, hasSize(1));
+ FlowRule ruleS3 = rulesS3.iterator().next();
+ assertThat(ruleS3.selector(), Is.is(
+ DefaultTrafficSelector
+ .builder(vlan100Selector)
+ .matchInPort(d3p1.port())
+ .build()
+ ));
+ assertThat(ruleS3.treatment(), Is.is(
+ DefaultTrafficTreatment
+ .builder()
+ .popVlan()
+ .pushMpls()
+ .setMpls(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
+ .setOutput(d3p0.port())
+ .build()
+ ));
+
+ sut.deactivate();
+
+ }
+
+ /**
+ * We test the proper compilation of p2p with
+ * selector, treatment and filtered points.
+ */
+ @Test
+ public void testCompilationNonTrivialForP2P() {
+
+ intent = LinkCollectionIntent.builder()
+ .appId(APP_ID)
+ .selector(ipPrefixSelector)
+ .treatment(ethDstTreatment)
+ .applyTreatmentOnEgress(true)
+ .links(p2pLinks)
+ .filteredIngressPoints(ImmutableSet.of(
+ new FilteredConnectPoint(d1p10, vlan100Selector)
+ ))
+ .filteredEgressPoints(ImmutableSet.of(
+ new FilteredConnectPoint(d3p0, mpls200Selector)
+ ))
+ .build();
+
+ sut.activate();
+
+ List<Intent> compiled = sut.compile(intent, Collections.emptyList());
+ assertThat(compiled, hasSize(1));
+
+ Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
+ assertThat(rules, hasSize(3));
+
+ Collection<FlowRule> rulesS1 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS1, hasSize(1));
+ FlowRule ruleS1 = rulesS1.iterator().next();
+ assertThat(ruleS1.selector(), Is.is(
+ DefaultTrafficSelector
+ .builder(ipPrefixSelector)
+ .matchInPort(d1p10.port())
+ .matchVlanId(((VlanIdCriterion) vlan100Selector.getCriterion(VLAN_VID)).vlanId())
+ .build()
+ ));
+ assertThat(ruleS1.treatment(), Is.is(
+ DefaultTrafficTreatment
+ .builder()
+ .setOutput(d1p0.port())
+ .build()
+ ));
+
+ Collection<FlowRule> rulesS2 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS2, hasSize(1));
+ FlowRule ruleS2 = rulesS2.iterator().next();
+ assertThat(ruleS2.selector(), Is.is(
+ DefaultTrafficSelector
+ .builder(ipPrefixSelector)
+ .matchInPort(d2p0.port())
+ .matchVlanId(((VlanIdCriterion) vlan100Selector.getCriterion(VLAN_VID)).vlanId())
+ .build()
+ ));
+ assertThat(ruleS2.treatment(), Is.is(
+ DefaultTrafficTreatment
+ .builder()
+ .setOutput(d2p1.port())
+ .build()
+ ));
+
+
+ Collection<FlowRule> rulesS3 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d3p1.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS3, hasSize(1));
+ FlowRule ruleS3 = rulesS3.iterator().next();
+ assertThat(ruleS3.selector(), Is.is(
+ DefaultTrafficSelector
+ .builder(ipPrefixSelector)
+ .matchInPort(d3p1.port())
+ .matchVlanId(((VlanIdCriterion) vlan100Selector.getCriterion(VLAN_VID)).vlanId())
+ .build()
+ ));
+ assertThat(ruleS3.treatment(), Is.is(
+ DefaultTrafficTreatment
+ .builder()
+ .setEthDst(((ModEtherInstruction) ethDstTreatment
+ .allInstructions()
+ .stream()
+ .filter(instruction -> instruction instanceof ModEtherInstruction)
+ .findFirst().get()).mac())
+ .popVlan()
+ .pushMpls()
+ .setMpls(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
+ .setOutput(d3p0.port())
+ .build()
+ ));
+
+ sut.deactivate();
+
+ }
+
+ /**
+ * We test the proper compilation of p2p with the VLAN
+ * encapsulation and trivial filtered points.
+ */
+ @Test
+ public void testVlanEncapsulationForP2P() {
+
+ intent = LinkCollectionIntent.builder()
+ .appId(APP_ID)
+ .selector(selector)
+ .treatment(treatment)
+ .constraints(constraintsForVlan)
+ .links(linksForMp2Sp)
+ .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d1p10, vlan100Selector)))
+ .filteredEgressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10, mpls200Selector)))
+ .build();
+
+ sut.activate();
+ /*
+ * We use the FIRST_FIT to simplify tests.
+ */
+ LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
+
+ List<Intent> compiled = sut.compile(intent, Collections.emptyList());
+ assertThat(compiled, hasSize(1));
+
+ Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
+ assertThat(rules, hasSize(3));
+
+ Collection<FlowRule> rulesS1 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS1, hasSize(1));
+ FlowRule ruleS1 = rulesS1.iterator().next();
+ assertThat(ruleS1.selector(), is(
+ DefaultTrafficSelector
+ .builder(vlan100Selector)
+ .matchInPort(d1p10.port())
+ .build()
+ ));
+ assertThat(ruleS1.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .setVlanId(VlanId.vlanId(LABEL))
+ .setOutput(d1p0.port())
+ .build()
+ ));
+
+ Collection<FlowRule> rulesS2 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS2, hasSize(1));
+ FlowRule ruleS2 = rulesS2.iterator().next();
+ assertThat(ruleS2.selector(), is(
+ DefaultTrafficSelector
+ .builder()
+ .matchInPort(d2p0.port())
+ .matchVlanId(VlanId.vlanId(LABEL))
+ .build()
+ ));
+ assertThat(ruleS2.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .setVlanId(VlanId.vlanId(LABEL))
+ .setOutput(d2p1.port())
+ .build()
+ ));
+
+ Collection<FlowRule> rulesS3 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d3p0.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS3, hasSize(1));
+ FlowRule ruleS3 = rulesS3.iterator().next();
+ assertThat(ruleS3.selector(), is(
+ DefaultTrafficSelector
+ .builder()
+ .matchInPort(d3p0.port())
+ .matchVlanId(VlanId.vlanId(LABEL))
+ .build()
+ ));
+ assertThat(ruleS3.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .popVlan()
+ .pushMpls()
+ .setMpls(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
+ .setOutput(d3p10.port())
+ .build()
+ ));
+
+ sut.deactivate();
+
+ }
+
+
+ /**
+ * We test the proper compilation of p2p with the MPLS
+ * encapsulation and trivial filtered points.
+ */
+ @Test
+ public void testMplsEncapsulationForP2P() {
+
+ intent = LinkCollectionIntent.builder()
+ .appId(APP_ID)
+ .selector(selector)
+ .treatment(treatment)
+ .constraints(constraintsForMPLS)
+ .links(linksForMp2Sp)
+ .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d1p10, vlan100Selector)))
+ .filteredEgressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10, mpls200Selector)))
+ .build();
+
+ sut.activate();
+ /*
+ * We use the FIRST_FIT to simplify tests.
+ */
+ LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
+
+ List<Intent> compiled = sut.compile(intent, Collections.emptyList());
+ assertThat(compiled, hasSize(1));
+
+ Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
+ assertThat(rules, hasSize(3));
+
+ Collection<FlowRule> rulesS1 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS1, hasSize(1));
+ FlowRule ruleS1 = rulesS1.iterator().next();
+ assertThat(ruleS1.selector(), is(
+ DefaultTrafficSelector
+ .builder(vlan100Selector)
+ .matchInPort(d1p10.port())
+ .build()
+ ));
+ assertThat(ruleS1.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .popVlan()
+ .pushMpls()
+ .setMpls(MplsLabel.mplsLabel(LABEL))
+ .setOutput(d1p0.port())
+ .build()
+ ));
+
+ Collection<FlowRule> rulesS2 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS2, hasSize(1));
+ FlowRule ruleS2 = rulesS2.iterator().next();
+ assertThat(ruleS2.selector(), is(
+ DefaultTrafficSelector
+ .builder()
+ .matchInPort(d2p0.port())
+ .matchMplsLabel(MplsLabel.mplsLabel(LABEL))
+ .matchEthType(Ethernet.MPLS_UNICAST)
+ .build()
+ ));
+ assertThat(ruleS2.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .setMpls(MplsLabel.mplsLabel(LABEL))
+ .setOutput(d2p1.port())
+ .build()
+ ));
+
+ Collection<FlowRule> rulesS3 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d3p0.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS3, hasSize(1));
+ FlowRule ruleS3 = rulesS3.iterator().next();
+ assertThat(ruleS3.selector(), is(
+ DefaultTrafficSelector
+ .builder()
+ .matchInPort(d3p0.port())
+ .matchMplsLabel(MplsLabel.mplsLabel(LABEL))
+ .matchEthType(Ethernet.MPLS_UNICAST)
+ .build()
+ ));
+ assertThat(ruleS3.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .setMpls(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
+ .setOutput(d3p10.port())
+ .build()
+ ));
+
+ sut.deactivate();
+
+ }
+
+ /**
+ * We test the proper compilation of p2p with the VLAN
+ * encapsulation, filtered points, selector and treatment.
+ */
+ @Test
+ public void testVlanEncapsulationNonTrivialForP2P() {
+
+ intent = LinkCollectionIntent.builder()
+ .appId(APP_ID)
+ .selector(ipPrefixSelector)
+ .treatment(ethDstTreatment)
+ .constraints(constraintsForVlan)
+ .links(linksForMp2Sp)
+ .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d1p10, vlan100Selector)))
+ .filteredEgressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10, mpls69Selector)))
+ .build();
+
+ sut.activate();
+ /*
+ * We use the FIRST_FIT to simplify tests.
+ */
+ LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
+
+ List<Intent> compiled = sut.compile(intent, Collections.emptyList());
+ assertThat(compiled, hasSize(1));
+
+ Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
+ assertThat(rules, hasSize(3));
+
+ Collection<FlowRule> rulesS1 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS1, hasSize(1));
+ FlowRule ruleS1 = rulesS1.iterator().next();
+ assertThat(ruleS1.selector(), is(
+ DefaultTrafficSelector
+ .builder(ipPrefixSelector)
+ .matchInPort(d1p10.port())
+ .matchVlanId(((VlanIdCriterion) vlan100Selector.getCriterion(VLAN_VID)).vlanId())
+ .build()
+ ));
+ assertThat(ruleS1.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .setVlanId(VlanId.vlanId(LABEL))
+ .setOutput(d1p0.port())
+ .build()
+ ));
+
+ Collection<FlowRule> rulesS2 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS2, hasSize(1));
+ FlowRule ruleS2 = rulesS2.iterator().next();
+ assertThat(ruleS2.selector(), is(
+ DefaultTrafficSelector
+ .builder()
+ .matchInPort(d2p0.port())
+ .matchVlanId(VlanId.vlanId(LABEL))
+ .build()
+ ));
+ assertThat(ruleS2.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .setVlanId(VlanId.vlanId(LABEL))
+ .setOutput(d2p1.port())
+ .build()
+ ));
+
+ Collection<FlowRule> rulesS3 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d3p0.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS3, hasSize(1));
+ FlowRule ruleS3 = rulesS3.iterator().next();
+ assertThat(ruleS3.selector(), is(
+ DefaultTrafficSelector
+ .builder()
+ .matchInPort(d3p0.port())
+ .matchVlanId(VlanId.vlanId(LABEL))
+ .build()
+ ));
+ assertThat(ruleS3.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .setEthDst(((ModEtherInstruction) ethDstTreatment
+ .allInstructions()
+ .stream()
+ .filter(instruction -> instruction instanceof ModEtherInstruction)
+ .findFirst().get()).mac())
+ .popVlan()
+ .pushMpls()
+ .setMpls(((MplsCriterion) mpls69Selector.getCriterion(MPLS_LABEL)).label())
+ .setOutput(d3p10.port())
+ .build()
+ ));
+
+ sut.deactivate();
+
+ }
+
+ /**
+ * We test the proper compilation of p2p with the MPLS
+ * encapsulation, filtered points, selector and treatment.
+ */
+ @Test
+ public void testMplsEncapsulationNonTrivialForP2P() {
+
+ intent = LinkCollectionIntent.builder()
+ .appId(APP_ID)
+ .selector(ipPrefixSelector)
+ .treatment(ethDstTreatment)
+ .constraints(constraintsForMPLS)
+ .links(linksForMp2Sp)
+ .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d1p10, vlan100Selector)))
+ .filteredEgressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10, mpls69Selector)))
+ .build();
+
+ sut.activate();
+ /*
+ * We use the FIRST_FIT to simplify tests.
+ */
+ LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
+
+ List<Intent> compiled = sut.compile(intent, Collections.emptyList());
+ assertThat(compiled, hasSize(1));
+
+ Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
+ assertThat(rules, hasSize(3));
+
+ Collection<FlowRule> rulesS1 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS1, hasSize(1));
+ FlowRule ruleS1 = rulesS1.iterator().next();
+ assertThat(ruleS1.selector(), is(
+ DefaultTrafficSelector
+ .builder(ipPrefixSelector)
+ .matchInPort(d1p10.port())
+ .matchVlanId(((VlanIdCriterion) vlan100Selector.getCriterion(VLAN_VID)).vlanId())
+ .build()
+ ));
+ assertThat(ruleS1.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .popVlan()
+ .pushMpls()
+ .setMpls(MplsLabel.mplsLabel(LABEL))
+ .setOutput(d1p0.port())
+ .build()
+ ));
+
+ Collection<FlowRule> rulesS2 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS2, hasSize(1));
+ FlowRule ruleS2 = rulesS2.iterator().next();
+ assertThat(ruleS2.selector(), is(
+ DefaultTrafficSelector
+ .builder()
+ .matchInPort(d2p0.port())
+ .matchMplsLabel(MplsLabel.mplsLabel(LABEL))
+ .matchEthType(Ethernet.MPLS_UNICAST)
+ .build()
+ ));
+ assertThat(ruleS2.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .setMpls(MplsLabel.mplsLabel(LABEL))
+ .setOutput(d2p1.port())
+ .build()
+ ));
+
+ Collection<FlowRule> rulesS3 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d3p0.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS3, hasSize(1));
+ FlowRule ruleS3 = rulesS3.iterator().next();
+ assertThat(ruleS3.selector(), is(
+ DefaultTrafficSelector
+ .builder()
+ .matchInPort(d3p0.port())
+ .matchMplsLabel(MplsLabel.mplsLabel(LABEL))
+ .matchEthType(Ethernet.MPLS_UNICAST)
+ .build()
+ ));
+ assertThat(ruleS3.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .setEthDst(((ModEtherInstruction) ethDstTreatment
+ .allInstructions()
+ .stream()
+ .filter(instruction -> instruction instanceof ModEtherInstruction)
+ .findFirst().get()).mac())
+ .setMpls(((MplsCriterion) mpls69Selector.getCriterion(MPLS_LABEL)).label())
+ .setOutput(d3p10.port())
+ .build()
+ ));
+
+ sut.deactivate();
+
+ }
+
+}
diff --git a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentCompilerTest.java b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentCompilerTest.java
index 3970f8d..45e8485 100644
--- a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentCompilerTest.java
+++ b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentCompilerTest.java
@@ -65,6 +65,10 @@
import static org.onosproject.net.flow.criteria.Criterion.Type.VLAN_VID;
import static org.onosproject.net.flow.instructions.L2ModificationInstruction.*;
+/**
+ * This set of tests are meant to test the LinkCollectionIntent
+ * compiler.
+ */
public class LinkCollectionIntentCompilerTest extends AbstractLinkCollectionTest {
@Before
@@ -110,6 +114,10 @@
Intent.unbindIdGenerator(idGenerator);
}
+ /**
+ * We test the proper compilation of a simple link collection intent
+ * with connect points, trivial treatment and trivial selector.
+ */
@Test
public void testCompile() {
sut.activate();
@@ -166,10 +174,14 @@
}
/**
- * Single point to multi point case.
+ * Single point to multi point case. Scenario is the follow:
+ *
* -1 of1 2-1 of2 2--1 of3 2-
* 3
* `-1 of4 2-
+ *
+ * We test the proper compilation of sp2mp with trivial selector,
+ * trivial treatment and different filtered points
*/
@Test
public void testFilteredConnectPointForSp() {
@@ -286,10 +298,14 @@
/**
* Multi point to single point intent with filtered connect point.
+ * Scenario is the follow:
*
* -1 of1 2-1 of2 2-1 of4 2-
* 3
* -1 of3 2---/
+ *
+ * We test the proper compilation of mp2sp intents with trivial selector,
+ * trivial treatment and different filtered point.
*/
@Test
public void testFilteredConnectPointForMp() {
@@ -408,9 +424,14 @@
/**
* Single point to multi point without filtered connect point case.
+ * Scenario is the follow:
+ *
* -1 of1 2-1 of2 2--1 of3 2-
* 3
* `-1 of4 2-
+ *
+ * We test the proper compilation of sp2mp with non trivial selector,
+ * non trivial treatment and simple connect points.
*/
@Test
public void nonTrivialTranslationForSp() {
@@ -527,10 +548,14 @@
/**
* Multi point to single point intent without filtered connect point.
+ * Scenario is the follow:
*
* -1 of1 2-1 of2 2-1 of4 2-
* 3
* -1 of3 2---/
+ *
+ * We test the proper compilation of mp2sp intent with non trivial selector,
+ * non trivial treatment and simple connect points.
*/
@Test
public void nonTrivialTranslationForMp() {
@@ -1085,282 +1110,4 @@
}
- /**
- * We test the proper compilation of p2p with
- * trivial selector and trivial treatment.
- */
- @Test
- public void p2p() {
-
- intent = LinkCollectionIntent.builder()
- .appId(APP_ID)
- .selector(selector)
- .treatment(treatment)
- .applyTreatmentOnEgress(true)
- .links(p2pLinks)
- .filteredIngressPoints(ImmutableSet.of(
- new FilteredConnectPoint(d1p10)
- ))
- .filteredEgressPoints(ImmutableSet.of(
- new FilteredConnectPoint(d3p0)
- ))
- .build();
-
- sut.activate();
-
- List<Intent> compiled = sut.compile(intent, Collections.emptyList());
- assertThat(compiled, hasSize(1));
-
- Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
- assertThat(rules, hasSize(3));
-
- Collection<FlowRule> rulesS1 = rules.stream()
- .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
- .collect(Collectors.toSet());
- assertThat(rulesS1, hasSize(1));
- FlowRule ruleS1 = rulesS1.iterator().next();
- assertThat(ruleS1.selector(), Is.is(
- DefaultTrafficSelector
- .builder()
- .matchInPort(d1p10.port())
- .build()
- ));
- assertThat(ruleS1.treatment(), Is.is(
- DefaultTrafficTreatment
- .builder()
- .setOutput(d1p0.port())
- .build()
- ));
-
- Collection<FlowRule> rulesS2 = rules.stream()
- .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
- .collect(Collectors.toSet());
- assertThat(rulesS2, hasSize(1));
- FlowRule ruleS2 = rulesS2.iterator().next();
- assertThat(ruleS2.selector(), Is.is(
- DefaultTrafficSelector
- .builder()
- .matchInPort(d2p0.port())
- .build()
- ));
- assertThat(ruleS2.treatment(), Is.is(
- DefaultTrafficTreatment
- .builder()
- .setOutput(d2p1.port())
- .build()
- ));
-
-
- Collection<FlowRule> rulesS3 = rules.stream()
- .filter(rule -> rule.deviceId().equals(d3p1.deviceId()))
- .collect(Collectors.toSet());
- assertThat(rulesS3, hasSize(1));
- FlowRule ruleS3 = rulesS3.iterator().next();
- assertThat(ruleS3.selector(), Is.is(
- DefaultTrafficSelector
- .builder()
- .matchInPort(d3p1.port())
- .build()
- ));
- assertThat(ruleS3.treatment(), Is.is(
- DefaultTrafficTreatment
- .builder()
- .setOutput(d3p0.port())
- .build()
- ));
-
- sut.deactivate();
-
- }
-
- /**
- * We test the proper compilation of p2p with
- * trivial selector, trivial treatment and filtered points.
- */
- @Test
- public void p2pFilteredPoint() {
-
- intent = LinkCollectionIntent.builder()
- .appId(APP_ID)
- .selector(selector)
- .treatment(treatment)
- .applyTreatmentOnEgress(true)
- .links(p2pLinks)
- .filteredIngressPoints(ImmutableSet.of(
- new FilteredConnectPoint(d1p10, vlan100Selector)
- ))
- .filteredEgressPoints(ImmutableSet.of(
- new FilteredConnectPoint(d3p0, mpls200Selector)
- ))
- .build();
-
- sut.activate();
-
- List<Intent> compiled = sut.compile(intent, Collections.emptyList());
- assertThat(compiled, hasSize(1));
-
- Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
- assertThat(rules, hasSize(3));
-
- Collection<FlowRule> rulesS1 = rules.stream()
- .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
- .collect(Collectors.toSet());
- assertThat(rulesS1, hasSize(1));
- FlowRule ruleS1 = rulesS1.iterator().next();
- assertThat(ruleS1.selector(), Is.is(
- DefaultTrafficSelector
- .builder(vlan100Selector)
- .matchInPort(d1p10.port())
- .build()
- ));
- assertThat(ruleS1.treatment(), Is.is(
- DefaultTrafficTreatment
- .builder()
- .setOutput(d1p0.port())
- .build()
- ));
-
- Collection<FlowRule> rulesS2 = rules.stream()
- .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
- .collect(Collectors.toSet());
- assertThat(rulesS2, hasSize(1));
- FlowRule ruleS2 = rulesS2.iterator().next();
- assertThat(ruleS2.selector(), Is.is(
- DefaultTrafficSelector
- .builder(vlan100Selector)
- .matchInPort(d2p0.port())
- .build()
- ));
- assertThat(ruleS2.treatment(), Is.is(
- DefaultTrafficTreatment
- .builder()
- .setOutput(d2p1.port())
- .build()
- ));
-
-
- Collection<FlowRule> rulesS3 = rules.stream()
- .filter(rule -> rule.deviceId().equals(d3p1.deviceId()))
- .collect(Collectors.toSet());
- assertThat(rulesS3, hasSize(1));
- FlowRule ruleS3 = rulesS3.iterator().next();
- assertThat(ruleS3.selector(), Is.is(
- DefaultTrafficSelector
- .builder(vlan100Selector)
- .matchInPort(d3p1.port())
- .build()
- ));
- assertThat(ruleS3.treatment(), Is.is(
- DefaultTrafficTreatment
- .builder()
- .popVlan()
- .pushMpls()
- .setMpls(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
- .setOutput(d3p0.port())
- .build()
- ));
-
- sut.deactivate();
-
- }
-
- /**
- * We test the proper compilation of p2p with
- * selector, treatment and filtered points.
- */
- @Test
- public void p2pNonTrivial() {
-
- intent = LinkCollectionIntent.builder()
- .appId(APP_ID)
- .selector(ipPrefixSelector)
- .treatment(ethDstTreatment)
- .applyTreatmentOnEgress(true)
- .links(p2pLinks)
- .filteredIngressPoints(ImmutableSet.of(
- new FilteredConnectPoint(d1p10, vlan100Selector)
- ))
- .filteredEgressPoints(ImmutableSet.of(
- new FilteredConnectPoint(d3p0, mpls200Selector)
- ))
- .build();
-
- sut.activate();
-
- List<Intent> compiled = sut.compile(intent, Collections.emptyList());
- assertThat(compiled, hasSize(1));
-
- Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
- assertThat(rules, hasSize(3));
-
- Collection<FlowRule> rulesS1 = rules.stream()
- .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
- .collect(Collectors.toSet());
- assertThat(rulesS1, hasSize(1));
- FlowRule ruleS1 = rulesS1.iterator().next();
- assertThat(ruleS1.selector(), Is.is(
- DefaultTrafficSelector
- .builder(ipPrefixSelector)
- .matchInPort(d1p10.port())
- .matchVlanId(((VlanIdCriterion) vlan100Selector.getCriterion(VLAN_VID)).vlanId())
- .build()
- ));
- assertThat(ruleS1.treatment(), Is.is(
- DefaultTrafficTreatment
- .builder()
- .setOutput(d1p0.port())
- .build()
- ));
-
- Collection<FlowRule> rulesS2 = rules.stream()
- .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
- .collect(Collectors.toSet());
- assertThat(rulesS2, hasSize(1));
- FlowRule ruleS2 = rulesS2.iterator().next();
- assertThat(ruleS2.selector(), Is.is(
- DefaultTrafficSelector
- .builder(ipPrefixSelector)
- .matchInPort(d2p0.port())
- .matchVlanId(((VlanIdCriterion) vlan100Selector.getCriterion(VLAN_VID)).vlanId())
- .build()
- ));
- assertThat(ruleS2.treatment(), Is.is(
- DefaultTrafficTreatment
- .builder()
- .setOutput(d2p1.port())
- .build()
- ));
-
-
- Collection<FlowRule> rulesS3 = rules.stream()
- .filter(rule -> rule.deviceId().equals(d3p1.deviceId()))
- .collect(Collectors.toSet());
- assertThat(rulesS3, hasSize(1));
- FlowRule ruleS3 = rulesS3.iterator().next();
- assertThat(ruleS3.selector(), Is.is(
- DefaultTrafficSelector
- .builder(ipPrefixSelector)
- .matchInPort(d3p1.port())
- .matchVlanId(((VlanIdCriterion) vlan100Selector.getCriterion(VLAN_VID)).vlanId())
- .build()
- ));
- assertThat(ruleS3.treatment(), Is.is(
- DefaultTrafficTreatment
- .builder()
- .setEthDst(((ModEtherInstruction) ethDstTreatment
- .allInstructions()
- .stream()
- .filter(instruction -> instruction instanceof ModEtherInstruction)
- .findFirst().get()).mac())
- .popVlan()
- .pushMpls()
- .setMpls(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
- .setOutput(d3p0.port())
- .build()
- ));
-
- sut.deactivate();
-
- }
-
}
diff --git a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/LinkCollectionOptimizationTest.java b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/LinkCollectionOptimizationTest.java
index 4b58fba..b0465f0 100644
--- a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/LinkCollectionOptimizationTest.java
+++ b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/LinkCollectionOptimizationTest.java
@@ -1057,4 +1057,487 @@
}
+ /**
+ * We test the proper optimization of sp2mp with trivial selector,
+ * trivial treatment, vlan encapsulation and co-located
+ * ingress/egress points.
+ */
+ @Test
+ public void testOptimizationCoLocatedPointsTrivialForSp() {
+
+ intent = LinkCollectionIntent.builder()
+ .appId(APP_ID)
+ .selector(selector)
+ .treatment(treatment)
+ .applyTreatmentOnEgress(true)
+ .links(linksForSp2MpCoLoc)
+ .constraints(constraintsForVlan)
+ .filteredIngressPoints(ImmutableSet.of(
+ new FilteredConnectPoint(d1p10)
+ ))
+ .filteredEgressPoints(ImmutableSet.of(
+ new FilteredConnectPoint(d1p11),
+ new FilteredConnectPoint(d2p10),
+ new FilteredConnectPoint(d3p10)
+ ))
+ .build();
+
+ sut.activate();
+
+ /*
+ * We use the FIRST_FIT to simplify tests.
+ */
+ LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
+
+ List<Intent> compiled = sut.compile(intent, Collections.emptyList());
+ assertThat(compiled, hasSize(1));
+
+ Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
+ assertThat(rules, hasSize(3));
+
+ Collection<FlowRule> rulesS1 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS1, hasSize(1));
+
+ FlowRule ruleS1 = rulesS1.iterator().next();
+ assertThat(ruleS1.selector(), is(
+ DefaultTrafficSelector
+ .builder(selector)
+ .matchInPort(d1p10.port())
+ .build()
+ ));
+ assertThat(ruleS1.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .pushVlan()
+ .setVlanId(VlanId.vlanId(LABEL))
+ .setOutput(d1p0.port())
+ .popVlan()
+ .setOutput(d1p11.port())
+ .build()
+ ));
+
+ Collection<FlowRule> rulesS2 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS2, hasSize(1));
+
+ FlowRule ruleS2 = rulesS2.iterator().next();
+ assertThat(ruleS2.selector(), is(
+ DefaultTrafficSelector
+ .builder()
+ .matchInPort(d2p0.port())
+ .matchVlanId(VlanId.vlanId(LABEL))
+ .build()
+ ));
+ assertThat(ruleS2.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .setVlanId(VlanId.vlanId(LABEL))
+ .setOutput(d2p1.port())
+ .popVlan()
+ .setOutput(d2p10.port())
+ .build()
+ ));
+
+ Collection<FlowRule> rulesS3 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d3p1.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS3, hasSize(1));
+
+ FlowRule ruleS3 = rulesS3.iterator().next();
+ assertThat(ruleS3.selector(), is(
+ DefaultTrafficSelector
+ .builder()
+ .matchInPort(d3p0.port())
+ .matchVlanId(VlanId.vlanId(LABEL))
+ .build()
+ ));
+ assertThat(ruleS3.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .popVlan()
+ .setOutput(d3p10.port())
+ .build()
+ ));
+
+ sut.deactivate();
+
+ }
+
+ /**
+ * We test the proper optimization of sp2mp with trivial selector,
+ * trivial treatment, mpls encapsulation and co-located
+ * filtered ingress/egress points.
+ */
+ @Test
+ public void testCoLocatedFilteredPointsTrivialForSp() {
+
+ intent = LinkCollectionIntent.builder()
+ .appId(APP_ID)
+ .selector(selector)
+ .treatment(treatment)
+ .applyTreatmentOnEgress(true)
+ .links(linksForSp2MpCoLoc)
+ .constraints(constraintsForMPLS)
+ .filteredIngressPoints(ImmutableSet.of(
+ new FilteredConnectPoint(d1p10, vlan100Selector)
+ ))
+ .filteredEgressPoints(ImmutableSet.of(
+ new FilteredConnectPoint(d1p11, vlan200Selector),
+ new FilteredConnectPoint(d2p10, vlan300Selector),
+ new FilteredConnectPoint(d3p10, vlan69Selector)
+ ))
+ .build();
+
+ sut.activate();
+
+ /*
+ * We use the FIRST_FIT to simplify tests.
+ */
+ LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
+
+ List<Intent> compiled = sut.compile(intent, Collections.emptyList());
+ assertThat(compiled, hasSize(1));
+
+ Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
+ assertThat(rules, hasSize(3));
+
+ Collection<FlowRule> rulesS1 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS1, hasSize(1));
+
+ FlowRule ruleS1 = rulesS1.iterator().next();
+ assertThat(ruleS1.selector(), is(
+ DefaultTrafficSelector
+ .builder(vlan100Selector)
+ .matchInPort(d1p10.port())
+ .build()
+ ));
+ assertThat(ruleS1.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .popVlan()
+ .pushMpls()
+ .copyTtlOut()
+ .setMpls(MplsLabel.mplsLabel(LABEL))
+ .setOutput(d1p0.port())
+ .copyTtlIn()
+ .popMpls(IPV4.ethType())
+ .pushVlan()
+ .setVlanId(((VlanIdCriterion) vlan200Selector.getCriterion(VLAN_VID)).vlanId())
+ .setOutput(d1p11.port())
+ .build()
+ ));
+
+
+ Collection<FlowRule> rulesS2 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS2, hasSize(1));
+
+ FlowRule ruleS2 = rulesS2.iterator().next();
+ assertThat(ruleS2.selector(), is(
+ DefaultTrafficSelector
+ .builder()
+ .matchInPort(d2p0.port())
+ .matchEthType(Ethernet.MPLS_UNICAST)
+ .matchMplsLabel(MplsLabel.mplsLabel(LABEL))
+ .build()
+ ));
+ assertThat(ruleS2.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .setMpls(MplsLabel.mplsLabel(LABEL))
+ .setOutput(d2p1.port())
+ .copyTtlIn()
+ .popMpls(IPV4.ethType())
+ .pushVlan()
+ .setVlanId(((VlanIdCriterion) vlan300Selector.getCriterion(VLAN_VID)).vlanId())
+ .setOutput(d2p10.port())
+ .build()
+ ));
+
+
+ Collection<FlowRule> rulesS3 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d3p1.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS3, hasSize(1));
+
+ FlowRule ruleS3 = rulesS3.iterator().next();
+ assertThat(ruleS3.selector(), is(
+ DefaultTrafficSelector
+ .builder()
+ .matchInPort(d3p0.port())
+ .matchEthType(Ethernet.MPLS_UNICAST)
+ .matchMplsLabel(MplsLabel.mplsLabel(LABEL))
+ .build()
+ ));
+ assertThat(ruleS3.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .copyTtlIn()
+ .popMpls(IPV4.ethType())
+ .pushVlan()
+ .setVlanId(((VlanIdCriterion) vlan69Selector.getCriterion(VLAN_VID)).vlanId())
+ .setOutput(d3p10.port())
+ .build()
+ ));
+
+ sut.deactivate();
+
+ }
+
+ /**
+ * We test the proper optimization of sp2mp with trivial selector,
+ * trivial treatment, vlan encapsulation and co-located
+ * different filtered ingress/egress points.
+ */
+ @Test
+ public void testCoLocatedDifferentFilteredPointsTrivialForSp() {
+
+ intent = LinkCollectionIntent.builder()
+ .appId(APP_ID)
+ .selector(selector)
+ .treatment(treatment)
+ .applyTreatmentOnEgress(true)
+ .links(linksForSp2MpCoLoc)
+ .constraints(constraintsForVlan)
+ .filteredIngressPoints(ImmutableSet.of(
+ new FilteredConnectPoint(d1p10, vlan100Selector)
+ ))
+ .filteredEgressPoints(ImmutableSet.of(
+ new FilteredConnectPoint(d1p11, mpls100Selector),
+ new FilteredConnectPoint(d2p10, vlan200Selector),
+ new FilteredConnectPoint(d3p10, mpls200Selector)
+ ))
+ .build();
+
+ sut.activate();
+
+ /*
+ * We use the FIRST_FIT to simplify tests.
+ */
+ LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
+
+ List<Intent> compiled = sut.compile(intent, Collections.emptyList());
+ assertThat(compiled, hasSize(1));
+
+ Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
+ assertThat(rules, hasSize(3));
+
+ Collection<FlowRule> rulesS1 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS1, hasSize(1));
+
+ FlowRule ruleS1 = rulesS1.iterator().next();
+ assertThat(ruleS1.selector(), is(
+ DefaultTrafficSelector
+ .builder(vlan100Selector)
+ .matchInPort(d1p10.port())
+ .build()
+ ));
+ assertThat(ruleS1.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .setVlanId(VlanId.vlanId(LABEL))
+ .setOutput(d1p0.port())
+ .popVlan()
+ .pushMpls()
+ .copyTtlOut()
+ .setMpls(((MplsCriterion) mpls100Selector.getCriterion(MPLS_LABEL)).label())
+ .setOutput(d1p11.port())
+ .build()
+ ));
+
+
+ Collection<FlowRule> rulesS2 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS2, hasSize(1));
+
+ FlowRule ruleS2 = rulesS2.iterator().next();
+ assertThat(ruleS2.selector(), is(
+ DefaultTrafficSelector
+ .builder()
+ .matchInPort(d2p0.port())
+ .matchVlanId(VlanId.vlanId(LABEL))
+ .build()
+ ));
+ assertThat(ruleS2.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .setVlanId(VlanId.vlanId(LABEL))
+ .setOutput(d2p1.port())
+ .setVlanId(((VlanIdCriterion) vlan200Selector.getCriterion(VLAN_VID)).vlanId())
+ .setOutput(d2p10.port())
+ .build()
+ ));
+
+
+ Collection<FlowRule> rulesS3 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d3p1.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS3, hasSize(1));
+
+ FlowRule ruleS3 = rulesS3.iterator().next();
+ assertThat(ruleS3.selector(), is(
+ DefaultTrafficSelector
+ .builder()
+ .matchVlanId(VlanId.vlanId(LABEL))
+ .matchInPort(d3p0.port())
+ .build()
+ ));
+ assertThat(ruleS3.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .popVlan()
+ .pushMpls()
+ .copyTtlOut()
+ .setMpls(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
+ .setOutput(d3p10.port())
+ .build()
+ ));
+
+ sut.deactivate();
+
+ }
+
+ /**
+ * We test the proper optimization of sp2mp with selector,
+ * treatment, mpls encapsulation and co-located
+ * different filtered ingress/egress points.
+ */
+ @Test
+ public void testCoLocatedDifferentFilteredPointsNonTrivialForSp() {
+
+ intent = LinkCollectionIntent.builder()
+ .appId(APP_ID)
+ .selector(ipPrefixSelector)
+ .treatment(ethDstTreatment)
+ .applyTreatmentOnEgress(true)
+ .links(linksForSp2MpCoLoc)
+ .constraints(constraintsForMPLS)
+ .filteredIngressPoints(ImmutableSet.of(
+ new FilteredConnectPoint(d1p10, vlan100Selector)
+ ))
+ .filteredEgressPoints(ImmutableSet.of(
+ new FilteredConnectPoint(d1p11, mpls100Selector),
+ new FilteredConnectPoint(d2p10, vlan200Selector),
+ new FilteredConnectPoint(d3p10, mpls200Selector)
+ ))
+ .build();
+
+ sut.activate();
+
+ /*
+ * We use the FIRST_FIT to simplify tests.
+ */
+ LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
+
+ List<Intent> compiled = sut.compile(intent, Collections.emptyList());
+ assertThat(compiled, hasSize(1));
+
+ Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
+ assertThat(rules, hasSize(3));
+
+ Collection<FlowRule> rulesS1 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS1, hasSize(1));
+
+ FlowRule ruleS1 = rulesS1.iterator().next();
+ assertThat(ruleS1.selector(), is(
+ DefaultTrafficSelector
+ .builder(ipPrefixSelector)
+ .matchInPort(d1p10.port())
+ .matchVlanId(((VlanIdCriterion) vlan100Selector.getCriterion(VLAN_VID)).vlanId())
+ .build()
+ ));
+ assertThat(ruleS1.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .popVlan()
+ .pushMpls()
+ .copyTtlOut()
+ .setMpls(MplsLabel.mplsLabel(LABEL))
+ .setOutput(d1p0.port())
+ .setEthDst(((ModEtherInstruction) ethDstTreatment
+ .allInstructions()
+ .stream()
+ .filter(instruction -> instruction instanceof ModEtherInstruction)
+ .findFirst().get()).mac())
+ .setMpls(((MplsCriterion) mpls100Selector.getCriterion(MPLS_LABEL)).label())
+ .setOutput(d1p11.port())
+ .build()
+ ));
+
+
+ Collection<FlowRule> rulesS2 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS2, hasSize(1));
+
+ FlowRule ruleS2 = rulesS2.iterator().next();
+ assertThat(ruleS2.selector(), is(
+ DefaultTrafficSelector
+ .builder()
+ .matchInPort(d2p0.port())
+ .matchEthType(Ethernet.MPLS_UNICAST)
+ .matchMplsLabel(MplsLabel.mplsLabel(LABEL))
+ .build()
+ ));
+ assertThat(ruleS2.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .setMpls(MplsLabel.mplsLabel(LABEL))
+ .setOutput(d2p1.port())
+ .setEthDst(((ModEtherInstruction) ethDstTreatment
+ .allInstructions()
+ .stream()
+ .filter(instruction -> instruction instanceof ModEtherInstruction)
+ .findFirst().get()).mac())
+ .copyTtlIn()
+ .popMpls(IPV4.ethType())
+ .pushVlan()
+ .setVlanId(((VlanIdCriterion) vlan200Selector.getCriterion(VLAN_VID)).vlanId())
+ .setOutput(d2p10.port())
+ .build()
+ ));
+
+
+ Collection<FlowRule> rulesS3 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d3p1.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS3, hasSize(1));
+
+ FlowRule ruleS3 = rulesS3.iterator().next();
+ assertThat(ruleS3.selector(), is(
+ DefaultTrafficSelector
+ .builder()
+ .matchEthType(Ethernet.MPLS_UNICAST)
+ .matchMplsLabel(MplsLabel.mplsLabel(LABEL))
+ .matchInPort(d3p0.port())
+ .build()
+ ));
+ assertThat(ruleS3.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .setEthDst(((ModEtherInstruction) ethDstTreatment
+ .allInstructions()
+ .stream()
+ .filter(instruction -> instruction instanceof ModEtherInstruction)
+ .findFirst().get()).mac())
+ .setMpls(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
+ .setOutput(d3p10.port())
+ .build()
+ ));
+
+ sut.deactivate();
+
+ }
+
}