[ONOS-5239] Adds encapsulation to LinkCollectionIntent
Changes:
- Adds encapsulation to LinkCollectionIntent;
- Cleans the code and adds comments;
- fixes ethertype issue for mplsPop
- Adds unit tests;
Change-Id: I4398426e73c5a9dd085689cb56162bd2c3b8f5af
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
new file mode 100644
index 0000000..9a8324c
--- /dev/null
+++ b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/AbstractLinkCollectionTest.java
@@ -0,0 +1,132 @@
+/*
+ * 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.onosproject.TestApplicationId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.core.IdGenerator;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.intent.Constraint;
+import org.onosproject.net.intent.IntentExtensionService;
+import org.onosproject.net.intent.LinkCollectionIntent;
+import org.onosproject.net.intent.MockIdGenerator;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static org.onosproject.net.NetTestTools.*;
+import static org.onosproject.net.NetTestTools.macDstTreatment;
+
+/**
+ * Abstract class to hold the common variables and pieces
+ * of code.
+ */
+class AbstractLinkCollectionTest {
+
+ static final String LABEL_SELECTION = "FIRST_FIT";
+ static final String LABEL = "1";
+
+ final ApplicationId appId = new TestApplicationId("test");
+
+ final ConnectPoint d2p0 = connectPoint("s2", 0);
+ final ConnectPoint d2p1 = connectPoint("s2", 1);
+ ConnectPoint d2p10 = connectPoint("s2", 10);
+
+ final ConnectPoint d3p0 = connectPoint("s3", 0);
+ final ConnectPoint d3p1 = connectPoint("s3", 1);
+ final ConnectPoint d3p10 = connectPoint("s3", 10);
+
+ final DeviceId of1Id = DeviceId.deviceId("of:of1");
+ final DeviceId of2Id = DeviceId.deviceId("of:of2");
+ final DeviceId of3Id = DeviceId.deviceId("of:of3");
+ final DeviceId of4Id = DeviceId.deviceId("of:of4");
+
+ final ConnectPoint of1p1 = connectPoint("of1", 1);
+ final ConnectPoint of1p2 = connectPoint("of1", 2);
+ final ConnectPoint of2p1 = connectPoint("of2", 1);
+ final ConnectPoint of2p2 = connectPoint("of2", 2);
+ final ConnectPoint of2p3 = connectPoint("of2", 3);
+ final ConnectPoint of3p1 = connectPoint("of3", 1);
+ final ConnectPoint of3p2 = connectPoint("of3", 2);
+ final ConnectPoint of4p1 = connectPoint("of4", 1);
+ final ConnectPoint of4p2 = connectPoint("of4", 2);
+
+ final ConnectPoint d1p0 = connectPoint("s1", 0);
+ final ConnectPoint d1p1 = connectPoint("s1", 1);
+ final ConnectPoint d1p10 = connectPoint("s1", 10);
+ final ConnectPoint d1p11 = connectPoint("s1", 11);
+
+ final Set<Link> links = ImmutableSet.of(
+ link(d1p1, d2p0),
+ link(d2p1, d3p1),
+ link(d1p1, d3p1)
+ );
+
+ final Set<Link> linksForMp2Sp = ImmutableSet.of(
+ link(d1p0, d2p0),
+ link(d2p1, d3p0)
+ );
+
+
+
+ final Set<Link> linksForSp2Mp = ImmutableSet.of(
+ link(d3p0, d2p1),
+ link(d2p0, d1p0)
+ );
+
+ final TrafficTreatment treatment = emptyTreatment();
+
+ final TrafficSelector selector = emptySelector();
+ final TrafficSelector vlan69Selector = vlanSelector("69");
+ final TrafficSelector vlan100Selector = vlanSelector("100");
+ final TrafficSelector vlan200Selector = vlanSelector("200");
+ final TrafficSelector vlan300Selector = vlanSelector("300");
+ final TrafficSelector mpls69Selector = mplsSelector("69");
+ final TrafficSelector mpls80Selector = mplsSelector("80");
+ final TrafficSelector mpls100Selector = mplsSelector("100");
+ final TrafficSelector mpls200Selector = mplsSelector("200");
+ final TrafficSelector ipPrefixSelector = ipPrefixDstSelector("192.168.100.0/24");
+ final TrafficTreatment ethDstTreatment = macDstTreatment("C0:FF:EE:C0:FF:EE");
+
+ final List<Constraint> constraintsForVlan = vlanConstraint();
+ final List<Constraint> constraintsForMPLS = mplsConstraint();
+
+ CoreService coreService;
+ IntentExtensionService intentExtensionService;
+ IntentConfigurableRegistrator registrator;
+ IdGenerator idGenerator = new MockIdGenerator();
+
+ LinkCollectionIntent intent;
+
+ LinkCollectionIntentCompiler sut;
+
+ List<FlowRule> getFlowRulesByDevice(DeviceId deviceId, Collection<FlowRule> flowRules) {
+ return flowRules.stream()
+ .filter(fr -> fr.deviceId().equals(deviceId))
+ .collect(Collectors.toList());
+ }
+
+}
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
new file mode 100644
index 0000000..588880a
--- /dev/null
+++ b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/LinkCollectionEncapIntentCompilerTest.java
@@ -0,0 +1,1354 @@
+/*
+ * 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.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.PortCriterion;
+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.onlab.packet.EthType.EtherType.IPV4;
+import static org.onosproject.net.NetTestTools.*;
+import static org.onosproject.net.flow.criteria.Criterion.Type.*;
+import static org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
+
+/**
+ * This set of tests are meant to test the encapsulation
+ * in the LinkCollectionIntent.
+ */
+public class LinkCollectionEncapIntentCompilerTest 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();
+
+ replay(coreService, intentExtensionService);
+ }
+
+ @After
+ public void tearDown() {
+ Intent.unbindIdGenerator(idGenerator);
+ }
+
+ /**
+ * We test the proper compilation of mp2Sp1 with the VLAN
+ * encapsulation, trivial selector.
+ */
+ @Test
+ public void testVlanEncapsulationForMp() {
+
+ intent = LinkCollectionIntent.builder()
+ .appId(APP_ID)
+ .selector(selector)
+ .treatment(treatment)
+ .constraints(constraintsForVlan)
+ .links(linksForMp2Sp)
+ .filteredIngressPoints(ImmutableSet.of(
+ new FilteredConnectPoint(d1p10),
+ new FilteredConnectPoint(d1p11),
+ new FilteredConnectPoint(d2p10)
+ ))
+ .filteredEgressPoints(ImmutableSet.of(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(5));
+
+ 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(intent.selector())
+ .matchInPort(d1p10.port())
+ .build()
+ ));
+ assertThat(ruleS1.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .pushVlan()
+ .setVlanId(VlanId.vlanId(LABEL))
+ .setOutput(d1p0.port())
+ .build()
+ ));
+
+ ruleS1 = rulesS1.stream()
+ .filter(rule -> {
+ PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+ return inPort.port().equals(d1p11.port());
+ })
+ .findFirst()
+ .get();
+ assertThat(ruleS1.selector(), is(
+ DefaultTrafficSelector
+ .builder(intent.selector())
+ .matchInPort(d1p11.port())
+ .build()
+ ));
+ assertThat(ruleS1.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .pushVlan()
+ .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(2));
+ FlowRule ruleS2 = rulesS2.stream()
+ .filter(rule -> {
+ PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+ return inPort.port().equals(d2p10.port());
+ })
+ .findFirst()
+ .get();
+ assertThat(ruleS2.selector(), is(
+ DefaultTrafficSelector
+ .builder(intent.selector())
+ .matchInPort(d2p10.port())
+ .build()
+ ));
+ assertThat(ruleS2.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .pushVlan()
+ .setVlanId(VlanId.vlanId(LABEL))
+ .setOutput(d2p1.port())
+ .build()
+ ));
+
+ ruleS2 = rulesS2.stream()
+ .filter(rule -> {
+ PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+ return inPort.port().equals(d2p0.port());
+ })
+ .findFirst()
+ .get();
+ 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()
+ .setOutput(d3p10.port())
+ .build()
+ ));
+
+ sut.deactivate();
+ }
+
+ /**
+ * We test the proper compilation of sp2mp with the MPLS
+ * encapsulation and trivial selector.
+ */
+ @Test
+ public void testMplsEncapsulationForSp() {
+
+ intent = LinkCollectionIntent.builder()
+ .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();
+
+ 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> 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(d3p10.port())
+ .build()
+ ));
+ assertThat(ruleS3.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .pushMpls()
+ .setMpls(MplsLabel.mplsLabel((LABEL)))
+ .setOutput(d3p0.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(d2p1.port())
+ .matchMplsLabel(MplsLabel.mplsLabel((LABEL)))
+ .matchEthType(Ethernet.MPLS_UNICAST)
+ .build()
+ ));
+ assertThat(ruleS2.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .setMpls(MplsLabel.mplsLabel(LABEL))
+ .setOutput(d2p0.port())
+ .popMpls(IPV4.ethType())
+ .setOutput(d2p10.port())
+ .build()
+ ));
+
+ 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()
+ .matchInPort(d1p0.port())
+ .matchMplsLabel(MplsLabel.mplsLabel((LABEL)))
+ .matchEthType(Ethernet.MPLS_UNICAST)
+ .build()
+ ));
+ assertThat(ruleS1.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .popMpls(IPV4.ethType())
+ .setOutput(d1p10.port())
+ .popMpls(IPV4.ethType())
+ .setOutput(d1p11.port())
+ .build()
+ ));
+
+ sut.deactivate();
+
+ }
+
+ /**
+ * We test the proper compilation of mp2sp with the MPLS
+ * encapsulation and filtered selector.
+ */
+ @Test
+ public void testMplsEncapsulationFilteredForMp() {
+
+ intent = LinkCollectionIntent.builder()
+ .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();
+
+ 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(5));
+
+ 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(vlan100Selector)
+ .matchInPort(d1p10.port())
+ .build()
+ ));
+ assertThat(ruleS1.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .popVlan()
+ .pushMpls()
+ .setMpls(MplsLabel.mplsLabel(LABEL))
+ .setOutput(d1p0.port())
+ .build()
+ ));
+
+ ruleS1 = rulesS1.stream()
+ .filter(rule -> {
+ PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+ return inPort.port().equals(d1p11.port());
+ })
+ .findFirst()
+ .get();
+ assertThat(ruleS1.selector(), is(
+ DefaultTrafficSelector
+ .builder(vlan200Selector)
+ .matchInPort(d1p11.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(2));
+ FlowRule ruleS2 = rulesS2.stream()
+ .filter(rule -> {
+ PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+ return inPort.port().equals(d2p10.port());
+ })
+ .findFirst()
+ .get();
+ assertThat(ruleS2.selector(), is(
+ DefaultTrafficSelector
+ .builder(vlan300Selector)
+ .matchInPort(d2p10.port())
+ .build()
+ ));
+ assertThat(ruleS2.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .popVlan()
+ .pushMpls()
+ .setMpls(MplsLabel.mplsLabel(LABEL))
+ .setOutput(d2p1.port())
+ .build()
+ ));
+
+ ruleS2 = rulesS2.stream()
+ .filter(rule -> {
+ PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+ return inPort.port().equals(d2p0.port());
+ })
+ .findFirst()
+ .get();
+ 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()
+ .popMpls(IPV4.ethType())
+ .pushVlan()
+ .setVlanId(((VlanIdCriterion) vlan69Selector.getCriterion(VLAN_VID)).vlanId())
+ .setOutput(d3p10.port())
+ .build()
+ ));
+
+ sut.deactivate();
+
+ }
+
+ /**
+ * We test the proper compilation of sp2mp with the VLAN
+ * encapsulation and filtered selector.
+ */
+ @Test
+ public void testVlanEncapsulationFilteredForSp() {
+
+ intent = LinkCollectionIntent.builder()
+ .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();
+
+ 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> 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(mpls69Selector)
+ .matchInPort(d3p10.port())
+ .build()
+ ));
+ assertThat(ruleS3.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .popMpls(IPV4.ethType())
+ .pushVlan()
+ .setVlanId(VlanId.vlanId(LABEL))
+ .setOutput(d3p0.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(d2p1.port())
+ .matchVlanId(VlanId.vlanId(LABEL))
+ .build()
+ ));
+ assertThat(ruleS2.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .setVlanId(VlanId.vlanId(LABEL))
+ .setOutput(d2p0.port())
+ .popVlan()
+ .pushMpls()
+ .setMpls(((MplsCriterion) mpls80Selector.getCriterion(MPLS_LABEL)).label())
+ .setOutput(d2p10.port())
+ .build()
+ ));
+
+ 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()
+ .matchInPort(d1p0.port())
+ .matchVlanId(VlanId.vlanId(LABEL))
+ .build()
+ ));
+ assertThat(ruleS1.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .popVlan()
+ .pushMpls()
+ .setMpls(((MplsCriterion) mpls100Selector.getCriterion(MPLS_LABEL)).label())
+ .setOutput(d1p10.port())
+ .popVlan()
+ .pushMpls()
+ .setMpls(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
+ .setOutput(d1p11.port())
+ .build()
+ ));
+
+ sut.deactivate();
+
+ }
+
+ /**
+ * We test the proper compilation of mp2sp with the VLAN
+ * encapsulation, filtered selectors, intent selector and intent treatment.
+ */
+ @Test
+ public void testVlanEncapsulationNonTrivialForMp() {
+
+ intent = LinkCollectionIntent.builder()
+ .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();
+
+ 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(5));
+
+ 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) mpls80Selector.getCriterion(MPLS_LABEL)).label())
+ .build()
+ ));
+ assertThat(ruleS1.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .popMpls(IPV4.ethType())
+ .pushVlan()
+ .setVlanId(VlanId.vlanId(LABEL))
+ .setOutput(d1p0.port())
+ .build()
+ ));
+
+ ruleS1 = rulesS1.stream()
+ .filter(rule -> {
+ PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+ return inPort.port().equals(d1p11.port());
+ })
+ .findFirst()
+ .get();
+ assertThat(ruleS1.selector(), is(
+ DefaultTrafficSelector
+ .builder(ipPrefixSelector)
+ .matchInPort(d1p11.port())
+ .matchMplsLabel(((MplsCriterion) mpls100Selector.getCriterion(MPLS_LABEL)).label())
+ .build()
+ ));
+ assertThat(ruleS1.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .popMpls(IPV4.ethType())
+ .pushVlan()
+ .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(2));
+ FlowRule ruleS2 = rulesS2.stream()
+ .filter(rule -> {
+ PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+ return inPort.port().equals(d2p10.port());
+ })
+ .findFirst()
+ .get();
+ assertThat(ruleS2.selector(), is(
+ DefaultTrafficSelector
+ .builder(ipPrefixSelector)
+ .matchInPort(d2p10.port())
+ .matchMplsLabel(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
+ .build()
+ ));
+ assertThat(ruleS2.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .popMpls(IPV4.ethType())
+ .pushVlan()
+ .setVlanId(VlanId.vlanId(LABEL))
+ .setOutput(d2p1.port())
+ .build()
+ ));
+
+ ruleS2 = rulesS2.stream()
+ .filter(rule -> {
+ PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+ return inPort.port().equals(d2p0.port());
+ })
+ .findFirst()
+ .get();
+ 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(ethDstTreatment)
+ .popVlan()
+ .pushMpls()
+ .setMpls(((MplsCriterion) mpls69Selector.getCriterion(MPLS_LABEL)).label())
+ .setOutput(d3p10.port())
+ .build()
+ ));
+
+ sut.deactivate();
+
+ }
+
+ /**
+ * We test the proper compilation of sp2mp with the MPLS
+ * encapsulation, filtered selector, intent selector, and
+ * intent treatment.
+ */
+ @Test
+ public void testMplsEncapsulationNonTrivialForSp() {
+
+ intent = LinkCollectionIntent.builder()
+ .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();
+
+ 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> 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(ipPrefixSelector)
+ .matchInPort(d3p10.port())
+ .matchVlanId(((VlanIdCriterion) vlan69Selector.getCriterion(VLAN_VID)).vlanId())
+ .build()
+ ));
+ assertThat(ruleS3.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .popVlan()
+ .pushMpls()
+ .setMpls(MplsLabel.mplsLabel(LABEL))
+ .setOutput(d3p0.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(d2p1.port())
+ .matchMplsLabel(MplsLabel.mplsLabel(LABEL))
+ .matchEthType(Ethernet.MPLS_UNICAST)
+ .build()
+ ));
+ assertThat(ruleS2.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .setMpls(MplsLabel.mplsLabel(LABEL))
+ .setOutput(d2p0.port())
+ .setEthDst(((ModEtherInstruction) ethDstTreatment
+ .allInstructions()
+ .stream()
+ .filter(instruction -> instruction instanceof ModEtherInstruction)
+ .findFirst().get()).mac())
+ .popMpls(IPV4.ethType())
+ .pushVlan()
+ .setVlanId(((VlanIdCriterion) vlan300Selector.getCriterion(VLAN_VID)).vlanId())
+ .setOutput(d2p10.port())
+ .build()
+ ));
+
+ 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()
+ .matchInPort(d1p0.port())
+ .matchMplsLabel(MplsLabel.mplsLabel(LABEL))
+ .matchEthType(Ethernet.MPLS_UNICAST)
+ .build()
+ ));
+ assertThat(ruleS1.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .setEthDst(((ModEtherInstruction) ethDstTreatment
+ .allInstructions()
+ .stream()
+ .filter(instruction -> instruction instanceof ModEtherInstruction)
+ .findFirst().get()).mac())
+ .popMpls(IPV4.ethType())
+ .pushVlan()
+ .setVlanId(((VlanIdCriterion) vlan100Selector.getCriterion(VLAN_VID)).vlanId())
+ .setOutput(d1p10.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(d1p11.port())
+ .build()
+ ));
+
+ sut.deactivate();
+
+ }
+
+ /**
+ * We test the proper compilation of mp2sp with the MPLS
+ * encapsulation and filtered selectors of different type.
+ */
+ @Test
+ public void testMplsEncapsulationDifferentFilterForMp() {
+
+ intent = LinkCollectionIntent.builder()
+ .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();
+
+ 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(5));
+
+ 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(vlan100Selector)
+ .matchInPort(d1p10.port())
+ .build()
+ ));
+ assertThat(ruleS1.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .popVlan()
+ .pushMpls()
+ .setMpls(MplsLabel.mplsLabel(LABEL))
+ .setOutput(d1p0.port())
+ .build()
+ ));
+
+ ruleS1 = rulesS1.stream()
+ .filter(rule -> {
+ PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+ return inPort.port().equals(d1p11.port());
+ })
+ .findFirst()
+ .get();
+ assertThat(ruleS1.selector(), is(
+ DefaultTrafficSelector
+ .builder(mpls200Selector)
+ .matchInPort(d1p11.port())
+ .build()
+ ));
+ assertThat(ruleS1.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .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(2));
+ FlowRule ruleS2 = rulesS2.stream()
+ .filter(rule -> {
+ PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+ return inPort.port().equals(d2p10.port());
+ })
+ .findFirst()
+ .get();
+ assertThat(ruleS2.selector(), is(
+ DefaultTrafficSelector
+ .builder(vlan200Selector)
+ .matchInPort(d2p10.port())
+ .build()
+ ));
+ assertThat(ruleS2.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .popVlan()
+ .pushMpls()
+ .setMpls(MplsLabel.mplsLabel(LABEL))
+ .setOutput(d2p1.port())
+ .build()
+ ));
+
+ ruleS2 = rulesS2.stream()
+ .filter(rule -> {
+ PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+ return inPort.port().equals(d2p0.port());
+ })
+ .findFirst()
+ .get();
+ 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) mpls100Selector.getCriterion(MPLS_LABEL)).label())
+ .setOutput(d3p10.port())
+ .build()
+ ));
+
+ sut.deactivate();
+
+ }
+
+ /**
+ * We test the proper compilation of sp2mp with the VLAN
+ * encapsulation and filtered selectors of different type.
+ */
+ @Test
+ public void testVlanEncapsulationDifferentFilter() {
+
+ intent = LinkCollectionIntent.builder()
+ .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();
+
+ 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> 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(vlan200Selector)
+ .matchInPort(d3p10.port())
+ .build()
+ ));
+ assertThat(ruleS3.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .setVlanId(VlanId.vlanId(LABEL))
+ .setOutput(d3p0.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(d2p1.port())
+ .matchVlanId(VlanId.vlanId(LABEL))
+ .build()
+ ));
+ assertThat(ruleS2.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .setVlanId(VlanId.vlanId(LABEL))
+ .setOutput(d2p0.port())
+ .popVlan()
+ .pushMpls()
+ .setMpls(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
+ .setOutput(d2p10.port())
+ .build()
+ ));
+
+ 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()
+ .matchInPort(d1p0.port())
+ .matchVlanId(VlanId.vlanId(LABEL))
+ .build()
+ ));
+ assertThat(ruleS1.treatment(), is(
+ DefaultTrafficTreatment
+ .builder()
+ .popVlan()
+ .pushMpls()
+ .setMpls(((MplsCriterion) mpls100Selector.getCriterion(MPLS_LABEL)).label())
+ .setOutput(d1p10.port())
+ .setVlanId(((VlanIdCriterion) vlan100Selector.getCriterion(VLAN_VID)).vlanId())
+ .setOutput(d1p11.port())
+ .build()
+ ));
+
+ sut.deactivate();
+
+ }
+
+ /**
+ * We test the proper compilation of p2p with the VLAN
+ * encapsulation and 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 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();
+
+ }
+
+}
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 e3b662a..87103aa 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
@@ -16,20 +16,16 @@
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.IpPrefix;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
-import org.onosproject.TestApplicationId;
import org.onosproject.cfg.ComponentConfigAdapter;
-import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
-import org.onosproject.core.IdGenerator;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultLink;
-import org.onosproject.net.DeviceId;
import org.onosproject.net.FilteredConnectPoint;
import org.onosproject.net.Link;
import org.onosproject.net.PortNumber;
@@ -38,11 +34,13 @@
import org.onosproject.net.flow.FlowRule;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.MplsCriterion;
+import org.onosproject.net.flow.criteria.PortCriterion;
+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.intent.MockIdGenerator;
import java.util.Collection;
import java.util.Collections;
@@ -58,75 +56,15 @@
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
+import static org.onlab.packet.EthType.EtherType.IPV4;
import static org.onosproject.net.Link.Type.DIRECT;
import static org.onosproject.net.NetTestTools.*;
+import static org.onosproject.net.flow.criteria.Criterion.Type.IN_PORT;
+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.*;
-public class LinkCollectionIntentCompilerTest {
-
- private final ApplicationId appId = new TestApplicationId("test");
-
- private final ConnectPoint d1p1 = connectPoint("s1", 1);
- private final ConnectPoint d2p0 = connectPoint("s2", 0);
- private final ConnectPoint d2p1 = connectPoint("s2", 1);
- private final ConnectPoint d3p1 = connectPoint("s3", 1);
- private final ConnectPoint d3p0 = connectPoint("s3", 10);
- private final ConnectPoint d1p0 = connectPoint("s1", 10);
-
- private final DeviceId of1Id = DeviceId.deviceId("of:of1");
- private final DeviceId of2Id = DeviceId.deviceId("of:of2");
- private final DeviceId of3Id = DeviceId.deviceId("of:of3");
- private final DeviceId of4Id = DeviceId.deviceId("of:of4");
-
- private final ConnectPoint of1p1 = connectPoint("of1", 1);
- private final ConnectPoint of1p2 = connectPoint("of1", 2);
- private final ConnectPoint of2p1 = connectPoint("of2", 1);
- private final ConnectPoint of2p2 = connectPoint("of2", 2);
- private final ConnectPoint of2p3 = connectPoint("of2", 3);
- private final ConnectPoint of3p1 = connectPoint("of3", 1);
- private final ConnectPoint of3p2 = connectPoint("of3", 2);
- private final ConnectPoint of4p1 = connectPoint("of4", 1);
- private final ConnectPoint of4p2 = connectPoint("of4", 2);
-
- private final Set<Link> links = ImmutableSet.of(
- DefaultLink.builder().providerId(PID).src(d1p1).dst(d2p0).type(DIRECT).build(),
- DefaultLink.builder().providerId(PID).src(d2p1).dst(d3p1).type(DIRECT).build(),
- DefaultLink.builder().providerId(PID).src(d1p1).dst(d3p1).type(DIRECT).build());
-
- private final TrafficSelector selector = DefaultTrafficSelector.builder().build();
- private final TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
-
- private final TrafficSelector vlan100Selector = DefaultTrafficSelector.builder()
- .matchVlanId(VlanId.vlanId("100"))
- .build();
-
- private final TrafficSelector vlan200Selector = DefaultTrafficSelector.builder()
- .matchVlanId(VlanId.vlanId("200"))
- .build();
-
- private final TrafficSelector ipPrefixSelector = DefaultTrafficSelector.builder()
- .matchIPDst(IpPrefix.valueOf("192.168.100.0/24"))
- .build();
-
- private final TrafficTreatment ethDstTreatment = DefaultTrafficTreatment.builder()
- .setEthDst(MacAddress.valueOf("C0:FF:EE:C0:FF:EE"))
- .build();
-
- private CoreService coreService;
- private IntentExtensionService intentExtensionService;
- private IntentConfigurableRegistrator registrator;
- private IdGenerator idGenerator = new MockIdGenerator();
-
- private LinkCollectionIntent intent;
-
- private LinkCollectionIntentCompiler sut;
-
-
-
- private List<FlowRule> getFlowRulesByDevice(DeviceId deviceId, Collection<FlowRule> flowRules) {
- return flowRules.stream()
- .filter(fr -> fr.deviceId().equals(deviceId))
- .collect(Collectors.toList());
- }
+public class LinkCollectionIntentCompilerTest extends AbstractLinkCollectionTest {
@Before
public void setUp() {
@@ -181,7 +119,7 @@
// if not found, get() raises an exception
FlowRule rule1 = rules.stream()
- .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
+ .filter(rule -> rule.deviceId().equals(d1p10.deviceId()))
.findFirst()
.get();
assertThat(rule1.selector(), is(
@@ -226,7 +164,7 @@
* `-1 of4 2-
*/
@Test
- public void testFilteredConnectPoint1() {
+ public void testFilteredConnectPointForSp() {
sut.activate();
Set<Link> testLinks = ImmutableSet.of(
DefaultLink.builder().providerId(PID).src(of1p2).dst(of2p1).type(DIRECT).build(),
@@ -346,7 +284,7 @@
* -1 of3 2---/
*/
@Test
- public void testFilteredConnectPoint2() {
+ public void testFilteredConnectPointForMp() {
sut.activate();
Set<Link> testlinks = ImmutableSet.of(
DefaultLink.builder().providerId(PID).src(of1p2).dst(of2p1).type(DIRECT).build(),
@@ -467,7 +405,7 @@
* `-1 of4 2-
*/
@Test
- public void nonTrivialTranslation1() {
+ public void nonTrivialTranslationForSp() {
sut.activate();
Set<Link> testLinks = ImmutableSet.of(
DefaultLink.builder().providerId(PID).src(of1p2).dst(of2p1).type(DIRECT).build(),
@@ -587,7 +525,7 @@
* -1 of3 2---/
*/
@Test
- public void nonTrivialTranslation2() {
+ public void nonTrivialTranslationForMp() {
sut.activate();
Set<Link> testlinks = ImmutableSet.of(
DefaultLink.builder().providerId(PID).src(of1p2).dst(of2p1).type(DIRECT).build(),
@@ -701,4 +639,442 @@
sut.deactivate();
}
+
+ /**
+ * We test the proper compilation of mp2sp with
+ * trivial selector, trivial treatment and 1 hop.
+ */
+ @Test
+ public void singleHopTestForMp() {
+
+ intent = LinkCollectionIntent.builder()
+ .appId(APP_ID)
+ .selector(selector)
+ .treatment(treatment)
+ .links(ImmutableSet.of())
+ .filteredIngressPoints(ImmutableSet.of(
+ new FilteredConnectPoint(d1p10),
+ new FilteredConnectPoint(d1p11)
+ ))
+ .filteredEgressPoints(ImmutableSet.of(new FilteredConnectPoint(d1p0)))
+ .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(2));
+
+ 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.is(
+ DefaultTrafficSelector
+ .builder()
+ .matchInPort(d1p10.port())
+ .build()
+ ));
+ assertThat(ruleS1.treatment(), Is.is(
+ DefaultTrafficTreatment
+ .builder()
+ .setOutput(d1p0.port())
+ .build()
+ ));
+
+ ruleS1 = rulesS1.stream()
+ .filter(rule -> {
+ PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+ return inPort.port().equals(d1p11.port());
+ })
+ .findFirst()
+ .get();
+ assertThat(ruleS1.selector(), Is.is(
+ DefaultTrafficSelector
+ .builder()
+ .matchInPort(d1p11.port())
+ .build()
+ ));
+ assertThat(ruleS1.treatment(), Is.is(
+ DefaultTrafficTreatment
+ .builder()
+ .setOutput(d1p0.port())
+ .build()
+ ));
+
+ sut.deactivate();
+
+ }
+
+ /**
+ * We test the proper compilation of sp2mp with
+ * trivial selector, trivial treatment and 1 hop.
+ */
+ @Test
+ public void singleHopTestForSp() {
+
+ intent = LinkCollectionIntent.builder()
+ .appId(APP_ID)
+ .selector(selector)
+ .treatment(treatment)
+ .applyTreatmentOnEgress(true)
+ .links(ImmutableSet.of())
+ .filteredEgressPoints(ImmutableSet.of(
+ new FilteredConnectPoint(d1p10),
+ new FilteredConnectPoint(d1p11)
+ ))
+ .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d1p0)))
+ .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(1));
+
+ Collection<FlowRule> rulesS1 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS1, hasSize(1));
+ FlowRule 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.is(
+ DefaultTrafficSelector
+ .builder()
+ .matchInPort(d1p0.port())
+ .build()
+ ));
+ assertThat(ruleS1.treatment(), Is.is(
+ DefaultTrafficTreatment
+ .builder()
+ .setOutput(d1p10.port())
+ .setOutput(d1p11.port())
+ .build()
+ ));
+
+ sut.deactivate();
+
+ }
+
+ /**
+ * We test the proper compilation of mp2sp with
+ * trivial selector, trivial treatment, filtered
+ * points and 1 hop.
+ */
+ @Test
+ public void singleHopTestFilteredForMp() {
+
+ intent = LinkCollectionIntent.builder()
+ .appId(APP_ID)
+ .selector(selector)
+ .treatment(treatment)
+ .links(ImmutableSet.of())
+ .filteredIngressPoints(ImmutableSet.of(
+ new FilteredConnectPoint(d1p10, vlan100Selector),
+ new FilteredConnectPoint(d1p11, mpls69Selector)
+ ))
+ .filteredEgressPoints(ImmutableSet.of(new FilteredConnectPoint(d1p0, vlan200Selector)))
+ .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(2));
+
+ 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.is(
+ DefaultTrafficSelector
+ .builder(vlan100Selector)
+ .matchInPort(d1p10.port())
+ .build()
+ ));
+ assertThat(ruleS1.treatment(), Is.is(
+ DefaultTrafficTreatment
+ .builder()
+ .setVlanId(((VlanIdCriterion) vlan200Selector.getCriterion(VLAN_VID)).vlanId())
+ .setOutput(d1p0.port())
+ .build()
+ ));
+
+ ruleS1 = rulesS1.stream()
+ .filter(rule -> {
+ PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+ return inPort.port().equals(d1p11.port());
+ })
+ .findFirst()
+ .get();
+ assertThat(ruleS1.selector(), Is.is(
+ DefaultTrafficSelector
+ .builder(mpls69Selector)
+ .matchInPort(d1p11.port())
+ .build()
+ ));
+ assertThat(ruleS1.treatment(), Is.is(
+ DefaultTrafficTreatment
+ .builder()
+ .popMpls(IPV4.ethType())
+ .pushVlan()
+ .setVlanId(((VlanIdCriterion) vlan200Selector.getCriterion(VLAN_VID)).vlanId())
+ .setOutput(d1p0.port())
+ .build()
+ ));
+
+ sut.deactivate();
+
+ }
+
+ /**
+ * We test the proper compilation of sp2mp with
+ * trivial selector, trivial treatment and 1 hop.
+ */
+ @Test
+ public void singleHopTestFilteredForSp() {
+
+ intent = LinkCollectionIntent.builder()
+ .appId(APP_ID)
+ .selector(selector)
+ .treatment(treatment)
+ .applyTreatmentOnEgress(true)
+ .links(ImmutableSet.of())
+ .filteredEgressPoints(ImmutableSet.of(
+ new FilteredConnectPoint(d1p10, vlan100Selector),
+ new FilteredConnectPoint(d1p11, mpls80Selector)
+ ))
+ .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d1p0, vlan200Selector)))
+ .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(1));
+
+ Collection<FlowRule> rulesS1 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS1, hasSize(1));
+ FlowRule 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.is(
+ DefaultTrafficSelector
+ .builder(vlan200Selector)
+ .matchInPort(d1p0.port())
+ .build()
+ ));
+ assertThat(ruleS1.treatment(), Is.is(
+ DefaultTrafficTreatment
+ .builder()
+ .setVlanId(((VlanIdCriterion) vlan100Selector.getCriterion(VLAN_VID)).vlanId())
+ .setOutput(d1p10.port())
+ .popVlan()
+ .pushMpls()
+ .setMpls(((MplsCriterion) mpls80Selector.getCriterion(MPLS_LABEL)).label())
+ .setOutput(d1p11.port())
+ .build()
+ ));
+
+ sut.deactivate();
+
+ }
+
+ /**
+ * We test the proper compilation of mp2sp with
+ * selector, treatment, filtered
+ * points and 1 hop.
+ */
+ @Test
+ public void singleHopNonTrivialForMp() {
+
+ intent = LinkCollectionIntent.builder()
+ .appId(APP_ID)
+ .selector(ipPrefixSelector)
+ .treatment(ethDstTreatment)
+ .links(ImmutableSet.of())
+ .filteredIngressPoints(ImmutableSet.of(
+ new FilteredConnectPoint(d1p10, vlan100Selector),
+ new FilteredConnectPoint(d1p11, mpls100Selector)
+ ))
+ .filteredEgressPoints(ImmutableSet.of(new FilteredConnectPoint(d1p0, vlan200Selector)))
+ .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(2));
+
+ 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.is(
+ DefaultTrafficSelector
+ .builder(ipPrefixSelector)
+ .matchVlanId(((VlanIdCriterion) vlan100Selector.getCriterion(VLAN_VID)).vlanId())
+ .matchInPort(d1p10.port())
+ .build()
+ ));
+ assertThat(ruleS1.treatment(), Is.is(
+ DefaultTrafficTreatment
+ .builder()
+ .setEthDst(((ModEtherInstruction) ethDstTreatment
+ .allInstructions()
+ .stream()
+ .filter(instruction -> instruction instanceof ModEtherInstruction)
+ .findFirst().get()).mac())
+ .setVlanId(((VlanIdCriterion) vlan200Selector.getCriterion(VLAN_VID)).vlanId())
+ .setOutput(d1p0.port())
+ .build()
+ ));
+
+ ruleS1 = rulesS1.stream()
+ .filter(rule -> {
+ PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+ return inPort.port().equals(d1p11.port());
+ })
+ .findFirst()
+ .get();
+ assertThat(ruleS1.selector(), Is.is(
+ DefaultTrafficSelector
+ .builder(ipPrefixSelector)
+ .matchMplsLabel(((MplsCriterion) mpls100Selector.getCriterion(MPLS_LABEL)).label())
+ .matchInPort(d1p11.port())
+ .build()
+ ));
+ assertThat(ruleS1.treatment(), Is.is(
+ DefaultTrafficTreatment
+ .builder()
+ .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(d1p0.port())
+ .build()
+ ));
+
+ sut.deactivate();
+
+ }
+
+ /**
+ * We test the proper compilation of sp2mp with
+ * selector, treatment and 1 hop.
+ */
+ @Test
+ public void singleHopNonTrivialForSp() {
+
+ intent = LinkCollectionIntent.builder()
+ .appId(APP_ID)
+ .selector(ipPrefixSelector)
+ .treatment(ethDstTreatment)
+ .applyTreatmentOnEgress(true)
+ .links(ImmutableSet.of())
+ .filteredEgressPoints(ImmutableSet.of(
+ new FilteredConnectPoint(d1p10, vlan100Selector),
+ new FilteredConnectPoint(d1p11, mpls200Selector)
+ ))
+ .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d1p0, vlan200Selector)))
+ .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(1));
+
+ Collection<FlowRule> rulesS1 = rules.stream()
+ .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
+ .collect(Collectors.toSet());
+ assertThat(rulesS1, hasSize(1));
+ FlowRule 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.is(
+ DefaultTrafficSelector
+ .builder(ipPrefixSelector)
+ .matchVlanId(((VlanIdCriterion) vlan200Selector.getCriterion(VLAN_VID)).vlanId())
+ .matchInPort(d1p0.port())
+ .build()
+ ));
+ assertThat(ruleS1.treatment(), Is.is(
+ DefaultTrafficTreatment
+ .builder()
+ .setEthDst(((ModEtherInstruction) ethDstTreatment
+ .allInstructions()
+ .stream()
+ .filter(instruction -> instruction instanceof ModEtherInstruction)
+ .findFirst().get()).mac())
+ .setVlanId(((VlanIdCriterion) vlan100Selector.getCriterion(VLAN_VID)).vlanId())
+ .setOutput(d1p10.port())
+ .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()
+ ));
+
+ sut.deactivate();
+
+ }
+
}