[SDFAB-861] Add a testcase to UP4 with PFCP agent

    - Due to only being able to add one application filter per ue
      session with the pfcpsim, created a new testcase to individually
      test the apllication filters from the params file plus the default
      application filter
    - Using a Mock SMF to send messages to the pfcp agent
    - Add a parameter to topo file to use mock_smf or p4rt cli to add
      flows
    - Modify ue ips to work around smf limitations
    - Modify teids for UL and DL to be different. This reduces
      differences between smf and p4rtcli generated flows

Change-Id: I1ba3ef43919dd375f5e5bf54e97f61c09c7323d9
diff --git a/TestON/tests/USECASE/SegmentRouting/UP4/UP4.params b/TestON/tests/USECASE/SegmentRouting/UP4/UP4.params
index e1f522c..184de59 100644
--- a/TestON/tests/USECASE/SegmentRouting/UP4/UP4.params
+++ b/TestON/tests/USECASE/SegmentRouting/UP4/UP4.params
@@ -1,5 +1,5 @@
 <PARAMS>
-    <testcases>1,2,3,4,5</testcases>
+    <testcases>1,2,3,4,5,11</testcases>
 
     <GRAPH>
         <nodeCluster>pairedleaves</nodeCluster>
@@ -18,6 +18,7 @@
 
     <UP4>
         <pdn_host>MgmtServer</pdn_host>
+        <ue_range>10.240.0.0/16</ue_range>
         <enodebs>
             <enodeb_1>
                 <host>Compute3</host>
@@ -36,24 +37,24 @@
         <slice_id>1</slice_id>
         <ues>
             <ue1>
-                <ue_address>10.240.0.1</ue_address>
-                <teid>100</teid>
+                <ue_address>10.240.0.10</ue_address>
+                <teid>10</teid>
                 <up_id>10</up_id>
                 <down_id>11</down_id>
                 <tc>0</tc>
                 <five_g>False</five_g>
             </ue1>
             <ue2>
-                <ue_address>10.240.0.2</ue_address>
-                <teid>200</teid>
+                <ue_address>10.240.0.20</ue_address>
+                <teid>20</teid>
                 <up_id>20</up_id>
                 <down_id>21</down_id>
                 <tc>0</tc>
                 <five_g>False</five_g>
             </ue2>
             <ue3>
-                <ue_address>10.240.0.3</ue_address>
-                <teid>250</teid>
+                <ue_address>10.240.0.30</ue_address>
+                <teid>30</teid>
                 <up_id>30</up_id>
                 <down_id>31</down_id>
                 <tc>0</tc>
@@ -67,7 +68,7 @@
                 <!-- MgmtServer -->
                 <ip_prefix>10.32.11.1/32</ip_prefix>
                 <ip_proto>17</ip_proto>
-                <port_range>80..80</port_range>
+                <port_range>80..400</port_range>
                 <priority>20</priority>
                 <action>allow</action>
             </allowPort>
diff --git a/TestON/tests/USECASE/SegmentRouting/UP4/UP4.py b/TestON/tests/USECASE/SegmentRouting/UP4/UP4.py
index 1b4b88e..88035d7 100644
--- a/TestON/tests/USECASE/SegmentRouting/UP4/UP4.py
+++ b/TestON/tests/USECASE/SegmentRouting/UP4/UP4.py
@@ -32,10 +32,16 @@
 
         main.step("Start scapy and p4rt client")
         # Use the first available ONOS instance CLI
-        onos_cli = main.Cluster.active(0).CLI
+        node = main.Cluster.active(0)
+        onos_cli = node.CLI
+        kubeconfig = node.k8s.kubeConfig
+        namespace = main.params['kubernetes']['namespace']
         up4 = UP4()
-        # Get the P4RT client connected to UP4 in the first available ONOS instance
-        up4.setup(main.Cluster.active(0).p4rtUp4)
+        nodeIP = node.Bench.kubectlCmd("get node %s --output=jsonpath='{.metadata.annotations.rke\.cattle\.io/external-ip}{\"\\n\"}'" % node.Bench.kubectlGetPodNode("pfcp-agent-0", kubeconfig, namespace))
+        # Connect P4RT and the mock smf if configured
+        up4.setup(node.p4rtUp4, mock_smf=node.mock_smf,
+                  pfcpAddress=nodeIP,
+                  pfcpPort=node.Bench.kubectlGetNodePort("pfcp-agent", kubeconfig, namespace))
 
         main.step("Program and Verify UPF entities via UP4")
         up4.attachUes()
