/*
 * Copyright 2014 Open Networking Laboratory
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.onosproject.net.flow.criteria;

import org.junit.Test;
import org.onosproject.net.PortNumber;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.Ip6Address;
import org.onlab.packet.MacAddress;
import org.onlab.packet.MplsLabel;
import org.onlab.packet.VlanId;

import com.google.common.testing.EqualsTester;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
import static org.onlab.junit.UtilityClassChecker.assertThatClassIsUtility;
import static org.onosproject.net.PortNumber.portNumber;

/**
 * Unit tests for the Criteria class and its subclasses.
 */
public class CriteriaTest {

    final PortNumber port1 = portNumber(1);
    final PortNumber port2 = portNumber(2);

    Criterion matchInPort1 = Criteria.matchInPort(port1);
    Criterion sameAsMatchInPort1 = Criteria.matchInPort(port1);
    Criterion matchInPort2 = Criteria.matchInPort(port2);

    Criterion matchInPhyPort1 = Criteria.matchInPhyPort(port1);
    Criterion sameAsMatchInPhyPort1 = Criteria.matchInPhyPort(port1);
    Criterion matchInPhyPort2 = Criteria.matchInPhyPort(port2);

    long metadata1 = 1;
    long metadata2 = 2;
    Criterion matchMetadata1 = Criteria.matchMetadata(metadata1);
    Criterion sameAsMatchMetadata1 = Criteria.matchMetadata(metadata1);
    Criterion matchMetadata2 = Criteria.matchMetadata(metadata2);

    private static final String MAC1 = "00:00:00:00:00:01";
    private static final String MAC2 = "00:00:00:00:00:02";
    private MacAddress mac1 = MacAddress.valueOf(MAC1);
    private MacAddress mac2 = MacAddress.valueOf(MAC2);
    Criterion matchEth1 = Criteria.matchEthSrc(mac1);
    Criterion sameAsMatchEth1 = Criteria.matchEthSrc(mac1);
    Criterion matchEth2 = Criteria.matchEthDst(mac2);

    int ethType1 = 1;
    int ethType2 = 2;
    Criterion matchEthType1 = Criteria.matchEthType(ethType1);
    Criterion sameAsMatchEthType1 = Criteria.matchEthType(ethType1);
    Criterion matchEthType2 = Criteria.matchEthType(ethType2);

    short vlan1 = 1;
    short vlan2 = 2;
    VlanId vlanId1 = VlanId.vlanId(vlan1);
    VlanId vlanId2 = VlanId.vlanId(vlan2);
    Criterion matchVlanId1 = Criteria.matchVlanId(vlanId1);
    Criterion sameAsMatchVlanId1 = Criteria.matchVlanId(vlanId1);
    Criterion matchVlanId2 = Criteria.matchVlanId(vlanId2);

    byte vlanPcp1 = 1;
    byte vlanPcp2 = 2;
    Criterion matchVlanPcp1 = Criteria.matchVlanPcp(vlanPcp1);
    Criterion sameAsMatchVlanPcp1 = Criteria.matchVlanPcp(vlanPcp1);
    Criterion matchVlanPcp2 = Criteria.matchVlanPcp(vlanPcp2);

    byte ipDscp1 = 1;
    byte ipDscp2 = 2;
    Criterion matchIpDscp1 = Criteria.matchIPDscp(ipDscp1);
    Criterion sameAsMatchIpDscp1 = Criteria.matchIPDscp(ipDscp1);
    Criterion matchIpDscp2 = Criteria.matchIPDscp(ipDscp2);

    byte ipEcn1 = 1;
    byte ipEcn2 = 2;
    Criterion matchIpEcn1 = Criteria.matchIPEcn(ipEcn1);
    Criterion sameAsMatchIpEcn1 = Criteria.matchIPEcn(ipEcn1);
    Criterion matchIpEcn2 = Criteria.matchIPEcn(ipEcn2);

    short protocol1 = 1;
    short protocol2 = 2;
    Criterion matchIpProtocol1 = Criteria.matchIPProtocol(protocol1);
    Criterion sameAsMatchIpProtocol1 = Criteria.matchIPProtocol(protocol1);
    Criterion matchIpProtocol2 = Criteria.matchIPProtocol(protocol2);

    private static final String IP1 = "1.2.3.4/24";
    private static final String IP2 = "5.6.7.8/24";
    private static final String IPV61 = "fe80::1/64";
    private static final String IPV62 = "fc80::2/64";
    private IpPrefix ip1 = IpPrefix.valueOf(IP1);
    private IpPrefix ip2 = IpPrefix.valueOf(IP2);
    private IpPrefix ipv61 = IpPrefix.valueOf(IPV61);
    private IpPrefix ipv62 = IpPrefix.valueOf(IPV62);
    Criterion matchIp1 = Criteria.matchIPSrc(ip1);
    Criterion sameAsMatchIp1 = Criteria.matchIPSrc(ip1);
    Criterion matchIp2 = Criteria.matchIPSrc(ip2);
    Criterion matchIpv61 = Criteria.matchIPSrc(ipv61);
    Criterion sameAsMatchIpv61 = Criteria.matchIPSrc(ipv61);
    Criterion matchIpv62 = Criteria.matchIPSrc(ipv62);

