Update Cluster Driver

Change-Id: I8a3a57e19637ff210548e57d41178e6f194cf694
diff --git a/TestON/tests/SCPF/SCPFportLat/SCPFportLat.params b/TestON/tests/SCPF/SCPFportLat/SCPFportLat.params
index 6dbd03d..65e02fa 100644
--- a/TestON/tests/SCPF/SCPFportLat/SCPFportLat.params
+++ b/TestON/tests/SCPF/SCPFportLat/SCPFportLat.params
@@ -23,7 +23,9 @@
         <pull>False</pull>
         <branch>master</branch>
     </GIT>
-
+    <CFG>
+        <defaultTopo>org.onosproject.net.topology.impl.DefaultTopologyProvider</defaultTopo>
+    </CFG>
     <TSHARK>
         <tsharkReusltPath>/tmp/tshark_portStatus</tsharkReusltPath>
         <ofpPortStatus>OF 1.3 146</ofpPortStatus>
diff --git a/TestON/tests/SCPF/SCPFportLat/SCPFportLat.py b/TestON/tests/SCPF/SCPFportLat/SCPFportLat.py
index 437d57b..c1dd9cc 100644
--- a/TestON/tests/SCPF/SCPFportLat/SCPFportLat.py
+++ b/TestON/tests/SCPF/SCPFportLat/SCPFportLat.py
@@ -69,6 +69,7 @@
             main.startUpSleep = int( main.params[ 'SLEEP' ][ 'startup' ] )
             main.measurementSleep = int( main.params[ 'SLEEP' ][ 'measure' ] )
             main.maxScale = int( main.params[ 'max' ] )
+            main.defaultTopoCfg = main.params[ 'CFG' ][ 'defaultTopo' ]
             main.interface = main.params[ 'TEST' ][ 'interface' ]
             main.timeout = int( main.params[ 'TIMEOUT' ][ 'timeout' ] )
             main.MNSleep = int( main.params[ 'SLEEP' ][ 'mininet' ] )
@@ -80,7 +81,7 @@
             else:
                 main.debug = False
 
-            stepResult = main.testSetUp.gitPulling()
+            stepResult = main.testSetUp.envSetup()
             main.log.info( "Create Database file " + main.dbFileName )
             resultsDB = open( main.dbFileName, "w+" )
             resultsDB.close()
@@ -97,25 +98,22 @@
     def CASE1( self, main ):
         # Clean up test environment and set up
         import time
-        main.testSetUp.getNumCtrls( True )
-        main.testSetUp.envSetup( includeGitPull=False, makeMaxNodes=False )
-        main.testSetUp.ONOSSetUp( main.Mininet1, True,
-                                  cellName=main.cellName, killRemoveMax=False,
-                                  CtrlsSet=False )
+        main.testSetUp.ONOSSetUp( main.Mininet1, main.Cluster, True,
+                                  cellName=main.cellName, killRemoveMax=False )
 
         main.log.info( "Configure apps" )
-        main.CLIs[0].setCfg( "org.onosproject.net.topology.impl.DefaultTopologyProvider",
-                            "maxEvents 1" )
-        main.CLIs[0].setCfg( "org.onosproject.net.topology.impl.DefaultTopologyProvider",
-                            "maxBatchMs 0" )
-        main.CLIs[0].setCfg( "org.onosproject.net.topology.impl.DefaultTopologyProvider",
-                            "maxIdleMs 0" )
-        time.sleep(1)
+        main.Cluster.active( 0 ).CLI.setCfg( main.defaultTopoCfg,
+                                                  "maxEvents 1" )
+        main.Cluster.active( 0 ).CLI.setCfg( main.defaultTopoCfg,
+                                                  "maxBatchMs 0" )
+        main.Cluster.active( 0 ).CLI.setCfg( main.defaultTopoCfg,
+                                                  "maxIdleMs 0" )
+        time.sleep( 1 )
         main.log.info( "Copy topology file to Mininet" )
         main.ONOSbench.copyMininetFile( main.topoName,
                                        main.dependencyPath,
                                        main.Mininet1.user_name,
-                                       main.Mininet1.ip_address)
+                                       main.Mininet1.ip_address )
         try:
             from tests.dependencies.utils import Utils
         except ImportError:
@@ -130,39 +128,61 @@
         main.log.info( "Start new mininet topology" )
         main.Mininet1.startNet()
         main.log.info( "Assign switch to controller to ONOS node 1" )
-        time.sleep(1)
-        main.Mininet1.assignSwController( sw='s1', ip=main.ONOSip[0] )
-        main.Mininet1.assignSwController( sw='s2', ip=main.ONOSip[0] )
+        time.sleep( 1 )
+        main.Mininet1.assignSwController( sw='s1',
+                                          ip=main.Cluster.active( 0 ).ipAddress )
+        main.Mininet1.assignSwController( sw='s2',
+                                          ip=main.Cluster.active( 0 ).ipAddress )
 
-        time.sleep(2)
+        time.sleep( 2 )
 
     def CASE2( self, main ):
         import time
         import numpy
         # dictionary for each node and each timestamps
-        resultDict = {'up' : {}, 'down' : {}}
+        resultDict = { 'up' : {}, 'down' : {} }
         for d in resultDict:
-            for i in range( 1, main.numCtrls + 1 ):
-                resultDict[d][ 'node' + str(i) ] = {}
-                resultDict[d][ 'node' + str(i) ][ 'Ave' ] = {}
-                resultDict[d][ 'node' + str(i) ][ 'Std' ] = {}
-                resultDict[d][ 'node' + str(i) ][ 'EtoE' ] = []
-                resultDict[d][ 'node' + str(i) ][ 'PtoD' ] = []
-                resultDict[d][ 'node' + str(i) ][ 'DtoL' ] = []
-                resultDict[d][ 'node' + str(i) ][ 'LtoG' ] = []
+            for i in range( 1, main.Cluster.numCtrls + 1 ):
+                resultDict[ d ][ 'node' + str( i ) ] = {}
+                resultDict[ d ][ 'node' + str( i ) ][ 'Ave' ] = {}
+                resultDict[ d ][ 'node' + str( i ) ][ 'Std' ] = {}
+                resultDict[ d ][ 'node' + str( i ) ][ 'EtoE' ] = []
+                resultDict[ d ][ 'node' + str( i ) ][ 'PtoD' ] = []
+                resultDict[ d ][ 'node' + str( i ) ][ 'DtoL' ] = []
+                resultDict[ d ][ 'node' + str( i ) ][ 'LtoG' ] = []
         for i in range( 1, main.sampleSize + main.warmUp ):
             main.log.info( "==========================================" )
-            main.log.info( "================iteration:{}==============".format(str (i) ) )
+            main.log.info( "================iteration:{}==============".format( str ( i ) ) )
             if i > main.warmUp:
                 # Portdown iteration
-                main.portFunc.capturePortStatusPack( main, main.device, main.interface, "down", resultDict, False )
-                time.sleep(2)
+                main.portFunc.capturePortStatusPack( main,
+                                                     main.device,
+                                                     main.interface,
+                                                     "down",
+                                                     resultDict,
+                                                     False )
+                time.sleep( 2 )
                 # PortUp iteration
-                main.portFunc.capturePortStatusPack( main, main.device, main.interface, "up", resultDict, False )
+                main.portFunc.capturePortStatusPack( main,
+                                                     main.device,
+                                                     main.interface,
+                                                     "up",
+                                                     resultDict,
+                                                     False )
             else:
                 # if warm up, keep old result dictionary
-                main.portFunc.capturePortStatusPack( main, main.device, main.interface, "down", resultDict, True)
-                main.portFunc.capturePortStatusPack( main, main.device, main.interface, "up", resultDict, True)
+                main.portFunc.capturePortStatusPack( main,
+                                                     main.device,
+                                                     main.interface,
+                                                     "down",
+                                                     resultDict,
+                                                     True )
+                main.portFunc.capturePortStatusPack( main,
+                                                     main.device,
+                                                     main.interface,
+                                                     "up",
+                                                     resultDict,
+                                                     True )
 
         # Dictionary for result
         maxDict  = {}
@@ -174,45 +194,45 @@
         maxDict[ 'up' ][ 'node' ] = 0
         EtoEtemp = 0
         for d in resultDict:
-            for i in range( 1, main.numCtrls + 1 ):
+            for i in range( 1, main.Cluster.numCtrls + 1 ):
                 # calculate average and std for result, and grep the max End to End data
