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