    Criterion matchTcpPort1 = Criteria.matchTcpSrc(1);
    Criterion sameAsMatchTcpPort1 = Criteria.matchTcpSrc(1);
    Criterion matchTcpPort2 = Criteria.matchTcpDst(2);

    Criterion matchUdpPort1 = Criteria.matchUdpSrc(1);
    Criterion sameAsMatchUdpPort1 = Criteria.matchUdpSrc(1);
    Criterion matchUdpPort2 = Criteria.matchUdpDst(2);

    Criterion matchSctpPort1 = Criteria.matchSctpSrc(1);
    Criterion sameAsMatchSctpPort1 = Criteria.matchSctpSrc(1);
    Criterion matchSctpPort2 = Criteria.matchSctpDst(2);

    short icmpType1 = 1;
    short icmpType2 = 2;
    Criterion matchIcmpType1 = Criteria.matchIcmpType(icmpType1);
    Criterion sameAsMatchIcmpType1 = Criteria.matchIcmpType(icmpType1);
    Criterion matchIcmpType2 = Criteria.matchIcmpType(icmpType2);

    short icmpCode1 = 1;
    short icmpCode2 = 2;
    Criterion matchIcmpCode1 = Criteria.matchIcmpCode(icmpCode1);
    Criterion sameAsMatchIcmpCode1 = Criteria.matchIcmpCode(icmpCode1);
    Criterion matchIcmpCode2 = Criteria.matchIcmpCode(icmpCode2);

    int flowLabel1 = 1;
    int flowLabel2 = 2;
    Criterion matchFlowLabel1 = Criteria.matchIPv6FlowLabel(flowLabel1);
    Criterion sameAsMatchFlowLabel1 = Criteria.matchIPv6FlowLabel(flowLabel1);
    Criterion matchFlowLabel2 = Criteria.matchIPv6FlowLabel(flowLabel2);

    short icmpv6Type1 = 1;
    short icmpv6Type2 = 2;
    Criterion matchIcmpv6Type1 = Criteria.matchIcmpv6Type(icmpv6Type1);
    Criterion sameAsMatchIcmpv6Type1 = Criteria.matchIcmpv6Type(icmpv6Type1);
    Criterion matchIcmpv6Type2 = Criteria.matchIcmpv6Type(icmpv6Type2);

    short icmpv6Code1 = 1;
    short icmpv6Code2 = 2;
    Criterion matchIcmpv6Code1 = Criteria.matchIcmpv6Code(icmpv6Code1);
    Criterion sameAsMatchIcmpv6Code1 = Criteria.matchIcmpv6Code(icmpv6Code1);
    Criterion matchIcmpv6Code2 = Criteria.matchIcmpv6Code(icmpv6Code2);

    private static final String IPV6_ADDR1 = "fe80::1";
    private static final String IPV6_ADDR2 = "fe80::2";
    private Ip6Address ip6TargetAddress1 = Ip6Address.valueOf(IPV6_ADDR1);
    private Ip6Address ip6TargetAddress2 = Ip6Address.valueOf(IPV6_ADDR2);
    Criterion matchIpv6TargetAddr1 =
        Criteria.matchIPv6NDTargetAddress(ip6TargetAddress1);
    Criterion sameAsMatchIpv6TargetAddr1 =
        Criteria.matchIPv6NDTargetAddress(ip6TargetAddress1);
    Criterion matchIpv6TargetAddr2 =
        Criteria.matchIPv6NDTargetAddress(ip6TargetAddress2);

    private static final String LL_MAC1 = "00:00:00:00:00:01";
    private static final String LL_MAC2 = "00:00:00:00:00:02";
    private MacAddress llMac1 = MacAddress.valueOf(LL_MAC1);
    private MacAddress llMac2 = MacAddress.valueOf(LL_MAC2);
    Criterion matchSrcLlAddr1 =
        Criteria.matchIPv6NDSourceLinkLayerAddress(llMac1);
    Criterion sameAsMatchSrcLlAddr1 =
        Criteria.matchIPv6NDSourceLinkLayerAddress(llMac1);
    Criterion matchSrcLlAddr2 =
        Criteria.matchIPv6NDSourceLinkLayerAddress(llMac2);
    Criterion matchTargetLlAddr1 =
        Criteria.matchIPv6NDTargetLinkLayerAddress(llMac1);
    Criterion sameAsMatchTargetLlAddr1 =
        Criteria.matchIPv6NDTargetLinkLayerAddress(llMac1);
    Criterion matchTargetLlAddr2 =
        Criteria.matchIPv6NDTargetLinkLayerAddress(llMac2);

    MplsLabel mpls1 = MplsLabel.mplsLabel(1);
    MplsLabel mpls2 = MplsLabel.mplsLabel(2);
    Criterion matchMpls1 = Criteria.matchMplsLabel(mpls1);
    Criterion sameAsMatchMpls1 = Criteria.matchMplsLabel(mpls1);
    Criterion matchMpls2 = Criteria.matchMplsLabel(mpls2);