-                EtoEtemp = numpy.average( resultDict[d][ 'node' + str(i) ][ 'EtoE' ] )
-                resultDict[d][ 'node' + str(i) ][ 'Ave' ][ 'EtoE' ] = EtoEtemp
-                if maxDict[d][ 'max' ] < EtoEtemp:
+                EtoEtemp = numpy.average( resultDict[ d ][ 'node' + str( i ) ][ 'EtoE' ] )
+                resultDict[ d ][ 'node' + str( i ) ][ 'Ave' ][ 'EtoE' ] = EtoEtemp
+                if maxDict[ d ][ 'max' ] < EtoEtemp:
                     # get max End to End latency
-                    maxDict[d][ 'max' ] = EtoEtemp
-                    maxDict[d][ 'node' ] = i
-                resultDict[d][ 'node' + str(i)][ 'Ave' ][ 'PtoD' ] = numpy.average(resultDict[d][ 'node' + str(i)][ 'PtoD' ] )
-                resultDict[d][ 'node' + str(i)][ 'Ave' ][ 'DtoL' ] = numpy.average(resultDict[d][ 'node' + str(i)][ 'DtoL' ] )
-                resultDict[d][ 'node' + str(i)][ 'Ave' ][ 'LtoG' ] = numpy.average(resultDict[d][ 'node' + str(i)][ 'LtoG' ] )
+                    maxDict[ d ][ 'max' ] = EtoEtemp
+                    maxDict[ d ][ 'node' ] = i
+                resultDict[ d ][ 'node' + str( i ) ][ 'Ave' ][ 'PtoD' ] = numpy.average( resultDict[ d ][ 'node' + str( i ) ][ 'PtoD' ] )
+                resultDict[ d ][ 'node' + str( i ) ][ 'Ave' ][ 'DtoL' ] = numpy.average( resultDict[ d ][ 'node' + str( i ) ][ 'DtoL' ] )
+                resultDict[ d ][ 'node' + str( i ) ][ 'Ave' ][ 'LtoG' ] = numpy.average( resultDict[ d ][ 'node' + str( i ) ][ 'LtoG' ] )
 
-                resultDict[d][ 'node' + str(i)][ 'Std' ][ 'EtoE' ] = numpy.std(resultDict[d][ 'node' + str(i)][ 'EtoE' ] )
-                resultDict[d][ 'node' + str(i)][ 'Std' ][ 'PtoD' ] = numpy.std(resultDict[d][ 'node' + str(i)][ 'PtoD' ] )
-                resultDict[d][ 'node' + str(i)][ 'Std' ][ 'DtoL' ] = numpy.std(resultDict[d][ 'node' + str(i)][ 'DtoL' ] )
-                resultDict[d][ 'node' + str(i)][ 'Std' ][ 'LtoG' ] = numpy.std(resultDict[d][ 'node' + str(i)][ 'LtoG' ] )
+                resultDict[ d ][ 'node' + str( i ) ][ 'Std' ][ 'EtoE' ] = numpy.std( resultDict[ d ][ 'node' + str( i ) ][ 'EtoE' ] )
+                resultDict[ d ][ 'node' + str( i ) ][ 'Std' ][ 'PtoD' ] = numpy.std( resultDict[ d ][ 'node' + str( i ) ][ 'PtoD' ] )
+                resultDict[ d ][ 'node' + str( i ) ][ 'Std' ][ 'DtoL' ] = numpy.std( resultDict[ d ][ 'node' + str( i ) ][ 'DtoL' ] )
+                resultDict[ d ][ 'node' + str( i ) ][ 'Std' ][ 'LtoG' ] = numpy.std( resultDict[ d ][ 'node' + str( i ) ][ 'LtoG' ] )
 
