Merge branch 'ONOS-Next' of https://github.com/OPENNETWORKINGLAB/ONLabTest into ONOS-Next
diff --git a/TestON/drivers/common/cli/emulator/mininetclidriver.py b/TestON/drivers/common/cli/emulator/mininetclidriver.py
index 13510f5..f8ee9c2 100644
--- a/TestON/drivers/common/cli/emulator/mininetclidriver.py
+++ b/TestON/drivers/common/cli/emulator/mininetclidriver.py
@@ -154,6 +154,7 @@
             main.log.info(self.name+": Checking reachabilty to the hosts using pingall")
             try:
                 response = self.execute(cmd="pingall",prompt="mininet>",timeout=120)
+                print "response: " + str(response)
             except pexpect.EOF:  
                 main.log.error(self.name + ": EOF exception found")
                 main.log.error(self.name + ":     " + self.handle.before)
diff --git a/TestON/drivers/common/cli/onosclidriver.py b/TestON/drivers/common/cli/onosclidriver.py
new file mode 100644
index 0000000..01e5838
--- /dev/null
+++ b/TestON/drivers/common/cli/onosclidriver.py
@@ -0,0 +1,500 @@
+#!/usr/bin/env python
+
+'''
+This driver enters the onos> prompt to issue commands.
+
+Please follow the coding style demonstrated by existing 
+functions and document properly.
+
+If you are a contributor to the driver, please
+list your email here for future contact:
+
+jhall@onlab.us
+andrew@onlab.us
+
+OCT 13 2014
+
+'''
+
+import sys
+import time
+import pexpect
+import re
+import traceback
+import os.path
+import pydoc
+sys.path.append("../")
+from drivers.common.clidriver import CLI
+
+class OnosCliDriver(CLI):
+
+    def __init__(self):
+        '''
+        Initialize client 
+        '''
+        super(CLI, self).__init__()
+
+    def connect(self,**connectargs):
+        '''
+        Creates ssh handle for ONOS cli.
+        '''
+        try:
+            for key in connectargs:
+                vars(self)[key] = connectargs[key]
+            self.home = "~/ONOS"
+            for key in self.options:
+                if key == "home":
+                    self.home = self.options['home']
+                    break
+
+
+            self.name = self.options['name']
+            self.handle = super(OnosCliDriver,self).connect(
+                    user_name = self.user_name, 
+                    ip_address = self.ip_address,
+                    port = self.port, 
+                    pwd = self.pwd, 
+                    home = self.home)
+           
+            self.handle.sendline("cd "+ self.home)
+            self.handle.expect("\$")
+            if self.handle:
+                return self.handle
+            else :
+                main.log.info("NO ONOS HANDLE")
+                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()
+        except:
+            main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
+            main.log.error( traceback.print_exc() )
+            main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
+            main.cleanup()
+            main.exit()
+
+    def disconnect(self):
+        '''
+        Called when Test is complete to disconnect the ONOS handle.
+        '''
+        response = ''
+        try:
+            self.handle.sendline("system:shutdown")
+            self.handle.expect("Confirm")
+            self.handle.sendline("Yes")
+            self.handle.expect("\$")
+
+        except pexpect.EOF:
+            main.log.error(self.name + ": EOF exception found")
+            main.log.error(self.name + ":     " + self.handle.before)
+        except:
+            main.log.error(self.name + ": Connection failed to the host")
+            response = main.FALSE
+        return response
+
+    def set_cell(self, cellname):
+        '''
+        Calls 'cell <name>' to set the environment variables on ONOSbench
+        
+        Before issuing any cli commands, set the environment variable first.
+        '''
+        try:
+            if not cellname:
+                main.log.error("Must define cellname")
+                main.cleanup()
+                main.exit()
+            else:
+                self.handle.sendline("cell "+str(cellname))
+                #Expect the cellname in the ONOS_CELL variable.
+                #Note that this variable name is subject to change
+                #   and that this driver will have to change accordingly
+                self.handle.expect("ONOS_CELL="+str(cellname))
+                handle_before = self.handle.before
+                handle_after = self.handle.after
+                #Get the rest of the handle
+                self.handle.sendline("")
+                self.handle.expect("\$")
+                handle_more = self.handle.before
+
+                main.log.info("Cell call returned: "+handle_before+
+                        handle_after + handle_more)
+
+                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()
+        except:
+            main.log.info(self.name+" ::::::")
+            main.log.error( traceback.print_exc())
+            main.log.info(self.name+" ::::::")
+            main.cleanup()
+            main.exit()
+        
+    def start_onos_cli(self, ONOS_ip):
+        try:
+            self.handle.sendline("")
+            self.handle.expect("\$")
+
+            #Wait for onos start (-w) and enter onos cli
+            self.handle.sendline("onos -w "+str(ONOS_ip))
+            self.handle.expect("onos>")
+
+        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 sendline(self, cmd_str):
+        '''
+        Send a completely user specified string to 
+        the onos> prompt. Use this function if you have 
+        a very specific command to send.
+        
+        Warning: There are no sanity checking to commands
+        sent using this method.
+        '''
+        try:
+            self.handle.sendline("")
+            self.handle.expect("onos>")
+
+            self.handle.sendline(cmd_str)
+            self.handle.expect("onos>")
+
+            handle = self.handle.before
+            
+            self.handle.sendline("")
+            self.handle.expect("onos>")
+            
+            handle += self.handle.before
+            handle += self.handle.after
+
+            main.log.info("Command sent.")
+
+            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()
+
+    #IMPORTANT NOTE:
+    #For all cli commands, naming convention should match
+    #the cli command replacing ':' with '_'.
+    #Ex) onos:topology > onos_topology
+    #    onos:links    > onos_links
+    #    feature:list  > feature_list
+   
+    def add_node(self, node_id, ONOS_ip, tcp_port=""):
+        '''
+        Adds a new cluster node by ID and address information.
+        Required:
+            * node_id
+            * ONOS_ip
+        Optional:
+            * tcp_port
+        '''
+        try:
+            self.handle.sendline("")
+            self.handle.expect("onos>")
+
+            self.handle.sendline("add-node "+
+                    str(node_id)+" "+
+                    str(ONOS_ip)+" "+
+                    str(tcp_port))
+            
+            i = self.handle.expect([
+                "Error",
+                "onos>" ])
+            
+            #Clear handle to get previous output
+            self.handle.sendline("")
+            self.handle.expect("onos>")
+
+            handle = self.handle.before
+
+            if i == 0:
+                main.log.error("Error in adding node")
+                main.log.error(handle)
+                return main.FALSE 
+            else:
+                main.log.info("Node "+str(ONOS_ip)+" added")
+                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()
+        except:
+            main.log.info(self.name+" ::::::")
+            main.log.error( traceback.print_exc())
+            main.log.info(self.name+" ::::::")
+            main.cleanup()
+            main.exit()
+
+    def remove_node(self, node_id):
+        '''
+        Removes a cluster by ID
+        Issues command: 'remove-node [<node-id>]'
+        Required:
+            * node_id
+        '''
+        try:
+            self.handle.sendline("")
+            self.handle.expect("onos>")
+
+            self.handle.sendline("remove-node "+str(node_id))
+            self.handle.expect("onos>")
+
+            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()
+        except:
+            main.log.info(self.name+" ::::::")
+            main.log.error( traceback.print_exc())
+            main.log.info(self.name+" ::::::")
+            main.cleanup()
+            main.exit()
+
+    def topology(self):
+        '''
+        Shows the current state of the topology
+        by issusing command: 'onos> onos:topology'
+        '''
+        try:
+            self.handle.sendline("")
+            self.handle.expect("onos>")
+            #either onos:topology or 'topology' will work in CLI
+            self.handle.sendline("onos:topology")
+            self.handle.expect("onos>")
+
+            handle = self.handle.before
+
+            main.log.info("onos:topology returned: " +
+                    str(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 feature_install(self, feature_str):
+        '''
+        Installs a specified feature 
+        by issuing command: 'onos> feature:install <feature_str>'
+        '''
+        try:
+            self.handle.sendline("")
+            self.handle.expect("onos>")
+
+            self.handle.sendline("feature:install "+str(feature_str))
+            self.handle.expect("onos>")
+
+            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()
+        except:
+            main.log.info(self.name+" ::::::")
+            main.log.error( traceback.print_exc())
+            main.log.info(self.name+" ::::::")
+            main.cleanup()
+            main.exit()
+       
+    def feature_uninstall(self, feature_str):
+        '''
+        Uninstalls a specified feature
+        by issuing command: 'onos> feature:uninstall <feature_str>'
+        '''
+        try:
+            self.handle.sendline("")
+            self.handle.expect("onos>")
+
+            self.handle.sendline("feature:uninstall "+str(feature_str))
+            self.handle.expect("onos>")
+
+            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()
+        except:
+            main.log.info(self.name+" ::::::")
+            main.log.error( traceback.print_exc())
+            main.log.info(self.name+" ::::::")
+            main.cleanup()
+            main.exit()
+        
+    def devices(self, grep_str=""):
+        '''
+        Lists all infrastructure devices
+        Optional argument:
+            * grep_str - pass in a string to grep
+        '''
+        try:
+            self.handle.sendline("")
+            self.handle.expect("onos>")
+
+            if not grep_str:
+                self.handle.sendline("devices")
+                self.handle.expect("onos>")
+            else:
+                self.handle.sendline("devices | grep '"+
+                        str(grep_str)+"'")
+                self.handle.expect("onos>")
+           
+            handle = self.handle.before
+            handle += self.handle.after
+
+            self.handle.sendline("")
+            self.handle.expect("onos>")
+
+            handle += self.handle.before
+            handle += self.handle.after
+
+            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 paths(self, src_id, dst_id):
+        '''
+        Returns string of paths, and the cost.
+        Issues command: onos:paths <src> <dst>
+        '''
+        try:
+            self.handle.sendline("")
+            self.handle.expect("onos>")
+
+            self.handle.sendline("onos:paths "+
+                    str(src_id) + " " + str(dst_id))
+            i = self.handle.expect([
+                "Error",
+                "onos>"])
+            
+            self.handle.sendline("")
+            self.handle.expect("onos>")
+
+            handle = self.handle.before
+
+            if i == 0:
+                main.log.error("Error in getting paths")
+                return handle
+            else:
+                path = handle.split(";")[0]
+                cost = handle.split(";")[1]
+                return (path, cost)
+        
+        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()
+
+
+
+    #Wrapper functions ****************
+    #Wrapper functions use existing driver
+    #functions and extends their use case.
+    #For example, we may use the output of
+    #a normal driver function, and parse it
+    #using a wrapper function
+
+    def get_all_devices_id(self):
+        '''
+        Use 'devices' function to obtain list of all devices
+        and parse the result to obtain a list of all device
+        id's. Returns this list. Returns empty list if no
+        devices exist
+        List is ordered sequentially 
+        
+        This function may be useful if you are not sure of the
+        device id, and wish to execute other commands using 
+        the ids. By obtaining the list of device ids on the fly,
+        you can iterate through the list to get mastership, etc.
+        '''
+        try:
+            #Call devices and store result string
+            devices_str = self.devices()
+            id_list = []
+            
+            if not devices_str:
+                main.log.info("There are no devices to get id from")
+                return id_list
+           
+            #Split the string into list by comma
+            device_list = devices_str.split(",")
+            #Get temporary list of all arguments with string 'id='
+            temp_list = [dev for dev in device_list if "id=" in dev]
+            #Split list further into arguments before and after string
+            # 'id='. Get the latter portion (the actual device id) and
+            # append to id_list
+            for arg in temp_list:
+                id_list.append(arg.split("id=")[1])
+            
+            return id_list
+
+        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 e6d699c..ff13e5d 100644
--- a/TestON/drivers/common/cli/onosdriver.py
+++ b/TestON/drivers/common/cli/onosdriver.py
@@ -235,10 +235,10 @@
             elif i==2:
                 main.log.info(self.name + ": Git Pull - pulling repository now")
                 self.handle.expect("ONOS\$", 120)
-                return 0
+                return main.TRUE
             elif i==3:
                 main.log.info(self.name + ": Git Pull - Already up to date")
-                return 1
+                return main.TRUE
             elif i==4:
                 main.log.info(self.name + ": Git Pull - Aborting... Are there conflicting git files?")
                 return main.ERROR
@@ -409,8 +409,10 @@
         #Create the cell file in the directory for writing (w+)
         cell_file = open(temp_directory+file_name , 'w+')
         
-        #Feature string is pre-defined environment variable
-        #that is required in the file
+        #Feature string is hardcoded environment variables
+        #That you may wish to use by default on startup.
+        #Note that you  may not want certain features listed
+        #on here.
         feature_string = "export ONOS_FEATURES=webconsole,onos-api,"+\
                          "onos-core-trivial,onos-cli,onos-openflow,"+\
                          "onos-app-fwd,onos-app-mobility,onos-app-tvue,"+\
@@ -423,7 +425,7 @@
         temp_onos_ip = onos_ip_addrs[0] 
         temp_list = []
         temp_list = temp_onos_ip.split(".")
-        #Omit last element of list
+        #Omit last element of list to format for NIC
         temp_list = temp_list[:-1]
         #Structure the nic string ip
         nic_addr = ".".join(temp_list) + ".*\n"
@@ -451,7 +453,7 @@
             #on the same cluster as the ONOS bench
             #Note that even if TestON is located on the same cluster
             #as ONOS bench, you must setup passwordless ssh
-            #in order to automate the test.
+            #between TestON and ONOS bench in order to automate the test.
             os.system("scp "+temp_directory+file_name+
                     " admin@"+bench_ip+":"+cell_directory)
 
@@ -584,8 +586,6 @@
             #Obtain return handle that consists of result from 
             #the onos command. The string may need to be 
             #configured further. 
-            #TODO: This function may need to return another 
-            #      type of variable depending on its use case
             return_string = handle_before + handle_after + handle_more
             return return_string
 
@@ -833,7 +833,8 @@
 
     def isup(self, node = ""):
         '''
-        Run's onos-wait-for-start which only returns once ONOS is at run level 100(ready for use)
+        Run's onos-wait-for-start which only returns once ONOS is at run 
+        level 100(ready for use)
 
         Returns: main.TRUE if ONOS is running and main.FALSE on timeout
         '''
@@ -864,3 +865,113 @@
             main.exit()
 
 
+    def get_topology(self, ip):
+        '''
+        parses the onos:topology output
+        Returns: a topology dict populated by the key values found in 
+                 the cli command.
+        '''
+
+        try:
+            #call the cli to get the topology summary
+            cmdstr = "onos:topology"
+            cli_result = self.onos_cli(ip, cmdstr)
+
+
+            #Parse the output
+            topology = {}
+            #for line in cli_result.split("\n"):
+            for line in cli_result.splitlines():
+                if not line.startswith("time="):
+                    continue
+                #else
+                print line
+                for var in line.split(","):
+                    print "'"+var+"'"
+                    print "'"+var.strip()+"'"
+                    key, value = var.strip().split("=")
+                    topology[key] = value
+            print topology
+            devices = topology.get('devices', False)
+            print devices
+            links = topology.get('links', False)
+            print links
+            clusters = topology.get('clusters', False)
+            print clusters
+            paths = topology.get('paths', False)
+            print paths
+
+            return topology
+        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 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/tests/ONOSNextTest/ONOSNextTest.params b/TestON/tests/ONOSNextTest/ONOSNextTest.params
index d2c7e51..01c432e 100755
--- a/TestON/tests/ONOSNextTest/ONOSNextTest.params
+++ b/TestON/tests/ONOSNextTest/ONOSNextTest.params
@@ -1,6 +1,6 @@
 <PARAMS>
     
-    <testcases>1,4,3</testcases>
+    <testcases>1,5</testcases>
 
     #Environment variables
     <ENV>
diff --git a/TestON/tests/ONOSNextTest/ONOSNextTest.py b/TestON/tests/ONOSNextTest/ONOSNextTest.py
index e4b7a48..cbf8afe 100755
--- a/TestON/tests/ONOSNextTest/ONOSNextTest.py
+++ b/TestON/tests/ONOSNextTest/ONOSNextTest.py
@@ -30,18 +30,6 @@
         
         main.case("Setting up test environment")
         
-        main.step("Git checkout and pull master")
-        #main.ONOSbench.git_checkout("master")
-        #git_pull_result = main.ONOSbench.git_pull()
-
-
-        main.step("Using mvn clean & install")
-        #clean_install_result = main.ONOSbench.clean_install()
-        clean_install_result = main.TRUE
-
-        main.step("Creating ONOS package")
-        package_result = main.ONOSbench.onos_package()
-
         main.step("Creating cell file")
         #params: (bench ip, cell name, mininet ip, *onos ips)
         cell_file_result = main.ONOSbench.create_cell_file(
@@ -52,6 +40,18 @@
         cell_result = main.ONOSbench.set_cell(cell_name)
         verify_result = main.ONOSbench.verify_cell()
         
+        main.step("Git checkout and pull master")
+        main.ONOSbench.git_checkout("master")
+        git_pull_result = main.ONOSbench.git_pull()
+
+
+        main.step("Using mvn clean & install")
+        clean_install_result = main.ONOSbench.clean_install()
+        #clean_install_result = main.TRUE
+
+        main.step("Creating ONOS package")
+        package_result = main.ONOSbench.onos_package()
+
         main.step("Installing ONOS package")
         onos_install_result = main.ONOSbench.onos_install()
         onos1_isup = main.ONOSbench.isup()
@@ -107,22 +107,31 @@
         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.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")
+        main.case("Pingall Test(No intents are added)")
         main.step("Assigning switches to controllers")
-        for i in range(1,29):
+        for i in range(1,5): #1 to (num of switches +1)
             main.Mininet1.assign_sw_controller(sw=str(i), 
                     ip1=ONOS1_ip, port1=ONOS1_port)
         switch_mastership = main.TRUE
-        for i in range (1,29):
+        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):
@@ -144,3 +153,61 @@
                 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
+        
+        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.onos_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.Mininet2.handle.sendline("sh ovs-vsctl set-controller s"+str(i)+
+                    " tcp:10.128.20.11")
+            main.Mininet2.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))
+    
+######
+#jhall@onlab.us
+#andrew@onlab.us
+######
diff --git a/TestON/tests/ONOSNextTest/ONOSNextTest.topo b/TestON/tests/ONOSNextTest/ONOSNextTest.topo
index 0f7388e..a5f544a 100755
--- a/TestON/tests/ONOSNextTest/ONOSNextTest.topo
+++ b/TestON/tests/ONOSNextTest/ONOSNextTest.topo
@@ -10,12 +10,21 @@
             <COMPONENTS> </COMPONENTS>
         </ONOSbench>
 
