AclServiceOFFlowBuilder UT added 60/42060/8
authorRavit Peretz <ravit.peretz@hpe.com>
Tue, 19 Jul 2016 12:37:06 +0000 (15:37 +0300)
committerRavit Peretz <ravit.peretz@hpe.com>
Wed, 27 Jul 2016 08:18:59 +0000 (11:18 +0300)
Change-Id: I52d6f2779139edba1012044caf5541ef8033e71a
Signed-off-by: Ravit Peretz <ravit.peretz@hpe.com>
vpnservice/aclservice/impl/src/main/java/org/opendaylight/netvirt/aclservice/utils/AclServiceOFFlowBuilder.java
vpnservice/aclservice/impl/src/test/java/org/opendaylight/netvirt/aclservice/utils/AclServiceOFFlowBuilderTest.java [new file with mode: 0644]
vpnservice/aclservice/impl/src/test/java/org/opendaylight/netvirt/aclservice/utils/AclServiceTestUtils.java [new file with mode: 0644]

index b810571d53c8168d37950a7b3afeda60453fd85f..9a79c70f0d38bc869d4dfc83fbe67a1b484fb1c9 100644 (file)
@@ -5,6 +5,7 @@
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
+
 package org.opendaylight.netvirt.aclservice.utils;
 
 import java.util.ArrayList;
