/*
 * 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());
    }

}