Add hosts and get_host command

    Initial commit of multinode Test
    minor text changes
diff --git a/TestON/drivers/common/cli/emulator/mininetclidriver.py b/TestON/drivers/common/cli/emulator/mininetclidriver.py
index ccf3baf..419ee06 100644
--- a/TestON/drivers/common/cli/emulator/mininetclidriver.py
+++ b/TestON/drivers/common/cli/emulator/mininetclidriver.py
@@ -808,6 +808,7 @@
 
         '''
         import json
+        #main.log.debug("Switches_json string: ", switches_json)
         output = {"switches":[]}
         for switch in topo.graph.switches: #iterate through the MN topology and pull out switches and and port info
             #print vars(switch)
@@ -818,7 +819,10 @@
             output['switches'].append({"name": switch.name, "dpid": str(switch.dpid).zfill(16), "ports": ports })
         #print output
 
+        #print "mn"
         #print json.dumps(output, sort_keys=True,indent=4,separators=(',', ': '))
+        #print "onos"
+        #print json.dumps(switches_json, sort_keys=True,indent=4,separators=(',', ': '))
 
 
         # created sorted list of dpid's in MN and ONOS for comparison
@@ -828,7 +832,7 @@
         mnDPIDs.sort()
         #print mnDPIDs
         if switches_json == "":#if rest call fails
-            main.log.error(self.name + ".compare_topo(): Empty JSON object given from ONOS")
+            main.log.error(self.name + ".compare_switches(): Empty JSON object given from ONOS")
             return main.FALSE
         onos=switches_json
         onosDPIDs=[]
@@ -1019,184 +1023,6 @@
         return link_results
 
 
-
-
-    def compare_topo(self, topo, onos_json):
-        '''
-        compares mn topology with ONOS topology
-        onos_list is a list of ONOS controllers, each element of the list should be (handle, name, ip, port)
-        onos_json is the output of the onos get_json function calling the /wm/onos/topology REST API
-        Returns: True if MN and ONOS topology match and False if the differ. 
-        Differences between ONOS and MN topology will be printed to the log.
-
-        Dependency: Requires STS to be installed on the TestON machine. STS can be pulled 
-        from https://github.com/ucb-sts/sts.git . Currently the required functions from STS are located in the 
-        topology_refactoring2 branch, but may be merged into the master branch soon. You may need to install some
-        python modules such as networkx to use the STS functions.
-
-        To install sts:
-            $ git clone git://github.com/ucb-sts/sts.git
-            $ cd sts
-            $ git clone -b debugger git://github.com/ucb-sts/pox.git
-            $ sudo apt-get install python-dev
-            $ ./tools/install_hassel_python.sh
-            $ sudo pip install networkx
-
-        Include sts in your PYTHONPATH. it should looks comething like: 
-            PYTHONPATH=/home/admin/TestON:/home/admin/sts
-
-        '''
-        import sys
-        sys.path.append("~/sts")
-        #NOTE: Create this once per Test and pass the TestONTopology object around. It takes too long to create this object.
-        #      This will make it easier to use the sts methods for severing links and solve that issue
-        import json
-
-        link_results = main.TRUE
-        switch_results = main.TRUE
-        port_results = main.TRUE
-
-        ########Switches#######
-        output = {"switches":[]}
-        for switch in topo.graph.switches: #iterate through the MN topology and pull out switches and and port info
-            ports = []
-            for port in switch.ports.values():
-                #print port.hw_addr.toStr(separator = '')
-                ports.append({'of_port': port.port_no, 'mac': str(port.hw_addr).replace('\'',''), 'name': port.name})
-            output['switches'].append({"name": switch.name, "dpid": str(switch.dpid).zfill(16), "ports": ports })
-        #print output
-
-        #print json.dumps(output, sort_keys=True,indent=4,separators=(',', ': '))
-
-
-        # created sorted list of dpid's in MN and ONOS for comparison
-        mnDPIDs=[]
-        for switch in output['switches']:
-            mnDPIDs.append(switch['dpid'])
-        mnDPIDs.sort()
-        #print mnDPIDs
-        if onos_json == "":#if rest call fails
-            main.log.error(self.name + ".compare_topo(): Empty JSON object given from ONOS rest call")
-            return main.FALSE
-        onos=onos_json
-        onosDPIDs=[]
-        for switch in onos['switches']:
-            onosDPIDs.append(switch['dpid'].replace(":",''))
-        onosDPIDs.sort()
-        #print onosDPIDs
-
-        if mnDPIDs!=onosDPIDs:
-            switch_results = main.FALSE
-            main.log.report( "Switches in MN but not in ONOS:")
-            main.log.report( str([switch for switch in mnDPIDs if switch not in onosDPIDs]))
-            main.log.report( "Switches in ONOS but not in MN:")
-            main.log.report(  str([switch for switch in onosDPIDs if switch not in mnDPIDs]))
-        else:#list of dpid's match in onos and mn
-            switch_results = main.TRUE
-
-        ################ports#############
-            for switch in output['switches']:
-                mn_ports = []
-                onos_ports = []
-                for port in switch['ports']:
-                    mn_ports.append(port['of_port'])
-                for onos_switch in onos['switches']:
-                    if onos_switch['dpid'].replace(':','') == switch['dpid']:
-                        for port in onos_switch['ports']:
-                            onos_ports.append(port['portNumber']) 
-                mn_ports.sort()
-                onos_ports.sort()
-                #print "mn_ports[] = ", mn_ports
-                #print "onos_ports90 = ", onos_ports
-                
-                #if mn_ports == onos_ports:
-                    #pass #don't set results to true here as this is just one of many checks and it might override a failure
-
-                #For OF1.3, the OFP_local port number is 0xfffffffe or 4294967294 instead of 0xfffe or 65534 in OF1.0, ONOS topology
-                #sees the correct port number, however MN topology as read from line 151 of https://github.com/ucb-sts/sts/blob/
-                #topology_refactoring2/sts/entities/teston_entities.py is 0xfffe which doesn't work correctly with OF1.3 switches.
-                #So a short term fix is to ignore the case when mn_port == 65534 and onos_port ==4294967294.
-                for mn_port,onos_port in zip(mn_ports,onos_ports):
-                    if mn_port == onos_port or (mn_port == 65534 and onos_port ==4294967294):
-                        continue
-                    else:
-                        port_results = main.FALSE
-                        break
-                '''
-                else: #the ports of this switch don't match
-                    port_results = main.FALSE
-                    main.log.report("ports in MN switch %s(%s) but not in ONOS:" % (switch['name'],switch['dpid'])) 
-                    main.log.report( str([port for port in mn_ports if port not in onos_ports]))
-                    main.log.report("ports in ONOS switch %s(%s) but not in MN:" % (switch['name'],switch['dpid']))
-                    main.log.report( str([port for port in onos_ports if port not in mn_ports]))
-                '''
-                if port_results == main.FALSE:
-                    main.log.report("ports in MN switch %s(%s) but not in ONOS:" % (switch['name'],switch['dpid'])) 
-                    main.log.report( str([port for port in mn_ports if port not in onos_ports]))
-                    main.log.report("ports in ONOS switch %s(%s) but not in MN:" % (switch['name'],switch['dpid']))
-                    main.log.report( str([port for port in onos_ports if port not in mn_ports]))
-
-        #######Links########
-        # iterate through MN links and check if and ONOS link exists in both directions
-        # NOTE: Will currently only show mn links as down if they are cut through STS. 
-        #       We can either do everything through STS or wait for up_network_links 
-        #       and down_network_links to be fully implemented.
-        for link in topo.patch_panel.network_links: 
-            #print "Link: %s" % link
-            #TODO: Find a more efficient search method
-            node1 = None
-            port1 = None
-            node2 = None
-            port2 = None
-            first_dir = main.FALSE
-            second_dir = main.FALSE
-            for switch in output['switches']:
-                if switch['name'] == link.node1.name:
-                    node1 = switch['dpid']
-                    for port in switch['ports']:
-                        if str(port['name']) == str(link.port1):
-                            port1 = port['of_port'] 
-                    if node1 is not None and node2 is not None:
-                        break
-                if switch['name'] == link.node2.name:
-                    node2 = switch['dpid']
-                    for port in switch['ports']: 
-                        if str(port['name']) == str(link.port2):
-                            port2 = port['of_port'] 
-                    if node1 is not None and node2 is not None:
-                        break
-            # check onos link from node1 to node2
-            for onos_link in onos['links']:
-                if onos_link['src']['dpid'].replace(":",'') == node1 and onos_link['dst']['dpid'].replace(":",'') == node2:
-                    if onos_link['src']['portNumber'] == port1 and onos_link['dst']['portNumber'] == port2:
-                        first_dir = main.TRUE
-                    else:
-                        main.log.report('the port numbers do not match for ' +str(link) + ' between ONOS and MN')
-                    #print node1, ' to ', node2
-                elif onos_link['src']['dpid'].replace(":",'') == node2 and onos_link['dst']['dpid'].replace(":",'') == node1:
-                    if onos_link['src']['portNumber'] == port2 and onos_link['dst']['portNumber'] == port1:
-                        second_dir = main.TRUE
-                    else:
-                        main.log.report('the port numbers do not match for ' +str(link) + ' between ONOS and MN')
-                    #print node2, ' to ', node1
-                else:#this is not the link you're looking for
-                    pass
-            if not first_dir:
-                main.log.report('ONOS has issues with the link from '+str(link.node1.name) +"(dpid: "+ str(node1)+"):"+str(link.port1)+"(portNumber: "+str(port1)+")"+ ' to ' + str(link.node2.name) +"(dpid: "+ str(node2)+"):"+str(link.port2)+"(portNumber: "+str(port2)+")")
-            if not second_dir:
-                main.log.report('ONOS has issues with the link from '+str(link.node2.name) +"(dpid: "+ str(node2)+"):"+str(link.port2)+"(portNumber: "+str(port2)+")"+ ' to ' + str(link.node1.name) +"(dpid: "+ str(node1)+"):"+str(link.port1)+"(portNumber: "+str(port1)+")")
-            link_results = link_results and first_dir and second_dir
-
-        
-        results =  switch_results and port_results and link_results
-#        if not results: #To print out both topologies
-#            main.log.error("Topology comparison failed, printing json objects, MN then ONOS")
-#            main.log.error(str(json.dumps(output, sort_keys=True,indent=4,separators=(',', ': '))))
-#            main.log.error('MN Links:')
-#            for link in topo.patch_panel.network_links: main.log.error(str("\tLink: %s" % link))
-#            main.log.error(str(json.dumps(onos, sort_keys=True,indent=4,separators=(',', ': '))))
-        return results
-
     def get_hosts(self):
         '''
         Returns a list of all hosts
