diff --git a/drivers/default/src/test/java/org/onosproject/driver/traceable/OfdpaPipelineTraceableTest.java b/drivers/default/src/test/java/org/onosproject/driver/traceable/OfdpaPipelineTraceableTest.java
new file mode 100644
index 0000000..49cb15a
--- /dev/null
+++ b/drivers/default/src/test/java/org/onosproject/driver/traceable/OfdpaPipelineTraceableTest.java
@@ -0,0 +1,768 @@
+/*
+ * Copyright 2020-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.driver.traceable;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import org.onosproject.driver.pipeline.ofdpa.Ofdpa2Pipeline;
+import org.onosproject.driver.pipeline.ofdpa.OvsOfdpaPipeline;
+import org.onosproject.net.DataPlaneEntity;
+import org.onosproject.net.PipelineTraceableHitChain;
+import org.onosproject.net.PipelineTraceableInput;
+import org.onosproject.net.PipelineTraceableOutput;
+import org.onosproject.net.PipelineTraceableOutput.PipelineTraceableResult;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.behaviour.PipelineTraceable;
+import org.onosproject.net.behaviour.Pipeliner;
+import org.onosproject.net.driver.DefaultDriverData;
+import org.onosproject.net.driver.DriverData;
+import org.onosproject.net.driver.DriverHandler;
+
+import java.util.List;
+
+import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.onosproject.driver.traceable.TraceableDataPlaneObjects.getDataPlaneEntities;
+import static org.onosproject.driver.traceable.TraceableDataPlaneObjects.getHitChains;
+import static org.onosproject.driver.traceable.TraceableTestObjects.IN_ARP_PACKET;
+import static org.onosproject.driver.traceable.TraceableTestObjects.IN_L2_BRIDG_UNTAG_PACKET;
+import static org.onosproject.driver.traceable.TraceableTestObjects.IN_L2_BROAD_UNTAG_PACKET;
+import static org.onosproject.driver.traceable.TraceableTestObjects.IN_L3_ECMP_PACKET;
+import static org.onosproject.driver.traceable.TraceableTestObjects.IN_L3_UCAST_UNTAG_PACKET;
+import static org.onosproject.driver.traceable.TraceableTestObjects.IN_MPLS_ECMP_PACKET;
+import static org.onosproject.driver.traceable.TraceableTestObjects.IN_MPLS_ECMP_PACKET_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.IN_PUNT_IP_PACKET;
+import static org.onosproject.driver.traceable.TraceableTestObjects.IN_PUNT_LLDP_PACKET;
+import static org.onosproject.driver.traceable.TraceableTestObjects.OFDPA_CP;
+import static org.onosproject.driver.traceable.TraceableTestObjects.OFDPA_DEVICE;
+import static org.onosproject.driver.traceable.TraceableTestObjects.OFDPA_DRIVER;
+import static org.onosproject.driver.traceable.TraceableTestObjects.OUT_L2_BROAD_EMPTY;
+import static org.onosproject.driver.traceable.TraceableTestObjects.OUT_L3_ECMP_PACKET;
+import static org.onosproject.driver.traceable.TraceableTestObjects.OUT_L3_ECMP_PACKET_1;
+import static org.onosproject.driver.traceable.TraceableTestObjects.OUT_L3_ECMP_PACKET_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.OUT_L3_ECMP_PACKET_OFDPA_1;
+import static org.onosproject.driver.traceable.TraceableTestObjects.OUT_L3_UCAST_UNTAG_PACKET;
+import static org.onosproject.driver.traceable.TraceableTestObjects.OUT_MPLS_ECMP_PACKET;
+import static org.onosproject.driver.traceable.TraceableTestObjects.OUT_PORT;
+import static org.onosproject.driver.traceable.TraceableTestObjects.OVS_OFDPA_DRIVER;
+import static org.onosproject.driver.traceable.TraceableTestObjects.PORT;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.ARP_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.ARP_OVS_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L2_BRIDG_NOT_ORDERED_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L2_BRIDG_NOT_ORDERED_OVS_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L2_BRIDG_UNTAG_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L2_BRIDG_UNTAG_OVS_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L2_BROAD_EMPTY_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L2_BROAD_EMPTY_OVS_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L2_BROAD_UNTAG_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L2_BROAD_UNTAG_OVS_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L3_ECMP_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L3_ECMP_OVS_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L3_UCAST_UNTAG_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L3_UCAST_UNTAG_OVS_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.MPLS_ECMP_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.MPLS_ECMP_OVS_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.PUNT_IP_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.PUNT_IP_OVS_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.PUNT_LLDP_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.PUNT_LLDP_OVS_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.UP_OFDPA_CP;
+import static org.onosproject.driver.traceable.TraceableTestObjects.UP_PORT;
+import static org.onosproject.driver.traceable.TraceableTestObjects.UP_PORT_1;
+
+/**
+ * Tests for Ofdpa pipeline traceable implementation.
+ */
+public class OfdpaPipelineTraceableTest {
+
+    private TraceableTestObjects.TestDriver ofdpaDriver = new TraceableTestObjects.TestDriver(OFDPA_DRIVER);
+    private TraceableTestObjects.TestDriver ovsOfdpaDriver = new TraceableTestObjects.TestDriver(OVS_OFDPA_DRIVER);
+
+    private DriverHandler testDriverHandlerOfdpa;
+    private DriverHandler testDriverHandlerOvsOfdpa;
+
+    @Before
+    public void setUp() {
+        testDriverHandlerOfdpa = createNiceMock(DriverHandler.class);
+        testDriverHandlerOvsOfdpa = createNiceMock(DriverHandler.class);
+        expect(testDriverHandlerOfdpa.hasBehaviour(Pipeliner.class)).andReturn(true).anyTimes();
+        expect(testDriverHandlerOvsOfdpa.hasBehaviour(Pipeliner.class)).andReturn(true).anyTimes();
+        expect(testDriverHandlerOfdpa.behaviour(Pipeliner.class)).andReturn(new Ofdpa2Pipeline()).anyTimes();
+        expect(testDriverHandlerOvsOfdpa.behaviour(Pipeliner.class)).andReturn(new OvsOfdpaPipeline()).anyTimes();
+        replay(testDriverHandlerOfdpa);
+        replay(testDriverHandlerOvsOfdpa);
+    }
+
+    private PipelineTraceable setUpOfdpa() {
+        PipelineTraceable behaviour = new OfdpaPipelineTraceable();
+        DriverData driverData = new DefaultDriverData(ofdpaDriver, OFDPA_DEVICE);
+        behaviour.setData(driverData);
+        behaviour.setHandler(testDriverHandlerOfdpa);
+        behaviour.init();
+        return behaviour;
+    }
+
+    private PipelineTraceable setUpOvsOfdpa() {
+        PipelineTraceable behaviour = new OfdpaPipelineTraceable();
+        DriverData driverData = new DefaultDriverData(ovsOfdpaDriver, OFDPA_DEVICE);
+        behaviour.setData(driverData);
+        behaviour.setHandler(testDriverHandlerOvsOfdpa);
+        behaviour.init();
+        return behaviour;
+    }
+
+    /**
+     * Test punt ip for ovs-ofdpa.
+     */
+    @Test
+    public void testOvsOfdpaPuntIP() {
+        PipelineTraceableInput pipelineInput = new PipelineTraceableInput(IN_PUNT_IP_PACKET, OFDPA_CP,
+                getDataPlaneEntities(OVS_OFDPA_DRIVER, PUNT_IP_OVS_OFDPA));
+        PipelineTraceable pipelineTraceable = setUpOvsOfdpa();
+
+        PipelineTraceableOutput pipelineOutput = pipelineTraceable.apply(pipelineInput);
+        assertNotNull(pipelineOutput);
+        assertThat(pipelineOutput.getHitChains().size(), is(1));
+        assertThat(pipelineOutput.getResult(), is(PipelineTraceableResult.SUCCESS));
+
+        PipelineTraceableHitChain hitChain = pipelineOutput.getHitChains().get(0);
+        assertNotNull(hitChain);
+        List<List<DataPlaneEntity>> chains = getHitChains(PUNT_IP_OVS_OFDPA);
+        assertThat(chains.size(), is(1));
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(PortNumber.CONTROLLER));
+        assertThat(hitChain.getHitChain().size(), is(7));
+        assertEquals(IN_PUNT_IP_PACKET, hitChain.getEgressPacket());
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(0), hitChain.getHitChain());
+    }
+
+    /**
+     * Test punt ip for ofdpa.
+     */
+    @Test
+    public void testOfdpaPuntIP() {
+        PipelineTraceableInput pipelineInput = new PipelineTraceableInput(IN_PUNT_IP_PACKET, OFDPA_CP,
+                getDataPlaneEntities(OFDPA_DRIVER, PUNT_IP_OFDPA));
+        PipelineTraceable pipelineTraceable = setUpOfdpa();
+
+        PipelineTraceableOutput pipelineOutput = pipelineTraceable.apply(pipelineInput);
+        assertNotNull(pipelineOutput);
+        assertThat(pipelineOutput.getHitChains().size(), is(1));
+        assertThat(pipelineOutput.getResult(), is(PipelineTraceableResult.SUCCESS));
+
+        PipelineTraceableHitChain hitChain = pipelineOutput.getHitChains().get(0);
+        assertNotNull(hitChain);
+        List<List<DataPlaneEntity>> chains = getHitChains(PUNT_IP_OFDPA);
+        assertThat(chains.size(), is(1));
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(PortNumber.CONTROLLER));
+        assertThat(hitChain.getHitChain().size(), is(4));
+        assertEquals(IN_PUNT_IP_PACKET, hitChain.getEgressPacket());
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(0), hitChain.getHitChain());
+    }
+
+    /**
+     * Test punt arp for ovs-ofdpa.
+     */
+    @Test
+    public void testOvsOfdpaArp() {
+        PipelineTraceableInput pipelineInput = new PipelineTraceableInput(IN_ARP_PACKET, OFDPA_CP,
+                getDataPlaneEntities(OVS_OFDPA_DRIVER, ARP_OVS_OFDPA));
+        PipelineTraceable pipelineTraceable = setUpOvsOfdpa();
+
+        PipelineTraceableOutput pipelineOutput = pipelineTraceable.apply(pipelineInput);
+        assertNotNull(pipelineOutput);
+        assertThat(pipelineOutput.getHitChains().size(), is(3));
+        assertThat(pipelineOutput.getResult(), is(PipelineTraceableResult.SUCCESS));
+
+        PipelineTraceableHitChain hitChain = pipelineOutput.getHitChains().get(0);
+        assertNotNull(hitChain);
+        List<List<DataPlaneEntity>> chains = getHitChains(ARP_OVS_OFDPA);
+        assertThat(chains.size(), is(3));
+
+        // This is the copy sent to the controller
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(PortNumber.CONTROLLER));
+        assertThat(hitChain.getHitChain().size(), is(7));
+        assertEquals(IN_ARP_PACKET, hitChain.getEgressPacket());
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(0), hitChain.getHitChain());
+
+        // This is the copy sent to the member port
+        hitChain = pipelineOutput.getHitChains().get(1);
+        assertNotNull(hitChain);
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(OUT_PORT));
+        assertThat(hitChain.getHitChain().size(), is(8));
+        assertEquals(IN_ARP_PACKET, hitChain.getEgressPacket());
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(1), hitChain.getHitChain());
+
+        // This is the copy sent on the input port
+        hitChain = pipelineOutput.getHitChains().get(2);
+        assertNotNull(hitChain);
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(PORT));
+        assertThat(hitChain.getHitChain().size(), is(8));
+        assertEquals(IN_ARP_PACKET, hitChain.getEgressPacket());
+        assertTrue(hitChain.isDropped());
+        assertEquals(chains.get(2), hitChain.getHitChain());
+    }
+
+    /**
+     * Test punt arp for ovs-ofdpa.
+     */
+    @Test
+    public void testOfdpaArp() {
+        PipelineTraceableInput pipelineInput = new PipelineTraceableInput(IN_ARP_PACKET, OFDPA_CP,
+                getDataPlaneEntities(OFDPA_DRIVER, ARP_OFDPA));
+        PipelineTraceable pipelineTraceable = setUpOfdpa();
+
+        PipelineTraceableOutput pipelineOutput = pipelineTraceable.apply(pipelineInput);
+        assertNotNull(pipelineOutput);
+        assertThat(pipelineOutput.getHitChains().size(), is(3));
+        assertThat(pipelineOutput.getResult(), is(PipelineTraceableResult.SUCCESS));
+
+        PipelineTraceableHitChain hitChain = pipelineOutput.getHitChains().get(0);
+        assertNotNull(hitChain);
+        List<List<DataPlaneEntity>> chains = getHitChains(ARP_OFDPA);
+        assertThat(chains.size(), is(3));
+
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(PortNumber.CONTROLLER));
+        assertThat(hitChain.getHitChain().size(), is(4));
+        assertEquals(IN_ARP_PACKET, hitChain.getEgressPacket());
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(0), hitChain.getHitChain());
+
+        hitChain = pipelineOutput.getHitChains().get(1);
+        assertNotNull(hitChain);
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(OUT_PORT));
+        assertThat(hitChain.getHitChain().size(), is(6));
+        assertEquals(IN_ARP_PACKET, hitChain.getEgressPacket());
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(1), hitChain.getHitChain());
+
+        hitChain = pipelineOutput.getHitChains().get(2);
+        assertNotNull(hitChain);
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(PORT));
+        assertThat(hitChain.getHitChain().size(), is(6));
+        assertEquals(IN_ARP_PACKET, hitChain.getEgressPacket());
+        assertTrue(hitChain.isDropped());
+        assertEquals(chains.get(2), hitChain.getHitChain());
+    }
+
+    /**
+     * Test punt lldp for ovs-ofdpa.
+     */
+    @Test
+    public void testOvsOfdpaPuntLldp() {
+        PipelineTraceableInput pipelineInput = new PipelineTraceableInput(IN_PUNT_LLDP_PACKET, OFDPA_CP,
+                getDataPlaneEntities(OVS_OFDPA_DRIVER, PUNT_LLDP_OVS_OFDPA));
+        PipelineTraceable pipelineTraceable = setUpOvsOfdpa();
+
+        PipelineTraceableOutput pipelineOutput = pipelineTraceable.apply(pipelineInput);
+        assertNotNull(pipelineOutput);
+        assertThat(pipelineOutput.getHitChains().size(), is(1));
+        assertThat(pipelineOutput.getResult(), is(PipelineTraceableResult.SUCCESS));
+
+        PipelineTraceableHitChain hitChain = pipelineOutput.getHitChains().get(0);
+        assertNotNull(hitChain);
+        List<List<DataPlaneEntity>> chains = getHitChains(PUNT_LLDP_OVS_OFDPA);
+        assertThat(chains.size(), is(1));
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(PortNumber.CONTROLLER));
+        assertThat(hitChain.getHitChain().size(), is(7));
+        assertEquals(IN_PUNT_LLDP_PACKET, hitChain.getEgressPacket());
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(0), hitChain.getHitChain());
+    }
+
+    /**
+     * Test punt lldp for ovs-ofdpa.
+     */
+    @Test
+    public void testOfdpaPuntLldp() {
+        PipelineTraceableInput pipelineInput = new PipelineTraceableInput(IN_PUNT_LLDP_PACKET, OFDPA_CP,
+                getDataPlaneEntities(OFDPA_DRIVER, PUNT_LLDP_OFDPA));
+        PipelineTraceable pipelineTraceable = setUpOfdpa();
+
+        PipelineTraceableOutput pipelineOutput = pipelineTraceable.apply(pipelineInput);
+        assertNotNull(pipelineOutput);
+        assertThat(pipelineOutput.getHitChains().size(), is(1));
+        assertThat(pipelineOutput.getResult(), is(PipelineTraceableResult.SUCCESS));
+
+        PipelineTraceableHitChain hitChain = pipelineOutput.getHitChains().get(0);
+        assertNotNull(hitChain);
+        List<List<DataPlaneEntity>> chains = getHitChains(PUNT_LLDP_OFDPA);
+        assertThat(chains.size(), is(1));
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(PortNumber.CONTROLLER));
+        assertThat(hitChain.getHitChain().size(), is(4));
+        assertEquals(IN_PUNT_LLDP_PACKET, hitChain.getEgressPacket());
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(0), hitChain.getHitChain());
+    }
+
+    /**
+     * Test l2 bridging with untagged hosts for ovs-ofdpa.
+     */
+    @Test
+    public void testOvsOfdpaL2BridingUntagged() {
+        PipelineTraceableInput pipelineInput = new PipelineTraceableInput(IN_L2_BRIDG_UNTAG_PACKET, OFDPA_CP,
+                getDataPlaneEntities(OVS_OFDPA_DRIVER, L2_BRIDG_UNTAG_OVS_OFDPA));
+        PipelineTraceable pipelineTraceable = setUpOvsOfdpa();
+
+        PipelineTraceableOutput pipelineOutput = pipelineTraceable.apply(pipelineInput);
+        assertNotNull(pipelineOutput);
+        assertThat(pipelineOutput.getHitChains().size(), is(1));
+        assertThat(pipelineOutput.getResult(), is(PipelineTraceableResult.SUCCESS));
+
+        PipelineTraceableHitChain hitChain = pipelineOutput.getHitChains().get(0);
+        assertNotNull(hitChain);
+        List<List<DataPlaneEntity>> chains = getHitChains(L2_BRIDG_UNTAG_OVS_OFDPA);
+        assertThat(chains.size(), is(1));
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(OUT_PORT));
+        assertThat(hitChain.getHitChain().size(), is(6));
+        assertEquals(IN_L2_BRIDG_UNTAG_PACKET, hitChain.getEgressPacket());
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(0), hitChain.getHitChain());
+    }
+
+    /**
+     * Test l2 bridging with untagged hosts for ofdpa.
+     */
+    @Test
+    public void testOfdpaL2BridingUntagged() {
+        PipelineTraceableInput pipelineInput = new PipelineTraceableInput(IN_L2_BRIDG_UNTAG_PACKET, OFDPA_CP,
+                getDataPlaneEntities(OFDPA_DRIVER, L2_BRIDG_UNTAG_OFDPA));
+        PipelineTraceable pipelineTraceable = setUpOfdpa();
+
+        PipelineTraceableOutput pipelineOutput = pipelineTraceable.apply(pipelineInput);
+        assertNotNull(pipelineOutput);
+        assertThat(pipelineOutput.getHitChains().size(), is(1));
+        assertThat(pipelineOutput.getResult(), is(PipelineTraceableResult.SUCCESS));
+
+        PipelineTraceableHitChain hitChain = pipelineOutput.getHitChains().get(0);
+        assertNotNull(hitChain);
+        List<List<DataPlaneEntity>> chains = getHitChains(L2_BRIDG_UNTAG_OFDPA);
+        assertThat(chains.size(), is(1));
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(OUT_PORT));
+        assertThat(hitChain.getHitChain().size(), is(4));
+        assertEquals(IN_L2_BRIDG_UNTAG_PACKET, hitChain.getEgressPacket());
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(0), hitChain.getHitChain());
+    }
+
+    /**
+     * Test l2 broadcast with untagged hosts for ovs-ofdpa.
+     */
+    @Test
+    public void testOvsOfdpaL2BroadcastUntagged() {
+        PipelineTraceableInput pipelineInput = new PipelineTraceableInput(IN_L2_BROAD_UNTAG_PACKET, OFDPA_CP,
+                getDataPlaneEntities(OVS_OFDPA_DRIVER, L2_BROAD_UNTAG_OVS_OFDPA));
+        PipelineTraceable pipelineTraceable = setUpOvsOfdpa();
+
+        PipelineTraceableOutput pipelineOutput = pipelineTraceable.apply(pipelineInput);
+        assertNotNull(pipelineOutput);
+        assertThat(pipelineOutput.getHitChains().size(), is(2));
+        assertThat(pipelineOutput.getResult(), is(PipelineTraceableResult.SUCCESS));
+
+        PipelineTraceableHitChain hitChain = pipelineOutput.getHitChains().get(0);
+        assertNotNull(hitChain);
+        List<List<DataPlaneEntity>> chains = getHitChains(L2_BROAD_UNTAG_OVS_OFDPA);
+        assertThat(chains.size(), is(2));
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(OUT_PORT));
+        assertThat(hitChain.getHitChain().size(), is(7));
+        assertEquals(IN_L2_BROAD_UNTAG_PACKET, hitChain.getEgressPacket());
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(0), hitChain.getHitChain());
+
+        // Dropped chain - input port!
+        hitChain = pipelineOutput.getHitChains().get(1);
+        assertNotNull(hitChain);
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(PORT));
+        assertThat(hitChain.getHitChain().size(), is(7));
+        assertEquals(IN_L2_BROAD_UNTAG_PACKET, hitChain.getEgressPacket());
+        assertTrue(hitChain.isDropped());
+        assertEquals(chains.get(1), hitChain.getHitChain());
+    }
+
+    /**
+     * Test l2 broadcast with untagged hosts for ofdpa.
+     */
+    @Test
+    public void testOfdpaL2BroadcastUntagged() {
+        PipelineTraceableInput pipelineInput = new PipelineTraceableInput(IN_L2_BROAD_UNTAG_PACKET, OFDPA_CP,
+                getDataPlaneEntities(OFDPA_DRIVER, L2_BROAD_UNTAG_OFDPA));
+        PipelineTraceable pipelineTraceable = setUpOfdpa();
+
+        PipelineTraceableOutput pipelineOutput = pipelineTraceable.apply(pipelineInput);
+        assertNotNull(pipelineOutput);
+        assertThat(pipelineOutput.getHitChains().size(), is(2));
+        assertThat(pipelineOutput.getResult(), is(PipelineTraceableResult.SUCCESS));
+
+        PipelineTraceableHitChain hitChain = pipelineOutput.getHitChains().get(0);
+        assertNotNull(hitChain);
+        List<List<DataPlaneEntity>> chains = getHitChains(L2_BROAD_UNTAG_OFDPA);
+        assertThat(chains.size(), is(2));
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(OUT_PORT));
+        assertThat(hitChain.getHitChain().size(), is(5));
+        assertEquals(IN_L2_BROAD_UNTAG_PACKET, hitChain.getEgressPacket());
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(0), hitChain.getHitChain());
+
+        // Dropped chain - input port!
+        hitChain = pipelineOutput.getHitChains().get(1);
+        assertNotNull(hitChain);
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(PORT));
+        assertThat(hitChain.getHitChain().size(), is(5));
+        assertEquals(IN_L2_BROAD_UNTAG_PACKET, hitChain.getEgressPacket());
+        assertTrue(hitChain.isDropped());
+        assertEquals(chains.get(1), hitChain.getHitChain());
+    }
+
+    /**
+     * Test l3 unicast routing for ovs-ofdpa.
+     */
+    @Test
+    public void testOvsOfdpaL3Unicast() {
+        PipelineTraceableInput pipelineInput = new PipelineTraceableInput(IN_L3_UCAST_UNTAG_PACKET, UP_OFDPA_CP,
+                getDataPlaneEntities(OVS_OFDPA_DRIVER, L3_UCAST_UNTAG_OVS_OFDPA));
+        PipelineTraceable pipelineTraceable = setUpOvsOfdpa();
+
+        PipelineTraceableOutput pipelineOutput = pipelineTraceable.apply(pipelineInput);
+        assertNotNull(pipelineOutput);
+
+        assertThat(pipelineOutput.getHitChains().size(), is(1));
+        assertThat(pipelineOutput.getResult(), is(PipelineTraceableResult.SUCCESS));
+
+        PipelineTraceableHitChain hitChain = pipelineOutput.getHitChains().get(0);
+        assertNotNull(hitChain);
+        List<List<DataPlaneEntity>> chains = getHitChains(L3_UCAST_UNTAG_OVS_OFDPA);
+        assertThat(chains.size(), is(1));
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(OUT_PORT));
+        assertThat(hitChain.getHitChain().size(), is(7));
+        assertEquals(OUT_L3_UCAST_UNTAG_PACKET, hitChain.getEgressPacket());
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(0), hitChain.getHitChain());
+    }
+
+    /**
+     * Test l3 unicast routing for ofdpa.
+     */
+    @Test
+    public void testOfdpaL3Unicast() {
+        PipelineTraceableInput pipelineInput = new PipelineTraceableInput(IN_L3_UCAST_UNTAG_PACKET, UP_OFDPA_CP,
+                getDataPlaneEntities(OFDPA_DRIVER, L3_UCAST_UNTAG_OFDPA));
+        PipelineTraceable pipelineTraceable = setUpOfdpa();
+
+        PipelineTraceableOutput pipelineOutput = pipelineTraceable.apply(pipelineInput);
+        assertNotNull(pipelineOutput);
+
+        assertThat(pipelineOutput.getHitChains().size(), is(1));
+        assertThat(pipelineOutput.getResult(), is(PipelineTraceableResult.SUCCESS));
+
+        PipelineTraceableHitChain hitChain = pipelineOutput.getHitChains().get(0);
+        assertNotNull(hitChain);
+        List<List<DataPlaneEntity>> chains = getHitChains(L3_UCAST_UNTAG_OFDPA);
+        assertThat(chains.size(), is(1));
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(OUT_PORT));
+        assertThat(hitChain.getHitChain().size(), is(6));
+        assertEquals(OUT_L3_UCAST_UNTAG_PACKET, hitChain.getEgressPacket());
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(0), hitChain.getHitChain());
+    }
+
+    /**
+     * Test l3 ecmp routing for ovs-ofdpa.
+     */
+    @Test
+    public void testOvsOfdpaL3Ecmp() {
+        PipelineTraceableInput pipelineInput = new PipelineTraceableInput(IN_L3_ECMP_PACKET, OFDPA_CP,
+                getDataPlaneEntities(OVS_OFDPA_DRIVER, L3_ECMP_OVS_OFDPA));
+        PipelineTraceable pipelineTraceable = setUpOvsOfdpa();
+
+        PipelineTraceableOutput pipelineOutput = pipelineTraceable.apply(pipelineInput);
+        assertNotNull(pipelineOutput);
+
+        assertThat(pipelineOutput.getHitChains().size(), is(2));
+        assertThat(pipelineOutput.getResult(), is(PipelineTraceableResult.SUCCESS));
+
+        PipelineTraceableHitChain hitChain = pipelineOutput.getHitChains().get(0);
+        assertNotNull(hitChain);
+        List<List<DataPlaneEntity>> chains = getHitChains(L3_ECMP_OVS_OFDPA);
+        assertThat(chains.size(), is(2));
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(UP_PORT));
+        assertThat(hitChain.getHitChain().size(), is(9));
+        assertEquals(OUT_L3_ECMP_PACKET, hitChain.getEgressPacket());
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(0), hitChain.getHitChain());
+
+        // 2nd spine!
+        hitChain = pipelineOutput.getHitChains().get(1);
+        assertNotNull(hitChain);
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(UP_PORT_1));
+        assertThat(hitChain.getHitChain().size(), is(9));
+        assertEquals(OUT_L3_ECMP_PACKET_1, hitChain.getEgressPacket());
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(1), hitChain.getHitChain());
+    }
+
+    /**
+     * Test l3 ecmp routing for ofdpa.
+     */
+    @Test
+    public void testOfdpaL3Ecmp() {
+        PipelineTraceableInput pipelineInput = new PipelineTraceableInput(IN_L3_ECMP_PACKET, OFDPA_CP,
+                getDataPlaneEntities(OFDPA_DRIVER, L3_ECMP_OFDPA));
+        PipelineTraceable pipelineTraceable = setUpOfdpa();
+
+        PipelineTraceableOutput pipelineOutput = pipelineTraceable.apply(pipelineInput);
+        assertNotNull(pipelineOutput);
+
+        assertThat(pipelineOutput.getHitChains().size(), is(2));
+        assertThat(pipelineOutput.getResult(), is(PipelineTraceableResult.SUCCESS));
+
+        PipelineTraceableHitChain hitChain = pipelineOutput.getHitChains().get(0);
+        assertNotNull(hitChain);
+        List<List<DataPlaneEntity>> chains = getHitChains(L3_ECMP_OFDPA);
+        assertThat(chains.size(), is(2));
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(UP_PORT));
+        assertThat(hitChain.getHitChain().size(), is(8));
+        assertEquals(OUT_L3_ECMP_PACKET_OFDPA, hitChain.getEgressPacket());
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(0), hitChain.getHitChain());
+
+        hitChain = pipelineOutput.getHitChains().get(1);
+        assertNotNull(hitChain);
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(UP_PORT_1));
+        assertThat(hitChain.getHitChain().size(), is(8));
+        assertEquals(OUT_L3_ECMP_PACKET_OFDPA_1, hitChain.getEgressPacket());
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(1), hitChain.getHitChain());
+    }
+
+    /**
+     * Test mpls ecmp routing for ovs-ofdpa.
+     */
+    @Test
+    public void testOvsOfdpaMplsEcmp() {
+        PipelineTraceableInput pipelineInput = new PipelineTraceableInput(IN_MPLS_ECMP_PACKET, UP_OFDPA_CP,
+                getDataPlaneEntities(OVS_OFDPA_DRIVER, MPLS_ECMP_OVS_OFDPA));
+        PipelineTraceable pipelineTraceable = setUpOvsOfdpa();
+
+        PipelineTraceableOutput pipelineOutput = pipelineTraceable.apply(pipelineInput);
+        assertNotNull(pipelineOutput);
+
+        assertThat(pipelineOutput.getHitChains().size(), is(1));
+        assertThat(pipelineOutput.getResult(), is(PipelineTraceableResult.SUCCESS));
+
+        PipelineTraceableHitChain hitChain = pipelineOutput.getHitChains().get(0);
+        assertNotNull(hitChain);
+        List<List<DataPlaneEntity>> chains = getHitChains(MPLS_ECMP_OVS_OFDPA);
+        assertThat(chains.size(), is(1));
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(UP_PORT_1));
+        assertThat(hitChain.getHitChain().size(), is(9));
+        assertEquals(OUT_MPLS_ECMP_PACKET, hitChain.getEgressPacket());
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(0), hitChain.getHitChain());
+    }
+
+    /**
+     * Test mpls ecmp routing for ofdpa.
+     */
+    @Test
+    public void testOfdpaMplsEcmp() {
+        PipelineTraceableInput pipelineInput = new PipelineTraceableInput(IN_MPLS_ECMP_PACKET_OFDPA, OFDPA_CP,
+                getDataPlaneEntities(OFDPA_DRIVER, MPLS_ECMP_OFDPA));
+        PipelineTraceable pipelineTraceable = setUpOfdpa();
+
+        PipelineTraceableOutput pipelineOutput = pipelineTraceable.apply(pipelineInput);
+        assertNotNull(pipelineOutput);
+
+        assertThat(pipelineOutput.getHitChains().size(), is(1));
+        assertThat(pipelineOutput.getResult(), is(PipelineTraceableResult.SUCCESS));
+
+        PipelineTraceableHitChain hitChain = pipelineOutput.getHitChains().get(0);
+        assertNotNull(hitChain);
+        List<List<DataPlaneEntity>> chains = getHitChains(MPLS_ECMP_OFDPA);
+        assertThat(chains.size(), is(1));
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(UP_PORT_1));
+        assertThat(hitChain.getHitChain().size(), is(7));
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(0), hitChain.getHitChain());
+        assertEquals(OUT_MPLS_ECMP_PACKET, hitChain.getEgressPacket());
+    }
+
+    /**
+     * Test failure due l2 flood group with no buckets for ovs-ofdpa.
+     */
+    @Test
+    public void testOvsOfdpaL2BroadEmpty() {
+        PipelineTraceableInput pipelineInput = new PipelineTraceableInput(IN_L2_BROAD_UNTAG_PACKET, OFDPA_CP,
+                getDataPlaneEntities(OVS_OFDPA_DRIVER, L2_BROAD_EMPTY_OVS_OFDPA));
+        PipelineTraceable pipelineTraceable = setUpOvsOfdpa();
+
+        PipelineTraceableOutput pipelineOutput = pipelineTraceable.apply(pipelineInput);
+        assertNotNull(pipelineOutput);
+        assertThat(pipelineOutput.getHitChains().size(), is(1));
+        assertThat(pipelineOutput.getResult(), is(PipelineTraceableResult.NO_GROUP_MEMBERS));
+
+        PipelineTraceableHitChain hitChain = pipelineOutput.getHitChains().get(0);
+        assertNotNull(hitChain);
+        List<List<DataPlaneEntity>> chains = getHitChains(L2_BROAD_EMPTY_OVS_OFDPA);
+        assertThat(chains.size(), is(1));
+
+        assertNull(hitChain.getOutputPort());
+        assertThat(hitChain.getHitChain().size(), is(6));
+        assertEquals(OUT_L2_BROAD_EMPTY, hitChain.getEgressPacket());
+        assertTrue(hitChain.isDropped());
+        assertEquals(chains.get(0), hitChain.getHitChain());
+    }
+
+    /**
+     * Test failure due l2 flood group with no buckets for ofdpa.
+     */
+    @Test
+    public void testOfdpaL2BroadEmpty() {
+        PipelineTraceableInput pipelineInput = new PipelineTraceableInput(IN_L2_BROAD_UNTAG_PACKET, OFDPA_CP,
+                getDataPlaneEntities(OFDPA_DRIVER, L2_BROAD_EMPTY_OFDPA));
+        PipelineTraceable pipelineTraceable = setUpOfdpa();
+
+        PipelineTraceableOutput pipelineOutput = pipelineTraceable.apply(pipelineInput);
+        assertNotNull(pipelineOutput);
+        assertThat(pipelineOutput.getHitChains().size(), is(1));
+        assertThat(pipelineOutput.getResult(), is(PipelineTraceableResult.NO_GROUP_MEMBERS));
+
+        PipelineTraceableHitChain hitChain = pipelineOutput.getHitChains().get(0);
+        assertNotNull(hitChain);
+        List<List<DataPlaneEntity>> chains = getHitChains(L2_BROAD_EMPTY_OFDPA);
+        assertThat(chains.size(), is(1));
+
+        assertNull(hitChain.getOutputPort());
+        assertThat(hitChain.getHitChain().size(), is(4));
+        assertEquals(OUT_L2_BROAD_EMPTY, hitChain.getEgressPacket());
+        assertTrue(hitChain.isDropped());
+        assertEquals(chains.get(0), hitChain.getHitChain());
+    }
+
+    /**
+     * Test l2 bridging with l2 interface group that has actions not in order for ovs-ofdpa.
+     */
+    @Test
+    public void testOvsOfdpaL2BridingNotOrdered() {
+        PipelineTraceableInput pipelineInput = new PipelineTraceableInput(IN_L2_BRIDG_UNTAG_PACKET, OFDPA_CP,
+                getDataPlaneEntities(OVS_OFDPA_DRIVER, L2_BRIDG_NOT_ORDERED_OVS_OFDPA));
+        PipelineTraceable pipelineTraceable = setUpOvsOfdpa();
+
+        PipelineTraceableOutput pipelineOutput = pipelineTraceable.apply(pipelineInput);
+        assertNotNull(pipelineOutput);
+        assertThat(pipelineOutput.getHitChains().size(), is(1));
+        assertThat(pipelineOutput.getResult(), is(PipelineTraceableResult.SUCCESS));
+
+        PipelineTraceableHitChain hitChain = pipelineOutput.getHitChains().get(0);
+        assertNotNull(hitChain);
+        List<List<DataPlaneEntity>> chains = getHitChains(L2_BRIDG_NOT_ORDERED_OVS_OFDPA);
+        assertThat(chains.size(), is(1));
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(OUT_PORT));
+        assertThat(hitChain.getHitChain().size(), is(6));
+        assertEquals(IN_L2_BRIDG_UNTAG_PACKET, hitChain.getEgressPacket());
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(0), hitChain.getHitChain());
+    }
+
+    /**
+     * Test l2 bridging with l2 interface group that has actions not in order for ofdpa.
+     */
+    @Test
+    public void testOfdpaL2BridingNotOrdered() {
+        PipelineTraceableInput pipelineInput = new PipelineTraceableInput(IN_L2_BRIDG_UNTAG_PACKET, OFDPA_CP,
+                getDataPlaneEntities(OFDPA_DRIVER, L2_BRIDG_NOT_ORDERED_OFDPA));
+        PipelineTraceable pipelineTraceable = setUpOfdpa();
+
+        PipelineTraceableOutput pipelineOutput = pipelineTraceable.apply(pipelineInput);
+        assertNotNull(pipelineOutput);
+        assertThat(pipelineOutput.getHitChains().size(), is(1));
+        assertThat(pipelineOutput.getResult(), is(PipelineTraceableResult.SUCCESS));
+
+        PipelineTraceableHitChain hitChain = pipelineOutput.getHitChains().get(0);
+        assertNotNull(hitChain);
+        List<List<DataPlaneEntity>> chains = getHitChains(L2_BRIDG_NOT_ORDERED_OFDPA);
+        assertThat(chains.size(), is(1));
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(OUT_PORT));
+        assertThat(hitChain.getHitChain().size(), is(4));
+        assertEquals(IN_L2_BRIDG_UNTAG_PACKET, hitChain.getEgressPacket());
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(0), hitChain.getHitChain());
+    }
+
+}
\ No newline at end of file
diff --git a/drivers/default/src/test/java/org/onosproject/driver/traceable/TraceableDataPlaneObjects.java b/drivers/default/src/test/java/org/onosproject/driver/traceable/TraceableDataPlaneObjects.java
new file mode 100644
index 0000000..5e52dde
--- /dev/null
+++ b/drivers/default/src/test/java/org/onosproject/driver/traceable/TraceableDataPlaneObjects.java
@@ -0,0 +1,1000 @@
+/*
+ * Copyright 2020-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.driver.traceable;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import org.onlab.packet.VlanId;
+import org.onosproject.core.DefaultApplicationId;
+import org.onosproject.core.GroupId;
+import org.onosproject.driver.extensions.Ofdpa3MplsType;
+import org.onosproject.driver.extensions.Ofdpa3SetMplsType;
+import org.onosproject.driver.pipeline.ofdpa.OfdpaPipelineUtility;
+import org.onosproject.driver.pipeline.ofdpa.OvsOfdpaPipeline;
+import org.onosproject.net.DataPlaneEntity;
+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 java.util.List;
+
+import static org.onlab.packet.EthType.EtherType.ARP;
+import static org.onlab.packet.EthType.EtherType.IPV4;
+import static org.onlab.packet.EthType.EtherType.LLDP;
+import static org.onlab.packet.EthType.EtherType.MPLS_UNICAST;
+import static org.onosproject.driver.traceable.TraceableTestObjects.*;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.ARP_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.ARP_OVS_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L2_BRIDG_NOT_ORDERED_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L2_BRIDG_NOT_ORDERED_OVS_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L2_BRIDG_UNTAG_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L2_BRIDG_UNTAG_OVS_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L2_BROAD_EMPTY_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L2_BROAD_EMPTY_OVS_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L2_BROAD_UNTAG_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L2_BROAD_UNTAG_OVS_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L3_ECMP_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L3_ECMP_OVS_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L3_UCAST_UNTAG_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L3_UCAST_UNTAG_OVS_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.MPLS_ECMP_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.MPLS_ECMP_OVS_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.PUNT_IP_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.PUNT_IP_OVS_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.PUNT_LLDP_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.PUNT_LLDP_OVS_OFDPA;
+
+/**
+ * Helper class for dataplane objects related to the Traceable tests.
+ */
+final class TraceableDataPlaneObjects {
+
+    private TraceableDataPlaneObjects() {
+        // Banning construction
+    }
+
+    // Groups
+    private static final GroupId L2_FLOOD_GROUP_ID = GroupId.valueOf(0x40140000);
+
+    private static final GroupId PUNT_GROUP_ID = GroupId.valueOf(OvsOfdpaPipeline.POP_VLAN_PUNT_GROUP_ID);
+    private static final TrafficTreatment PUNT_BUCKET_TREATMENT = DefaultTrafficTreatment.builder()
+            .popVlan()
+            .punt()
+            .build();
+    private static final GroupBucket PUNT_BUCKET = DefaultGroupBucket.createIndirectGroupBucket(
+            PUNT_BUCKET_TREATMENT);
+    private static final GroupBuckets PUNT_BUCKETS = new GroupBuckets(ImmutableList.of(PUNT_BUCKET));
+    private static final Group PUNT_GROUP = new DefaultGroup(PUNT_GROUP_ID, OFDPA_DEVICE,
+            Group.Type.INDIRECT, PUNT_BUCKETS);
+
+    private static final GroupId L2_IFACE_GROUP_ID = GroupId.valueOf(0x140000 | (int) OUT_PORT.toLong());
+    private static final TrafficTreatment L2_IFACE_BUCKET_TREATMENT = DefaultTrafficTreatment.builder()
+            .popVlan()
+            .setOutput(OUT_PORT)
+            .build();
+    private static final GroupBucket L2_IFACE_BUCKET = DefaultGroupBucket.createIndirectGroupBucket(
+            L2_IFACE_BUCKET_TREATMENT);
+    private static final GroupBuckets L2_IFACE_BUCKETS = new GroupBuckets(ImmutableList.of(L2_IFACE_BUCKET));
+    private static final Group L2_IFACE_GROUP = new DefaultGroup(L2_IFACE_GROUP_ID, OFDPA_DEVICE,
+            Group.Type.INDIRECT, L2_IFACE_BUCKETS);
+
+    private static final GroupId L2_IFACE_GROUP_ID_1 = GroupId.valueOf(0x140000 | (int) PORT.toLong());
+    private static final TrafficTreatment L2_IFACE_BUCKET_TREATMENT_1 = DefaultTrafficTreatment.builder()
+            .popVlan()
+            .setOutput(PORT)
+            .build();
+    private static final GroupBucket L2_IFACE_BUCKET_1 = DefaultGroupBucket.createIndirectGroupBucket(
+            L2_IFACE_BUCKET_TREATMENT_1);
+    private static final GroupBuckets L2_IFACE_BUCKETS_1 = new GroupBuckets(ImmutableList.of(L2_IFACE_BUCKET_1));
+    private static final Group L2_IFACE_GROUP_1 = new DefaultGroup(L2_IFACE_GROUP_ID_1, OFDPA_DEVICE,
+            Group.Type.INDIRECT, L2_IFACE_BUCKETS_1);
+
+    private static final GroupId L2_IFACE_GROUP_ID_2 = GroupId.valueOf(0xffe000 | (int) UP_PORT.toLong());
+    private static final TrafficTreatment L2_IFACE_BUCKET_TREATMENT_2 = DefaultTrafficTreatment.builder()
+            .popVlan()
+            .setOutput(UP_PORT)
+            .build();
+    private static final GroupBucket L2_IFACE_BUCKET_2 = DefaultGroupBucket.createIndirectGroupBucket(
+            L2_IFACE_BUCKET_TREATMENT_2);
+    private static final GroupBuckets L2_IFACE_BUCKETS_2 = new GroupBuckets(ImmutableList.of(L2_IFACE_BUCKET_2));
+    private static final Group L2_IFACE_GROUP_2 = new DefaultGroup(L2_IFACE_GROUP_ID_2, OFDPA_DEVICE,
+            Group.Type.INDIRECT, L2_IFACE_BUCKETS_2);
+
+    private static final GroupId L2_IFACE_GROUP_ID_3 = GroupId.valueOf(0xffe000 | (int) UP_PORT_1.toLong());
+    private static final TrafficTreatment L2_IFACE_BUCKET_TREATMENT_3 = DefaultTrafficTreatment.builder()
+            .popVlan()
+            .setOutput(UP_PORT_1)
+            .build();
+    private static final GroupBucket L2_IFACE_BUCKET_3 = DefaultGroupBucket.createIndirectGroupBucket(
+            L2_IFACE_BUCKET_TREATMENT_3);
+    private static final GroupBuckets L2_IFACE_BUCKETS_3 = new GroupBuckets(ImmutableList.of(L2_IFACE_BUCKET_3));
+    private static final Group L2_IFACE_GROUP_3 = new DefaultGroup(L2_IFACE_GROUP_ID_3, OFDPA_DEVICE,
+            Group.Type.INDIRECT, L2_IFACE_BUCKETS_3);
+
+    private static final GroupId L2_IFACE_GROUP_ID_NOT_ORDERED = GroupId.valueOf(0x140000 | (int) OUT_PORT.toLong());
+    private static final TrafficTreatment L2_IFACE_BUCKET_TREATMENT_NOT_ORDERED = DefaultTrafficTreatment.builder()
+            .setOutput(OUT_PORT)
+            .popVlan()
+            .build();
+    private static final GroupBucket L2_IFACE_BUCKET_NOT_ORDERED = DefaultGroupBucket.createIndirectGroupBucket(
+            L2_IFACE_BUCKET_TREATMENT_NOT_ORDERED);
+    private static final GroupBuckets L2_IFACE_BUCKETS_NOT_ORDERED = new GroupBuckets(ImmutableList.of(
+            L2_IFACE_BUCKET_NOT_ORDERED));
+    private static final Group L2_IFACE_GROUP_NOT_ORDERED = new DefaultGroup(L2_IFACE_GROUP_ID_NOT_ORDERED,
+            OFDPA_DEVICE, Group.Type.INDIRECT, L2_IFACE_BUCKETS_NOT_ORDERED);
+
+    private static final TrafficTreatment L2_FLOOD_BUCKET_TREATMENT = DefaultTrafficTreatment.builder()
+            .group(L2_IFACE_GROUP_ID)
+            .build();
+    private static final GroupBucket L2_FLOOD_BUCKET = DefaultGroupBucket.createAllGroupBucket(
+            L2_FLOOD_BUCKET_TREATMENT);
+    private static final TrafficTreatment L2_FLOOD_BUCKET_TREATMENT_1 = DefaultTrafficTreatment.builder()
+            .group(L2_IFACE_GROUP_ID_1)
+            .build();
+    private static final GroupBucket L2_FLOOD_BUCKET_1 = DefaultGroupBucket.createAllGroupBucket(
+            L2_FLOOD_BUCKET_TREATMENT_1);
+    private static final GroupBuckets L2_FLOOD_BUCKETS = new GroupBuckets(ImmutableList.of(
+            L2_FLOOD_BUCKET, L2_FLOOD_BUCKET_1));
+    private static final Group L2_FLOOD_GROUP = new DefaultGroup(L2_FLOOD_GROUP_ID, OFDPA_DEVICE,
+            Group.Type.ALL, L2_FLOOD_BUCKETS);
+
+    private static final GroupBuckets L2_FLOOD_EMPTY_BUCKETS = new GroupBuckets(ImmutableList.of());
+    private static final Group L2_FLOOD_EMPTY_GROUP = new DefaultGroup(L2_FLOOD_GROUP_ID, OFDPA_DEVICE,
+            Group.Type.ALL, L2_FLOOD_EMPTY_BUCKETS);
+
+    private static final GroupId L3_UCAST_GROUP_ID = GroupId.valueOf(0x20000026);
+    private static final TrafficTreatment L3_UCAST_BUCKET_TREATMENT = DefaultTrafficTreatment.builder()
+            .setEthSrc(LEAF_MAC)
+            .setEthDst(HOST_MAC)
+            .setVlanId(HOST_VLAN)
+            .group(L2_IFACE_GROUP_ID)
+            .build();
+    private static final GroupBucket L3_UCAST_BUCKET = DefaultGroupBucket.createIndirectGroupBucket(
+            L3_UCAST_BUCKET_TREATMENT);
+    private static final GroupBuckets L3_UCAST_BUCKETS = new GroupBuckets(ImmutableList.of(L3_UCAST_BUCKET));
+    private static final Group L3_UCAST_GROUP = new DefaultGroup(L3_UCAST_GROUP_ID, OFDPA_DEVICE,
+            Group.Type.INDIRECT, L3_UCAST_BUCKETS);
+
+    private static final GroupId L3_UCAST_GROUP_ID_1 = GroupId.valueOf(0x20000027);
+    private static final TrafficTreatment L3_UCAST_BUCKET_TREATMENT_1 = DefaultTrafficTreatment.builder()
+            .setEthSrc(LEAF_MAC)
+            .setEthDst(SPINE_MAC)
+            .setVlanId(DEFAULT_VLAN)
+            .group(L2_IFACE_GROUP_ID_3)
+            .build();
+    private static final GroupBucket L3_UCAST_BUCKET_1 = DefaultGroupBucket.createIndirectGroupBucket(
+            L3_UCAST_BUCKET_TREATMENT_1);
+    private static final GroupBuckets L3_UCAST_BUCKETS_1 = new GroupBuckets(ImmutableList.of(L3_UCAST_BUCKET_1));
+    private static final Group L3_UCAST_GROUP_1 = new DefaultGroup(L3_UCAST_GROUP_ID_1, OFDPA_DEVICE,
+            Group.Type.INDIRECT, L3_UCAST_BUCKETS_1);
+
+    private static final GroupId MPLS_IFACE_GROUP_ID = GroupId.valueOf(0x9000000c);
+    private static final TrafficTreatment MPLS_IFACE_BUCKET_TREATMENT = DefaultTrafficTreatment.builder()
+            .setEthSrc(LEAF_MAC)
+            .setEthDst(SPINE_MAC)
+            .setVlanId(DEFAULT_VLAN)
+            .group(L2_IFACE_GROUP_ID_2)
+            .build();
+    private static final GroupBucket MPLS_IFACE_BUCKET = DefaultGroupBucket.createIndirectGroupBucket(
+            MPLS_IFACE_BUCKET_TREATMENT);
+    private static final GroupBuckets MPLS_IFACE_BUCKETS = new GroupBuckets(ImmutableList.of(MPLS_IFACE_BUCKET));
+    private static final Group MPLS_IFACE_GROUP = new DefaultGroup(MPLS_IFACE_GROUP_ID, OFDPA_DEVICE,
+            Group.Type.INDIRECT, MPLS_IFACE_BUCKETS);
+
+    private static final GroupId MPLS_IFACE_GROUP_ID_1 = GroupId.valueOf(0x9000000d);
+    private static final TrafficTreatment MPLS_IFACE_BUCKET_TREATMENT_1 = DefaultTrafficTreatment.builder()
+            .setEthSrc(LEAF_MAC)
+            .setEthDst(SPINE_MAC_1)
+            .setVlanId(DEFAULT_VLAN)
+            .group(L2_IFACE_GROUP_ID_3)
+            .build();
+    private static final GroupBucket MPLS_IFACE_BUCKET_1 = DefaultGroupBucket.createIndirectGroupBucket(
+            MPLS_IFACE_BUCKET_TREATMENT_1);
+    private static final GroupBuckets MPLS_IFACE_BUCKETS_1 = new GroupBuckets(ImmutableList.of(MPLS_IFACE_BUCKET_1));
+    private static final Group MPLS_IFACE_GROUP_1 = new DefaultGroup(MPLS_IFACE_GROUP_ID_1, OFDPA_DEVICE,
+            Group.Type.INDIRECT, MPLS_IFACE_BUCKETS_1);
+
+    private static final GroupId MPLS_L3VPN_GROUP_ID = GroupId.valueOf(0x9200000d);
+    private static final TrafficTreatment MPLS_L3VPN_BUCKET_TREATMENT = DefaultTrafficTreatment.builder()
+            .popVlan()
+            .pushMpls()
+            .setMpls(MPLS_LABEL)
+            .group(MPLS_IFACE_GROUP_ID)
+            .pushVlan()
+            .setVlanId(VlanId.vlanId(VlanId.RESERVED))
+            .build();
+    private static final GroupBucket MPLS_L3VPN_BUCKET = DefaultGroupBucket.createIndirectGroupBucket(
+            MPLS_L3VPN_BUCKET_TREATMENT);
+    private static final GroupBuckets MPLS_L3VPN_BUCKETS = new GroupBuckets(ImmutableList.of(MPLS_L3VPN_BUCKET));
+    private static final Group MPLS_L3VPN_GROUP = new DefaultGroup(MPLS_L3VPN_GROUP_ID, OFDPA_DEVICE,
+            Group.Type.INDIRECT, MPLS_L3VPN_BUCKETS);
+
+    private static final GroupId MPLS_L3VPN_GROUP_ID_1 = GroupId.valueOf(0x9200000e);
+    private static final TrafficTreatment MPLS_L3VPN_BUCKET_TREATMENT_1 = DefaultTrafficTreatment.builder()
+            .popVlan()
+            .pushMpls()
+            .setMpls(MPLS_LABEL)
+            .group(MPLS_IFACE_GROUP_ID_1)
+            .pushVlan()
+            .setVlanId(VlanId.vlanId(VlanId.RESERVED))
+            .build();
+    private static final GroupBucket MPLS_L3VPN_BUCKET_1 = DefaultGroupBucket.createIndirectGroupBucket(
+            MPLS_L3VPN_BUCKET_TREATMENT_1);
+    private static final GroupBuckets MPLS_L3VPN_BUCKETS_1 = new GroupBuckets(ImmutableList.of(MPLS_L3VPN_BUCKET_1));
+    private static final Group MPLS_L3VPN_GROUP_1 = new DefaultGroup(MPLS_L3VPN_GROUP_ID_1, OFDPA_DEVICE,
+            Group.Type.INDIRECT, MPLS_L3VPN_BUCKETS_1);
+
+    private static final TrafficTreatment MPLS_L3VPN_OFDPA_BUCKET_TREATMENT = DefaultTrafficTreatment.builder()
+            .pushMpls()
+            .setMpls(MPLS_LABEL)
+            .group(MPLS_IFACE_GROUP_ID)
+            .copyTtlOut()
+            .setMplsBos(true)
+            .build();
+    private static final GroupBucket MPLS_L3VPN_OFDPA_BUCKET = DefaultGroupBucket.createIndirectGroupBucket(
+            MPLS_L3VPN_OFDPA_BUCKET_TREATMENT);
+    private static final GroupBuckets MPLS_L3VPN_OFDPA_BUCKETS = new GroupBuckets(ImmutableList.of(
+            MPLS_L3VPN_OFDPA_BUCKET));
+    private static final Group MPLS_L3VPN_OFDPA_GROUP = new DefaultGroup(MPLS_L3VPN_GROUP_ID, OFDPA_DEVICE,
+            Group.Type.INDIRECT, MPLS_L3VPN_OFDPA_BUCKETS);
+
+    private static final TrafficTreatment MPLS_L3VPN_OFDPA_BUCKET_TREATMENT_1 = DefaultTrafficTreatment.builder()
+            .pushMpls()
+            .setMpls(MPLS_LABEL)
+            .group(MPLS_IFACE_GROUP_ID_1)
+            .copyTtlOut()
+            .setMplsBos(true)
+            .build();
+    private static final GroupBucket MPLS_L3VPN_OFDPA_BUCKET_1 = DefaultGroupBucket.createIndirectGroupBucket(
+            MPLS_L3VPN_OFDPA_BUCKET_TREATMENT_1);
+    private static final GroupBuckets MPLS_L3VPN_OFDPA_BUCKETS_1 = new GroupBuckets(ImmutableList.of(
+            MPLS_L3VPN_OFDPA_BUCKET_1));
+    private static final Group MPLS_L3VPN_OFDPA_GROUP_1 = new DefaultGroup(MPLS_L3VPN_GROUP_ID_1, OFDPA_DEVICE,
+            Group.Type.INDIRECT, MPLS_L3VPN_OFDPA_BUCKETS_1);
+
+    private static final GroupId L3_ECMP_GROUP_ID = GroupId.valueOf(0x7000000e);
+    private static final TrafficTreatment L3_ECMP_BUCKET_TREATMENT = DefaultTrafficTreatment.builder()
+            .group(MPLS_L3VPN_GROUP_ID)
+            .build();
+    private static final GroupBucket L3_ECMP_BUCKET = DefaultGroupBucket.createSelectGroupBucket(
+            L3_ECMP_BUCKET_TREATMENT);
+    private static final TrafficTreatment L3_ECMP_BUCKET_TREATMENT_1 = DefaultTrafficTreatment.builder()
+            .group(MPLS_L3VPN_GROUP_ID_1)
+            .build();
+    private static final GroupBucket L3_ECMP_BUCKET_1 = DefaultGroupBucket.createSelectGroupBucket(
+            L3_ECMP_BUCKET_TREATMENT_1);
+    private static final GroupBuckets L3_ECMP_BUCKETS = new GroupBuckets(ImmutableList.of(L3_ECMP_BUCKET,
+            L3_ECMP_BUCKET_1));
+    private static final Group L3_ECMP_GROUP = new DefaultGroup(L3_ECMP_GROUP_ID, OFDPA_DEVICE,
+            Group.Type.SELECT, L3_ECMP_BUCKETS);
+
+    private static final TrafficTreatment L3_ECMP_OFDPA_BUCKET_TREATMENT = DefaultTrafficTreatment.builder()
+            .group(MPLS_L3VPN_GROUP_ID)
+            .build();
+    private static final GroupBucket L3_ECMP_OFDPA_BUCKET = DefaultGroupBucket.createSelectGroupBucket(
+            L3_ECMP_OFDPA_BUCKET_TREATMENT);
+    private static final TrafficTreatment L3_ECMP_OFDPA_BUCKET_TREATMENT_1 = DefaultTrafficTreatment.builder()
+            .group(MPLS_L3VPN_GROUP_ID_1)
+            .build();
+    private static final GroupBucket L3_ECMP_OFDPA_BUCKET_1 = DefaultGroupBucket.createSelectGroupBucket(
+            L3_ECMP_OFDPA_BUCKET_TREATMENT_1);
+    private static final GroupBuckets L3_ECMP_OFDPA_BUCKETS = new GroupBuckets(ImmutableList.of(L3_ECMP_OFDPA_BUCKET,
+            L3_ECMP_OFDPA_BUCKET_1));
+    private static final Group L3_ECMP_OFDPA_GROUP = new DefaultGroup(L3_ECMP_GROUP_ID, OFDPA_DEVICE,
+            Group.Type.SELECT, L3_ECMP_OFDPA_BUCKETS);
+
+    private static final GroupId MPLS_ECMP_GROUP_ID = GroupId.valueOf(0x7000000f);
+    private static final TrafficTreatment MPLS_ECMP_BUCKET_TREATMENT = DefaultTrafficTreatment.builder()
+            .group(L3_UCAST_GROUP_ID_1)
+            .build();
+    private static final GroupBucket MPLS_ECMP_BUCKET = DefaultGroupBucket.createSelectGroupBucket(
+            MPLS_ECMP_BUCKET_TREATMENT);
+    private static final GroupBuckets MPLS_ECMP_BUCKETS = new GroupBuckets(ImmutableList.of(MPLS_ECMP_BUCKET));
+    private static final Group MPLS_ECMP_GROUP = new DefaultGroup(MPLS_ECMP_GROUP_ID, OFDPA_DEVICE,
+            Group.Type.SELECT, MPLS_ECMP_BUCKETS);
+
+    // Flows
+    private static final TrafficSelector EMPTY_SELECTOR = DefaultTrafficSelector.emptySelector();
+    private static final TrafficTreatment EMPTY_TREATMENT = DefaultTrafficTreatment.emptyTreatment();
+
+    private static final TrafficTreatment TABLE_0_FLOW_TREATMENT = DefaultTrafficTreatment.builder()
+            .transition(OfdpaPipelineUtility.VLAN_TABLE)
+            .build();
+    private static final FlowRule TABLE_0_MISS_OVS = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.PORT_TABLE)
+            .withPriority(0)
+            .withSelector(EMPTY_SELECTOR)
+            .withTreatment(TABLE_0_FLOW_TREATMENT)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_0_MISS_FLOW_ENTRY_OVS = new DefaultFlowEntry(TABLE_0_MISS_OVS);
+
+    private static final TrafficSelector TABLE_10_FLOW_SELECTOR = DefaultTrafficSelector.builder()
+            .matchInPort(PORT)
+            .matchVlanId(VlanId.NONE)
+            .build();
+    private static final TrafficTreatment TABLE_10_FLOW_TREATMENT = DefaultTrafficTreatment.builder()
+            .pushVlan()
+            .setVlanId(HOST_VLAN)
+            .transition(OfdpaPipelineUtility.TMAC_TABLE)
+            .build();
+    private static final FlowRule TABLE_10_FLOW = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.VLAN_TABLE)
+            .withPriority(32768)
+            .withSelector(TABLE_10_FLOW_SELECTOR)
+            .withTreatment(TABLE_10_FLOW_TREATMENT)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_10_FLOW_ENTRY = new DefaultFlowEntry(TABLE_10_FLOW);
+
+    private static final TrafficTreatment TABLE_10_FLOW_TREATMENT_1 = DefaultTrafficTreatment.builder()
+            .setVlanId(HOST_VLAN)
+            .transition(OfdpaPipelineUtility.TMAC_TABLE)
+            .build();
+    private static final FlowRule TABLE_10_FLOW_1 = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.VLAN_TABLE)
+            .withPriority(32768)
+            .withSelector(TABLE_10_FLOW_SELECTOR)
+            .withTreatment(TABLE_10_FLOW_TREATMENT_1)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_10_FLOW_ENTRY_1 = new DefaultFlowEntry(TABLE_10_FLOW_1);
+
+    private static final TrafficSelector TABLE_10_FLOW_SELECTOR_2 = DefaultTrafficSelector.builder()
+            .matchInPort(PORT)
+            .matchVlanId(HOST_VLAN)
+            .build();
+    private static final TrafficTreatment TABLE_10_FLOW_TREATMENT_2 = DefaultTrafficTreatment.builder()
+            .transition(OfdpaPipelineUtility.TMAC_TABLE)
+            .build();
+    private static final FlowRule TABLE_10_FLOW_2 = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.VLAN_TABLE)
+            .withPriority(32768)
+            .withSelector(TABLE_10_FLOW_SELECTOR_2)
+            .withTreatment(TABLE_10_FLOW_TREATMENT_2)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_10_FLOW_ENTRY_2 = new DefaultFlowEntry(TABLE_10_FLOW_2);
+
+    private static final TrafficSelector TABLE_10_DEFAULT_FLOW_SELECTOR = DefaultTrafficSelector.builder()
+            .matchInPort(UP_PORT)
+            .matchVlanId(VlanId.NONE)
+            .build();
+    private static final TrafficTreatment TABLE_10_DEFAULT_FLOW_TREATMENT = DefaultTrafficTreatment.builder()
+            .pushVlan()
+            .setVlanId(DEFAULT_VLAN)
+            .transition(OfdpaPipelineUtility.TMAC_TABLE)
+            .build();
+    private static final FlowRule TABLE_10_DEFAULT_FLOW = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.VLAN_TABLE)
+            .withPriority(32768)
+            .withSelector(TABLE_10_DEFAULT_FLOW_SELECTOR)
+            .withTreatment(TABLE_10_DEFAULT_FLOW_TREATMENT)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_10_DEFAULT_FLOW_ENTRY = new DefaultFlowEntry(TABLE_10_DEFAULT_FLOW);
+
+    private static final TrafficSelector TABLE_10_DEFAULT_FLOW_SELECTOR_1 = DefaultTrafficSelector.builder()
+            .matchInPort(UP_PORT)
+            .matchVlanId(VlanId.NONE)
+            .build();
+    private static final TrafficTreatment TABLE_10_DEFAULT_FLOW_TREATMENT_1 = DefaultTrafficTreatment.builder()
+            .setVlanId(DEFAULT_VLAN)
+            .transition(OfdpaPipelineUtility.TMAC_TABLE)
+            .build();
+    private static final FlowRule TABLE_10_DEFAULT_FLOW_1 = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.VLAN_TABLE)
+            .withPriority(32768)
+            .withSelector(TABLE_10_DEFAULT_FLOW_SELECTOR_1)
+            .withTreatment(TABLE_10_DEFAULT_FLOW_TREATMENT_1)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_10_DEFAULT_FLOW_ENTRY_1 = new DefaultFlowEntry(TABLE_10_DEFAULT_FLOW_1);
+
+    private static final TrafficSelector TABLE_10_DEFAULT_FLOW_SELECTOR_2 = DefaultTrafficSelector.builder()
+            .matchInPort(UP_PORT)
+            .matchVlanId(DEFAULT_VLAN)
+            .build();
+    private static final TrafficTreatment TABLE_10_DEFAULT_FLOW_TREATMENT_2 = DefaultTrafficTreatment.builder()
+            .transition(OfdpaPipelineUtility.TMAC_TABLE)
+            .build();
+    private static final FlowRule TABLE_10_DEFAULT_FLOW_2 = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.VLAN_TABLE)
+            .withPriority(32768)
+            .withSelector(TABLE_10_DEFAULT_FLOW_SELECTOR_2)
+            .withTreatment(TABLE_10_DEFAULT_FLOW_TREATMENT_2)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_10_DEFAULT_FLOW_ENTRY_2 = new DefaultFlowEntry(TABLE_10_DEFAULT_FLOW_2);
+
+    private static final TrafficTreatment TABLE_20_FLOW_TREATMENT = DefaultTrafficTreatment.builder()
+            .transition(OfdpaPipelineUtility.BRIDGING_TABLE)
+            .build();
+    private static final FlowRule TABLE_20_MISS_OVS = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.TMAC_TABLE)
+            .withPriority(0)
+            .withSelector(EMPTY_SELECTOR)
+            .withTreatment(TABLE_20_FLOW_TREATMENT)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_20_MISS_FLOW_ENTRY_OVS = new DefaultFlowEntry(TABLE_20_MISS_OVS);
+
+    private static final TrafficSelector TABLE_20_IPV4_FLOW_SELECTOR = DefaultTrafficSelector.builder()
+            .matchInPort(UP_PORT)
+            .matchEthDst(LEAF_MAC)
+            .matchEthType(IPV4.ethType().toShort())
+            .matchVlanId(DEFAULT_VLAN)
+            .build();
+    private static final TrafficTreatment TABLE_20_IPV4_FLOW_TREATMENT = DefaultTrafficTreatment.builder()
+            .transition(OfdpaPipelineUtility.UNICAST_ROUTING_TABLE)
+            .build();
+    private static final FlowRule TABLE_20_IPV4_FLOW = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.TMAC_TABLE)
+            .withPriority(32768)
+            .withSelector(TABLE_20_IPV4_FLOW_SELECTOR)
+            .withTreatment(TABLE_20_IPV4_FLOW_TREATMENT)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_20_IPV4_FLOW_ENTRY = new DefaultFlowEntry(TABLE_20_IPV4_FLOW);
+
+    private static final TrafficSelector TABLE_20_IPV4_FLOW_SELECTOR_1 = DefaultTrafficSelector.builder()
+            .matchInPort(PORT)
+            .matchEthDst(LEAF_MAC)
+            .matchEthType(IPV4.ethType().toShort())
+            .matchVlanId(HOST_VLAN)
+            .build();
+    private static final TrafficTreatment TABLE_20_IPV4_FLOW_TREATMENT_1 = DefaultTrafficTreatment.builder()
+            .transition(OfdpaPipelineUtility.UNICAST_ROUTING_TABLE)
+            .build();
+    private static final FlowRule TABLE_20_IPV4_FLOW_1 = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.TMAC_TABLE)
+            .withPriority(32768)
+            .withSelector(TABLE_20_IPV4_FLOW_SELECTOR_1)
+            .withTreatment(TABLE_20_IPV4_FLOW_TREATMENT_1)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_20_IPV4_FLOW_ENTRY_1 = new DefaultFlowEntry(TABLE_20_IPV4_FLOW_1);
+
+    private static final TrafficSelector TABLE_20_MPLS_FLOW_SELECTOR = DefaultTrafficSelector.builder()
+            .matchInPort(UP_PORT)
+            .matchEthDst(LEAF_MAC)
+            .matchEthType(MPLS_UNICAST.ethType().toShort())
+            .matchVlanId(DEFAULT_VLAN)
+            .build();
+    private static final TrafficTreatment TABLE_20_MPLS_FLOW_TREATMENT = DefaultTrafficTreatment.builder()
+            .transition(OfdpaPipelineUtility.MPLS_TABLE_0)
+            .build();
+    private static final FlowRule TABLE_20_MPLS_FLOW = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.TMAC_TABLE)
+            .withPriority(32768)
+            .withSelector(TABLE_20_MPLS_FLOW_SELECTOR)
+            .withTreatment(TABLE_20_MPLS_FLOW_TREATMENT)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_20_MPLS_FLOW_ENTRY = new DefaultFlowEntry(TABLE_20_MPLS_FLOW);
+
+    private static final TrafficTreatment TABLE_23_FLOW_TREATMENT = DefaultTrafficTreatment.builder()
+            .transition(OfdpaPipelineUtility.MPLS_TABLE_1)
+            .build();
+    private static final FlowRule TABLE_23_MISS_OVS = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.MPLS_TABLE_0)
+            .withPriority(0)
+            .withSelector(EMPTY_SELECTOR)
+            .withTreatment(TABLE_23_FLOW_TREATMENT)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_23_MISS_FLOW_ENTRY_OVS = new DefaultFlowEntry(TABLE_23_MISS_OVS);
+
+    private static final TrafficSelector TABLE_24_MPLS_FLOW_SELECTOR = DefaultTrafficSelector.builder()
+            .matchEthType(MPLS_UNICAST.ethType().toShort())
+            .matchMplsLabel(MPLS_LABEL)
+            .matchMplsBos(true)
+            .build();
+    private static final TrafficTreatment TABLE_24_MPLS_FLOW_TREATMENT = DefaultTrafficTreatment.builder()
+            .transition(OfdpaPipelineUtility.ACL_TABLE)
+            .deferred()
+            .popMpls(IPV4.ethType())
+            .decMplsTtl()
+            .group(MPLS_ECMP_GROUP_ID)
+            .build();
+    private static final FlowRule TABLE_24_MPLS_FLOW = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.MPLS_TABLE_1)
+            .withPriority(100)
+            .withSelector(TABLE_24_MPLS_FLOW_SELECTOR)
+            .withTreatment(TABLE_24_MPLS_FLOW_TREATMENT)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_24_MPLS_FLOW_ENTRY = new DefaultFlowEntry(TABLE_24_MPLS_FLOW);
+
+    private static final TrafficTreatment TABLE_24_MPLS_FLOW_TREATMENT_OFDPA = DefaultTrafficTreatment.builder()
+            .transition(OfdpaPipelineUtility.MPLS_L3_TYPE_TABLE)
+            .copyTtlIn()
+            .decMplsTtl()
+            .extension(new Ofdpa3SetMplsType(Ofdpa3MplsType.L3_PHP), OFDPA_DEVICE)
+            .deferred()
+            .group(MPLS_ECMP_GROUP_ID)
+            .build();
+    private static final FlowRule TABLE_24_MPLS_FLOW_OFDPA = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.MPLS_TABLE_1)
+            .withPriority(100)
+            .withSelector(TABLE_24_MPLS_FLOW_SELECTOR)
+            .withTreatment(TABLE_24_MPLS_FLOW_TREATMENT_OFDPA)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_24_MPLS_FLOW_ENTRY_OFDPA = new DefaultFlowEntry(TABLE_24_MPLS_FLOW_OFDPA);
+
+    private static final TrafficSelector TABLE_30_UNI_FLOW_SELECTOR = DefaultTrafficSelector.builder()
+            .matchEthType(IPV4.ethType().toShort())
+            .matchIPDst(IP_DST)
+            .build();
+    private static final TrafficTreatment TABLE_30_UNI_FLOW_TREATMENT = DefaultTrafficTreatment.builder()
+            .deferred()
+            .group(L3_UCAST_GROUP_ID)
+            .transition(OfdpaPipelineUtility.ACL_TABLE)
+            .build();
+    private static final FlowRule TABLE_30_UNI_FLOW = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.UNICAST_ROUTING_TABLE)
+            .withPriority(64010)
+            .withSelector(TABLE_30_UNI_FLOW_SELECTOR)
+            .withTreatment(TABLE_30_UNI_FLOW_TREATMENT)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_30_UNI_FLOW_ENTRY = new DefaultFlowEntry(TABLE_30_UNI_FLOW);
+
+    private static final TrafficSelector TABLE_30_ECMP_FLOW_SELECTOR = DefaultTrafficSelector.builder()
+            .matchEthType(IPV4.ethType().toShort())
+            .matchIPDst(PREFIX_DST)
+            .build();
+    private static final TrafficTreatment TABLE_30_ECMP_FLOW_TREATMENT = DefaultTrafficTreatment.builder()
+            .deferred()
+            .group(L3_ECMP_GROUP_ID)
+            .transition(OfdpaPipelineUtility.ACL_TABLE)
+            .build();
+    private static final FlowRule TABLE_30_ECMP_FLOW = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.UNICAST_ROUTING_TABLE)
+            .withPriority(48010)
+            .withSelector(TABLE_30_ECMP_FLOW_SELECTOR)
+            .withTreatment(TABLE_30_ECMP_FLOW_TREATMENT)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_30_ECMP_FLOW_ENTRY = new DefaultFlowEntry(TABLE_30_ECMP_FLOW);
+
+    private static final TrafficSelector TABLE_50_FLOW_SELECTOR = DefaultTrafficSelector.builder()
+            .matchVlanId(HOST_VLAN)
+            .build();
+    private static final TrafficTreatment TABLE_50_FLOW_TREATMENT = DefaultTrafficTreatment.builder()
+            .deferred()
+            .group(L2_FLOOD_GROUP_ID)
+            .transition(OfdpaPipelineUtility.ACL_TABLE)
+            .build();
+    private static final FlowRule TABLE_50_FLOW = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.BRIDGING_TABLE)
+            .withPriority(5)
+            .withSelector(TABLE_50_FLOW_SELECTOR)
+            .withTreatment(TABLE_50_FLOW_TREATMENT)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_50_FLOW_ENTRY = new DefaultFlowEntry(TABLE_50_FLOW);
+
+    private static final TrafficSelector TABLE_50_FLOW_SELECTOR_BRIDG = DefaultTrafficSelector.builder()
+            .matchVlanId(HOST_VLAN)
+            .matchEthDst(HOST_MAC)
+            .build();
+    private static final TrafficTreatment TABLE_50_FLOW_TREATMENT_BRIDG = DefaultTrafficTreatment.builder()
+            .deferred()
+            .group(L2_IFACE_GROUP_ID)
+            .transition(OfdpaPipelineUtility.ACL_TABLE)
+            .build();
+    private static final FlowRule TABLE_50_FLOW_BRIDG = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.BRIDGING_TABLE)
+            .withPriority(100)
+            .withSelector(TABLE_50_FLOW_SELECTOR_BRIDG)
+            .withTreatment(TABLE_50_FLOW_TREATMENT_BRIDG)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_50_FLOW_ENTRY_BRIDG = new DefaultFlowEntry(TABLE_50_FLOW_BRIDG);
+
+    private static final TrafficSelector TABLE_60_FLOW_SELECTOR = DefaultTrafficSelector.builder()
+            .matchEthType(IPV4.ethType().toShort())
+            .matchIPDst(IP_PUNT)
+            .build();
+    private static final TrafficTreatment TABLE_60_FLOW_TREATMENT_OVS = DefaultTrafficTreatment.builder()
+            .wipeDeferred()
+            .transition(OvsOfdpaPipeline.PUNT_TABLE)
+            .build();
+    private static final FlowRule TABLE_60_FLOW_OVS = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.ACL_TABLE)
+            .withPriority(40000)
+            .withSelector(TABLE_60_FLOW_SELECTOR)
+            .withTreatment(TABLE_60_FLOW_TREATMENT_OVS)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_60_FLOW_ENTRY = new DefaultFlowEntry(TABLE_60_FLOW_OVS);
+
+    private static final TrafficTreatment TABLE_60_FLOW_TREATMENT_OFDPA = DefaultTrafficTreatment.builder()
+            .wipeDeferred()
+            .punt()
+            .build();
+    private static final FlowRule TABLE_60_FLOW_OFDPA = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.ACL_TABLE)
+            .withPriority(40000)
+            .withSelector(TABLE_60_FLOW_SELECTOR)
+            .withTreatment(TABLE_60_FLOW_TREATMENT_OFDPA)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_60_FLOW_ENTRY_OFDPA = new DefaultFlowEntry(TABLE_60_FLOW_OFDPA);
+
+    private static final FlowRule TABLE_60_MISS_OVS = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.ACL_TABLE)
+            .withPriority(0)
+            .withSelector(EMPTY_SELECTOR)
+            .withTreatment(EMPTY_TREATMENT)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_60_MISS_FLOW_ENTRY_OVS = new DefaultFlowEntry(TABLE_60_MISS_OVS);
+
+    private static final TrafficSelector TABLE_60_FLOW_SELECTOR_ARP = DefaultTrafficSelector.builder()
+            .matchEthType(ARP.ethType().toShort())
+            .build();
+    private static final TrafficTreatment TABLE_60_FLOW_TREATMENT_ARP_OVS = DefaultTrafficTreatment.builder()
+            .transition(OvsOfdpaPipeline.PUNT_TABLE)
+            .build();
+    private static final FlowRule TABLE_60_FLOW_ARP_OVS = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.ACL_TABLE)
+            .withPriority(30000)
+            .withSelector(TABLE_60_FLOW_SELECTOR_ARP)
+            .withTreatment(TABLE_60_FLOW_TREATMENT_ARP_OVS)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_60_FLOW_ENTRY_ARP_OVS = new DefaultFlowEntry(TABLE_60_FLOW_ARP_OVS);
+
+    private static final TrafficTreatment TABLE_60_FLOW_TREATMENT_ARP_OFDPA = DefaultTrafficTreatment.builder()
+            .punt()
+            .build();
+    private static final FlowRule TABLE_60_FLOW_ARP_OFDPA = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.ACL_TABLE)
+            .withPriority(30000)
+            .withSelector(TABLE_60_FLOW_SELECTOR_ARP)
+            .withTreatment(TABLE_60_FLOW_TREATMENT_ARP_OFDPA)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_60_FLOW_ENTRY_ARP_OFDPA = new DefaultFlowEntry(TABLE_60_FLOW_ARP_OFDPA);
+
+    private static final TrafficSelector TABLE_60_FLOW_SELECTOR_LLDP = DefaultTrafficSelector.builder()
+            .matchEthType(LLDP.ethType().toShort())
+            .build();
+    private static final TrafficTreatment TABLE_60_FLOW_TREATMENT_LLDP = DefaultTrafficTreatment.builder()
+            .wipeDeferred()
+            .transition(OvsOfdpaPipeline.PUNT_TABLE)
+            .build();
+    private static final FlowRule TABLE_60_FLOW_LLDP = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.ACL_TABLE)
+            .withPriority(40000)
+            .withSelector(TABLE_60_FLOW_SELECTOR_LLDP)
+            .withTreatment(TABLE_60_FLOW_TREATMENT_LLDP)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_60_FLOW_ENTRY_LLDP = new DefaultFlowEntry(TABLE_60_FLOW_LLDP);
+
+    private static final TrafficTreatment TABLE_60_FLOW_TREATMENT_LLDP_OFDPA = DefaultTrafficTreatment.builder()
+            .wipeDeferred()
+            .punt()
+            .build();
+    private static final FlowRule TABLE_60_FLOW_LLDP_OFDPA = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.ACL_TABLE)
+            .withPriority(40000)
+            .withSelector(TABLE_60_FLOW_SELECTOR_LLDP)
+            .withTreatment(TABLE_60_FLOW_TREATMENT_LLDP_OFDPA)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_60_FLOW_ENTRY_LLDP_OFDPA = new DefaultFlowEntry(TABLE_60_FLOW_LLDP_OFDPA);
+
+    private static final TrafficSelector TABLE_63_FLOW_SELECTOR = DefaultTrafficSelector.builder()
+            .matchInPort(OFDPA_CP.port())
+            .matchVlanId(HOST_VLAN)
+            .build();
+    private static final TrafficTreatment TABLE_63_FLOW_TREATMENT = DefaultTrafficTreatment.builder()
+            .group(GroupId.valueOf(OvsOfdpaPipeline.POP_VLAN_PUNT_GROUP_ID))
+            .build();
+    private static final FlowRule TABLE_63_FLOW = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OvsOfdpaPipeline.PUNT_TABLE)
+            .withPriority(40000)
+            .withSelector(TABLE_63_FLOW_SELECTOR)
+            .withTreatment(TABLE_63_FLOW_TREATMENT)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_63_FLOW_ENTRY = new DefaultFlowEntry(TABLE_63_FLOW);
+
+    // Represents the device state
+    public static List<DataPlaneEntity> getDataPlaneEntities(String driverName, TraceableTest test) {
+        List<FlowEntry> flowRules = ImmutableList.of();
+        List<Group> groups = ImmutableList.of();
+        // Flow and groups by device
+        if (driverName.equals(OFDPA_DRIVER)) {
+            flowRules = ImmutableList.of(
+                    // Vlan 1 table
+                    TABLE_10_FLOW_ENTRY_1, TABLE_10_FLOW_ENTRY_2, TABLE_10_DEFAULT_FLOW_ENTRY_1,
+                    TABLE_10_DEFAULT_FLOW_ENTRY_2,
+                    // TMAC table
+                    TABLE_20_IPV4_FLOW_ENTRY, TABLE_20_IPV4_FLOW_ENTRY_1, TABLE_20_MPLS_FLOW_ENTRY,
+                    // MPLS 1 table
+                    TABLE_24_MPLS_FLOW_ENTRY_OFDPA,
+                    // Unicast table
+                    TABLE_30_UNI_FLOW_ENTRY, TABLE_30_ECMP_FLOW_ENTRY,
+                    // Bridging table
+                    TABLE_50_FLOW_ENTRY, TABLE_50_FLOW_ENTRY_BRIDG,
+                    // ACL table
+                    TABLE_60_FLOW_ENTRY_OFDPA, TABLE_60_FLOW_ENTRY_ARP_OFDPA, TABLE_60_FLOW_ENTRY_LLDP_OFDPA);
+            groups = Lists.newArrayList(
+                    // L3 ECMP groups
+                    L3_ECMP_OFDPA_GROUP,
+                    // MPLS ECMP groups
+                    MPLS_ECMP_GROUP,
+                    // L3 groups
+                    L3_UCAST_GROUP, L3_UCAST_GROUP_1,
+                    // MPLS L3 VPN groups
+                    MPLS_L3VPN_OFDPA_GROUP, MPLS_L3VPN_OFDPA_GROUP_1,
+                    // MPLS iface groups
+                    MPLS_IFACE_GROUP, MPLS_IFACE_GROUP_1,
+                    // L2 groups
+                    L2_FLOOD_GROUP,
+                    L2_IFACE_GROUP, L2_IFACE_GROUP_1, L2_IFACE_GROUP_2, L2_IFACE_GROUP_3);
+        } else if (driverName.equals(OVS_OFDPA_DRIVER)) {
+            flowRules = ImmutableList.of(
+                    // Port table
+                    TABLE_0_MISS_FLOW_ENTRY_OVS,
+                    // Vlan 1 table
+                    TABLE_10_FLOW_ENTRY, TABLE_10_DEFAULT_FLOW_ENTRY,
+                    // TMAC table
+                    TABLE_20_MISS_FLOW_ENTRY_OVS, TABLE_20_IPV4_FLOW_ENTRY, TABLE_20_IPV4_FLOW_ENTRY_1,
+                    TABLE_20_MPLS_FLOW_ENTRY,
+                    // MPLS 0 table
+                    TABLE_23_MISS_FLOW_ENTRY_OVS,
+                    // MPLS 1 table
+                    TABLE_24_MPLS_FLOW_ENTRY,
+                    // Unicast table
+                    TABLE_30_UNI_FLOW_ENTRY, TABLE_30_ECMP_FLOW_ENTRY,
+                    // Bridging table
+                    TABLE_50_FLOW_ENTRY, TABLE_50_FLOW_ENTRY_BRIDG,
+                    // ACL table
+                    TABLE_60_MISS_FLOW_ENTRY_OVS, TABLE_60_FLOW_ENTRY, TABLE_60_FLOW_ENTRY_ARP_OVS,
+                    TABLE_60_FLOW_ENTRY_LLDP,
+                    // Punt table
+                    TABLE_63_FLOW_ENTRY);
+            groups = Lists.newArrayList(
+                    // Punt groups
+                    PUNT_GROUP,
+                    // L3 ECMP groups
+                    L3_ECMP_GROUP,
+                    // MPLS ECMP groups
+                    MPLS_ECMP_GROUP,
+                    // L3 groups
+                    L3_UCAST_GROUP, L3_UCAST_GROUP_1,
+                    // MPLS L3 VPN groups
+                    MPLS_L3VPN_GROUP, MPLS_L3VPN_GROUP_1,
+                    // MPLS iface groups
+                    MPLS_IFACE_GROUP, MPLS_IFACE_GROUP_1,
+                    // L2 groups
+                    L2_FLOOD_GROUP,
+                    L2_IFACE_GROUP, L2_IFACE_GROUP_1, L2_IFACE_GROUP_2, L2_IFACE_GROUP_3);
+        }
+        // Inject failure scenarios
+        if (test.equals(L2_BROAD_EMPTY_OFDPA) || test.equals(L2_BROAD_EMPTY_OVS_OFDPA)) {
+            groups.remove(L2_FLOOD_GROUP);
+            groups.add(L2_FLOOD_EMPTY_GROUP);
+        } else if (test.equals(L2_BRIDG_NOT_ORDERED_OFDPA) || test.equals(L2_BRIDG_NOT_ORDERED_OVS_OFDPA)) {
+            groups.remove(L2_IFACE_GROUP);
+            groups.add(L2_IFACE_GROUP_NOT_ORDERED);
+        }
+        List<DataPlaneEntity> dataPlaneEntities = Lists.newArrayList();
+        flowRules.forEach(flowRule -> dataPlaneEntities.add(new DataPlaneEntity(flowRule)));
+        groups.forEach(group -> dataPlaneEntities.add(new DataPlaneEntity(group)));
+        return dataPlaneEntities;
+    }
+
+    // Returns the expected hit chains (order matters!)
+    public static List<List<DataPlaneEntity>> getHitChains(TraceableTest test) {
+        List<List<FlowEntry>> flowRules = Lists.newArrayList();
+        List<List<Group>> groups = Lists.newArrayList();
+        // Flows and groups by test
+        if (test.equals(PUNT_IP_OFDPA)) {
+            flowRules.add(ImmutableList.of(
+                    TABLE_10_FLOW_ENTRY_1, TABLE_10_FLOW_ENTRY_2,
+                    TABLE_50_FLOW_ENTRY, TABLE_60_FLOW_ENTRY));
+        } else if (test.equals(PUNT_IP_OVS_OFDPA)) {
+            flowRules.add(ImmutableList.of(
+                    TABLE_0_MISS_FLOW_ENTRY_OVS, TABLE_10_FLOW_ENTRY, TABLE_20_MISS_FLOW_ENTRY_OVS,
+                    TABLE_50_FLOW_ENTRY, TABLE_60_FLOW_ENTRY, TABLE_63_FLOW_ENTRY));
+            groups.add(ImmutableList.of(PUNT_GROUP));
+        } else if (test.equals(ARP_OFDPA)) {
+            flowRules.add(ImmutableList.of(
+                    TABLE_10_FLOW_ENTRY_1, TABLE_10_FLOW_ENTRY_2,
+                    TABLE_50_FLOW_ENTRY, TABLE_60_FLOW_ENTRY_ARP_OFDPA));
+            groups.add(ImmutableList.of());
+            flowRules.add(ImmutableList.of(
+                    TABLE_10_FLOW_ENTRY_1, TABLE_10_FLOW_ENTRY_2,
+                    TABLE_50_FLOW_ENTRY, TABLE_60_FLOW_ENTRY_ARP_OFDPA));
+            groups.add(ImmutableList.of(L2_FLOOD_GROUP, L2_IFACE_GROUP));
+            flowRules.add(ImmutableList.of(
+                    TABLE_10_FLOW_ENTRY_1, TABLE_10_FLOW_ENTRY_2,
+                    TABLE_50_FLOW_ENTRY, TABLE_60_FLOW_ENTRY_ARP_OFDPA));
+            groups.add(ImmutableList.of(L2_FLOOD_GROUP, L2_IFACE_GROUP_1));
+        } else if (test.equals(ARP_OVS_OFDPA)) {
+            flowRules.add(ImmutableList.of(
+                    TABLE_0_MISS_FLOW_ENTRY_OVS, TABLE_10_FLOW_ENTRY, TABLE_20_MISS_FLOW_ENTRY_OVS,
+                    TABLE_50_FLOW_ENTRY, TABLE_60_FLOW_ENTRY_ARP_OVS, TABLE_63_FLOW_ENTRY));
+            groups.add(ImmutableList.of(PUNT_GROUP));
+            flowRules.add(ImmutableList.of(
+                    TABLE_0_MISS_FLOW_ENTRY_OVS, TABLE_10_FLOW_ENTRY, TABLE_20_MISS_FLOW_ENTRY_OVS,
+                    TABLE_50_FLOW_ENTRY, TABLE_60_FLOW_ENTRY_ARP_OVS, TABLE_63_FLOW_ENTRY));
+            groups.add(ImmutableList.of(L2_FLOOD_GROUP, L2_IFACE_GROUP));
+            flowRules.add(ImmutableList.of(
+                    TABLE_0_MISS_FLOW_ENTRY_OVS, TABLE_10_FLOW_ENTRY, TABLE_20_MISS_FLOW_ENTRY_OVS,
+                    TABLE_50_FLOW_ENTRY, TABLE_60_FLOW_ENTRY_ARP_OVS, TABLE_63_FLOW_ENTRY));
+            groups.add(ImmutableList.of(L2_FLOOD_GROUP, L2_IFACE_GROUP_1));
+        } else if (test.equals(PUNT_LLDP_OFDPA)) {
+            flowRules.add(ImmutableList.of(
+                    TABLE_10_FLOW_ENTRY_1, TABLE_10_FLOW_ENTRY_2,
+                    TABLE_50_FLOW_ENTRY, TABLE_60_FLOW_ENTRY_LLDP_OFDPA));
+        } else if (test.equals(PUNT_LLDP_OVS_OFDPA)) {
+            flowRules.add(ImmutableList.of(
+                    TABLE_0_MISS_FLOW_ENTRY_OVS, TABLE_10_FLOW_ENTRY, TABLE_20_MISS_FLOW_ENTRY_OVS,
+                    TABLE_50_FLOW_ENTRY, TABLE_60_FLOW_ENTRY_LLDP, TABLE_63_FLOW_ENTRY));
+            groups.add(ImmutableList.of(PUNT_GROUP));
+        } else if (test.equals(L2_BRIDG_UNTAG_OFDPA)) {
+            flowRules.add(ImmutableList.of(
+                    TABLE_10_FLOW_ENTRY_1, TABLE_10_FLOW_ENTRY_2,
+                    TABLE_50_FLOW_ENTRY_BRIDG));
+            groups.add(ImmutableList.of(L2_IFACE_GROUP));
+        } else if (test.equals(L2_BRIDG_UNTAG_OVS_OFDPA)) {
+            flowRules.add(ImmutableList.of(
+                    TABLE_0_MISS_FLOW_ENTRY_OVS, TABLE_10_FLOW_ENTRY, TABLE_20_MISS_FLOW_ENTRY_OVS,
+                    TABLE_50_FLOW_ENTRY_BRIDG, TABLE_60_MISS_FLOW_ENTRY_OVS));
+            groups.add(ImmutableList.of(L2_IFACE_GROUP));
+        } else if (test.equals(L2_BROAD_UNTAG_OFDPA)) {
+            flowRules.add(ImmutableList.of(
+                    TABLE_10_FLOW_ENTRY_1, TABLE_10_FLOW_ENTRY_2,
+                    TABLE_50_FLOW_ENTRY));
+            groups.add(ImmutableList.of(L2_FLOOD_GROUP, L2_IFACE_GROUP));
+            flowRules.add(ImmutableList.of(
+                    TABLE_10_FLOW_ENTRY_1, TABLE_10_FLOW_ENTRY_2,
+                    TABLE_50_FLOW_ENTRY));
+            groups.add(ImmutableList.of(L2_FLOOD_GROUP, L2_IFACE_GROUP_1));
+        } else if (test.equals(L2_BROAD_UNTAG_OVS_OFDPA)) {
+            flowRules.add(ImmutableList.of(
+                    TABLE_0_MISS_FLOW_ENTRY_OVS, TABLE_10_FLOW_ENTRY, TABLE_20_MISS_FLOW_ENTRY_OVS,
+                    TABLE_50_FLOW_ENTRY, TABLE_60_MISS_FLOW_ENTRY_OVS));
+            groups.add(ImmutableList.of(L2_FLOOD_GROUP, L2_IFACE_GROUP));
+            flowRules.add(ImmutableList.of(
+                    TABLE_0_MISS_FLOW_ENTRY_OVS, TABLE_10_FLOW_ENTRY, TABLE_20_MISS_FLOW_ENTRY_OVS,
+                    TABLE_50_FLOW_ENTRY, TABLE_60_MISS_FLOW_ENTRY_OVS));
+            groups.add(ImmutableList.of(L2_FLOOD_GROUP, L2_IFACE_GROUP_1));
+        } else if (test.equals(L3_UCAST_UNTAG_OFDPA)) {
+            flowRules.add(ImmutableList.of(
+                    TABLE_10_DEFAULT_FLOW_ENTRY_1, TABLE_10_DEFAULT_FLOW_ENTRY_2, TABLE_20_IPV4_FLOW_ENTRY,
+                    TABLE_30_UNI_FLOW_ENTRY));
+            groups.add(ImmutableList.of(L3_UCAST_GROUP, L2_IFACE_GROUP));
+        } else if (test.equals(L3_UCAST_UNTAG_OVS_OFDPA)) {
+            flowRules.add(ImmutableList.of(
+                    TABLE_0_MISS_FLOW_ENTRY_OVS, TABLE_10_DEFAULT_FLOW_ENTRY, TABLE_20_IPV4_FLOW_ENTRY,
+                    TABLE_30_UNI_FLOW_ENTRY, TABLE_60_MISS_FLOW_ENTRY_OVS));
+            groups.add(ImmutableList.of(L3_UCAST_GROUP, L2_IFACE_GROUP));
+        } else if (test.equals(L3_ECMP_OVS_OFDPA)) {
+            flowRules.add(ImmutableList.of(
+                    TABLE_0_MISS_FLOW_ENTRY_OVS, TABLE_10_FLOW_ENTRY, TABLE_20_IPV4_FLOW_ENTRY_1,
+                    TABLE_30_ECMP_FLOW_ENTRY, TABLE_60_MISS_FLOW_ENTRY_OVS));
+            groups.add(ImmutableList.of(L3_ECMP_GROUP, MPLS_L3VPN_GROUP, MPLS_IFACE_GROUP, L2_IFACE_GROUP_2));
+            flowRules.add(ImmutableList.of(
+                    TABLE_0_MISS_FLOW_ENTRY_OVS, TABLE_10_FLOW_ENTRY, TABLE_20_IPV4_FLOW_ENTRY_1,
+                    TABLE_30_ECMP_FLOW_ENTRY, TABLE_60_MISS_FLOW_ENTRY_OVS));
+            groups.add(ImmutableList.of(L3_ECMP_GROUP, MPLS_L3VPN_GROUP_1, MPLS_IFACE_GROUP_1, L2_IFACE_GROUP_3));
+        } else if (test.equals(L3_ECMP_OFDPA)) {
+            flowRules.add(ImmutableList.of(
+                    TABLE_10_FLOW_ENTRY_1, TABLE_10_FLOW_ENTRY_2, TABLE_20_IPV4_FLOW_ENTRY_1,
+                    TABLE_30_ECMP_FLOW_ENTRY));
+            groups.add(ImmutableList.of(L3_ECMP_OFDPA_GROUP, MPLS_L3VPN_OFDPA_GROUP, MPLS_IFACE_GROUP,
+                    L2_IFACE_GROUP_2));
+            flowRules.add(ImmutableList.of(
+                    TABLE_10_FLOW_ENTRY_1, TABLE_10_FLOW_ENTRY_2, TABLE_20_IPV4_FLOW_ENTRY_1,
+                    TABLE_30_ECMP_FLOW_ENTRY));
+            groups.add(ImmutableList.of(L3_ECMP_OFDPA_GROUP, MPLS_L3VPN_OFDPA_GROUP_1, MPLS_IFACE_GROUP_1,
+                    L2_IFACE_GROUP_3));
+        } else if (test.equals(MPLS_ECMP_OVS_OFDPA)) {
+            flowRules.add(ImmutableList.of(
+                    TABLE_0_MISS_FLOW_ENTRY_OVS, TABLE_10_DEFAULT_FLOW_ENTRY, TABLE_20_MPLS_FLOW_ENTRY,
+                    TABLE_23_MISS_FLOW_ENTRY_OVS, TABLE_24_MPLS_FLOW_ENTRY, TABLE_60_MISS_FLOW_ENTRY_OVS));
+            groups.add(ImmutableList.of(MPLS_ECMP_GROUP, L3_UCAST_GROUP_1, L2_IFACE_GROUP_3));
+        } else if (test.equals(MPLS_ECMP_OFDPA)) {
+            flowRules.add(ImmutableList.of(
+                    TABLE_10_DEFAULT_FLOW_ENTRY_1, TABLE_10_DEFAULT_FLOW_ENTRY_2, TABLE_20_MPLS_FLOW_ENTRY,
+                    TABLE_24_MPLS_FLOW_ENTRY_OFDPA));
+            groups.add(ImmutableList.of(MPLS_ECMP_GROUP, L3_UCAST_GROUP_1, L2_IFACE_GROUP_3));
+        } else if (test.equals(L2_BROAD_EMPTY_OFDPA)) {
+            flowRules.add(ImmutableList.of(
+                    TABLE_10_FLOW_ENTRY_1, TABLE_10_FLOW_ENTRY_2,
+                    TABLE_50_FLOW_ENTRY));
+            groups.add(ImmutableList.of(L2_FLOOD_EMPTY_GROUP));
+        } else if (test.equals(L2_BROAD_EMPTY_OVS_OFDPA)) {
+            flowRules.add(ImmutableList.of(
+                    TABLE_0_MISS_FLOW_ENTRY_OVS, TABLE_10_FLOW_ENTRY, TABLE_20_MISS_FLOW_ENTRY_OVS,
+                    TABLE_50_FLOW_ENTRY, TABLE_60_MISS_FLOW_ENTRY_OVS));
+            groups.add(ImmutableList.of(L2_FLOOD_EMPTY_GROUP));
+        } else if (test.equals(L2_BRIDG_NOT_ORDERED_OFDPA)) {
+            flowRules.add(ImmutableList.of(
+                    TABLE_10_FLOW_ENTRY_1, TABLE_10_FLOW_ENTRY_2,
+                    TABLE_50_FLOW_ENTRY_BRIDG));
+            groups.add(ImmutableList.of(L2_IFACE_GROUP_NOT_ORDERED));
+        } else if (test.equals(L2_BRIDG_NOT_ORDERED_OVS_OFDPA)) {
+            flowRules.add(ImmutableList.of(
+                    TABLE_0_MISS_FLOW_ENTRY_OVS, TABLE_10_FLOW_ENTRY, TABLE_20_MISS_FLOW_ENTRY_OVS,
+                    TABLE_50_FLOW_ENTRY_BRIDG, TABLE_60_MISS_FLOW_ENTRY_OVS));
+            groups.add(ImmutableList.of(L2_IFACE_GROUP_NOT_ORDERED));
+        }
+        List<List<DataPlaneEntity>> chains = Lists.newArrayList();
+        List<DataPlaneEntity> dataPlaneEntities = Lists.newArrayList();
+        int end = Math.max(flowRules.size(), groups.size());
+        int i = 0;
+        while (i < end) {
+            if (i < flowRules.size()) {
+                flowRules.get(i).forEach(flowRule -> dataPlaneEntities.add(new DataPlaneEntity(flowRule)));
+            }
+            if (i < groups.size()) {
+                groups.get(i).forEach(group -> dataPlaneEntities.add(new DataPlaneEntity(group)));
+            }
+            chains.add(ImmutableList.copyOf(dataPlaneEntities));
+            dataPlaneEntities.clear();
+            i = i + 1;
+        }
+        return chains;
+    }
+
+}
diff --git a/drivers/default/src/test/java/org/onosproject/driver/traceable/TraceableTestObjects.java b/drivers/default/src/test/java/org/onosproject/driver/traceable/TraceableTestObjects.java
new file mode 100644
index 0000000..4ea803c
--- /dev/null
+++ b/drivers/default/src/test/java/org/onosproject/driver/traceable/TraceableTestObjects.java
@@ -0,0 +1,234 @@
+/*
+ * Copyright 2020-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.driver.traceable;
+
+import org.onlab.packet.EthType;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.MplsLabel;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.driver.DriverAdapter;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.TrafficSelector;
+
+import static org.onlab.packet.EthType.EtherType.IPV4;
+import static org.onlab.packet.EthType.EtherType.MPLS_UNICAST;
+
+/**
+ * Helper class for objects related to the Traceable tests.
+ */
+final class TraceableTestObjects {
+
+    private TraceableTestObjects() {
+        // Banning construction
+    }
+
+    // Test drivers name
+    static final String OFDPA_DRIVER = "ofdpa";
+    static final String OVS_OFDPA_DRIVER = "ofdpa-ovs";
+
+    // Test device ids
+    static final DeviceId OFDPA_DEVICE = DeviceId.deviceId("ofdpaDevice");
+
+    // Input ports
+    static final PortNumber PORT = PortNumber.portNumber("1");
+    static final PortNumber OUT_PORT = PortNumber.portNumber("3");
+    static final PortNumber UP_PORT = PortNumber.portNumber("10");
+    static final PortNumber UP_PORT_1 = PortNumber.portNumber("11");
+    static final ConnectPoint OFDPA_CP = ConnectPoint.deviceConnectPoint(OFDPA_DEVICE + "/" + PORT.toLong());
+    static final ConnectPoint UP_OFDPA_CP = ConnectPoint.deviceConnectPoint(OFDPA_DEVICE + "/" + UP_PORT.toLong());
+
+    // Misc
+    static final VlanId HOST_VLAN = VlanId.vlanId((short) 100);
+    static final VlanId DEFAULT_VLAN = VlanId.vlanId((short) 4094);
+    static final IpPrefix IP_PUNT = IpPrefix.valueOf("10.0.2.254/32");
+    static final MacAddress HOST_MAC = MacAddress.valueOf("00:AA:00:00:00:02");
+    static final IpPrefix IP_DST = IpPrefix.valueOf("10.0.2.2/32");
+    static final IpPrefix IP_DST_1 = IpPrefix.valueOf("10.0.3.1/32");
+    static final MacAddress LEAF_MAC = MacAddress.valueOf("00:00:00:00:02:04");
+    static final IpPrefix PREFIX_DST = IpPrefix.valueOf("10.0.3.0/24");
+    static final MacAddress SPINE_MAC = MacAddress.valueOf("00:00:00:00:02:26");
+    static final MacAddress SPINE_MAC_1 = MacAddress.valueOf("00:00:00:00:02:26");
+    static final MplsLabel MPLS_LABEL = MplsLabel.mplsLabel(205);
+
+    // Input packets
+    static final TrafficSelector IN_PUNT_IP_PACKET = DefaultTrafficSelector.builder()
+            .matchInPort(OFDPA_CP.port())
+            .matchEthType(IPV4.ethType().toShort())
+            .matchVlanId(VlanId.NONE)
+            .matchIPDst(IP_PUNT)
+            .build();
+
+    static final TrafficSelector IN_ARP_PACKET = DefaultTrafficSelector.builder()
+            .matchInPort(OFDPA_CP.port())
+            .matchIPDst(IpPrefix.valueOf("255.255.255.255/32"))
+            .matchEthType(EthType.EtherType.ARP.ethType().toShort())
+            .matchVlanId(VlanId.NONE)
+            .build();
+
+    static final TrafficSelector IN_PUNT_LLDP_PACKET = DefaultTrafficSelector.builder()
+            .matchInPort(OFDPA_CP.port())
+            .matchEthType(EthType.EtherType.LLDP.ethType().toShort())
+            .matchVlanId(VlanId.NONE)
+            .build();
+
+    static final TrafficSelector IN_L2_BRIDG_UNTAG_PACKET = DefaultTrafficSelector.builder()
+            .matchInPort(OFDPA_CP.port())
+            .matchEthType(IPV4.ethType().toShort())
+            .matchVlanId(VlanId.NONE)
+            .matchEthDst(HOST_MAC)
+            .build();
+
+    static final TrafficSelector IN_L2_BROAD_UNTAG_PACKET = DefaultTrafficSelector.builder()
+            .matchInPort(OFDPA_CP.port())
+            .matchVlanId(VlanId.NONE)
+            .build();
+
+    static final TrafficSelector IN_L3_UCAST_UNTAG_PACKET = DefaultTrafficSelector.builder()
+            .matchInPort(UP_OFDPA_CP.port())
+            .matchEthDst(LEAF_MAC)
+            .matchEthType(IPV4.ethType().toShort())
+            .matchVlanId(VlanId.NONE)
+            .matchIPDst(IP_DST)
+            .build();
+
+    static final TrafficSelector IN_L3_ECMP_PACKET = DefaultTrafficSelector.builder()
+            .matchInPort(OFDPA_CP.port())
+            .matchEthDst(LEAF_MAC)
+            .matchEthType(IPV4.ethType().toShort())
+            .matchVlanId(VlanId.NONE)
+            .matchIPDst(IP_DST_1)
+            .build();
+
+    static final TrafficSelector IN_MPLS_ECMP_PACKET = DefaultTrafficSelector.builder()
+            .matchInPort(UP_OFDPA_CP.port())
+            .matchEthDst(LEAF_MAC)
+            .matchEthType(MPLS_UNICAST.ethType().toShort())
+            .matchVlanId(VlanId.NONE)
+            .matchIPDst(IP_DST_1)
+            .matchMplsLabel(MPLS_LABEL)
+            .matchMplsBos(true)
+            .build();
+
+    static final TrafficSelector IN_MPLS_ECMP_PACKET_OFDPA = DefaultTrafficSelector.builder()
+            .matchInPort(UP_OFDPA_CP.port())
+            .matchEthDst(LEAF_MAC)
+            .matchEthType(MPLS_UNICAST.ethType().toShort())
+            .matchVlanId(VlanId.NONE)
+            .matchIPDst(IP_DST_1)
+            .matchMplsLabel(MPLS_LABEL)
+            .matchMplsBos(true)
+            .matchMetadata(IPV4.ethType().toShort())
+            .build();
+
+    // Egress packets
+    static final TrafficSelector OUT_L3_UCAST_UNTAG_PACKET = DefaultTrafficSelector.builder(IN_L3_UCAST_UNTAG_PACKET)
+            .matchEthSrc(LEAF_MAC)
+            .matchEthDst(HOST_MAC)
+            .build();
+
+    static final TrafficSelector OUT_L3_ECMP_PACKET = DefaultTrafficSelector.builder(IN_L3_ECMP_PACKET)
+            .matchEthSrc(LEAF_MAC)
+            .matchEthDst(SPINE_MAC)
+            .matchEthType(MPLS_UNICAST.ethType().toShort())
+            .matchMplsLabel(MPLS_LABEL)
+            .matchMplsBos(true)
+            .build();
+
+    static final TrafficSelector OUT_L3_ECMP_PACKET_1 = DefaultTrafficSelector.builder(IN_L3_ECMP_PACKET)
+            .matchEthSrc(LEAF_MAC)
+            .matchEthDst(SPINE_MAC_1)
+            .matchEthType(MPLS_UNICAST.ethType().toShort())
+            .matchMplsLabel(MPLS_LABEL)
+            .matchMplsBos(true)
+            .build();
+
+    static final TrafficSelector OUT_L3_ECMP_PACKET_OFDPA = DefaultTrafficSelector.builder(IN_L3_ECMP_PACKET)
+            .matchEthSrc(LEAF_MAC)
+            .matchEthDst(SPINE_MAC)
+            .matchEthType(MPLS_UNICAST.ethType().toShort())
+            .matchMplsLabel(MPLS_LABEL)
+            .matchMplsBos(true)
+            .matchMetadata(IPV4.ethType().toShort())
+            .build();
+
+    static final TrafficSelector OUT_L3_ECMP_PACKET_OFDPA_1 = DefaultTrafficSelector.builder(IN_L3_ECMP_PACKET)
+            .matchEthSrc(LEAF_MAC)
+            .matchEthDst(SPINE_MAC_1)
+            .matchEthType(MPLS_UNICAST.ethType().toShort())
+            .matchMplsLabel(MPLS_LABEL)
+            .matchMplsBos(true)
+            .matchMetadata(IPV4.ethType().toShort())
+            .build();
+
+    static final TrafficSelector OUT_MPLS_ECMP_PACKET = DefaultTrafficSelector.builder()
+            .matchInPort(UP_OFDPA_CP.port())
+            .matchEthSrc(LEAF_MAC)
+            .matchEthDst(SPINE_MAC)
+            .matchEthType(IPV4.ethType().toShort())
+            .matchVlanId(VlanId.NONE)
+            .matchIPDst(IP_DST_1)
+            .build();
+
+    static final TrafficSelector OUT_L2_BROAD_EMPTY = DefaultTrafficSelector.builder()
+            .matchInPort(OFDPA_CP.port())
+            .matchVlanId(HOST_VLAN)
+            .build();
+
+    // Test cases
+    enum TraceableTest {
+        PUNT_IP_OFDPA,
+        PUNT_IP_OVS_OFDPA,
+        ARP_OFDPA,
+        ARP_OVS_OFDPA,
+        PUNT_LLDP_OFDPA,
+        PUNT_LLDP_OVS_OFDPA,
+        L2_BRIDG_UNTAG_OFDPA,
+        L2_BRIDG_UNTAG_OVS_OFDPA,
+        L2_BROAD_UNTAG_OFDPA,
+        L2_BROAD_UNTAG_OVS_OFDPA,
+        L3_UCAST_UNTAG_OFDPA,
+        L3_UCAST_UNTAG_OVS_OFDPA,
+        L3_ECMP_OFDPA,
+        L3_ECMP_OVS_OFDPA,
+        MPLS_ECMP_OFDPA,
+        MPLS_ECMP_OVS_OFDPA,
+        L2_BROAD_EMPTY_OFDPA,
+        L2_BROAD_EMPTY_OVS_OFDPA,
+        L2_BRIDG_NOT_ORDERED_OFDPA,
+        L2_BRIDG_NOT_ORDERED_OVS_OFDPA,
+    }
+
+    // Test driver class
+    static class TestDriver extends DriverAdapter {
+
+        private String name;
+
+        public TestDriver(String name) {
+            this.name = name;
+        }
+
+        @Override
+        public String name() {
+            return name;
+        }
+
+    }
+}
