Fix for T3 test paths
Change-Id: I1ab45904f360349abaa5489c9ca89a5d1a69c82e
(cherry picked from commit d5aa3416e53c2ffd1e11faad23d9b2567f2a21fd)
diff --git a/src/test/java/org/onosproject/t3/impl/T3TestObjects.java b/src/test/java/org/onosproject/t3/impl/T3TestObjects.java
new file mode 100644
index 0000000..ff44e43
--- /dev/null
+++ b/src/test/java/org/onosproject/t3/impl/T3TestObjects.java
@@ -0,0 +1,328 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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.t3.impl;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import org.onlab.packet.EthType;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.core.DefaultApplicationId;
+import org.onosproject.core.GroupId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultHost;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.DefaultFlowEntry;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowEntry;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.group.DefaultGroup;
+import org.onosproject.net.group.DefaultGroupBucket;
+import org.onosproject.net.group.Group;
+import org.onosproject.net.group.GroupBucket;
+import org.onosproject.net.group.GroupBuckets;
+import org.onosproject.net.provider.ProviderId;
+
+/**
+ * Helper class for objects related to the Troubleshoot Manager Test.
+ */
+final class T3TestObjects {
+
+ private T3TestObjects(){
+ //banning construction
+ }
+
+ private static final String HOST_ONE_MAC = "00:00:00:00:00:01";
+ private static final String HOST_TWO_MAC = "00:00:00:00:00:02";
+ private static final String HOST_ONE_VLAN = "None";
+ private static final String HOST_TWO_VLAN = "None";
+ private static final String HOST_ONE = HOST_ONE_MAC + "/" + HOST_ONE_VLAN;
+ private static final String HOST_TWO = HOST_TWO_MAC + "/" + HOST_TWO_VLAN;
+
+ //Single Flow Test
+ static final DeviceId SINGLE_FLOW_DEVICE = DeviceId.deviceId("SingleFlowDevice");
+ private static final TrafficSelector SINGLE_FLOW_SELECTOR = DefaultTrafficSelector.builder()
+ .matchInPort(PortNumber.portNumber(1))
+ .matchIPSrc(IpPrefix.valueOf("127.0.0.1/32"))
+ .matchIPDst(IpPrefix.valueOf("127.0.0.2/32"))
+ .build();
+
+ private static final TrafficTreatment OUTPUT_FLOW_TREATMENT = DefaultTrafficTreatment.builder()
+ .setOutput(PortNumber.portNumber(2)).build();
+ private static final FlowRule SINGLE_FLOW = DefaultFlowEntry.builder().forDevice(SINGLE_FLOW_DEVICE)
+ .forTable(0)
+ .withPriority(100)
+ .withSelector(SINGLE_FLOW_SELECTOR)
+ .withTreatment(OUTPUT_FLOW_TREATMENT)
+ .fromApp(new DefaultApplicationId(0, "TestApp"))
+ .makePermanent()
+ .build();
+ static final FlowEntry SINGLE_FLOW_ENTRY = new DefaultFlowEntry(SINGLE_FLOW);
+
+ static final ConnectPoint SINGLE_FLOW_IN_CP = ConnectPoint.deviceConnectPoint(SINGLE_FLOW_DEVICE + "/" + 1);
+
+ static final ConnectPoint SINGLE_FLOW_OUT_CP = ConnectPoint.deviceConnectPoint(SINGLE_FLOW_DEVICE + "/" + 2);
+
+ //Dual Flow Test
+ static final DeviceId DUAL_FLOW_DEVICE = DeviceId.deviceId("DualFlowDevice");
+ private static final TrafficTreatment TRANSITION_FLOW_TREATMENT = DefaultTrafficTreatment.builder()
+ .setVlanId(VlanId.vlanId((short) 100))
+ .transition(10)
+ .build();
+ private static final TrafficSelector VLAN_FLOW_SELECTOR = DefaultTrafficSelector.builder()
+ .matchVlanId(VlanId.vlanId((short) 100))
+ .build();
+ private static final FlowRule FIRST_FLOW = DefaultFlowEntry.builder().forDevice(DUAL_FLOW_DEVICE)
+ .forTable(0)
+ .withPriority(100)
+ .withSelector(SINGLE_FLOW_SELECTOR)
+ .withTreatment(TRANSITION_FLOW_TREATMENT)
+ .fromApp(new DefaultApplicationId(0, "TestApp"))
+ .makePermanent()
+ .build();
+ static final FlowEntry FIRST_FLOW_ENTRY = new DefaultFlowEntry(FIRST_FLOW);
+ private static final FlowRule SECOND_FLOW = DefaultFlowEntry.builder().forDevice(DUAL_FLOW_DEVICE)
+ .forTable(10)
+ .withPriority(100)
+ .withSelector(VLAN_FLOW_SELECTOR)
+ .withTreatment(OUTPUT_FLOW_TREATMENT)
+ .fromApp(new DefaultApplicationId(0, "TestApp"))
+ .makePermanent()
+ .build();
+ static final FlowEntry SECOND_FLOW_ENTRY = new DefaultFlowEntry(SECOND_FLOW);
+
+ static final ConnectPoint DUAL_FLOW_IN_CP = ConnectPoint.deviceConnectPoint(DUAL_FLOW_DEVICE + "/" + 1);
+
+ static final ConnectPoint DUAL_FLOW_OUT_CP = ConnectPoint.deviceConnectPoint(DUAL_FLOW_DEVICE + "/" + 2);
+
+ //Flow and Group Test
+ static final DeviceId GROUP_FLOW_DEVICE = DeviceId.deviceId("GroupFlowDevice");
+
+ private static final GroupId GROUP_ID = GroupId.valueOf(1);
+
+ private static final TrafficTreatment GROUP_FLOW_TREATMENT = DefaultTrafficTreatment.builder()
+ .group(GROUP_ID)
+ .build();
+ private static final FlowRule GROUP_FLOW = DefaultFlowEntry.builder().forDevice(GROUP_FLOW_DEVICE)
+ .forTable(0)
+ .withPriority(100)
+ .withSelector(SINGLE_FLOW_SELECTOR)
+ .withTreatment(GROUP_FLOW_TREATMENT)
+ .fromApp(new DefaultApplicationId(0, "TestApp"))
+ .makePermanent()
+ .build();
+ static final FlowEntry GROUP_FLOW_ENTRY = new DefaultFlowEntry(GROUP_FLOW);
+
+ private static final GroupBucket BUCKET = DefaultGroupBucket.createSelectGroupBucket(OUTPUT_FLOW_TREATMENT);
+
+ private static final GroupBuckets BUCKETS = new GroupBuckets(ImmutableList.of(BUCKET));
+
+ static final Group GROUP = new DefaultGroup(GROUP_ID, GROUP_FLOW_DEVICE, Group.Type.SELECT, BUCKETS);
+
+ static final ConnectPoint GROUP_FLOW_IN_CP = ConnectPoint.deviceConnectPoint(GROUP_FLOW_DEVICE + "/" + 1);
+
+ static final ConnectPoint GROUP_FLOW_OUT_CP = ConnectPoint.deviceConnectPoint(GROUP_FLOW_DEVICE + "/" + 2);
+
+ //topology
+
+ static final DeviceId TOPO_FLOW_DEVICE = DeviceId.deviceId("SingleFlowDevice1");
+
+ static final DeviceId TOPO_FLOW_2_DEVICE = DeviceId.deviceId("SingleFlowDevice2");
+
+ static final DeviceId TOPO_FLOW_3_DEVICE = DeviceId.deviceId("SingleFlowDevice3");
+
+ private static final TrafficSelector TOPO_FLOW_SELECTOR = DefaultTrafficSelector.builder()
+ .matchInPort(PortNumber.portNumber(1))
+ .matchIPSrc(IpPrefix.valueOf("127.0.0.1/32"))
+ .matchIPDst(IpPrefix.valueOf("127.0.0.3/32"))
+ .build();
+
+ private static final FlowRule TOPO_SINGLE_FLOW = DefaultFlowEntry.builder().forDevice(TOPO_FLOW_DEVICE)
+ .forTable(0)
+ .withPriority(100)
+ .withSelector(TOPO_FLOW_SELECTOR)
+ .withTreatment(OUTPUT_FLOW_TREATMENT)
+ .fromApp(new DefaultApplicationId(0, "TestApp"))
+ .makePermanent()
+ .build();
+
+ static final FlowEntry TOPO_SINGLE_FLOW_ENTRY = new DefaultFlowEntry(TOPO_SINGLE_FLOW);
+
+ static final ConnectPoint TOPO_FLOW_1_IN_CP = ConnectPoint.deviceConnectPoint(TOPO_FLOW_DEVICE + "/" + 1);
+
+ static final ConnectPoint TOPO_FLOW_1_OUT_CP = ConnectPoint.deviceConnectPoint(TOPO_FLOW_DEVICE + "/" + 2);
+
+ static final ConnectPoint TOPO_FLOW_2_IN_CP = ConnectPoint.deviceConnectPoint(TOPO_FLOW_2_DEVICE + "/" + 1);
+
+ static final ConnectPoint TOPO_FLOW_2_OUT_CP = ConnectPoint.deviceConnectPoint(TOPO_FLOW_2_DEVICE + "/" + 2);
+
+ static final ConnectPoint TOPO_FLOW_3_IN_CP = ConnectPoint.deviceConnectPoint(TOPO_FLOW_3_DEVICE + "/" + 1);
+
+ static final ConnectPoint TOPO_FLOW_3_OUT_CP = ConnectPoint.deviceConnectPoint(TOPO_FLOW_3_DEVICE + "/" + 2);
+
+
+ //Topology with Groups
+
+ static final DeviceId TOPO_GROUP_FLOW_DEVICE = DeviceId.deviceId("TopoGroupFlowDevice");
+
+ private static final TrafficSelector TOPO_SECOND_INPUT_FLOW_SELECTOR = DefaultTrafficSelector.builder()
+ .matchInPort(PortNumber.portNumber(3))
+ .matchIPSrc(IpPrefix.valueOf("127.0.0.1/32"))
+ .matchIPDst(IpPrefix.valueOf("127.0.0.3/32"))
+ .build();
+
+ private static final FlowRule TOPO_SECOND_INPUT_FLOW = DefaultFlowEntry.builder().forDevice(TOPO_FLOW_3_DEVICE)
+ .forTable(0)
+ .withPriority(100)
+ .withSelector(TOPO_SECOND_INPUT_FLOW_SELECTOR)
+ .withTreatment(OUTPUT_FLOW_TREATMENT)
+ .fromApp(new DefaultApplicationId(0, "TestApp"))
+ .makePermanent()
+ .build();
+
+ private static final TrafficTreatment OUTPUT_2_FLOW_TREATMENT = DefaultTrafficTreatment.builder()
+ .setOutput(PortNumber.portNumber(3)).build();
+
+
+ private static final GroupId TOPO_GROUP_ID = GroupId.valueOf(1);
+
+ private static final TrafficTreatment TOPO_GROUP_FLOW_TREATMENT = DefaultTrafficTreatment.builder()
+ .group(TOPO_GROUP_ID)
+ .build();
+ private static final FlowRule TOPO_GROUP_FLOW = DefaultFlowEntry.builder().forDevice(TOPO_GROUP_FLOW_DEVICE)
+ .forTable(0)
+ .withPriority(100)
+ .withSelector(TOPO_FLOW_SELECTOR)
+ .withTreatment(TOPO_GROUP_FLOW_TREATMENT)
+ .fromApp(new DefaultApplicationId(0, "TestApp"))
+ .makePermanent()
+ .build();
+ static final FlowEntry TOPO_GROUP_FLOW_ENTRY = new DefaultFlowEntry(TOPO_GROUP_FLOW);
+
+ private static final GroupBucket BUCKET_2 = DefaultGroupBucket.createSelectGroupBucket(OUTPUT_2_FLOW_TREATMENT);
+
+ private static final GroupBuckets BUCKETS_MULTIPLE = new GroupBuckets(ImmutableList.of(BUCKET, BUCKET_2));
+
+ static final Group TOPO_GROUP = new DefaultGroup(TOPO_GROUP_ID, TOPO_GROUP_FLOW_DEVICE,
+ Group.Type.SELECT, BUCKETS_MULTIPLE);
+
+ static final FlowEntry TOPO_SECOND_INPUT_FLOW_ENTRY = new DefaultFlowEntry(TOPO_SECOND_INPUT_FLOW);
+
+ static final DeviceId TOPO_FLOW_4_DEVICE = DeviceId.deviceId("SingleFlowDevice4");
+
+ static final ConnectPoint TOPO_FLOW_IN_CP = ConnectPoint.deviceConnectPoint(TOPO_GROUP_FLOW_DEVICE + "/" + 1);
+
+ static final ConnectPoint TOPO_FLOW_OUT_CP_1 = ConnectPoint.deviceConnectPoint(TOPO_GROUP_FLOW_DEVICE + "/" + 2);
+
+ protected static final ConnectPoint TOPO_FLOW_OUT_CP_2 =
+ ConnectPoint.deviceConnectPoint(TOPO_GROUP_FLOW_DEVICE + "/" + 3);
+
+ static final ConnectPoint TOPO_FLOW_4_IN_CP = ConnectPoint.deviceConnectPoint(TOPO_FLOW_4_DEVICE + "/" + 1);
+
+ static final ConnectPoint TOPO_FLOW_3_IN_2_CP = ConnectPoint.deviceConnectPoint(TOPO_FLOW_3_DEVICE + "/" + 3);
+
+ static final ConnectPoint TOPO_FLOW_4_OUT_CP = ConnectPoint.deviceConnectPoint(TOPO_FLOW_4_DEVICE + "/" + 2);
+
+
+ //hardware
+
+ static final DeviceId HARDWARE_DEVICE = DeviceId.deviceId("HardwareDevice");
+
+ static final ConnectPoint HARDWARE_DEVICE_IN_CP = ConnectPoint.deviceConnectPoint(HARDWARE_DEVICE + "/" + 1);
+
+ static final ConnectPoint HARDWARE_DEVICE_OUT_CP = ConnectPoint.deviceConnectPoint(HARDWARE_DEVICE + "/" + 2);
+
+ private static final TrafficSelector HARDWARE_FLOW_SELECTOR = DefaultTrafficSelector.builder()
+ .matchInPort(PortNumber.portNumber(1))
+ .matchIPSrc(IpPrefix.valueOf("127.0.0.1/32"))
+ .matchIPDst(IpPrefix.valueOf("127.0.0.2/32"))
+ .build();
+
+ private static final TrafficTreatment HW_TRANSITION_FLOW_TREATMENT = DefaultTrafficTreatment.builder()
+ .pushMpls()
+ .transition(27)
+ .build();
+
+ private static final FlowRule HARDWARE_FLOW = DefaultFlowEntry.builder().forDevice(TOPO_FLOW_3_DEVICE)
+ .forTable(0)
+ .withPriority(100)
+ .withSelector(HARDWARE_FLOW_SELECTOR)
+ .withTreatment(HW_TRANSITION_FLOW_TREATMENT)
+ .fromApp(new DefaultApplicationId(0, "TestApp"))
+ .makePermanent()
+ .build();
+
+ static final FlowEntry HARDWARE_FLOW_ENTRY = new DefaultFlowEntry(HARDWARE_FLOW);
+
+ private static final TrafficSelector HARDWARE_ETH_FLOW_SELECTOR = DefaultTrafficSelector.builder()
+ .matchInPort(PortNumber.portNumber(1))
+ .matchIPSrc(IpPrefix.valueOf("127.0.0.1/32"))
+ .matchIPDst(IpPrefix.valueOf("127.0.0.2/32"))
+ .matchEthType(EthType.EtherType.IPV4.ethType().toShort())
+ .build();
+
+ private static final FlowRule HARDWARE_ETH_FLOW = DefaultFlowEntry.builder().forDevice(TOPO_FLOW_3_DEVICE)
+ .forTable(30)
+ .withPriority(100)
+ .withSelector(HARDWARE_ETH_FLOW_SELECTOR)
+ .withTreatment(OUTPUT_FLOW_TREATMENT)
+ .fromApp(new DefaultApplicationId(0, "TestApp"))
+ .makePermanent()
+ .build();
+
+ static final FlowEntry HARDWARE_ETH_FLOW_ENTRY = new DefaultFlowEntry(HARDWARE_ETH_FLOW);
+
+
+
+
+ //helper elements
+
+ static final Host H1 = new DefaultHost(ProviderId.NONE, HostId.hostId(HOST_ONE), MacAddress.valueOf(100),
+ VlanId.NONE, new HostLocation(SINGLE_FLOW_DEVICE, PortNumber.portNumber(2), 0),
+ ImmutableSet.of(IpAddress.valueOf("127.0.0.2")));
+
+ static final Host H2 = new DefaultHost(ProviderId.NONE, HostId.hostId(HOST_TWO), MacAddress.valueOf(100),
+ VlanId.NONE, new HostLocation(TOPO_FLOW_3_DEVICE, PortNumber.portNumber(2), 0),
+ ImmutableSet.of(IpAddress.valueOf("127.0.0.3")));
+
+ static final TrafficSelector PACKET_OK = DefaultTrafficSelector.builder()
+ .matchInPort(PortNumber.portNumber(1))
+ .matchEthType(EthType.EtherType.IPV4.ethType().toShort())
+ .matchIPSrc(IpPrefix.valueOf("127.0.0.1/32"))
+ .matchIPDst(IpPrefix.valueOf("127.0.0.2/32"))
+ .build();
+
+ static final TrafficSelector PACKET_OK_TOPO = DefaultTrafficSelector.builder()
+ .matchInPort(PortNumber.portNumber(1))
+ .matchIPSrc(IpPrefix.valueOf("127.0.0.1/32"))
+ .matchIPDst(IpPrefix.valueOf("127.0.0.3/32"))
+ .build();
+
+ static final TrafficSelector PACKET_FAIL = DefaultTrafficSelector.builder()
+ .matchInPort(PortNumber.portNumber(1))
+ .matchIPSrc(IpPrefix.valueOf("127.0.0.1/32"))
+ .matchIPDst(IpPrefix.valueOf("127.0.0.99/32"))
+ .build();
+}
diff --git a/src/test/java/org/onosproject/t3/impl/TroubleshootManagerTest.java b/src/test/java/org/onosproject/t3/impl/TroubleshootManagerTest.java
new file mode 100644
index 0000000..28ab5b2
--- /dev/null
+++ b/src/test/java/org/onosproject/t3/impl/TroubleshootManagerTest.java
@@ -0,0 +1,335 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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.t3.impl;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.EthType;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultLink;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.Link;
+import org.onosproject.net.driver.DefaultDriver;
+import org.onosproject.net.driver.Driver;
+import org.onosproject.net.driver.DriverServiceAdapter;
+import org.onosproject.net.flow.FlowEntry;
+import org.onosproject.net.flow.FlowRuleServiceAdapter;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.EthTypeCriterion;
+import org.onosproject.net.flow.criteria.VlanIdCriterion;
+import org.onosproject.net.group.Group;
+import org.onosproject.net.group.GroupServiceAdapter;
+import org.onosproject.net.host.HostServiceAdapter;
+import org.onosproject.net.link.LinkServiceAdapter;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.t3.api.StaticPacketTrace;
+import org.slf4j.Logger;
+
+import java.util.HashMap;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.onosproject.t3.impl.T3TestObjects.*;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Test Class for Troubleshoot Manager.
+ */
+public class TroubleshootManagerTest {
+
+ private static final Logger log = getLogger(TroubleshootManager.class);
+
+ private TroubleshootManager mngr;
+
+ @Before
+ public void setUp() throws Exception {
+ mngr = new TroubleshootManager();
+ mngr.flowRuleService = new TestFlowRuleService();
+ mngr.hostService = new TestHostService();
+ mngr.linkService = new TestLinkService();
+ mngr.driverService = new TestDriverService();
+ mngr.groupService = new TestGroupService();
+
+ assertNotNull("Manager should not be null", mngr);
+
+ assertNotNull("Flow rule Service should not be null", mngr.flowRuleService);
+ assertNotNull("Host Service should not be null", mngr.hostService);
+ assertNotNull("Group Service should not be null", mngr.groupService);
+ assertNotNull("Driver Service should not be null", mngr.driverService);
+ assertNotNull("Link Service should not be null", mngr.linkService);
+ }
+
+ /**
+ * Tests failure on device with no flows.
+ */
+ @Test
+ public void noFlows() {
+ StaticPacketTrace traceFail = mngr.trace(PACKET_OK, ConnectPoint.deviceConnectPoint("test/1"));
+ assertNotNull("Trace should not be null", traceFail);
+ assertNull("Trace should have 0 output", traceFail.getGroupOuputs(SINGLE_FLOW_DEVICE));
+ log.info("trace {}", traceFail.resultMessage());
+ }
+
+ /**
+ * Test a single flow rule that has output port in it.
+ */
+ @Test
+ public void testSingleFlowRule() {
+
+ testSuccess(PACKET_OK, SINGLE_FLOW_IN_CP, SINGLE_FLOW_DEVICE, SINGLE_FLOW_OUT_CP, 1);
+
+ testFaliure(PACKET_FAIL, SINGLE_FLOW_IN_CP, SINGLE_FLOW_DEVICE);
+ }
+
+ /**
+ * Tests two flow rule the last one of which has output port in it.
+ */
+ @Test
+ public void testDualFlowRule() {
+
+ //Test Success
+
+ StaticPacketTrace traceSuccess = testSuccess(PACKET_OK, DUAL_FLOW_IN_CP, DUAL_FLOW_DEVICE,
+ DUAL_FLOW_OUT_CP, 1);
+
+ //Testing Vlan
+ Criterion criterion = traceSuccess.getGroupOuputs(DUAL_FLOW_DEVICE).get(0).
+ getFinalPacket().getCriterion(Criterion.Type.VLAN_VID);
+ assertNotNull("Packet Should have Vlan", criterion);
+
+ VlanIdCriterion vlanIdCriterion = (VlanIdCriterion) criterion;
+
+ assertEquals("Vlan should be 100", VlanId.vlanId((short) 100), vlanIdCriterion.vlanId());
+
+ //Test Faliure
+ testFaliure(PACKET_FAIL, DUAL_FLOW_IN_CP, DUAL_FLOW_DEVICE);
+
+ }
+
+ /**
+ * Test a single flow rule that points to a group with output port in it.
+ */
+ @Test
+ public void flowAndGroup() throws Exception {
+
+ StaticPacketTrace traceSuccess = testSuccess(PACKET_OK, GROUP_FLOW_IN_CP, GROUP_FLOW_DEVICE,
+ GROUP_FLOW_OUT_CP, 1);
+
+ assertTrue("Wrong Output Group", traceSuccess.getGroupOuputs(GROUP_FLOW_DEVICE)
+ .get(0).getGroups().contains(GROUP));
+
+ }
+
+ /**
+ * Test path through a 3 device topology.
+ */
+ @Test
+ public void singlePathTopology() throws Exception {
+
+ StaticPacketTrace traceSuccess = testSuccess(PACKET_OK_TOPO, TOPO_FLOW_1_IN_CP,
+ TOPO_FLOW_3_DEVICE, TOPO_FLOW_3_OUT_CP, 1);
+
+ assertTrue("Incorrect path",
+ traceSuccess.getCompletePaths().get(0).contains(TOPO_FLOW_2_IN_CP));
+ assertTrue("Incorrect path",
+ traceSuccess.getCompletePaths().get(0).contains(TOPO_FLOW_2_OUT_CP));
+ assertTrue("Incorrect path",
+ traceSuccess.getCompletePaths().get(0).contains(TOPO_FLOW_3_IN_CP));
+
+ }
+
+ /**
+ * Test path through a 4 device topology with first device that has groups with multiple output buckets.
+ */
+ @Test
+ public void testGroupTopo() throws Exception {
+
+ StaticPacketTrace traceSuccess = testSuccess(PACKET_OK_TOPO, TOPO_FLOW_IN_CP,
+ TOPO_FLOW_3_DEVICE, TOPO_FLOW_3_OUT_CP, 2);
+
+ assertTrue("Incorrect groups",
+ traceSuccess.getGroupOuputs(TOPO_GROUP_FLOW_DEVICE).get(0).getGroups().contains(TOPO_GROUP));
+ assertTrue("Incorrect bucket",
+ traceSuccess.getGroupOuputs(TOPO_GROUP_FLOW_DEVICE).get(1).getGroups().contains(TOPO_GROUP));
+ }
+
+ /**
+ * Test HW support in a single device with 2 flow rules to check hit of static HW rules.
+ */
+ @Test
+ public void hardwareTest() throws Exception {
+
+ StaticPacketTrace traceSuccess = testSuccess(PACKET_OK, HARDWARE_DEVICE_IN_CP,
+ HARDWARE_DEVICE, HARDWARE_DEVICE_OUT_CP, 1);
+
+ assertEquals("wrong ETH type", EthType.EtherType.IPV4.ethType(),
+ ((EthTypeCriterion) traceSuccess.getGroupOuputs(HARDWARE_DEVICE).get(0).getFinalPacket()
+ .getCriterion(Criterion.Type.ETH_TYPE)).ethType());
+
+ }
+
+ private StaticPacketTrace testSuccess(TrafficSelector packet, ConnectPoint in, DeviceId deviceId, ConnectPoint out,
+ int paths) {
+ StaticPacketTrace traceSuccess = mngr.trace(packet, in);
+
+ log.info("trace {}", traceSuccess);
+
+ log.info("trace {}", traceSuccess.resultMessage());
+
+ assertNotNull("trace should not be null", traceSuccess);
+ assertEquals("Trace should have " + paths + " output", paths, traceSuccess.getGroupOuputs(deviceId).size());
+ assertEquals("Trace should only have " + paths + "output", paths, traceSuccess.getCompletePaths().size());
+ assertTrue("Trace should be successful",
+ traceSuccess.resultMessage().contains("Reached required destination Host"));
+ assertEquals("Incorrect Output CP", out,
+ traceSuccess.getGroupOuputs(deviceId).get(0).getOutput());
+
+ return traceSuccess;
+ }
+
+ private void testFaliure(TrafficSelector packet, ConnectPoint in, DeviceId deviceId) {
+ StaticPacketTrace traceFail = mngr.trace(packet, in);
+
+ log.info("trace {}", traceFail.resultMessage());
+
+ assertNotNull("Trace should not be null", traceFail);
+ assertNull("Trace should have 0 output", traceFail.getGroupOuputs(deviceId));
+ }
+
+ private class TestFlowRuleService extends FlowRuleServiceAdapter {
+ @Override
+ public Iterable<FlowEntry> getFlowEntries(DeviceId deviceId) {
+ if (deviceId.equals(SINGLE_FLOW_DEVICE)) {
+ return ImmutableList.of(SINGLE_FLOW_ENTRY);
+ } else if (deviceId.equals(DUAL_FLOW_DEVICE)) {
+ return ImmutableList.of(FIRST_FLOW_ENTRY, SECOND_FLOW_ENTRY);
+ } else if (deviceId.equals(GROUP_FLOW_DEVICE)) {
+ return ImmutableList.of(GROUP_FLOW_ENTRY);
+ } else if (deviceId.equals(TOPO_FLOW_DEVICE) ||
+ deviceId.equals(TOPO_FLOW_2_DEVICE) ||
+ deviceId.equals(TOPO_FLOW_3_DEVICE) ||
+ deviceId.equals(TOPO_FLOW_4_DEVICE)) {
+ return ImmutableList.of(TOPO_SINGLE_FLOW_ENTRY, TOPO_SECOND_INPUT_FLOW_ENTRY);
+ } else if (deviceId.equals(TOPO_GROUP_FLOW_DEVICE)) {
+ return ImmutableList.of(TOPO_GROUP_FLOW_ENTRY);
+ } else if (deviceId.equals(HARDWARE_DEVICE)) {
+ return ImmutableList.of(HARDWARE_ETH_FLOW_ENTRY, HARDWARE_FLOW_ENTRY);
+ }
+ return ImmutableList.of();
+ }
+ }
+
+ private class TestDriverService extends DriverServiceAdapter {
+ @Override
+ public Driver getDriver(DeviceId deviceId) {
+ if (deviceId.equals(HARDWARE_DEVICE)) {
+ return new DefaultDriver("ofdpa", ImmutableList.of(),
+ "test", "test", "test", new HashMap<>(), new HashMap<>());
+ }
+ return new DefaultDriver("NotHWDriver", ImmutableList.of(),
+ "test", "test", "test", new HashMap<>(), new HashMap<>());
+ }
+ }
+
+ private class TestGroupService extends GroupServiceAdapter {
+ @Override
+ public Iterable<Group> getGroups(DeviceId deviceId) {
+ if (deviceId.equals(GROUP_FLOW_DEVICE)) {
+ return ImmutableList.of(GROUP);
+ } else if (deviceId.equals(TOPO_GROUP_FLOW_DEVICE)) {
+ return ImmutableList.of(TOPO_GROUP);
+ }
+ return ImmutableList.of();
+ }
+ }
+
+ private class TestHostService extends HostServiceAdapter {
+ @Override
+ public Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
+ if (connectPoint.equals(TOPO_FLOW_3_OUT_CP)) {
+ return ImmutableSet.of(H2);
+ }
+ return ImmutableSet.of(H1);
+ }
+
+ @Override
+ public Set<Host> getHostsByMac(MacAddress mac) {
+ if (mac.equals(H1.mac())) {
+ return ImmutableSet.of(H1);
+ } else if (mac.equals(H2.mac())) {
+ return ImmutableSet.of(H2);
+ }
+ return ImmutableSet.of();
+ }
+
+ @Override
+ public Set<Host> getHostsByIp(IpAddress ip) {
+ if ((H1.ipAddresses().contains(ip))) {
+ return ImmutableSet.of(H1);
+ } else if ((H2.ipAddresses().contains(ip))) {
+ return ImmutableSet.of(H2);
+ }
+ return ImmutableSet.of();
+ }
+ }
+
+ private class TestLinkService extends LinkServiceAdapter {
+ @Override
+ public Set<Link> getEgressLinks(ConnectPoint connectPoint) {
+ if (connectPoint.equals(TOPO_FLOW_1_OUT_CP)
+ || connectPoint.equals(TOPO_FLOW_OUT_CP_1)) {
+ return ImmutableSet.of(DefaultLink.builder()
+ .providerId(ProviderId.NONE)
+ .type(Link.Type.DIRECT)
+ .src(connectPoint)
+ .dst(TOPO_FLOW_2_IN_CP)
+ .build());
+ } else if (connectPoint.equals(TOPO_FLOW_2_OUT_CP)) {
+ return ImmutableSet.of(DefaultLink.builder()
+ .providerId(ProviderId.NONE)
+ .type(Link.Type.DIRECT)
+ .src(TOPO_FLOW_2_OUT_CP)
+ .dst(TOPO_FLOW_3_IN_CP)
+ .build());
+ } else if (connectPoint.equals(TOPO_FLOW_OUT_CP_2)) {
+ return ImmutableSet.of(DefaultLink.builder()
+ .providerId(ProviderId.NONE)
+ .type(Link.Type.DIRECT)
+ .src(TOPO_FLOW_OUT_CP_2)
+ .dst(TOPO_FLOW_4_IN_CP)
+ .build());
+ } else if (connectPoint.equals(TOPO_FLOW_4_OUT_CP)) {
+ return ImmutableSet.of(DefaultLink.builder()
+ .providerId(ProviderId.NONE)
+ .type(Link.Type.DIRECT)
+ .src(TOPO_FLOW_4_OUT_CP)
+ .dst(TOPO_FLOW_3_IN_2_CP)
+ .build());
+ }
+ return ImmutableSet.of();
+ }
+ }
+}
\ No newline at end of file