    int ipv6ExthdrFlags1 =
        Criterion.IPv6ExthdrFlags.NONEXT.getValue() |
        Criterion.IPv6ExthdrFlags.ESP.getValue() |
        Criterion.IPv6ExthdrFlags.AUTH.getValue() |
        Criterion.IPv6ExthdrFlags.DEST.getValue() |
        Criterion.IPv6ExthdrFlags.FRAG.getValue() |
        Criterion.IPv6ExthdrFlags.ROUTER.getValue() |
        Criterion.IPv6ExthdrFlags.HOP.getValue() |
        Criterion.IPv6ExthdrFlags.UNREP.getValue();
    int ipv6ExthdrFlags2 = ipv6ExthdrFlags1 |
        Criterion.IPv6ExthdrFlags.UNSEQ.getValue();
    Criterion matchIpv6ExthdrFlags1 =
        Criteria.matchIPv6ExthdrFlags(ipv6ExthdrFlags1);
    Criterion sameAsMatchIpv6ExthdrFlags1 =
        Criteria.matchIPv6ExthdrFlags(ipv6ExthdrFlags1);
    Criterion matchIpv6ExthdrFlags2 =
        Criteria.matchIPv6ExthdrFlags(ipv6ExthdrFlags2);

    int lambda1 = 1;
    int lambda2 = 2;
    Criterion matchLambda1 = Criteria.matchLambda(lambda1);
    Criterion sameAsMatchLambda1 = Criteria.matchLambda(lambda1);
    Criterion matchLambda2 = Criteria.matchLambda(lambda2);

    short signalLambda1 = 1;
    short signalLambda2 = 2;
    Criterion matchSignalLambda1 = Criteria.matchOpticalSignalType(signalLambda1);
    Criterion sameAsMatchSignalLambda1 = Criteria.matchOpticalSignalType(signalLambda1);
    Criterion matchSignalLambda2 = Criteria.matchOpticalSignalType(signalLambda2);

    /**
     * Checks that a Criterion object has the proper type, and then converts
     * it to the proper type.
     *
     * @param criterion Criterion object to convert
     * @param type Enumerated type value for the Criterion class
     * @param clazz Desired Criterion class
     * @param <T> The type the caller wants returned
     * @return converted object
     */
    @SuppressWarnings("unchecked")
    private <T> T checkAndConvert(Criterion criterion, Criterion.Type type, Class clazz) {
        assertThat(criterion, is(notNullValue()));
        assertThat(criterion.type(), is(equalTo(type)));
        assertThat(criterion, instanceOf(clazz));
        return (T) criterion;
    }

    /**
     * Check that the Criteria class is a valid utility class.
     */
    @Test
    public void testCriteriaUtility() {
        assertThatClassIsUtility(Criteria.class);
    }

    /**
     * Check that the Criteria implementations are immutable.
     */
    @Test
    public void testCriteriaImmutability() {
        assertThatClassIsImmutable(Criteria.PortCriterion.class);
        assertThatClassIsImmutable(Criteria.MetadataCriterion.class);
        assertThatClassIsImmutable(Criteria.EthCriterion.class);
        assertThatClassIsImmutable(Criteria.EthTypeCriterion.class);
        assertThatClassIsImmutable(Criteria.VlanIdCriterion.class);
        assertThatClassIsImmutable(Criteria.VlanPcpCriterion.class);
        assertThatClassIsImmutable(Criteria.IPDscpCriterion.class);
        assertThatClassIsImmutable(Criteria.IPEcnCriterion.class);
        assertThatClassIsImmutable(Criteria.IPProtocolCriterion.class);
        assertThatClassIsImmutable(Criteria.IPCriterion.class);
        assertThatClassIsImmutable(Criteria.TcpPortCriterion.class);
        assertThatClassIsImmutable(Criteria.UdpPortCriterion.class);
        assertThatClassIsImmutable(Criteria.SctpPortCriterion.class);
        assertThatClassIsImmutable(Criteria.IcmpTypeCriterion.class);
        assertThatClassIsImmutable(Criteria.IcmpCodeCriterion.class);
        assertThatClassIsImmutable(Criteria.IPv6FlowLabelCriterion.class);
        assertThatClassIsImmutable(Criteria.Icmpv6TypeCriterion.class);
        assertThatClassIsImmutable(Criteria.Icmpv6CodeCriterion.class);
        assertThatClassIsImmutable(Criteria.IPv6NDTargetAddressCriterion.class);
        assertThatClassIsImmutable(Criteria.IPv6NDLinkLayerAddressCriterion.class);
        assertThatClassIsImmutable(Criteria.MplsCriterion.class);
        assertThatClassIsImmutable(Criteria.IPv6ExthdrFlagsCriterion.class);
        assertThatClassIsImmutable(Criteria.LambdaCriterion.class);
        assertThatClassIsImmutable(Criteria.OpticalSignalTypeCriterion.class);
    }

    // PortCriterion class

    /**
     * Test the matchInPort method.
     */
    @Test
    public void testMatchInPortMethod() {
        PortNumber p1 = portNumber(1);
        Criterion matchInPort = Criteria.matchInPort(p1);
        Criteria.PortCriterion portCriterion =
                checkAndConvert(matchInPort,
                                Criterion.Type.IN_PORT,
                                Criteria.PortCriterion.class);
        assertThat(portCriterion.port(), is(equalTo(p1)));
    }

