Template update
diff --git a/TestON/drivers/common/cli/emulator/mininetclidriver.py b/TestON/drivers/common/cli/emulator/mininetclidriver.py
index ce6e02d..32339a4 100644
--- a/TestON/drivers/common/cli/emulator/mininetclidriver.py
+++ b/TestON/drivers/common/cli/emulator/mininetclidriver.py
@@ -1371,20 +1371,30 @@
             response = main.FALSE
         return response
 
-    def arping( self, src, dest, destmac ):
-        self.handle.sendline( '' )
-        self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
-
-        self.handle.sendline( src + ' arping ' + dest )
+    def arping( self, host="", ip="10.128.20.211" ):
+        """
+        Description:
+            Sends arp message from mininet host for hosts discovery
+        Required:
+            host - hosts name
+        Optional:
+            ip - ip address that does not exist in the network so there would
+                 be no reply.
+        """
+        cmd = " py " + host  + ".cmd(\"arping -c 1 " + ip + "\")"
         try:
-            self.handle.expect( [ destmac, pexpect.EOF, pexpect.TIMEOUT ] )
-            main.log.info( self.name + ": ARP successful" )
-            self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
+            main.log.warn( "Sending: " + cmd )
+            self.handle.sendline( cmd )
+            response = self.handle.before
+            self.handle.sendline( "" )
+            self.handle.expect( "mininet>" )
             return main.TRUE
-        except Exception:
-            main.log.warn( self.name + ": ARP FAILURE" )
-            self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
-            return main.FALSE
+
+        except pexpect.EOF:
+            main.log.error( self.name + ": EOF exception found" )
+            main.log.error( self.name + ":     " + self.handle.before )
+            main.cleanup()
+            main.exit()
 
     def decToHex( self, num ):
         return hex( num ).split( 'x' )[ 1 ]
diff --git a/TestON/drivers/common/cli/emulator/remotemininetdriver.py b/TestON/drivers/common/cli/emulator/remotemininetdriver.py
index 6e7d0a4..8419489 100644
--- a/TestON/drivers/common/cli/emulator/remotemininetdriver.py
+++ b/TestON/drivers/common/cli/emulator/remotemininetdriver.py
@@ -95,6 +95,31 @@
             main.log.warn( outputs )
             return main.TRUE
 
+    def arping( self, host="", ip="10.128.20.211" ):
+        """
+        Description:
+            Sends arp message from mininet host for hosts discovery
+        Required:
+            host - hosts name
+        Optional:
+            ip - ip address that does not exist in the network so there would
+                 be no reply.
+        """
+        cmd = " py " + host  + ".cmd(\"arping -c 1 " + ip + "\")"
+        try:
+            main.log.warn( "Sending: " + cmd )
+            self.handle.sendline( cmd )
+            response = self.handle.before
+            self.handle.sendline( "" )
+            self.handle.expect( "mininet>" )
+            return main.TRUE
+
+        except pexpect.EOF:
+            main.log.error( self.name + ": EOF exception found" )
+            main.log.error( self.name + ":     " + self.handle.before )
+            main.cleanup()
+            main.exit()
+
     def pingLong( self, **pingParams ):
         """
         Starts a continuous ping on the mininet host outputting
@@ -344,29 +369,49 @@
             main.cleanup()
             main.exit()
 
-    def runOpticalMnScript( self, ctrllerIP = None ):
+    def runOpticalMnScript( self,name = 'onos', ctrllerIP = None ):
         import time
+        import types
         """