@@ -697,3 +703,80 @@
         # Teardown
         run.cleanup(main)
 
+    def CASE11(self, main):
+        main.case("Fabric UPF traffic terminated in the fabric using pfcpsim to generate UE sessions")
+        """
+        Program UPF entities for UEs
+        Verify UPF entities
+        Generate traffic from UE to PDN
+        Verify traffic received from PDN
+        Generate traffic from PDN to UE
+        Verify traffic received from UE
+        Remove UPF entities for UEs
+        Verify removed UPF entities
+        """
+        try:
+            from tests.USECASE.SegmentRouting.dependencies.up4 import UP4
+            from tests.USECASE.SegmentRouting.dependencies.Testcaselib import \
+                Testcaselib as run
+        except ImportError as e:
+            main.log.error("Import not found. Exiting the test")
+            main.log.error(e)
+            main.cleanAndExit()
+        n_switches = int(main.params["TOPO"]["switchNum"])
+
+        run.initTest(main)
+        main.log.info(main.Cluster.numCtrls)
+        main.Cluster.setRunningNode(3)
+        run.installOnos(main, skipPackage=True, cliSleep=5)
+
+        main.step("Start scapy and p4rt client")
+        # Use the first available ONOS instance CLI
+        node = main.Cluster.active(0)
+        onos_cli = node.CLI
+        kubeconfig = node.k8s.kubeConfig
+        namespace = main.params['kubernetes']['namespace']
+
+        # Use pfcpctl instead of pr4untime to add ue sessions
+        smf = main.ONOScell.createMockSMFComponent( "pfcpsim", node.ip_address )
+        main.ONOScell.mock_smf = True
+        node.mock_smf = smf
+
+        up4 = UP4()
+        nodeIP = node.Bench.kubectlCmd("get node %s --output=jsonpath='{.metadata.annotations.rke\.cattle\.io/external-ip}{\"\\n\"}'" % node.Bench.kubectlGetPodNode("pfcp-agent-0", kubeconfig, namespace))
+
+        # Connect P4RT and the mock smf if configured
+        up4.setup(node.p4rtUp4, mock_smf=node.mock_smf,
+                  pfcpAddress=nodeIP,
+                  pfcpPort=node.Bench.kubectlGetNodePort("pfcp-agent", kubeconfig, namespace))
+        app_filters = up4.app_filters
+        app_filters.update( up4.DEFAULT_APP)
+        for name, app in app_filters.iteritems():
+            up4.app_filters = { name: app }
+            main.step("Program and Verify UPF entities via pfcp for app: %s" % name)
+            up4.attachUes()
+            up4.verifyUp4Flow(onos_cli)
+
+            # ------- Test Upstream traffic (enb->pdn)
+            for app_filter_name in up4.app_filters:
+                main.step("Test upstream traffic %s" % app_filter_name)
+                up4.testUpstreamTraffic(app_filter_name=app_filter_name)
+
+            # ------- Test Downstream traffic (pdn->enb)
+            for app_filter_name in up4.app_filters:
+                main.step("Test downstream traffic %s" % app_filter_name)
+                up4.testDownstreamTraffic(app_filter_name=app_filter_name)
+
+            main.step("Remove and Verify UPF entities via pfcp for app: %s" % name)
+            up4.detachUes()
+            up4.verifyNoUesFlow(onos_cli)
+
+            # hack to make sure next iteration uses different seids
+            for ue_name in up4.emulated_ues:
+                up4.emulated_ues[ue_name]["seid"] = None
+        main.step("Stop scapy and p4rt client")
+        up4.teardown()
+
+        run.cleanup(main)
+
+
diff --git a/TestON/tests/USECASE/SegmentRouting/UP4/UP4.topo b/TestON/tests/USECASE/SegmentRouting/UP4/UP4.topo
index 731c259..56bfdbb 100644
--- a/TestON/tests/USECASE/SegmentRouting/UP4/UP4.topo
+++ b/TestON/tests/USECASE/SegmentRouting/UP4/UP4.topo
@@ -24,6 +24,7 @@
                 <onos_home>~/onos/</onos_home>  # defines where onos home is on the target cell machine. Defaults to entry in "home" if empty.
                 <nodes> 3 </nodes>  # number of nodes in the cluster
                 <up4_port>51001</up4_port> # Port where the UP4 P4Runtime server is listening
+                <mock_smf>False</mock_smf>
             </COMPONENTS>
         </ONOScell>