@@ -24,31 +25,34 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160218.acl.transport.header.fields.DestinationPortRange;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160218.acl.transport.header.fields.SourcePortRange;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class AclServiceOFFlowBuilder {
 
-    private AclServiceOFFlowBuilder() {
-    }
+    private static final Logger LOG =
+            LoggerFactory.getLogger(AclServiceOFFlowBuilder.class);
 
     /**
      * Converts IP matches into flows.
-     * @param matches the matches
+     * @param matches
+     *            the matches
      * @return the map containing the flows and the respective flow id
      */
-    public static Map<String,List<MatchInfoBase>>  programIpFlow(Matches matches) {
-        new HashMap<>();
-        AceIp acl = (AceIp)matches.getAceType();
-        if (acl.getProtocol() == NwConstants.IP_PROT_TCP) {
-            return programTcpFlow(acl);
-        } else if (acl.getProtocol() == NwConstants.IP_PROT_UDP) {
-            return programUdpFlow(acl);
-        } else if (acl.getProtocol() == NwConstants.IP_PROT_ICMP) {
-            return programIcmpFlow(acl);
-        } else if (acl.getProtocol() != -1) {
-            return programOtherProtocolFlow(acl);
+    public static Map<String, List<MatchInfoBase>> programIpFlow(Matches matches) {
+        if (matches != null) {
+            AceIp acl = (AceIp) matches.getAceType();
+            if (acl.getProtocol() == NwConstants.IP_PROT_TCP) {
+                return programTcpFlow(acl);
+            } else if (acl.getProtocol() == NwConstants.IP_PROT_UDP) {
+                return programUdpFlow(acl);
+            } else if (acl.getProtocol() == NwConstants.IP_PROT_ICMP) {
+                return programIcmpFlow(acl);
+            } else if (acl.getProtocol() != -1) {
+                return programOtherProtocolFlow(acl);
+            }
         }
         return null;
-
     }
 
     /** Converts generic protocol matches to flows.
@@ -296,16 +300,26 @@ public class AclServiceOFFlowBuilder {
      *
      */
     public static Map<Integer,Integer>  getLayer4MaskForRange(int portMin, int portMax) {
-        int [] offset = {32768,16384,8192,4096,2048,1024,512,256,128,64,32,16,8,4,2,1};
-        int[] mask = {0x8000,0xC000,0xE000,0xF000,0xF800,0xFC00,0xFE00,0xFF00,
-                      0xFF80,0xFFC0,0xFFE0,0xFFF0,0xFFF8,0xFFFC,0xFFFE,0xFFFF};
+        final int[] offset = { 32768, 16384, 8192, 4096, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1 };
+        final int[] mask = { 0x8000, 0xC000, 0xE000, 0xF000, 0xF800, 0xFC00, 0xFE00, 0xFF00, 0xFF80, 0xFFC0, 0xFFE0,
+            0xFFF0, 0xFFF8, 0xFFFC, 0xFFFE, 0xFFFF };
         int noOfPorts = portMax - portMin + 1;
         Map<Integer,Integer> portMap = new HashMap<>();
         if (noOfPorts == 1) {
             portMap.put(portMin, mask[15]);
             return portMap;
         }
+        if (noOfPorts < 0) { // TODO: replace with infrautils.counter in case of high repetitive usage
+            LOG.warn("Cannot convert port range into a set of masked port ranges - Illegal port range {}-{}", portMin,
+                    portMax);
+            return portMap;
+        }
         String binaryNoOfPorts = Integer.toBinaryString(noOfPorts);
+        if (binaryNoOfPorts.length() > 16) { // TODO: replace with infrautils.counter in case of high repetitive usage
+            LOG.warn("Cannot convert port range into a set of masked port ranges - Illegal port range {}-{}", portMin,
+                    portMax);
+            return portMap;
+        }
         int medianOffset = 16 - binaryNoOfPorts.length();
         int medianLength = offset[medianOffset];
         int median = 0;
diff --git a/vpnservice/aclservice/impl/src/test/java/org/opendaylight/netvirt/aclservice/utils/AclServiceOFFlowBuilderTest.java b/vpnservice/aclservice/impl/src/test/java/org/opendaylight/netvirt/aclservice/utils/AclServiceOFFlowBuilderTest.java
new file mode 100644 (file)
index 0000000..a49d489
--- /dev/null
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2016 Hewlett Packard Enterprise, Co. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netvirt.aclservice.utils;
+
+import static com.google.common.collect.Iterables.filter;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import com.google.common.collect.Iterables;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.Test;
+import org.opendaylight.genius.mdsalutil.MatchFieldType;
+import org.opendaylight.genius.mdsalutil.MatchInfo;
+import org.opendaylight.genius.mdsalutil.MatchInfoBase;
+import org.opendaylight.genius.mdsalutil.NwConstants;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.ace.Matches;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIpBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.ace.ip.version.AceIpv4Builder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
+
+
+public class AclServiceOFFlowBuilderTest {
+
+    @Test
+    public void testProgramIpFlow_NullMatches() {
+        Matches matches = null;
+        Map<String, List<MatchInfoBase>> flowMap = AclServiceOFFlowBuilder.programIpFlow(matches);
+        assertNull(flowMap);
+    }
+
+    @Test
+    public void testprogramOtherProtocolFlow() {
+        AceIpBuilder builder = AclServiceTestUtils.prepareAceIpBuilder("10.1.1.1/24", "20.1.1.1/24", null, null,
+                (short) 1);
+        Map<String, List<MatchInfoBase>> flowMatchesMap =
+                AclServiceOFFlowBuilder.programOtherProtocolFlow(builder.build());
+        List<MatchInfoBase> flowMatches = flowMatchesMap.get("OTHER_PROTO" + "1");
+        AclServiceTestUtils.verifyGeneralFlows(flowMatches, "1", "10.1.1.1", "20.1.1.1", "24");
+    }
+
+    @Test
+    public void testprogramIcmpFlow() {
+        AceIpBuilder builder = AclServiceTestUtils.prepareAceIpBuilder("10.1.1.1/24", "20.1.1.1/24", "1024", "2048",
+                (short) 1);
+        Map<String, List<MatchInfoBase>> flowMatchesMap = AclServiceOFFlowBuilder.programIcmpFlow(builder.build());
+        List<MatchInfoBase> flowMatches = flowMatchesMap.entrySet().iterator().next().getValue();
+
+        AclServiceTestUtils.verifyGeneralFlows(flowMatches, "1", "10.1.1.1", "20.1.1.1", "24");
+
+        Iterable<MatchInfoBase> icmpv4Matches = filter(flowMatches,
+                (item -> ((MatchInfo) item).getMatchField().equals(MatchFieldType.icmp_v4)));
+        AclServiceTestUtils.verifyMatchValues((MatchInfo) Iterables.get(icmpv4Matches, 0), "1024", "2048");
+        AclServiceTestUtils.verifyMatchValues((MatchInfo) Iterables.get(icmpv4Matches, 1), "4096", "8192");
+    }
+
+    @Test
+    public void testprogramTcpFlow_NoSrcDstPortRange() {
+        AceIpBuilder builder = AclServiceTestUtils.prepareAceIpBuilder("10.1.1.1/24", "20.1.1.1/24", null, null,
+                (short) 1);
+
+        Map<String, List<MatchInfoBase>> flowMatchesMap = AclServiceOFFlowBuilder.programTcpFlow(builder.build());
+        List<MatchInfoBase> flowMatches = flowMatchesMap.get("TCP_SOURCE_ALL_");
+
+        AclServiceTestUtils.verifyGeneralFlows(flowMatches, "1", "10.1.1.1", "20.1.1.1", "24");
+        AclServiceTestUtils.verifyMatchFieldTypeDontExist(flowMatches, MatchFieldType.tcp_src);
+        AclServiceTestUtils.verifyMatchFieldTypeDontExist(flowMatches, MatchFieldType.tcp_dst);
+    }
+
+    @Test
+    public void testprogramTcpFlow_WithSrcDstPortRange() {
+        AceIpBuilder builder = AclServiceTestUtils.prepareAceIpBuilder("10.1.1.1/24", "20.1.1.1/24", "1024", "1024",
+                (short) 1);
+
+        Map<String, List<MatchInfoBase>> flowMatchesMap = AclServiceOFFlowBuilder.programTcpFlow(builder.build());
+
+        List<MatchInfoBase> srcFlowMatches = new ArrayList<MatchInfoBase>();
+        List<MatchInfoBase> dstFlowMatches = new ArrayList<MatchInfoBase>();
+
+        for (String flowId : flowMatchesMap.keySet()) {
+            if (flowId.startsWith("TCP_SOURCE_")) {
+                srcFlowMatches.addAll(flowMatchesMap.get(flowId));
+            }
+            if (flowId.startsWith("TCP_DESTINATION_")) {
+                dstFlowMatches.addAll(flowMatchesMap.get(flowId));
+            }
+        }
+
+        AclServiceTestUtils.verifyGeneralFlows(srcFlowMatches, "1", "10.1.1.1", "20.1.1.1", "24");
+        Iterable<MatchInfoBase> tcpSrcMatches = filter(srcFlowMatches,
+                (item -> ((MatchInfo) item).getMatchField().equals(MatchFieldType.tcp_src)));
+
+        AclServiceTestUtils.verifyMatchValues((MatchInfo) Iterables.getFirst(tcpSrcMatches, null), "1024");
+
+        AclServiceTestUtils.verifyGeneralFlows(dstFlowMatches, "1", "10.1.1.1", "20.1.1.1", "24");
+        Iterable<MatchInfoBase> tcpDstMatches = filter(dstFlowMatches,
+                (item -> ((MatchInfo) item).getMatchField().equals(MatchFieldType.tcp_dst)));
+
+        AclServiceTestUtils.verifyMatchValues((MatchInfo) Iterables.getFirst(tcpDstMatches, null), "1024");
+    }
+
+    @Test
+    public void testProgramUdpFlow_NoSrcDstPortRange() {
+        AceIpBuilder builder = new AceIpBuilder();
+        AceIpv4Builder v4builder = new AceIpv4Builder();
+        v4builder.setSourceIpv4Network(new Ipv4Prefix("10.1.1.1/24"));
+        v4builder.setDestinationIpv4Network(new Ipv4Prefix("20.1.1.1/24"));
+        builder.setAceIpVersion(v4builder.build());
+        builder.setSourcePortRange(null);
+        builder.setDestinationPortRange(null);
+        short protocol = 1;
+        builder.setProtocol(protocol);
+
+        Map<String, List<MatchInfoBase>> flowMatchesMap = AclServiceOFFlowBuilder.programUdpFlow(builder.build());
+
+        List<MatchInfoBase> flowMatches = flowMatchesMap.get("UDP_SOURCE_ALL_");
+
+        AclServiceTestUtils.verifyGeneralFlows(flowMatches, "1", "10.1.1.1", "20.1.1.1", "24");
+        AclServiceTestUtils.verifyMatchFieldTypeDontExist(flowMatches, MatchFieldType.udp_src);
+        AclServiceTestUtils.verifyMatchFieldTypeDontExist(flowMatches, MatchFieldType.udp_dst);
+    }
+
+    @Test
+    public void testprogramUdpFlow_WithSrcDstPortRange() {
+        AceIpBuilder builder = AclServiceTestUtils.prepareAceIpBuilder("10.1.1.1/24", "20.1.1.1/24", "1024", "1024",
+                (short) 1);
+
+        Map<String, List<MatchInfoBase>> flowMatchesMap = AclServiceOFFlowBuilder.programUdpFlow(builder.build());
+        List<MatchInfoBase> srcFlowMatches = new ArrayList<MatchInfoBase>();
+        List<MatchInfoBase> dstFlowMatches = new ArrayList<MatchInfoBase>();
+
+        for (String flowId : flowMatchesMap.keySet()) {
+            if (flowId.startsWith("UDP_SOURCE_")) {
+                srcFlowMatches.addAll(flowMatchesMap.get(flowId));
+            }
+            if (flowId.startsWith("UDP_DESTINATION_")) {
+                dstFlowMatches.addAll(flowMatchesMap.get(flowId));
+            }
+        }
+
+        AclServiceTestUtils.verifyGeneralFlows(srcFlowMatches, "1", "10.1.1.1", "20.1.1.1", "24");
+
+        Iterable<MatchInfoBase> udpSrcMatches = filter(srcFlowMatches,
+                (item -> ((MatchInfo) item).getMatchField().equals(MatchFieldType.udp_src)));
+        AclServiceTestUtils.verifyMatchValues((MatchInfo) Iterables.getFirst(udpSrcMatches, null), "1024");
+
+        AclServiceTestUtils.verifyGeneralFlows(dstFlowMatches, "1", "10.1.1.1", "20.1.1.1", "24");
+
+        Iterable<MatchInfoBase> udpDstMatches = filter(dstFlowMatches,
+                (item -> ((MatchInfo) item).getMatchField().equals(MatchFieldType.udp_dst)));
+        AclServiceTestUtils.verifyMatchValues((MatchInfo) Iterables.getFirst(udpDstMatches, null), "1024");
+    }
+
+    @Test
+    public void testaddDstIpMatches_v4() {
+        AceIpBuilder builder = new AceIpBuilder();
+        AceIpv4Builder v4builder = new AceIpv4Builder();
+        v4builder.setDestinationIpv4Network(new Ipv4Prefix("10.1.1.1/24"));
+        builder.setAceIpVersion(v4builder.build());
+
+        List<MatchInfoBase> flowMatches = AclServiceOFFlowBuilder.addDstIpMatches(builder.build());
+
+        AclServiceTestUtils.verifyMatchInfo(flowMatches, MatchFieldType.eth_type,
+                Integer.toString(NwConstants.ETHTYPE_IPV4));
+        AclServiceTestUtils.verifyMatchInfo(flowMatches, MatchFieldType.ipv4_destination, "10.1.1.1", "24");
+    }
+
+    @Test
+    public void testaddDstIpMatches_v4NoDstNetwork() {
+        AceIpBuilder builder = new AceIpBuilder();
+        AceIpv4Builder v4builder = new AceIpv4Builder();
+        v4builder.setDestinationIpv4Network(null);
+        builder.setAceIpVersion(v4builder.build());
+
+        List<MatchInfoBase> flowMatches = AclServiceOFFlowBuilder.addDstIpMatches(builder.build());
+
+        AclServiceTestUtils.verifyMatchInfo(flowMatches, MatchFieldType.eth_type,
+                Integer.toString(NwConstants.ETHTYPE_IPV4));
+        AclServiceTestUtils.verifyMatchFieldTypeDontExist(flowMatches, MatchFieldType.ipv4_destination);
+    }
+
+    @Test
+    public void testaddSrcIpMatches_v4() {
+        AceIpBuilder builder = new AceIpBuilder();
+        AceIpv4Builder v4builder = new AceIpv4Builder();
+        v4builder.setSourceIpv4Network(new Ipv4Prefix("10.1.1.1/24"));
+        builder.setAceIpVersion(v4builder.build());
+
+        List<MatchInfoBase> flowMatches = AclServiceOFFlowBuilder.addSrcIpMatches(builder.build());
+
+        AclServiceTestUtils.verifyMatchInfo(flowMatches, MatchFieldType.eth_type,
+                Integer.toString(NwConstants.ETHTYPE_IPV4));
+        AclServiceTestUtils.verifyMatchInfo(flowMatches, MatchFieldType.ipv4_source, "10.1.1.1", "24");
+    }
+
+    @Test
+    public void testaddSrcIpMatches_v4NoSrcNetwork() {
+        AceIpBuilder builder = new AceIpBuilder();
+        AceIpv4Builder v4builder = new AceIpv4Builder();
+        v4builder.setSourceIpv4Network(null);
+        builder.setAceIpVersion(v4builder.build());
+
+        List<MatchInfoBase> flowMatches = AclServiceOFFlowBuilder.addSrcIpMatches(builder.build());
+        AclServiceTestUtils.verifyMatchInfo(flowMatches, MatchFieldType.eth_type,
+                Integer.toString(NwConstants.ETHTYPE_IPV4));
+        AclServiceTestUtils.verifyMatchFieldTypeDontExist(flowMatches, MatchFieldType.ipv4_source);
+    }
+
+    @Test
+    public void testgetLayer4MaskForRange_SinglePort() {
+        Map<Integer, Integer> layer4MaskForRange = AclServiceOFFlowBuilder.getLayer4MaskForRange(1111, 1111);
+        assertEquals("port L4 mask missing", 1, layer4MaskForRange.size());
+    }
+
+    @Test
+    public void testgetLayer4MaskForRange_MultiplePorts() {
+        Map<Integer, Integer> layer4MaskForRange = AclServiceOFFlowBuilder.getLayer4MaskForRange(1024, 2048);
+        assertEquals("port L4 mask missing", 2, layer4MaskForRange.size());
+    }
+
+    @Test
+    public void testgetLayer4MaskForRange_IllegalPortRange_ExceedMin() {
+        Map<Integer, Integer> layer4MaskForRange = AclServiceOFFlowBuilder.getLayer4MaskForRange(0, 1);
+
+        assertEquals("port L4 mask missing", 1, layer4MaskForRange.size());
+    }
+
+    @Test
+    public void testgetLayer4MaskForRange_IllegalPortRange_ExceedMax() {
+        Map<Integer, Integer> layer4MaskForRange = AclServiceOFFlowBuilder.getLayer4MaskForRange(1, 65536);
+        assertEquals("Illegal ports range", 0, layer4MaskForRange.size());
+    }
+
+    @Test
+    public void testgetLayer4MaskForRange_IllegalPortRange_MinGreaterThanMax() {
+        Map<Integer, Integer> layer4MaskForRange = AclServiceOFFlowBuilder.getLayer4MaskForRange(8192, 4096);
+        assertEquals("Illegal ports range", 0, layer4MaskForRange.size());
+    }
+}
diff --git a/vpnservice/aclservice/impl/src/test/java/org/opendaylight/netvirt/aclservice/utils/AclServiceTestUtils.java b/vpnservice/aclservice/impl/src/test/java/org/opendaylight/netvirt/aclservice/utils/AclServiceTestUtils.java
new file mode 100644 (file)
index 0000000..5f1cf6f
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2016 Hewlett Packard Enterprise, Co. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netvirt.aclservice.utils;
+
+import static com.google.common.collect.Iterables.filter;
+import static org.junit.Assert.assertTrue;
+
+import com.google.common.collect.Iterables;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.Assert;
+import org.opendaylight.genius.mdsalutil.MatchFieldType;
+import org.opendaylight.genius.mdsalutil.MatchInfo;
+import org.opendaylight.genius.mdsalutil.MatchInfoBase;
+import org.opendaylight.genius.mdsalutil.NwConstants;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIpBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.ace.ip.version.AceIpv4Builder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160218.acl.transport.header.fields.DestinationPortRangeBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160218.acl.transport.header.fields.SourcePortRangeBuilder;
+
+
+public class AclServiceTestUtils {
+
+    public static void verifyGeneralFlows(List<MatchInfoBase> srcFlowMatches, String protocol, String srcIpv4Net,
+            String dstIpv4Net, String mask) {
+        verifyMatchInfo(srcFlowMatches, MatchFieldType.eth_type, Integer.toString(NwConstants.ETHTYPE_IPV4));
+        verifyMatchInfo(srcFlowMatches, MatchFieldType.ip_proto, protocol);
+        verifyMatchInfo(srcFlowMatches, MatchFieldType.ipv4_source, srcIpv4Net, mask);
+        verifyMatchInfo(srcFlowMatches, MatchFieldType.ipv4_destination, dstIpv4Net, mask);
+    }
+
+    public static AceIpBuilder prepareAceIpBuilder(String srcIpv4Net, String dstIpv4Net, String lowerPort,
+            String upperPort, short protocol) {
+        AceIpBuilder builder = new AceIpBuilder();
+        AceIpv4Builder v4builder = new AceIpv4Builder();
+        if (srcIpv4Net != null) {
+            v4builder.setSourceIpv4Network(new Ipv4Prefix(srcIpv4Net));
+        } else {
+            v4builder.setSourceIpv4Network(null);
+        }
+
+        if (dstIpv4Net != null) {
+            v4builder.setDestinationIpv4Network(new Ipv4Prefix(dstIpv4Net));
+        } else {
+            v4builder.setDestinationIpv4Network(null);
+        }
+        builder.setAceIpVersion(v4builder.build());
+        if (lowerPort != null && upperPort != null) {
+            SourcePortRangeBuilder srcPortBuilder = new SourcePortRangeBuilder();
+            srcPortBuilder.setLowerPort(PortNumber.getDefaultInstance(lowerPort));
+            srcPortBuilder.setUpperPort(PortNumber.getDefaultInstance(upperPort));
+            builder.setSourcePortRange(srcPortBuilder.build());
+            DestinationPortRangeBuilder dstPortBuilder = new DestinationPortRangeBuilder();
+            dstPortBuilder.setLowerPort(PortNumber.getDefaultInstance(lowerPort));
+            dstPortBuilder.setUpperPort(PortNumber.getDefaultInstance(upperPort));
+            builder.setDestinationPortRange(dstPortBuilder.build());
+        }
+        builder.setProtocol(protocol);
+        return builder;
+    }
+
+    public static void verifyMatchInfo(List<MatchInfoBase> flowMatches, MatchFieldType matchType, String... params) {
+        Iterable<MatchInfoBase> matches = filter(flowMatches,
+                (item -> ((MatchInfo) item).getMatchField().equals(matchType)));
+        for (MatchInfoBase baseMatch : matches) {
+            verifyMatchValues((MatchInfo) baseMatch, params);
+        }
+    }
+
+    public static void verifyMatchValues(MatchInfo match, String... params) {
+        switch (match.getMatchField()) {
+            case tcp_src:
+            case tcp_dst:
+            case ip_proto:
+            case udp_src:
+            case udp_dst:
+            case eth_type:
+                long[] values = Arrays.stream(params).mapToLong(l -> Long.parseLong(l)).toArray();
+                Assert.assertArrayEquals(values, match.getMatchValues());
+                break;
+            case ipv4_source:
+            case ipv4_destination:
+                Assert.assertArrayEquals(params, match.getStringMatchValues());
+                break;
+            default:
+                assertTrue("match type is not supported", true);
+                break;
+        }
+    }
+
+    public static void verifyMatchFieldTypeDontExist(List<MatchInfoBase> flowMatches, MatchFieldType matchType) {
+        Iterable<MatchInfoBase> matches = filter(flowMatches,
+                (item -> ((MatchInfo) item).getMatchField().equals(matchType)));
+        Assert.assertTrue("unexpected match type " + matchType.name(), Iterables.isEmpty(matches));
+    }
+}