+        <ONOScli>
+            <host>10.128.20.10</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>2</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOScli>
+
         <ONOS1>
             <host>10.128.20.11</host>
             <user>sdn</user>
             <password>sdn</password>
             <type>OnosDriver</type>
-            <connect_order>2</connect_order>
+            <connect_order>3</connect_order>
             <COMPONENTS> </COMPONENTS>
         </ONOS1>
 
@@ -24,7 +33,7 @@
             <user>admin</user>
             <password>onos_test</password>
             <type>MininetCliDriver</type>
-            <connect_order>3</connect_order>
+            <connect_order>4</connect_order>
             <COMPONENTS>
                 #Specify the Option for mininet
                 <arg1> --topo tree,2,3</arg1>
@@ -34,5 +43,19 @@
             </COMPONENTS>
         </Mininet1>
 
+        <Mininet2>
+            <host>10.128.10.91</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>MininetCliDriver</type>
+            <connect_order>5</connect_order>
+            <COMPONENTS> 
+                <arg1> --custom topo-intentTPtest.py </arg1>
+                <arg2> --arp --mac</arg2>
+                <arg3> --topo mytopo</arg3>
+                <controller> remote </controller>
+            </COMPONENTS>
+        </Mininet2>
+
     </COMPONENT>
 </TOPOLOGY>