    /**
     * Test the matchInPhyPort method.
     */
    @Test
    public void testMatchInPhyPortMethod() {
        PortNumber p1 = portNumber(1);
        Criterion matchInPhyPort = Criteria.matchInPhyPort(p1);
        Criteria.PortCriterion portCriterion =
                checkAndConvert(matchInPhyPort,
                                Criterion.Type.IN_PHY_PORT,
                                Criteria.PortCriterion.class);
        assertThat(portCriterion.port(), is(equalTo(p1)));
    }

    /**
     * Test the equals() method of the PortCriterion class.
     */
    @Test
    public void testPortCriterionEquals() {
        new EqualsTester()
                .addEqualityGroup(matchInPort1, sameAsMatchInPort1)
                .addEqualityGroup(matchInPort2)
                .testEquals();

        new EqualsTester()
                .addEqualityGroup(matchInPhyPort1, sameAsMatchInPhyPort1)
                .addEqualityGroup(matchInPhyPort2)
                .testEquals();
    }

    // MetadataCriterion class

    /**
     * Test the matchMetadata method.
     */
    @Test
    public void testMatchMetadataMethod() {
        Long metadata = 12L;
        Criterion matchMetadata = Criteria.matchMetadata(metadata);
        Criteria.MetadataCriterion metadataCriterion =
                checkAndConvert(matchMetadata,
                                Criterion.Type.METADATA,
                                Criteria.MetadataCriterion.class);
        assertThat(metadataCriterion.metadata(), is(equalTo(metadata)));
    }

    /**
     * Test the equals() method of the MetadataCriterion class.
     */
    @Test
    public void testMetadataCriterionEquals() {
        new EqualsTester()
                .addEqualityGroup(matchMetadata1, sameAsMatchMetadata1)
                .addEqualityGroup(matchMetadata2)
                .testEquals();
    }

    // EthCriterion class

    /**
     * Test the matchEthDst method.
     */
    @Test
    public void testMatchEthDstMethod() {
        Criterion matchEthDst = Criteria.matchEthDst(mac1);
        Criteria.EthCriterion ethCriterion =
                checkAndConvert(matchEthDst,
                        Criterion.Type.ETH_DST,
                        Criteria.EthCriterion.class);
        assertThat(ethCriterion.mac(), is(equalTo(mac1)));
    }

    /**
     * Test the matchEthSrc method.
     */
    @Test
    public void testMatchEthSrcMethod() {
        Criterion matchEthSrc = Criteria.matchEthSrc(mac1);
        Criteria.EthCriterion ethCriterion =
                checkAndConvert(matchEthSrc,
                                Criterion.Type.ETH_SRC,
                                Criteria.EthCriterion.class);
        assertThat(ethCriterion.mac(), is(mac1));
    }

    /**
     * Test the equals() method of the EthCriterion class.
     */
    @Test
    public void testEthCriterionEquals() {
        new EqualsTester()
                .addEqualityGroup(matchEth1, sameAsMatchEth1)
                .addEqualityGroup(matchEth2)
                .testEquals();
    }

    // EthTypeCriterion class

    /**
     * Test the matchEthType method.
     */
    @Test
    public void testMatchEthTypeMethod() {
        int ethType = 12;
        Criterion matchEthType = Criteria.matchEthType(ethType);
        Criteria.EthTypeCriterion ethTypeCriterion =
                checkAndConvert(matchEthType,
                                Criterion.Type.ETH_TYPE,
                                Criteria.EthTypeCriterion.class);
        assertThat(ethTypeCriterion.ethType(), is(equalTo(ethType)));
    }

    /**
     * Test the equals() method of the EthTypeCriterion class.
     */
    @Test
    public void testEthTypeCriterionEquals() {
        new EqualsTester()
                .addEqualityGroup(matchEthType1, sameAsMatchEthType1)
                .addEqualityGroup(matchEthType2)
                .testEquals();
    }

    // VlanIdCriterion class

    /**
     * Test the matchVlanId method.
     */
    @Test
    public void testMatchVlanIdMethod() {
        Criterion matchVlanId = Criteria.matchVlanId(vlanId1);
        Criteria.VlanIdCriterion vlanIdCriterion =
                checkAndConvert(matchVlanId,
                        Criterion.Type.VLAN_VID,
                        Criteria.VlanIdCriterion.class);
        assertThat(vlanIdCriterion.vlanId(), is(equalTo(vlanId1)));
    }

    /**
     * Test the equals() method of the VlanIdCriterion class.
     */
    @Test
    public void testVlanIdCriterionEquals() {
        new EqualsTester()
                .addEqualityGroup(matchVlanId1, sameAsMatchVlanId1)
                .addEqualityGroup(matchVlanId2)
                .testEquals();
    }

    // VlanPcpCriterion class

    /**
     * Test the matchVlanPcp method.
     */
    @Test
    public void testMatchVlanPcpMethod() {
        Criterion matchVlanPcp = Criteria.matchVlanPcp(vlanPcp1);
        Criteria.VlanPcpCriterion vlanPcpCriterion =
                checkAndConvert(matchVlanPcp,
                        Criterion.Type.VLAN_PCP,
                        Criteria.VlanPcpCriterion.class);
        assertThat(vlanPcpCriterion.priority(), is(equalTo(vlanPcp1)));
    }

    /**
     * Test the equals() method of the VlanPcpCriterion class.
     */
    @Test
    public void testVlanPcpCriterionEquals() {
        new EqualsTester()
                .addEqualityGroup(matchVlanPcp1, sameAsMatchVlanPcp1)
                .addEqualityGroup(matchVlanPcp2)
                .testEquals();
    }