-            This function is only meant for Packet Optical.
-            It runs python script "opticalTest.py" to create the
-            packet layer( mn ) and optical topology
-            
-            TODO: If no ctrllerIP is provided, a default 
+            Description:
+                This function is only meant for Packet Optical.
+                It runs python script "opticalTest.py" to create the
+                packet layer( mn ) and optical topology
+            Optional:
+                name - Name of onos directory. (ONOS | onos)
+            Required:
+                ctrllerIP = Controller(s) IP address
+            TODO: If no ctrllerIP is provided, a default
                 $OC1 can be accepted
         """
         try:
             self.handle.sendline( "" )
             self.handle.expect( "\$" )
-            self.handle.sendline( "cd ~/onos/tools/test/topos" )
+            self.handle.sendline( "cd ~/" + name + "/tools/test/topos" )
             self.handle.expect( "topos\$" )
             if ctrllerIP == None:
                 main.log.info( "You need to specify the IP" )
                 return main.FALSE
             else:
-                cmd = "sudo -E python opticalTest.py " + ctrllerIP
+                controller = ''
+                if isinstance( ctrllerIP, types.ListType ):
+                    for i in xrange( len( ctrllerIP ) ):
+                        controller += ctrllerIP[i] + ' '
+                    main.log.info( "Mininet topology is being loaded with " +
+                                   "controllers: " + controller )
+                elif isinstance( ctrllerIP, types.StringType ):
+                    controller = ctrllerIP
+                    main.log.info( "Mininet topology is being loaded with " +
+                                   "controller: " + controller )
+                else:
+                    main.log.info( "You need to specify a valid IP" )
+                    return main.FALSE
+                cmd = "sudo -E python opticalTest.py " + controller
+                main.log.info( self.name + ": cmd = " + cmd )
                 self.handle.sendline( cmd )
                 self.handle.expect( "Press ENTER to push Topology.json" )
-                time.sleep(15)
+                time.sleep(30)
+                self.handle.sendline( "" )
                 self.handle.sendline( "" )
                 self.handle.expect("mininet>")
                 return main.TRUE
diff --git a/TestON/tests/SingleFunc/SingleFunc.params b/TestON/tests/SingleFunc/SingleFunc.params
index 58427cc..553b15b 100755
--- a/TestON/tests/SingleFunc/SingleFunc.params
+++ b/TestON/tests/SingleFunc/SingleFunc.params
@@ -1,6 +1,6 @@
 <PARAMS>
 
-    <testcases>10,11</testcases>
+    <testcases>10,11,1000</testcases>
     <ENV>
         <cellName>single_func</cellName>
     </ENV>
@@ -14,6 +14,7 @@
     </CTRL>
     <MININET>
         <switch>7</switch>
+        <links>20</links>
         <topo>~/mininet/custom/newFuncTopo.py</topo>
     </MININET>
 
diff --git a/TestON/tests/SingleFunc/SingleFunc.py b/TestON/tests/SingleFunc/SingleFunc.py
index 4fcb074..93fd0a3 100644
--- a/TestON/tests/SingleFunc/SingleFunc.py
+++ b/TestON/tests/SingleFunc/SingleFunc.py
@@ -31,6 +31,7 @@
         main.ONOS1ip = os.environ[ 'OC1' ]
         main.ONOS1port = main.params[ 'CTRL' ][ 'port1' ]
         main.numSwitch = int( main.params[ 'MININET' ][ 'switch' ] )
+        main.numLinks = int( main.params[ 'MININET' ][ 'links' ] )
         gitBranch = main.params[ 'GIT' ][ 'branch' ]
         topology = main.params[ 'MININET' ][ 'topo' ]
         PULLCODE = False
@@ -136,7 +137,7 @@
 
     def CASE11( self, main ):
         """
-        Assign mastership to controllers
+            Assign mastership to controllers
         """
         import re
         main.log.report( "Assigning switches to controllers" )
@@ -167,106 +168,240 @@
 
     def CASE1000( self, main ):
         """
