[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/drivers/common/clidriver.py b/TestON/drivers/common/clidriver.py
index 1e4d233..4f081ea 100644
--- a/TestON/drivers/common/clidriver.py
+++ b/TestON/drivers/common/clidriver.py
@@ -156,7 +156,7 @@
 
     def disconnect( self ):
         result = self.preDisconnect()
-        result = super( CLI, self ).disconnect( self )
+        result = super( CLI, self ).disconnect( )
         result = main.TRUE
 
     def Prompt( self ):
@@ -1220,6 +1220,49 @@
             main.log.exception( self.name + ": Uncaught exception!" )
             return None
 
+    def kubectlCmd( self, cmd, kubeconfig=None, namespace=None ):
+        """
+        Run an arbitrary command using kubectl
+        Arguments:
+        - cmd: Command string to send to kubectl
+        Optional Arguments:
+        - kubeconfig: The path to a kubeconfig file
+        - namespace: The namespace to search in
+        Returns a string of the node name or None
+        """
+        try:
+            self.handle.sendline( "" )
+            self.handle.expect( self.prompt )
+            main.log.debug( self.handle.before + self.handle.after )
+            cmdStr = "kubectl %s %s %s" % (
+                        "--kubeconfig %s" % kubeconfig if kubeconfig else "",
+                        "-n %s" % namespace if namespace else "",
+                        cmd )
+            main.log.info( self.name + ": sending: " + repr( cmdStr ) )
+            self.handle.sendline( cmdStr )
+            i = self.handle.expect( [ "not found", "error", "The connection to the server", self.prompt ] )
+            if i == 3:
+                output = self.handle.before
+                main.log.debug( self.name + ": " + output )
+                output = output.splitlines()
+                main.log.warn( output )
+                return output[1] if len( output ) == 3 else None
+            else:
+                main.log.error( self.name + ": Error executing command" )
+                main.log.debug( self.name + ": " + self.handle.before + str( self.handle.after ) )
+                return None
+        except pexpect.EOF:
+            main.log.error( self.name + ": EOF exception found" )
+            main.log.error( self.name + ":     " + self.handle.before )
+            return None
+        except pexpect.TIMEOUT:
+            main.log.exception( self.name + ": TIMEOUT exception found" )
+            main.log.error( self.name + ":    " + self.handle.before )
+            return None
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            return None
+
     def sternLogs( self, podString, dstPath, kubeconfig=None, namespace=None, since='1h', wait=60 ):
         """
         Use stern to get the logs from a pod
@@ -1425,7 +1468,7 @@
         except pexpect.TIMEOUT:
             main.log.exception( self.name + ": TIMEOUT exception found" )
             main.log.error( self.name + ":    " + self.handle.before )
-            return main.FALSE
+            return self.checkPortForward( podName, portsList, kubeconfig, namespace )
         except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             return main.FALSE
@@ -1459,6 +1502,7 @@
                 main.log.warn( "%s: port-forwarding session to %s closed, attempting to reestablish." % ( self.name, podName ) )
                 return self.kubectlPortForward( podName, portsList, kubeconfig, namespace )
             elif i == 1:
+                main.log.debug( "%s: We seem to still be in port-forwarding session" % self.name )
                 # Still in a command, port-forward is probably still active
                 return main.TRUE
         except pexpect.EOF:
@@ -1665,6 +1709,58 @@
             main.log.exception( self.name + ": Uncaught exception!" )
             return main.FALSE
 
+    def kubectlGetServiceIP( self, serviceName, kubeconfig=None, namespace=None, timeout=240 ):
+        try:
+            cmdStr = "kubectl %s %s get service %s " \
+                     "--output=jsonpath='{.spec.clusterIP}{\"\\n\"}'" % (
+                "--kubeconfig %s" % kubeconfig if kubeconfig else "",
+                "-n %s" % namespace if namespace else "",
+                serviceName )
+            main.log.info( self.name + ": sending: " + repr( cmdStr ) )
+            self.handle.sendline( cmdStr )
+            self.handle.expect( self.prompt, timeout=timeout )
+            output = self.handle.before
+            clusterIP = output.splitlines()
+            main.log.debug( repr( clusterIP ) )
+            return clusterIP[-2]
+        except pexpect.EOF:
+            main.log.error( self.name + ": EOF exception found" )
+            main.log.error( self.name + ":     " + self.handle.before )
+            return None
+        except pexpect.TIMEOUT:
+            main.log.exception( self.name + ": TIMEOUT exception found" )
+            main.log.error( self.name + ":    " + self.handle.before )
+            return None
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            return None
+
+    def kubectlGetNodePort( self, serviceName, kubeconfig=None, namespace=None, timeout=240 ):
+        try:
+            cmdStr = "kubectl %s %s get service %s " \
+                     "--output=jsonpath='{.spec.ports[*].nodePort}{\"\\n\"}'" % (
+                "--kubeconfig %s" % kubeconfig if kubeconfig else "",
+                "-n %s" % namespace if namespace else "",
+                serviceName )
+            main.log.info( self.name + ": sending: " + repr( cmdStr ) )
+            self.handle.sendline( cmdStr )
+            self.handle.expect( self.prompt, timeout=timeout )
+            output = self.handle.before
+            clusterIP = output.splitlines()
+            main.log.debug( repr( clusterIP ) )
+            return clusterIP[-2]
+        except pexpect.EOF:
+            main.log.error( self.name + ": EOF exception found" )
+            main.log.error( self.name + ":     " + self.handle.before )
+            return None
+        except pexpect.TIMEOUT:
+            main.log.exception( self.name + ": TIMEOUT exception found" )
+            main.log.error( self.name + ":    " + self.handle.before )
+            return None
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            return None
+
     def clearBuffer(self):
         i = 0
         response = ''