    // IPDscpCriterion class

    /**
     * Test the matchIPDscp method.
     */
    @Test
    public void testMatchIPDscpMethod() {
        Criterion matchIPDscp = Criteria.matchIPDscp(ipDscp1);
        Criteria.IPDscpCriterion ipDscpCriterion =
                checkAndConvert(matchIPDscp,
                        Criterion.Type.IP_DSCP,
                        Criteria.IPDscpCriterion.class);
        assertThat(ipDscpCriterion.ipDscp(), is(equalTo(ipDscp1)));
    }

    /**
     * Test the equals() method of the IPDscpCriterion class.
     */
    @Test
    public void testIPDscpCriterionEquals() {
        new EqualsTester()
                .addEqualityGroup(matchIpDscp1, sameAsMatchIpDscp1)
                .addEqualityGroup(matchIpDscp2)
                .testEquals();
    }

    // IPEcnCriterion class

    /**
     * Test the matchIPEcn method.
     */
    @Test
    public void testMatchIPEcnMethod() {
        Criterion matchIPEcn = Criteria.matchIPEcn(ipEcn1);
        Criteria.IPEcnCriterion ipEcnCriterion =
                checkAndConvert(matchIPEcn,
                        Criterion.Type.IP_ECN,
                        Criteria.IPEcnCriterion.class);
        assertThat(ipEcnCriterion.ipEcn(), is(equalTo(ipEcn1)));
    }

    /**
     * Test the equals() method of the IPEcnCriterion class.
     */
    @Test
    public void testIPEcnCriterionEquals() {
        new EqualsTester()
                .addEqualityGroup(matchIpEcn1, sameAsMatchIpEcn1)
                .addEqualityGroup(matchIpEcn2)
                .testEquals();
    }

    // IpProtocolCriterion class

    /**
     * Test the matchIpProtocol method.
     */
    @Test
    public void testMatchIpProtocolMethod() {
        Criterion matchIPProtocol = Criteria.matchIPProtocol(protocol1);
        Criteria.IPProtocolCriterion ipProtocolCriterion =
                checkAndConvert(matchIPProtocol,
                        Criterion.Type.IP_PROTO,
                        Criteria.IPProtocolCriterion.class);
        assertThat(ipProtocolCriterion.protocol(), is(equalTo(protocol1)));
    }

    /**
     * Test the equals() method of the IpProtocolCriterion class.
     */
    @Test
    public void testIpProtocolCriterionEquals() {
        new EqualsTester()
                .addEqualityGroup(matchIpProtocol1, sameAsMatchIpProtocol1)
                .addEqualityGroup(matchIpProtocol2)
                .testEquals();
    }

    // IPCriterion class

    /**
     * Test the matchIPSrc method: IPv4.
     */
    @Test
    public void testMatchIPSrcMethod() {
        Criterion matchIpSrc = Criteria.matchIPSrc(ip1);
        Criteria.IPCriterion ipCriterion =
                checkAndConvert(matchIpSrc,
                                Criterion.Type.IPV4_SRC,
                                Criteria.IPCriterion.class);
        assertThat(ipCriterion.ip(), is(ip1));
    }

    /**
     * Test the matchIPDst method: IPv4.
     */
    @Test
    public void testMatchIPDstMethod() {
        Criterion matchIPDst = Criteria.matchIPDst(ip1);
        Criteria.IPCriterion ipCriterion =
                checkAndConvert(matchIPDst,
                        Criterion.Type.IPV4_DST,
                        Criteria.IPCriterion.class);
        assertThat(ipCriterion.ip(), is(equalTo(ip1)));
    }

    /**
     * Test the matchIPSrc method: IPv6.
     */
    @Test
    public void testMatchIPv6SrcMethod() {
        Criterion matchIpv6Src = Criteria.matchIPv6Src(ipv61);
        Criteria.IPCriterion ipCriterion =
                checkAndConvert(matchIpv6Src,
                        Criterion.Type.IPV6_SRC,
                        Criteria.IPCriterion.class);
        assertThat(ipCriterion.ip(), is(ipv61));
    }

    /**
     * Test the matchIPDst method: IPv6.
     */
    @Test
    public void testMatchIPv6DstMethod() {
        Criterion matchIPv6Dst = Criteria.matchIPv6Dst(ipv61);
        Criteria.IPCriterion ipCriterion =
                checkAndConvert(matchIPv6Dst,
                        Criterion.Type.IPV6_DST,
                        Criteria.IPCriterion.class);
        assertThat(ipCriterion.ip(), is(equalTo(ipv61)));
    }

    /**
     * Test the equals() method of the IpCriterion class.
     */
    @Test
    public void testIPCriterionEquals() {
        new EqualsTester()
                .addEqualityGroup(matchIp1, sameAsMatchIp1)
                .addEqualityGroup(matchIp2)
                .testEquals();

        new EqualsTester()
                .addEqualityGroup(matchIpv61, sameAsMatchIpv61)
                .addEqualityGroup(matchIpv62)
                .testEquals();
    }

    // TcpPortCriterion class