-                main.log.report( "=====node{} Summary:=====".format( str(i) ) )
-                main.log.report( "=============Port {}=======".format( str(d) ) )
+                main.log.report( "=====node{} Summary:=====".format( str( i ) ) )
+                main.log.report( "=============Port {}=======".format( str( d ) ) )
                 main.log.report(
-                    "End to End average: {}".format( str(resultDict[d][ 'node' + str(i) ][ 'Ave' ][ 'EtoE' ] ) ) )
+                    "End to End average: {}".format( str( resultDict[ d ][ 'node' + str( i ) ][ 'Ave' ][ 'EtoE' ] ) ) )
                 main.log.report(
-                    "End to End Std: {}".format( str(resultDict[d][ 'node' + str(i) ][ 'Std' ][ 'EtoE' ] ) ) )
+                    "End to End Std: {}".format( str( resultDict[ d ][ 'node' + str( i ) ][ 'Std' ][ 'EtoE' ] ) ) )
                 main.log.report(
-                    "Package to Device average: {}".format( str(resultDict[d][ 'node' + str(i)][ 'Ave' ][ 'PtoD' ] ) ) )
+                    "Package to Device average: {}".format( str( resultDict[ d ][ 'node' + str( i ) ][ 'Ave' ][ 'PtoD' ] ) ) )
                 main.log.report(
-                    "Package to Device Std: {}".format( str( resultDict[d][ 'node' + str(i)][ 'Std' ][ 'PtoD' ] ) ))
+                    "Package to Device Std: {}".format( str( resultDict[ d ][ 'node' + str( i ) ][ 'Std' ][ 'PtoD' ] ) ) )
                 main.log.report(
-                    "Device to Link average: {}".format( str( resultDict[d][ 'node' + str(i)][ 'Ave' ][ 'DtoL' ] ) ) )
+                    "Device to Link average: {}".format( str( resultDict[ d ][ 'node' + str( i ) ][ 'Ave' ][ 'DtoL' ] ) ) )
                 main.log.report(
-                    "Device to Link Std: {}".format( str( resultDict[d][ 'node' + str(i)][ 'Std' ][ 'DtoL' ] ) ))
+                    "Device to Link Std: {}".format( str( resultDict[ d ][ 'node' + str( i ) ][ 'Std' ][ 'DtoL' ] ) ) )
                 main.log.report(
-                    "Link to Grapg average: {}".format( str( resultDict[d][ 'node' + str(i)][ 'Ave' ][ 'LtoG' ] ) ) )
+                    "Link to Grapg average: {}".format( str( resultDict[ d ][ 'node' + str( i ) ][ 'Ave' ][ 'LtoG' ] ) ) )
                 main.log.report(
-                    "Link to Grapg Std: {}".format( str( resultDict[d][ 'node' + str(i)][ 'Std' ][ 'LtoG' ] ) ) )
+                    "Link to Grapg Std: {}".format( str( resultDict[ d ][ 'node' + str( i ) ][ 'Std' ][ 'LtoG' ] ) ) )
 
         with open( main.dbFileName, "a" ) as dbFile:
             # Scale number
-            temp = str( main.numCtrls )
+            temp = str( main.Cluster.numCtrls )
             temp += ",'baremetal1'"
             # put result
             temp += "," + str( resultDict[ 'up' ][ 'node' + str( maxDict[ 'up' ][ 'node' ] ) ][ 'Ave' ][ 'EtoE' ] )
diff --git a/TestON/tests/SCPF/SCPFportLat/SCPFportLat.topo b/TestON/tests/SCPF/SCPFportLat/SCPFportLat.topo
index c840e11..684335a 100644
--- a/TestON/tests/SCPF/SCPFportLat/SCPFportLat.topo
+++ b/TestON/tests/SCPF/SCPFportLat/SCPFportLat.topo
@@ -2,104 +2,32 @@
 
     <COMPONENT>
 
-        <ONOSbench>
-            <host>localhost</host>
+        <ONOScell>
+            <host>localhost</host>  # ONOS "bench" machine
             <user>sdn</user>
             <password>rocks</password>
-            <type>OnosDriver</type>
+            <type>OnosClusterDriver</type>
             <connect_order>1</connect_order>
             <COMPONENTS>
-                <home>~/onos</home>
-                <nodes>7</nodes>
-                <prompt></prompt>
-            </COMPONENTS>
-        </ONOSbench>
-
-        <ONOScli1>
-            <host>localhost</host>
-            <user>sdn</user>
-            <password>rocks</password>
-            <type>OnosCliDriver</type>
-            <connect_order>2</connect_order>
-            <COMPONENTS>
+                <cluster_name></cluster_name>  # Used as a prefix for cluster components. Defaults to 'ONOS'
+                <diff_clihost></diff_clihost>  # if it has different host other than localhost for CLI. True or empty. OC# will be used if True.
                 <karaf_username></karaf_username>
                 <karaf_password></karaf_password>