-            Add host intents between 2 host
+            Add host intents between 2 host:
+                - Discover hosts
+                - Add host intents
+                - Check intents
+                - Check flows
+                - Ping hosts
+                - Reroute
+                    - Link down
+                    - Ping hosts
+                    - Link up
+                    - Ping hosts
+                - Remove intents
         """
         import time
         import json
+        import re
+        """
+            Create your item(s) here
+            item = { 'name': '', 'host1':
+                     { 'name': '', 'MAC': '00:00:00:00:00:0X',
+                       'id':'00:00:00:00:00:0X/-X' } , 'host2':
+                     { 'name': '', 'MAC': '00:00:00:00:00:0X',
+                       'id':'00:00:00:00:00:0X/-X'}, 'link': { 'switch1': '',
+                       'switch2': '', 'num':'' } }
+        """
+        # Local variables
+        items = []
+        ipv4 = { 'name': 'IPV4', 'host1':
+                 { 'name': 'h1', 'MAC': '00:00:00:00:00:01',
+                   'id':'00:00:00:00:00:01/-1' } , 'host2':
+                 { 'name': 'h9', 'MAC': '00:00:00:00:00:09',
+                   'id':'00:00:00:00:00:01/-1'}, 'link': { 'switch1': 's5',
+                   'switch2': 's2', 'num':'18' } }
+        dualStack1 = { 'name': 'DUALSTACK1', 'host1':
+                 { 'name': 'h3', 'MAC': '00:00:00:00:00:03',
+                   'id':'00:00:00:00:00:03/-1' } , 'host2':
+                 { 'name': '', 'MAC': '00:00:00:00:00:0B',
+                   'id':'00:00:00:00:00:0B/-1'}, 'link': { 'switch1': 's5',
+                   'switch2': 's2', 'num':'18' } }
+        items.append( ipv4 )
+        # Global variables
         
-        item = []
-        
-        ipv4 = { 'name':'', 'host1':, 'host2': }
-
         main.case( "Add host intents between 2 host" )
-
-        main.step(" Discover host using arping" )
         
+        for item in items:
+            stepResult = main.TRUE
+            h1Name = item[ 'host1' ][ 'name' ]
+            h2Name = item[ 'host2' ][ 'name' ]
+            h1Mac = item[ 'host1' ][ 'MAC' ]
+            h2Mac = item[ 'host2' ][ 'MAC' ]
+            h1Id = item[ 'host1' ][ 'id']
+            h2Id = item[ 'host2' ][ 'id']
+            # Link down/up for rerouting
+            sw1 = item[ 'link' ][ 'switch1' ]
+            sw2 = item[ 'link' ][ 'switch2' ]
+            remLink = item[ 'link' ][ 'num' ]
+            intentsId = []
+            main.step( item[ 'name' ] + ": Add host intents between " + h1Name
+                        + " and " + h2Name )
+            main.log.info( item[ 'name' ] + ": Discover host using arping" )
+            main.Mininet1.arping( host=h1Name )
+            main.Mininet1.arping( host=h2Name )
+            host1 = main.ONOScli1.getHost( mac=h1Mac )
+            host2 = main.ONOScli1.getHost( mac=h2Mac )
+            print host1
+            print host2
+            # Adding intents
+            main.log.info( item[ 'name' ] + ": Adding host intents" )
+            intent1 = main.ONOScli1.addHostIntent( hostIdOne=h1Id,
+                                                   hostIdTwo=h2Id )
+            intentsId.append( intent1 )
+            time.sleep( 5 )
+            intent2 = main.ONOScli1.addHostIntent( hostIdOne=h2Id,
+                                                   hostIdTwo=h1Id )
+            intentsId.append( intent2 )
+            # Checking intents
+            main.log.info( item[ 'name' ] + ": Check host intents state" )
+            time.sleep( 20 )
+            intentResult = main.ONOScli1.checkIntentState( intentsId=intentsId )
+            if not intentResult:
+                main.log.info( item[ 'name' ] +  ": Check host intents state" +
+                               " again")
+                intentResult = main.ONOScli1.checkIntentState(
+                                                          intentsId=intentsId )
+            # Ping hosts
+            time.sleep( 10 )
+            main.log.info( item[ 'name' ] + ": Ping " + h1Name + " and " +
+                           h2Name )
+            pingResult1 = main.Mininet1.pingHost( src=h1Name , target=h2Name )
+            if not pingResult1:
+                main.log.info( item[ 'name' ] + ": " + h1Name + " cannot ping "
+                               + h2Name )
+            pingResult2 = main.Mininet1.pingHost( src=h2Name , target=h1Name )
+            if not pingResult2:
+                main.log.info( item[ 'name' ] + ": " + h2Name + " cannot ping "
+                               + h1Name )
+            pingResult = pingResult1 and pingResult2
+            if pingResult:
+                main.log.info( item[ 'name' ] + ": Successfully pinged " +
+                               "both hosts" )
+            else:
+                main.log.info( item[ 'name' ] + ": Failed to ping " +
+                               "both hosts" )
+            # Rerouting ( link down )
+            main.log.info( item[ 'name' ] + ": Bring link down between " +
+                           sw1 + " and " + sw2 )
+            main.Mininet1.link( end1=sw1,
+                                end2=sw2,
+                                option="down" )
+            time.sleep( 5 )
 
+            # Check onos topology
+            main.log.info( item[ 'name' ] + ": Checking ONOS topology " )
+            topologyResult = main.ONOScli1.topology()
+            statusResult = main.ONOSbench.checkStatus( topologyResult,
+                                                       main.numSwitch,
+                                                       remLink )
+            if not statusResult:
+                main.log.info( item[ 'name' ] + ": Topology mismatch" )
+            else:
+                main.log.info( item[ 'name' ] + ": Topology match" )
 
-        main.step( "Discover host using arping" )
-        step1Result = main.TRUE
-        main.hostMACs = []
-        main.hostId = []
-        #Listing host MAC addresses
-        for i in range( 1 , 7 ):
-            main.hostMACs.append( "00:00:00:00:00:" +
-                                str( hex( i )[ 2: ] ).zfill( 2 ).upper() )
-        for macs in main.hostMACs:
-            main.hostId.append( macs + "/-1" )
-        host1 = main.hostId[ 0 ]
-        host2 = main.hostId[ 1 ]
-        # Use arping to discover the hosts
-        main.LincOE2.arping( host = "h1" )
-        main.LincOE2.arping( host = "h2" )
-        time.sleep( 5 )
-        hostsDict = main.ONOS3.hosts()
-        if not len( hostsDict ):
-            step1Result = main.FALSE
-        # Adding host intent
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=step1Result,
-            onpass="Hosts discovered",
-            onfail="Failed to discover hosts")
+            # Ping hosts
+            main.log.info( item[ 'name' ] + ": Ping " + h1Name + " and " +
+                           h2Name )
+            pingResult1 = main.Mininet1.pingHost( src=h1Name , target=h2Name )
+            if not pingResult1:
+                main.log.info( item[ 'name' ] + ": " + h1Name + " cannot ping "
+                               + h2Name )
+            pingResult2 = main.Mininet1.pingHost( src=h2Name , target=h1Name )
+            if not pingResult2:
+                main.log.info( item[ 'name' ] + ": " + h2Name + " cannot ping "
+                               + h1Name )
+            pingResult = pingResult1 and pingResult2
+            if pingResult:
+                main.log.info( item[ 'name' ] + ": Successfully pinged " +
+                               "both hosts" )
+            else:
+                main.log.info( item[ 'name' ] + ": Failed to ping " +
+                               "both hosts" )
+            # link up
+            main.log.info( item[ 'name' ] + ": Bring link up between " +
+                           sw1 + " and " + sw2 )
+            main.Mininet1.link( end1=sw1,
+                                end2=sw2,
+                                option="up" )
+            time.sleep( 5 )
 
-        main.step( "Adding host intents to h1 and h2" )
-        step2Result = main.TRUE
-        intentsId = []
-        intent1 = main.ONOS3.addHostIntent( hostIdOne = host1,
-                                            hostIdTwo = host2 )
-        intentsId.append( intent1 )
-        time.sleep( 5 )
-        intent2 = main.ONOS3.addHostIntent( hostIdOne = host2,
-                                            hostIdTwo = host1 )
-        intentsId.append( intent2 )
-        # Checking intents state before pinging
-        main.log.info( "Checking intents state" )
-        time.sleep( 15 )
-        intentResult = main.ONOS3.checkIntentState( intentsId = intentsId )
-        #check intent state again if intents are not in installed state
-        if not intentResult:
-           intentResult = main.ONOS3.checkIntentState( intentsId = intentsId )
-        step2Result = intentResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=step2Result,
-                                 onpass="All intents are in INSTALLED state ",
-                                 onfail="Some of the intents are not in " +
-                                        "INSTALLED state " )
+            # Check onos topology
+            main.log.info( item[ 'name' ] + ": Checking ONOS topology " )
+            topologyResult = main.ONOScli1.topology()
+            statusResult = main.ONOSbench.checkStatus( topologyResult,
+                                                       main.numSwitch,
+                                                       main.numLinks )
+            if not statusResult:
+                main.log.info( item[ 'name' ] + ": Topology mismatch" )
+            else:
+                main.log.info( item[ 'name' ] + ": Topology match" )
 
-        # pinging h1 to h2 and then ping h2 to h1
-        main.step( "Pinging h1 and h2" )
-        step3Result = main.TRUE
-        pingResult = main.TRUE
-        pingResult = main.LincOE2.pingHostOptical( src="h1", target="h2" )
-        pingResult = pingResult and main.LincOE2.pingHostOptical( src="h2",
-                                                                  target="h1" )
-        step3Result = pingResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=step3Result,
-                                 onpass="Pinged successfully between h1 and h2",
-                                 onfail="Pinged failed between h1 and h2" )
-        # Removed all added host intents
-        main.step( "Removing host intents" )
-        step4Result = main.TRUE
-        removeResult = main.TRUE
-        # Check remaining intents
-        intentsJson = json.loads( main.ONOS3.intents() )
-        main.ONOS3.removeIntent( intentId=intent1, purge=True )
-        main.ONOS3.removeIntent( intentId=intent2, purge=True )
-        for intents in intentsJson:
-            main.ONOS3.removeIntent( intentId=intents.get( 'id' ),
-                                     app='org.onosproject.optical',
-                                     purge=True )
-        print json.loads( main.ONOS3.intents() )
-        if len( json.loads( main.ONOS3.intents() ) ):
-            removeResult = main.FALSE
-        step4Result = removeResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=step4Result,
-                                 onpass="Successfully removed host intents",
-                                 onfail="Failed to remove host intents" )
-        case25Result = step1Result and step2Result and step3Result and \
-                       step4Result
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=case25Result,
-                                 onpass="Add host intent successful",
-                                 onfail="Add host intent failed" )
+            # Ping hosts
+            main.log.info( item[ 'name' ] + ": Ping " + h1Name + " and " +
+                           h2Name )
+            pingResult1 = main.Mininet1.pingHost( src=h1Name , target=h2Name )
+            if not pingResult1:
+                main.log.info( item[ 'name' ] + ": " + h1Name + " cannot ping "
+                               + h2Name )
+            pingResult2 = main.Mininet1.pingHost( src=h2Name , target=h1Name )
+            if not pingResult2:
+                main.log.info( item[ 'name' ] + ": " + h2Name + " cannot ping "
+                               + h1Name )
+            pingResult = pingResult1 and pingResult2
+            if pingResult:
+                main.log.info( item[ 'name' ] + ": Successfully pinged " +
+                               "both hosts" )
+            else:
+                main.log.info( item[ 'name' ] + ": Failed to ping " +
+                               "both hosts" )
+
+            # Remove intents
+            for intent in intentsId:
+                main.ONOScli1.removeIntent( intentId=intent, purge=True )
+
+            print main.ONOScli1.intents()
+            stepResult = pingResult
+            utilities.assert_equals( expect=main.TRUE,
+                                     actual=stepResult,
+                                     onpass=item[ 'name' ] +
+                                            " host intent successful",
+                                     onfail=item[ 'name' ] +
+                                            "Add host intent failed" )
+    def CASE2000( self, main ):
+        """
+            Add point intents between 2 hosts:
+                - Get device ids
+                - Add point intents
+                - Check intents
+                - Check flows
+                - Ping hosts
+                - Reroute
+                    - Link down
+                    - Ping hosts
+                    - Link up
+                    - Ping hosts
+                - Remove intents
+        """
+
+    def CASE3000( self, main ):
+        """
+            Add single point to multi point intents
+                - Get device ids
+                - Add single point to multi point intents
+                - Check intents
+                - Check flows
+                - Ping hosts
+                - Reroute
+                    - Link down
+                    - Ping hosts
+                    - Link up
+                    - Ping hosts
+                - Remove intents
+        """
+
+    def CASE4000( self, main ):
+        """
+            Add multi point to single point intents
+                - Get device ids
+                - Add multi point to single point intents
+                - Check intents
+                - Check flows
+                - Ping hosts
+                - Reroute
+                    - Link down
+                    - Ping hosts
+                    - Link up
+                    - Ping hosts
+                - Remove intents
+        """