    /**
     * Test the matchTcpSrc method.
     */
    @Test
    public void testMatchTcpSrcMethod() {
        Criterion matchTcpSrc = Criteria.matchTcpSrc(1);
        Criteria.TcpPortCriterion tcpPortCriterion =
                checkAndConvert(matchTcpSrc,
                                Criterion.Type.TCP_SRC,
                                Criteria.TcpPortCriterion.class);
        assertThat(tcpPortCriterion.tcpPort(), is(equalTo(1)));
    }

    /**
     * Test the matchTcpDst method.
     */
    @Test
    public void testMatchTcpDstMethod() {
        Criterion matchTcpDst = Criteria.matchTcpDst(1);
        Criteria.TcpPortCriterion tcpPortCriterion =
                checkAndConvert(matchTcpDst,
                        Criterion.Type.TCP_DST,
                        Criteria.TcpPortCriterion.class);
        assertThat(tcpPortCriterion.tcpPort(), is(equalTo(1)));
    }

    /**
     * Test the equals() method of the TcpPortCriterion class.
     */
    @Test
    public void testTcpPortCriterionEquals() {
        new EqualsTester()
                .addEqualityGroup(matchTcpPort1, sameAsMatchTcpPort1)
                .addEqualityGroup(matchTcpPort2)
                .testEquals();
    }

    // UdpPortCriterion class

    /**
     * Test the matchUdpSrc method.
     */
    @Test
    public void testMatchUdpSrcMethod() {
        Criterion matchUdpSrc = Criteria.matchUdpSrc(1);
        Criteria.UdpPortCriterion udpPortCriterion =
                checkAndConvert(matchUdpSrc,
                                Criterion.Type.UDP_SRC,
                                Criteria.UdpPortCriterion.class);
        assertThat(udpPortCriterion.udpPort(), is(equalTo(1)));
    }

    /**
     * Test the matchUdpDst method.
     */
    @Test
    public void testMatchUdpDstMethod() {
        Criterion matchUdpDst = Criteria.matchUdpDst(1);
        Criteria.UdpPortCriterion udpPortCriterion =
                checkAndConvert(matchUdpDst,
                        Criterion.Type.UDP_DST,
                        Criteria.UdpPortCriterion.class);
        assertThat(udpPortCriterion.udpPort(), is(equalTo(1)));
    }

    /**
     * Test the equals() method of the UdpPortCriterion class.
     */
    @Test
    public void testUdpPortCriterionEquals() {
        new EqualsTester()
                .addEqualityGroup(matchUdpPort1, sameAsMatchUdpPort1)
                .addEqualityGroup(matchUdpPort2)
                .testEquals();
    }

    // SctpPortCriterion class

    /**
     * Test the matchSctpSrc method.
     */
    @Test
    public void testMatchSctpSrcMethod() {
        Criterion matchSctpSrc = Criteria.matchSctpSrc(1);
        Criteria.SctpPortCriterion sctpPortCriterion =
                checkAndConvert(matchSctpSrc,
                                Criterion.Type.SCTP_SRC,
                                Criteria.SctpPortCriterion.class);
        assertThat(sctpPortCriterion.sctpPort(), is(equalTo(1)));
    }

    /**
     * Test the matchSctpDst method.
     */
    @Test
    public void testMatchSctpDstMethod() {
        Criterion matchSctpDst = Criteria.matchSctpDst(1);
        Criteria.SctpPortCriterion sctpPortCriterion =
                checkAndConvert(matchSctpDst,
                        Criterion.Type.SCTP_DST,
                        Criteria.SctpPortCriterion.class);
        assertThat(sctpPortCriterion.sctpPort(), is(equalTo(1)));
    }

    /**
     * Test the equals() method of the SctpPortCriterion class.
     */
    @Test
    public void testSctpPortCriterionEquals() {
        new EqualsTester()
                .addEqualityGroup(matchSctpPort1, sameAsMatchSctpPort1)
                .addEqualityGroup(matchSctpPort2)
                .testEquals();
    }

    // IcmpTypeCriterion class

    /**
     * Test the matchIcmpType method.
     */
    @Test
    public void testMatchIcmpTypeMethod() {
        short icmpType = 12;
        Criterion matchIcmpType = Criteria.matchIcmpType(icmpType);
        Criteria.IcmpTypeCriterion icmpTypeCriterion =
                checkAndConvert(matchIcmpType,
                                Criterion.Type.ICMPV4_TYPE,
                                Criteria.IcmpTypeCriterion.class);
        assertThat(icmpTypeCriterion.icmpType(), is(equalTo(icmpType)));
    }

    /**
     * Test the equals() method of the IcmpTypeCriterion class.
     */
    @Test
    public void testIcmpTypeCriterionEquals() {
        new EqualsTester()
                .addEqualityGroup(matchIcmpType1, sameAsMatchIcmpType1)
                .addEqualityGroup(matchIcmpType2)
                .testEquals();
    }

    // IcmpCodeCriterion class

    /**
     * Test the matchIcmpCode method.
     */
    @Test
    public void testMatchIcmpCodeMethod() {
        short icmpCode = 12;
        Criterion matchIcmpCode = Criteria.matchIcmpCode(icmpCode);
        Criteria.IcmpCodeCriterion icmpCodeCriterion =
                checkAndConvert(matchIcmpCode,
                                Criterion.Type.ICMPV4_CODE,
                                Criteria.IcmpCodeCriterion.class);
        assertThat(icmpCodeCriterion.icmpCode(), is(equalTo(icmpCode)));
    }