diff --git a/TestON/drivers/common/cli/onosclidriver.py b/TestON/drivers/common/cli/onosclidriver.py
index 6b7a02e..1caf0ec 100644
--- a/TestON/drivers/common/cli/onosclidriver.py
+++ b/TestON/drivers/common/cli/onosclidriver.py
@@ -208,6 +208,8 @@
             handle += self.handle.after
 
             main.log.info("Command sent.")
+            ansi_escape = re.compile(r'\x1b[^m]*m')
+            handle = ansi_escape.sub('', handle)
 
             return handle
         except pexpect.EOF:
@@ -688,8 +690,95 @@
             main.cleanup()
             main.exit()
     
-    #TODO:
-    #def hosts(self):
+    def hosts(self, json_format=True, grep_str=""):
+        '''
+        Lists all discovered hosts 
+        Optional argument:
+            * grep_str - pass in a string to grep
+        '''
+        try:
+            self.handle.sendline("")
+            self.handle.expect("onos>")
+            
+            if json_format:
+                if not grep_str:
+                    self.handle.sendline("hosts -j")
+                    self.handle.expect("hosts -j")
+                    self.handle.expect("onos>")
+                else:
+                    self.handle.sendline("hosts -j | grep '"+
+                        str(grep_str)+"'")
+                    self.handle.expect("hosts -j | grep '"+str(grep_str)+"'")
+                    self.handle.expect("onos>")
+                handle = self.handle.before
+                '''
+                handle variable here contains some ANSI escape color code sequences at the end which are invisible in the print command output
+                To make that escape sequence visible, use repr() function. The repr(handle) output when printed shows the ANSI escape sequences.
+                In json.loads(somestring), this somestring variable is actually repr(somestring) and json.loads would fail with the escape sequence.
+                So we take off that escape sequence using 
+                ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
+                handle1 = ansi_escape.sub('', handle) 
+                '''
+                #print "repr(handle) =", repr(handle)
+                ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
+                handle1 = ansi_escape.sub('', handle)
+                #print "repr(handle1) = ", repr(handle1)
+                return handle1
+            else:
+                if not grep_str:
+                    self.handle.sendline("hosts")
+                    self.handle.expect("onos>")
+                else:
+                    self.handle.sendline("hosts | grep '"+
+                        str(grep_str)+"'")
+                    self.handle.expect("onos>")
+                handle = self.handle.before
+                print "handle =",handle
+                return handle
+        except pexpect.EOF:
+            main.log.error(self.name + ": EOF exception found")
+            main.log.error(self.name + ":    " + self.handle.before)
+            main.cleanup()
+            main.exit()
+        except:
+            main.log.info(self.name+" ::::::")
+            main.log.error( traceback.print_exc())
+            main.log.info(self.name+" ::::::")
+            main.cleanup()
+            main.exit()
+
+    def get_host(self, mac):
+        '''
+        Return the first host from the hosts api whose 'id' contains 'mac'
+        Note: mac must be a colon seperated mac address, but could be a partial mac address
+        Return None if there is no match
+        '''
+        import json
+        try:
+            if mac == None:
+                return None
+            else:
+                mac = mac
+                raw_hosts = self.hosts()
+                hosts_json = json.loads(raw_hosts)
+                #search json for the host with mac then return the device
+                for host in hosts_json:
+                    print "%s in  %s?" % (mac, host['id'])
+                    if mac in host['id']:
+                        return host
+            return None
+        except pexpect.EOF:
+            main.log.error(self.name + ": EOF exception found")
+            main.log.error(self.name + ":    " + self.handle.before)
+            main.cleanup()
+            main.exit()
+        except:
+            main.log.info(self.name+" ::::::")
+            main.log.error( traceback.print_exc())
+            main.log.info(self.name+" ::::::")
+            main.cleanup()
+            main.exit()
+
 
     def get_hosts_id(self, host_list):
         '''
@@ -1162,4 +1251,65 @@
             main.cleanup()
             main.exit()
 
+    def check_status(self, ip, numoswitch, numolink, log_level="info"):
+        '''
+        Checks the number of swithes & links that ONOS sees against the 
+        supplied values. By default this will report to main.log, but the 
+        log level can be specifid.
+        
+        Params: ip = ip used for the onos cli
+                numoswitch = expected number of switches
+                numlink = expected number of links
+                log_level = level to log to. Currently accepts 'info', 'warn' and 'report'
+
+
+        log_level can
+
+        Returns: main.TRUE if the number of switchs and links are correct, 
+                 main.FALSE if the numer of switches and links is incorrect,
+                 and main.ERROR otherwise
+        '''
+
+        try:
+            topology = self.get_topology(ip)
+            if topology == {}:
+                return main.ERROR
+            output = ""
+            #Is the number of switches is what we expected
+            devices = topology.get('devices',False)
+            links = topology.get('links',False)
+            if devices == False or links == False:
+                return main.ERROR
+            switch_check = ( int(devices) == int(numoswitch) )
+            #Is the number of links is what we expected
+            link_check = ( int(links) == int(numolink) )
+            if (switch_check and link_check):
+                #We expected the correct numbers
+                output = output + "The number of links and switches match "\
+                        + "what was expected"
+                result = main.TRUE
+            else:
+                output = output + \
+                        "The number of links and switches does not match what was expected"
+                result = main.FALSE
+            output = output + "\n ONOS sees %i devices (%i expected) and %i links (%i expected)"\
+                    % ( int(devices), int(numoswitch), int(links), int(numolink) )
+            if log_level == "report":
+                main.log.report(output)
+            elif log_level == "warn":
+                main.log.warn(output)
+            else:
+                main.log.info(output)
+            return result 
+        except pexpect.EOF:
+            main.log.error(self.name + ": EOF exception found")
+            main.log.error(self.name + ":    " + self.handle.before)
+            main.cleanup()
+            main.exit()
+        except:
+            main.log.info(self.name+" ::::::")
+            main.log.error( traceback.print_exc())
+            main.log.info(self.name+" ::::::")
+            main.cleanup()
+            main.exit()
     #***********************************
diff --git a/TestON/drivers/common/cli/onosdriver.py b/TestON/drivers/common/cli/onosdriver.py
index 17b74ec..e924c29 100644
--- a/TestON/drivers/common/cli/onosdriver.py
+++ b/TestON/drivers/common/cli/onosdriver.py
@@ -366,10 +366,14 @@
             self.handle.sendline("export TERM=xterm-256color")
             self.handle.expect("xterm-256color")
             self.handle.expect("\$")
-            self.handle.sendline("cd " + self.home + "; git log -1 --pretty=fuller --decorate=short | grep -A 5 \"commit\" --color=never; cd \.\.")
-            self.handle.expect("cd ..")
+            self.handle.sendline("\n")
+            self.handle.expect("\$")
+            self.handle.sendline("cd " + self.home + "; git log -1 --pretty=fuller --decorate=short | grep -A 6 \"commit\" --color=never")
+            self.handle.expect("--color=never")
             self.handle.expect("\$")
             response=(self.name +": \n"+ str(self.handle.before + self.handle.after))
+            self.handle.sendline("cd " + self.home)
+            self.handle.expect("\$")
             lines=response.splitlines()
             for line in lines:
                 print line
@@ -631,10 +635,10 @@
                 main.log.warn("Network is unreachable")
                 return main.FALSE
             elif i == 1:
-                main.log.info("ONOS was installed on the VM and started")
+                main.log.info("ONOS was installed on " + node + " and started")
                 return main.TRUE
             elif i == 2: 
-                main.log.info("Installation of ONOS on the VM timed out")
+                main.log.info("Installation of ONOS on " + node + " timed out")
                 return main.FALSE
 
         except pexpect.EOF:
diff --git a/TestON/tests/JonTest/JonTest.params b/TestON/tests/JonTest/JonTest.params
new file mode 100755
index 0000000..f0b64a5
--- /dev/null
+++ b/TestON/tests/JonTest/JonTest.params
@@ -0,0 +1,18 @@
+<PARAMS>
+    
+    <testcases>1,4,3,7</testcases>
+    
+    <Git>True</Git>
+    #Environment variables
+    <ENV>
+        <cellName>multi</cellName>
+    </ENV>
+
+    <CTRL>
+        <ip1>10.128.30.11</ip1>
+        <port1>6633</port1>
+        <ip2>10.128.30.12</ip2>
+        <port2>6633</port2>
+    </CTRL>
+
+</PARAMS>
diff --git a/TestON/tests/JonTest/JonTest.py b/TestON/tests/JonTest/JonTest.py
new file mode 100755
index 0000000..5ed17db
--- /dev/null
+++ b/TestON/tests/JonTest/JonTest.py
@@ -0,0 +1,376 @@
+
+#Testing the basic functionality of ONOS Next
+#For sanity and driver functionality excercises only.
+
+import time
+import sys
+import os
+import re
+
+class JonTest:
+    def __init__(self):
+        self.default = ''
+
+    def CASE1(self, main):
+        '''
+        Startup sequence:
+        git pull
+        mvn clean install
+        onos-package
+        cell <name>
+        onos-verify-cell
+        onos-install -f
+        onos-wait-for-start
+        '''
+        import time
+        
+        PULL_CODE = False
+        if main.params['Git'] == 'True':
+            PULL_CODE = True
+        cell_name = main.params['ENV']['cellName']
+        ONOS1_ip = main.params['CTRL']['ip1']
+        ONOS1_port = main.params['CTRL']['port1']
+        ONOS2_ip = main.params['CTRL']['ip2']
+        ONOS2_port = main.params['CTRL']['port2']
+        
+        main.case("Setting up test environment")
+        
+        main.step("Applying cell variable to environment")
+        cell_result = main.ONOSbench.set_cell(cell_name)
+        #cell_result = main.ONOSbench.set_cell("temp_cell_2")
+        verify_result = main.ONOSbench.verify_cell()
+
+        if PULL_CODE:
+            main.step("Git checkout and pull master")
+            #main.log.report("Skipping git pull")
+            main.ONOSbench.git_checkout("master")
+            git_pull_result = main.ONOSbench.git_pull()
+            main.log.report(main.ONOSbench.get_version())
+
+            main.step("Using mvn clean & install")
+            clean_install_result = main.FALSE
+            if git_pull_result:
+                clean_install_result = main.ONOSbench.clean_install()
+            else:
+                main.log.report("git pull failed so skipping mvn clean install")
+
+        main.step("Creating ONOS package")
+        package_result = main.ONOSbench.onos_package()
+
+        main.step("Installing ONOS package")
+        onos1_install_result = main.ONOSbench.onos_install(options="-f", node=ONOS1_ip)
+        onos2_install_result = main.ONOSbench.onos_install(options="-f", node=ONOS2_ip)
+        onos1_isup = main.ONOSbench.isup(ONOS1_ip)
+        onos2_isup = main.ONOSbench.isup(ONOS2_ip)
+   
+        main.step("Starting ONOS service")
+        start_result = main.TRUE
+        #start_result = main.ONOSbench.onos_start(ONOS1_ip)
+
+        case1_result = (clean_install_result and package_result and\
+                cell_result and verify_result and onos1_install_result and\
+                onos2_install_result and onos1_isup and onos2_isup )
+        utilities.assert_equals(expect=main.TRUE, actual=case1_result,
+                onpass="Test startup successful",
+                onfail="Test startup NOT successful")
+
+
+    def CASE11(self, main):
+        '''
+        Cleanup sequence:
+        onos-service <node_ip> stop
+        onos-uninstall
+
+        TODO: Define rest of cleanup
+        
+        '''
+
+        ONOS1_ip = main.params['CTRL']['ip1']
+
+        main.case("Cleaning up test environment")
+
+        main.step("Testing ONOS kill function")
+        kill_result = main.ONOSbench.onos_kill(ONOS1_ip)
+
+        main.step("Stopping ONOS service")
+        stop_result = main.ONOSbench.onos_stop(ONOS1_ip)
+
+        main.step("Uninstalling ONOS service") 
+        uninstall_result = main.ONOSbench.onos_uninstall()
+
+    def CASE3(self, main):
+        '''
+        Test 'onos' command and its functionality in driver
+        '''
+        
+        ONOS1_ip = main.params['CTRL']['ip1']
+
+        main.case("Testing 'onos' command")
+
+        main.step("Sending command 'onos -w <onos-ip> system:name'")
+        cmdstr1 = "system:name"
+        cmd_result1 = main.ONOSbench.onos_cli(ONOS1_ip, cmdstr1) 
+        main.log.info("onos command returned: "+cmd_result1)
+
+        main.step("Sending command 'onos -w <onos-ip> onos:topology'")
+        cmdstr2 = "onos:topology"
+        cmd_result2 = main.ONOSbench.onos_cli(ONOS1_ip, cmdstr2)
+        main.log.info("onos command returned: "+cmd_result2)
+        
+        main.step("Testing check_status")
+        check_status_results = main.FALSE
+        check_status_results =  main.ONOSbench.check_status(ONOS1_ip, 4, 6)
+        main.log.info("Results of check_status " + str(check_status_results))
+
+        main.step("Sending command 'onos -w <onos-ip> bundle:list'")
+        cmdstr3 = "bundle:list"
+        cmd_result3 = main.ONOSbench.onos_cli(ONOS1_ip, cmdstr3)
+        main.log.info("onos command returned: "+cmd_result3)
+        case3_result = (cmd_result1 and cmd_result2 and\
+                check_status_results and cmd_result3 )
+        utilities.assert_equals(expect=main.TRUE, actual=case3_result,
+                onpass="Test case 3 successful",
+                onfail="Test case 3 NOT successful")
+
+    def CASE4(self, main):
+        import re
+        import time
+        main.case("Pingall Test(No intents are added)")
+        main.step("Assigning switches to controllers")
+        for i in range(1,5): #1 to (num of switches +1)
+            main.Mininet1.assign_sw_controller(sw=str(i),count=2, 
+                    ip1=ONOS1_ip, port1=ONOS1_port,
+                    ip2=ONOS2_ip, port2=ONOS2_port)
+
+        switch_mastership = main.TRUE
+        for i in range (1,5):
+            response = main.Mininet1.get_sw_controller("s"+str(i))
+            print("Response is " + str(response))
+            if re.search("tcp:"+ONOS1_ip,response):
+                switch_mastership = switch_mastership and main.TRUE
+            else:
+                switch_mastership = main.FALSE
+
+
+        #REACTIVE FWD test
+        main.step("Pingall")
+        ping_result = main.FALSE
+        time1 = time.time()
+        ping_result = main.Mininet1.pingall()
+        time2 = time.time()
+        print "Time for pingall: %2f seconds" % (time2 - time1)
+      
+        case4_result = switch_mastership and ping_result
+        utilities.assert_equals(expect=main.TRUE, actual=case4_result,
+                onpass="Pingall Test successful",
+                onfail="Pingall Test NOT successful")
+
+    def CASE5(self, main):
+        '''
+        Test the ONOS-cli functionality
+        
+        Below are demonstrations of what the 
+        ONOS cli driver functions can be used for.
+        '''
+        import time
+        import json
+
+        cell_name = main.params['ENV']['cellName']
+        ONOS1_ip = main.params['CTRL']['ip1']
+        
+        main.case("Testing the ONOS-cli")
+        
+        main.step("Set cell for ONOS-cli environment")
+        main.ONOScli.set_cell(cell_name)
+
+        main.step("Start ONOS-cli")
+        main.ONOScli.start_onos_cli(ONOS1_ip)
+
+        main.step("issue command: onos:topology")
+        topology_obj = main.ONOScli.topology()
+
+        main.step("issue various feature:install <str> commands")
+        #main.ONOScli.feature_install("onos-app-fwd")
+        #main.ONOScli.feature_install("onos-rest")
+
+        main.step("Add a bad node")
+        node_result = main.ONOScli.add_node("111", "10.128.20.")
+        if node_result == main.TRUE:
+            main.log.info("Node successfully added")
+
+        main.step("Add a correct node")
+        node_result = main.ONOScli.add_node("111", "10.128.20.12")
+
+        main.step("Assign switches and list devices")
+        for i in range(1,8):
+            main.Mininet1.handle.sendline("sh ovs-vsctl set-controller s"+str(i)+
+                    " tcp:10.128.20.11")
+            main.Mininet1.handle.expect("mininet>")
+        #Need to sleep to allow switch add processing
+        time.sleep(5)
+        list_result = main.ONOScli.devices()
+        main.log.info(list_result)
+
+        main.step("Get all devices id")
+        devices_id_list = main.ONOScli.get_all_devices_id()
+        main.log.info(devices_id_list)
+
+        main.step("Get path and cost between device 1 and 7")
+        (path, cost) = main.ONOScli.paths(devices_id_list[0], devices_id_list[6])
+        main.log.info("Path: "+str(path))
+        main.log.info("Cost: "+str(cost))
+
+        main.step("Get nodes currently visible")
+        nodes_str = main.ONOScli.nodes()
+        main.log.info(nodes_str)
+
+        main.step("Get all nodes id's")
+        node_id_list = main.ONOScli.get_all_nodes_id()
+        main.log.info(node_id_list)
+
+        main.step("Set device "+str(devices_id_list[0])+" to role: standby")
+        device_role_result = main.ONOScli.device_role(
+                devices_id_list[0], node_id_list[0], "standby")
+        if device_role_result == main.TRUE:
+            main.log.report("Device role successfully set")
+
+        main.step("Revert device role to master")
+        device_role = main.ONOScli.device_role(
+                devices_id_list[0], node_id_list[0], "master")
+
+        main.step("Check devices / role again")
+        dev_result = main.ONOScli.devices()
+        main.log.info(dev_result)
+       
+        #Sample steps to push intents ***********
+        # * Obtain host id in ONOS format 
+        # * Push intents
+        main.step("Get list of hosts from Mininet")
+        host_list = main.Mininet2.get_hosts()
+        main.log.info(host_list)
+
+        main.step("Get host list in ONOS format")
+        host_onos_list = main.ONOScli.get_hosts_id(host_list)
+        main.log.info(host_onos_list)
+
+        main.step("Ensure that reactive forwarding is installed")
+        feature_result = main.ONOScli.feature_install("onos-app-fwd")
+
+        time.sleep(5)
+
+        main.Mininet2.handle.sendline("\r")
+        main.Mininet2.handle.sendline("h4 ping h5 -c 1")
+
+        time.sleep(5)
+
+        main.step("Get hosts")
+        main.ONOScli.handle.sendline("hosts")
+        main.ONOScli.handle.expect("onos>")
+        hosts = main.ONOScli.handle.before
+        main.log.info(hosts)
+
+        main.step("Install host-to-host-intents between h4 and h5")
+        intent_install = main.ONOScli.add_host_intent(
+                host_onos_list[3], host_onos_list[4])
+        main.log.info(intent_install)
+
+        main.step("Uninstall reactive forwarding to test host-to-host intent")
+        main.ONOScli.feature_uninstall("onos-app-fwd")
+
+        main.step("Get intents installed on ONOS")
+        get_intent_result = main.ONOScli.intents()
+        main.log.info(get_intent_result)
+        #****************************************
+
+
+    def CASE7(self, main):
+        '''
+        Test compare topo functions
+        '''
+        import sys
+        sys.path.append("/home/admin/sts") # Trying to remove some dependancies, #FIXME add this path to params
+        from sts.topology.teston_topology import TestONTopology # assumes that sts is already in you PYTHONPATH
+        import json
+
+        main.step("Create TestONTopology object")
+        ctrls = []
+        count = 1
+        while True:
+            temp = ()
+            if ('ip' + str(count)) in main.params['CTRL']:
+                temp = temp + (getattr(main,('ONOS' + str(count))),)
+                temp = temp + ("ONOS"+str(count),)
+                temp = temp + (main.params['CTRL']['ip'+str(count)],)
+                temp = temp + (eval(main.params['CTRL']['port'+str(count)]),)
+                ctrls.append(temp)
+                count = count + 1
+            else:
+                break
+        MNTopo = TestONTopology(main.Mininet1, ctrls) # can also add Intent API info for intent operations
+
+        ONOS1_ip = main.params['CTRL']['ip1']
+        ONOS2_ip = main.params['CTRL']['ip2']
+
+        main.ONOScli1.start_onos_cli(ONOS1_ip)
+        main.ONOScli2.start_onos_cli(ONOS2_ip)
+    
+        main.step("Collecting topology information from ONOS")
+        devices1 = main.ONOScli1.devices()
+        devices2 = main.ONOScli2.devices()
+        switch1 = main.ONOScli1.get_device("0000000000000001")
+        hosts1 = main.ONOScli1.hosts()
+        hosts2 = main.ONOScli2.hosts()
+        host1 = main.ONOScli1.get_host("00:00:00:00:00:01")
+        print json.dumps(json.loads(hosts1), sort_keys=True,indent=4,separators=(',', ': '))
+        print json.dumps(json.loads(hosts2), sort_keys=True,indent=4,separators=(',', ': '))
+        print json.dumps(host1, sort_keys=True,indent=4,separators=(',', ': '))
+        ports1 = main.ONOScli1.ports()
+        ports2 = main.ONOScli2.ports()
+        links1 = main.ONOScli1.links()
+        links2 = main.ONOScli2.links()
+
+
+        main.step("Comparing ONOS topology to MN")
+        #results =  main.Mininet1.compare_topo(MNTopo, json.loads(devices))
+        switches_results1 =  main.Mininet1.compare_switches(MNTopo, json.loads(devices1))
+        utilities.assert_equals(expect=main.TRUE, actual=switches_results1,
+                onpass="ONOS1 Switches view is correct",
+                onfail="ONOS1 Switches view is incorrect")
+
+        switches_results2 =  main.Mininet1.compare_switches(MNTopo, json.loads(devices2))
+        utilities.assert_equals(expect=main.TRUE, actual=switches_results2,
+                onpass="ONOS2 Switches view is correct",
+                onfail="ONOS2 Switches view is incorrect")
+
+
+        ports_results1 =  main.Mininet1.compare_ports(MNTopo, json.loads(ports1))
+        utilities.assert_equals(expect=main.TRUE, actual=ports_results1,
+                onpass="ONOS1 Ports view is correct",
+                onfail="ONOS1 Ports view is incorrect")
+
+        ports_results2 =  main.Mininet1.compare_ports(MNTopo, json.loads(ports2))
+        utilities.assert_equals(expect=main.TRUE, actual=ports_results2,
+                onpass="ONOS2 Ports view is correct",
+                onfail="ONOS2 Ports view is incorrect")
+
+        links_results1 =  main.Mininet1.compare_links(MNTopo, json.loads(links1))
+        utilities.assert_equals(expect=main.TRUE, actual=links_results1,
+                onpass="ONOS1 Links view is correct",
+                onfail="ONOS1 Links view is incorrect")
+
+        links_results2 =  main.Mininet1.compare_links(MNTopo, json.loads(links2))
+        utilities.assert_equals(expect=main.TRUE, actual=links_results2,
+                onpass="ONOS2 Links view is correct",
+                onfail="ONOS2 Links view is incorrect")
+
+        topo_result = switches_results1 and switches_results2 \
+                and ports_results1 and ports_results2\
+                and links_results1 and links_results2
+        utilities.assert_equals(expect=main.TRUE, actual=topo_result,
+                onpass="Topology Check Test successful",
+                onfail="Topology Check Test NOT successful")
+
+######
+#jhall@onlab.us
+#andrew@onlab.us
+######
diff --git a/TestON/tests/JonTest/JonTest.topo b/TestON/tests/JonTest/JonTest.topo
new file mode 100755
index 0000000..bf8cb18
--- /dev/null
+++ b/TestON/tests/JonTest/JonTest.topo
@@ -0,0 +1,65 @@
+<TOPOLOGY>
+    <COMPONENT>
+
+        <ONOSbench>
+            <host>10.128.30.10</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosDriver</type>
+            <connect_order>1</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOSbench>
+
+        <ONOScli1>
+            <host>10.128.30.10</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>2</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOScli1>
+
+        <ONOScli2>
+            <host>10.128.30.10</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>2</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOScli2>
+
+        <ONOS1>
+            <host>10.128.30.11</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>3</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS1>
+
+        <ONOS2>
+            <host>10.128.30.12</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>3</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS2>
+
+        <Mininet1>
+            <host>10.128.11.11</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>MininetCliDriver</type>
+            <connect_order>4</connect_order>
+            <COMPONENTS>
+                #Specify the Option for mininet
+                <arg1> --topo tree,2,3</arg1>
+                <arg2> </arg2>
+                <arg3> </arg3>
+                <controller> remote </controller>
+            </COMPONENTS>
+        </Mininet1>
+
+    </COMPONENT>
+</TOPOLOGY>
diff --git a/TestON/tests/JonTest/__init__.py b/TestON/tests/JonTest/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/JonTest/__init__.py