-                <prompt></prompt>
+                <web_user></web_user>
+                <web_pass></web_pass>
+                <rest_port></rest_port>
+                <prompt></prompt>  # TODO: we technically need a few of these, one per component
+                <onos_home></onos_home>  # defines where onos home is
+                <nodes> 7 </nodes>  # number of nodes in the cluster
             </COMPONENTS>
-        </ONOScli1>
-
-        <ONOScli2>
-            <host>localhost</host>
-            <user>sdn</user>
-            <password>rocks</password>
-            <type>OnosCliDriver</type>
-            <connect_order>3</connect_order>
-            <COMPONENTS>
-                <prompt></prompt>
-            </COMPONENTS>
-        </ONOScli2>
-
-        <ONOScli3>
-            <host>localhost</host>
-            <user>sdn</user>
-            <password>rocks</password>
-            <type>OnosCliDriver</type>
-            <connect_order>4</connect_order>
-            <COMPONENTS>
-                <prompt></prompt>
-            </COMPONENTS>
-        </ONOScli3>
-
-        <ONOScli4>
-            <host>localhost</host>
-            <user>sdn</user>
-            <password>rocks</password>
-            <type>OnosCliDriver</type>
-            <connect_order>5</connect_order>
-            <COMPONENTS>
-                <prompt></prompt>
-            </COMPONENTS>
-        </ONOScli4>
-
-        <ONOScli5>
-            <host>localhost</host>
-            <user>sdn</user>
-            <password>rocks</password>
-            <type>OnosCliDriver</type>
-            <connect_order>6</connect_order>
-            <COMPONENTS>
-                <prompt></prompt>
-            </COMPONENTS>
-        </ONOScli5>
-
-        <ONOScli6>
-            <host>localhost</host>
-            <user>sdn</user>
-            <password>rocks</password>
-            <type>OnosCliDriver</type>
-            <connect_order>7</connect_order>
-            <COMPONENTS>
-                <prompt></prompt>
-            </COMPONENTS>
-        </ONOScli6>
-
-        <ONOScli7>
-            <host>localhost</host>
-            <user>sdn</user>
-            <password>rocks</password>
-            <type>OnosCliDriver</type>
-            <connect_order>8</connect_order>
-            <COMPONENTS>
-                <prompt></prompt>
-            </COMPONENTS>
-        </ONOScli7>
+        </ONOScell>
 
         <Mininet1>
             <host>OCN</host>
             <user>sdn</user>
             <password>rocks</password>
             <type>MininetCliDriver</type>
-            <connect_order>9</connect_order>
+            <connect_order>2</connect_order>
             <COMPONENTS>
                 <arg1> --custom ~/mininet/custom/topo-perf-2sw.py </arg1>
                 <arg2> --topo mytopo</arg2>
diff --git a/TestON/tests/SCPF/SCPFportLat/dependencies/portFunc.py b/TestON/tests/SCPF/SCPFportLat/dependencies/portFunc.py
index 4bbbfe1..f650521 100644
--- a/TestON/tests/SCPF/SCPFportLat/dependencies/portFunc.py
+++ b/TestON/tests/SCPF/SCPFportLat/dependencies/portFunc.py
@@ -57,11 +57,11 @@
         if len( resultText ) > 1:
             tsharkResultTime = int( float( resultText[1] ) * 1000.0 )
             resultFile.close()
-            for i in range( 1, main.numCtrls + 1 ):
+            for i in range( 1, main.Cluster.numCtrls + 1 ):
                 main.log.info( "================================================" )
                 # get onos metrics timestamps
                 try:
-                    response = json.loads( main.CLIs[i - 1].topologyEventsMetrics() )
+                    response = json.loads( main.Cluster.active( i - 1 ).CLI.topologyEventsMetrics() )
                     deviceTime = int( response.get( "topologyDeviceEventTimestamp" ).get( "value" ) )
                     main.log.info( "ONOS{} device Event timestemp: {}".format( i, deviceTime ) )