    /**
     * Test the equals() method of the IcmpCodeCriterion class.
     */
    @Test
    public void testIcmpCodeCriterionEquals() {
        new EqualsTester()
                .addEqualityGroup(matchIcmpCode1, sameAsMatchIcmpCode1)
                .addEqualityGroup(matchIcmpCode2)
                .testEquals();
    }

    // IPv6FlowLabelCriterion class

    /**
     * Test the matchIPv6FlowLabel method.
     */
    @Test
    public void testMatchIPv6FlowLabelMethod() {
        int flowLabel = 12;
        Criterion matchFlowLabel = Criteria.matchIPv6FlowLabel(flowLabel);
        Criteria.IPv6FlowLabelCriterion flowLabelCriterion =
                checkAndConvert(matchFlowLabel,
                                Criterion.Type.IPV6_FLABEL,
                                Criteria.IPv6FlowLabelCriterion.class);
        assertThat(flowLabelCriterion.flowLabel(), is(equalTo(flowLabel)));
    }

    /**
     * Test the equals() method of the IPv6FlowLabelCriterion class.
     */
    @Test
    public void testIPv6FlowLabelCriterionEquals() {
        new EqualsTester()
                .addEqualityGroup(matchFlowLabel1, sameAsMatchFlowLabel1)
                .addEqualityGroup(matchFlowLabel2)
                .testEquals();
    }

    // Icmpv6TypeCriterion class

    /**
     * Test the matchIcmpv6Type method.
     */
    @Test
    public void testMatchIcmpv6TypeMethod() {
        short icmpv6Type = 12;
        Criterion matchIcmpv6Type = Criteria.matchIcmpv6Type(icmpv6Type);
        Criteria.Icmpv6TypeCriterion icmpv6TypeCriterion =
                checkAndConvert(matchIcmpv6Type,
                                Criterion.Type.ICMPV6_TYPE,
                                Criteria.Icmpv6TypeCriterion.class);
        assertThat(icmpv6TypeCriterion.icmpv6Type(), is(equalTo(icmpv6Type)));
    }

    /**
     * Test the equals() method of the Icmpv6TypeCriterion class.
     */
    @Test
    public void testIcmpv6TypeCriterionEquals() {
        new EqualsTester()
                .addEqualityGroup(matchIcmpv6Type1, sameAsMatchIcmpv6Type1)
                .addEqualityGroup(matchIcmpv6Type2)
                .testEquals();
    }

    // Icmpv6CodeCriterion class

    /**
     * Test the matchIcmpv6Code method.
     */
    @Test
    public void testMatchIcmpv6CodeMethod() {
        short icmpv6Code = 12;
        Criterion matchIcmpv6Code = Criteria.matchIcmpv6Code(icmpv6Code);
        Criteria.Icmpv6CodeCriterion icmpv6CodeCriterion =
                checkAndConvert(matchIcmpv6Code,
                                Criterion.Type.ICMPV6_CODE,
                                Criteria.Icmpv6CodeCriterion.class);
        assertThat(icmpv6CodeCriterion.icmpv6Code(), is(equalTo(icmpv6Code)));
    }

    /**
     * Test the equals() method of the Icmpv6CodeCriterion class.
     */
    @Test
    public void testIcmpv6CodeCriterionEquals() {
        new EqualsTester()
                .addEqualityGroup(matchIcmpv6Code1, sameAsMatchIcmpv6Code1)
                .addEqualityGroup(matchIcmpv6Code2)
                .testEquals();
    }

    // IPv6NDTargetAddressCriterion class

    /**
     * Test the matchIPv6NDTargetAddress method.
     */
    @Test
    public void testMatchIPv6NDTargetAddressMethod() {
        Criterion matchTargetAddress =
            Criteria.matchIPv6NDTargetAddress(ip6TargetAddress1);
        Criteria.IPv6NDTargetAddressCriterion targetAddressCriterion =
                checkAndConvert(matchTargetAddress,
                                Criterion.Type.IPV6_ND_TARGET,
                                Criteria.IPv6NDTargetAddressCriterion.class);
        assertThat(targetAddressCriterion.targetAddress(),
                   is(ip6TargetAddress1));
    }

    /**
     * Test the equals() method of the IPv6NDTargetAddressCriterion class.
     */
    @Test
    public void testIPv6NDTargetAddressCriterionEquals() {
        new EqualsTester()
                .addEqualityGroup(matchIpv6TargetAddr1,
                                  sameAsMatchIpv6TargetAddr1)
                .addEqualityGroup(matchIpv6TargetAddr2)
                .testEquals();
    }

    // IPv6NDLinkLayerAddressCriterion class

    /**
     * Test the matchIPv6NDSourceLinkLayerAddress method.
     */
    @Test
    public void testMatchIPv6NDSourceLinkLayerAddressMethod() {
        Criterion matchSrcLlAddr =
            Criteria.matchIPv6NDSourceLinkLayerAddress(llMac1);
        Criteria.IPv6NDLinkLayerAddressCriterion srcLlCriterion =
                checkAndConvert(matchSrcLlAddr,
                        Criterion.Type.IPV6_ND_SLL,
                        Criteria.IPv6NDLinkLayerAddressCriterion.class);
        assertThat(srcLlCriterion.mac(), is(equalTo(llMac1)));
    }

    /**
     * Test the matchIPv6NDTargetLinkLayerAddress method.
     */
    @Test
    public void testMatchIPv6NDTargetLinkLayerAddressMethod() {
        Criterion matchTargetLlAddr =
            Criteria.matchIPv6NDTargetLinkLayerAddress(llMac1);
        Criteria.IPv6NDLinkLayerAddressCriterion targetLlCriterion =
                checkAndConvert(matchTargetLlAddr,
                        Criterion.Type.IPV6_ND_TLL,
                        Criteria.IPv6NDLinkLayerAddressCriterion.class);
        assertThat(targetLlCriterion.mac(), is(equalTo(llMac1)));
    }

    /**
     * Test the equals() method of the IPv6NDLinkLayerAddressCriterion class.
     */
    @Test
    public void testIPv6NDLinkLayerAddressCriterionEquals() {
        new EqualsTester()
                .addEqualityGroup(matchSrcLlAddr1, sameAsMatchSrcLlAddr1)
                .addEqualityGroup(matchSrcLlAddr2)
                .testEquals();

        new EqualsTester()
                .addEqualityGroup(matchTargetLlAddr1, sameAsMatchTargetLlAddr1)
                .addEqualityGroup(matchTargetLlAddr2)
                .testEquals();
    }

    // MplsCriterion class

    /**
     * Test the matchMplsLabel method.
     */
    @Test
    public void testMatchMplsLabelMethod() {
        Criterion matchMplsLabel = Criteria.matchMplsLabel(mpls1);
        Criteria.MplsCriterion mplsCriterion =
                checkAndConvert(matchMplsLabel,
                        Criterion.Type.MPLS_LABEL,
                        Criteria.MplsCriterion.class);
        assertThat(mplsCriterion.label(), is(equalTo(mpls1)));
    }

    /**
     * Test the equals() method of the MplsCriterion class.
     */
    @Test
    public void testMplsCriterionEquals() {
        new EqualsTester()
                .addEqualityGroup(matchMpls1, sameAsMatchMpls1)
                .addEqualityGroup(matchMpls2)
                .testEquals();
    }

    // IPv6ExthdrFlagsCriterion class

    /**
     * Test the matchIPv6ExthdrFlags method.
     */
    @Test
    public void testMatchIPv6ExthdrFlagsMethod() {
        Criterion matchExthdrFlags =
            Criteria.matchIPv6ExthdrFlags(ipv6ExthdrFlags1);
        Criteria.IPv6ExthdrFlagsCriterion exthdrFlagsCriterion =
                checkAndConvert(matchExthdrFlags,
                        Criterion.Type.IPV6_EXTHDR,
                        Criteria.IPv6ExthdrFlagsCriterion.class);
        assertThat(exthdrFlagsCriterion.exthdrFlags(),
                   is(equalTo(ipv6ExthdrFlags1)));
    }

    /**
     * Test the equals() method of the IPv6ExthdrFlagsCriterion class.
     */
    @Test
    public void testIPv6ExthdrFlagsCriterionEquals() {
        new EqualsTester()
                .addEqualityGroup(matchIpv6ExthdrFlags1,
                                  sameAsMatchIpv6ExthdrFlags1)
                .addEqualityGroup(matchIpv6ExthdrFlags2)
                .testEquals();
    }

    // LambdaCriterion class

    /**
     * Test the matchLambda method.
     */
    @Test
    public void testMatchLambdaMethod() {
        Criterion matchLambda = Criteria.matchLambda(lambda1);
        Criteria.LambdaCriterion lambdaCriterion =
                checkAndConvert(matchLambda,
                        Criterion.Type.OCH_SIGID,
                        Criteria.LambdaCriterion.class);
        assertThat(lambdaCriterion.lambda(), is(equalTo(lambda1)));
    }

    /**
     * Test the equals() method of the LambdaCriterion class.
     */
    @Test
    public void testLambdaCriterionEquals() {
        new EqualsTester()
                .addEqualityGroup(matchLambda1, sameAsMatchLambda1)
                .addEqualityGroup(matchLambda2)
                .testEquals();
    }

    // OpticalSignalTypeCriterion class

    /**
     * Test the matchOpticalSignalType method.
     */
    @Test
    public void testMatchOpticalSignalTypeMethod() {
        Criterion matchLambda = Criteria.matchOpticalSignalType(signalLambda1);
        Criteria.OpticalSignalTypeCriterion opticalSignalTypeCriterion =
                checkAndConvert(matchLambda,
                        Criterion.Type.OCH_SIGTYPE,
                        Criteria.OpticalSignalTypeCriterion.class);
        assertThat(opticalSignalTypeCriterion.signalType(), is(equalTo(signalLambda1)));
    }

    /**
     * Test the equals() method of the OpticalSignalTypeCriterion class.
     */
    @Test
    public void testOpticalSignalTypeCriterionEquals() {
        new EqualsTester()
                .addEqualityGroup(matchSignalLambda1, sameAsMatchSignalLambda1)
                .addEqualityGroup(matchSignalLambda2)
                .testEquals();
    }
}
