Changed copyMininetFile of onosdriver to scp function in clidriver

Change-Id: I52a11e7f97e727777e3ea891b453d4741fc32d1e
diff --git a/TestON/tests/SAMPscaleTopo/Dependency/multiovs.py b/TestON/tests/SAMPscaleTopo/Dependency/multiovs.py
new file mode 100755
index 0000000..0545013
--- /dev/null
+++ b/TestON/tests/SAMPscaleTopo/Dependency/multiovs.py
@@ -0,0 +1,274 @@
+#!/usr/bin/python
+
+"""
+Multiple ovsdb OVS!!
+
+We scale up by creating multiple ovsdb instances,
+each of which is shared by several OVS switches
+
+The shell may also be shared among switch instances,
+which causes switch.cmd() and switch.popen() to be
+delegated to the ovsdb instance.
+
+"""
+
+from mininet.net import Mininet
+from mininet.node import Node, OVSSwitch
+from mininet.node import OVSBridge
+from mininet.link import Link, OVSIntf
+from mininet.topo import LinearTopo, SingleSwitchTopo
+from mininet.topolib import TreeTopo
+from mininet.log import setLogLevel, info
+from mininet.cli import CLI
+from mininet.clean import Cleanup, sh
+
+from itertools import groupby
+from operator import attrgetter
+
+class OVSDB( Node ):
+    "Namespace for an OVSDB instance"
+
+    privateDirs = [ '/etc/openvswitch',
+                    '/var/run/openvswitch',
+                    '/var/log/openvswitch' ]
+
+    # Control network
+    ipBase = '172.123.123.0/24'
+    cnet = None
+    nat = None
+
+    @classmethod
+    def startControlNet( cls ):
+        "Start control net if necessary and return it"
+        cnet = cls.cnet
+        if not cnet:
+            info( '### Starting control network\n' )
+            cnet = Mininet( ipBase=cls.ipBase )
+            cswitch = cnet.addSwitch( 'ovsbr0', cls=OVSBridge )
+            # Add NAT - note this can conflict with data network NAT
+            info( '### Adding NAT for control and data networks'
+                  ' (use --nat flush=0 for data network)\n' )
+            cls.cnet = cnet
+            cls.nat = cnet.addNAT( 'ovsdbnat0')
+            cnet.start()
+            info( '### Control network started\n' )
+        return cnet
+
+    def stopControlNet( self ):
+        info( '\n### Stopping control network\n' )
+        cls = self.__class__
+        cls.cnet.stop()
+        info( '### Control network stopped\n' )
+
+    def addSwitch( self, switch ):
+        "Add a switch to our namespace"
+        # Attach first switch to cswitch!
+        self.switches.append( switch )
+
+    def delSwitch( self, switch ):
+        "Delete a switch from our namespace, and terminate if none left"
+        self.switches.remove( switch )
+        if not self.switches:
+            self.stopOVS()
+
+    ovsdbCount = 0
+
+    def startOVS( self ):
+        "Start new OVS instance"
+        self.cmd( 'ovsdb-tool create /etc/openvswitch/conf.db' )
+        self.cmd( 'ovsdb-server /etc/openvswitch/conf.db'
+                  ' -vfile:emer -vfile:err -vfile:info'
+                  ' --remote=punix:/var/run/openvswitch/db.sock '
+                  ' --log-file=/var/log/openvswitch/ovsdb-server.log'
+                  ' --pidfile=/var/run/openvswitch/ovsdb-server-mn.pid'
+                  ' --no-chdir'
+                  ' --detach' )
+
+        self.cmd( 'ovs-vswitchd unix:/var/run/openvswitch/db.sock'
+                  ' -vfile:emer -vfile:err -vfile:info'
+                  ' --mlockall --log-file=/var/log/openvswitch/ovs-vswitchd.log'
+                  ' --pidfile=/var/run/openvswitch/ovs-vswitchd-mn.pid'
+                  ' --no-chdir'
+                  ' --detach' )
+
+    def stopOVS( self ):
+        self.cmd( 'kill',
+                  '`cat /var/run/openvswitch/ovs-vswitchd-mn.pid`',
+                  '`cat /var/run/openvswitch/ovsdb-server-mn.pid`' )
+        self.cmd( 'wait' )
+        self.__class__.ovsdbCount -= 1
+        if self.__class__.ovsdbCount <= 0:
+            self.stopControlNet()
+
+    @classmethod
+    def cleanUpOVS( cls ):
+        "Clean up leftover ovsdb-server/ovs-vswitchd processes"
+        info( '*** Shutting down extra ovsdb-server/ovs-vswitchd processes\n' )
+        sh( 'pkill -f mn.pid' )
+
+    def self( self, *args, **kwargs ):
+        "A fake constructor that sets params and returns self"
+        self.params = kwargs
+        return self
+
+    def __init__( self, **kwargs ):
+        cls = self.__class__
+        cls.ovsdbCount += 1
+        cnet = self.startControlNet()
+        # Create a new ovsdb namespace
+        self.switches = []
+        name = 'ovsdb%d' % cls.ovsdbCount
+        kwargs.update( inNamespace=True )
+        kwargs.setdefault( 'privateDirs', self.privateDirs )
+        super( OVSDB, self ).__init__( name, **kwargs )
+        ovsdb = cnet.addHost( name, cls=self.self, **kwargs )
+        link = cnet.addLink( ovsdb, cnet.switches[ 0 ] )
+        cnet.switches[ 0 ].attach( link.intf2 )
+        ovsdb.configDefault()
+        ovsdb.setDefaultRoute( 'via %s' % self.nat.intfs[ 0 ].IP() )
+        ovsdb.startOVS()
+
+
+# Install cleanup callback
+Cleanup.addCleanupCallback( OVSDB.cleanUpOVS )
+
+
+class OVSSwitchNS( OVSSwitch ):
+    "OVS Switch in shared OVSNS namespace"
+
+    isSetup = False
+
+    @classmethod
+    def batchStartup( cls, switches ):
+        result = []
+        for ovsdb, switchGroup in groupby( switches, attrgetter( 'ovsdb') ):
+            switchGroup = list( switchGroup )
+            info( '(%s)' % ovsdb )
+            result += OVSSwitch.batchStartup( switchGroup, run=ovsdb.cmd )
+        return result
+
+    @classmethod
+    def batchShutdown( cls, switches ):
+        result = []
+        for ovsdb, switchGroup in groupby( switches, attrgetter( 'ovsdb') ):
+            switchGroup = list( switchGroup )
+            info( '(%s)' % ovsdb )
+            for switch in switches:
+                if switch.pid == ovsdb.pid:
+                    switch.pid = None
+                    switch.shell = None
+            result += OVSSwitch.batchShutdown( switchGroup, run=ovsdb.cmd )
+            for switch in switchGroup:
+                switch.ovsdbFree()
+        return result
+
+    # OVSDB allocation
+    groupSize = 64
+    switchCount = 0
+    lastOvsdb = None
+
+    @classmethod
+    def ovsdbAlloc( cls, switch ):
+        "Allocate (possibly new) OVSDB instance for switch"
+        if cls.switchCount % switch.groupSize == 0:
+            cls.lastOvsdb = OVSDB()
+        cls.switchCount += 1
+        cls.lastOvsdb.addSwitch( switch )
+        return cls.lastOvsdb
+
+    def ovsdbFree( self ):
+        "Deallocate OVSDB instance for switch"
+        self.ovsdb.delSwitch( self )
+
+    def startShell( self, *args, **kwargs ):
+        "Start shell in shared OVSDB namespace"
+        ovsdb = self.ovsdbAlloc( self )
+        kwargs.update( mnopts='-da %d ' % ovsdb.pid )
+        self.ns = [ 'net' ]
+        self.ovsdb = ovsdb
+        self._waiting = False
+        if self.privateShell:
+            super( OVSSwitchNS, self ).startShell( *args, **kwargs )
+        else:
+            # Delegate methods and initialize local vars
+            attrs = ( 'cmd', 'cmdPrint', 'sendCmd', 'waitOutput',
+                      'monitor', 'write', 'read',
+                      'pid', 'shell', 'stdout',)
+            for attr in attrs:
+                setattr( self, attr, getattr( ovsdb, attr ) )
+        self.defaultIntf().updateIP()
+
+    @property
+    def waiting( self ):
+        "Optionally delegated to ovsdb"
+        return self._waiting if self.privateShell else self.ovsdb.waiting
+
+    @waiting.setter
+    def waiting( self, value ):
+        "Optionally delegated to ovsdb (read only!)"
+        if self.privateShell:
+            _waiting = value
+
+    def start( self, controllers ):
+        "Update controller IP addresses if necessary"
+        for controller in controllers:
+            if controller.IP() == '127.0.0.1' and not controller.intfs:
+                controller.intfs[ 0 ] = self.ovsdb.nat.intfs[ 0 ]
+        super( OVSSwitchNS, self ).start( controllers )
+
+    def stop( self, *args, **kwargs ):
+        "Stop and free OVSDB namespace if necessary"
+        self.ovsdbFree()
+
+    def terminate( self, *args, **kwargs ):
+        if self.privateShell:
+            super( OVSSwitchNS, self ).terminate( *args, **kwargs )
+        else:
+            self.pid = None
+            self.shell= None
+
+    def defaultIntf( self ):
+        return self.ovsdb.defaultIntf()
+
+    def __init__( self, *args, **kwargs ):
+        """n: number of OVS instances per OVSDB
+           shell: run private shell/bash process? (False)
+           If shell is shared/not private, cmd() and popen() are
+           delegated to the OVSDB instance, which is different than
+           regular OVSSwitch semantics!!"""
+        self.groupSize = kwargs.pop( 'n', self.groupSize )
+        self.privateShell = kwargs.pop( 'shell', False )
+        super( OVSSwitchNS, self ).__init__( *args, **kwargs )
+
+class OVSLinkNS( Link ):
+    "OVSLink that supports OVSSwitchNS"
+
+    def __init__( self, node1, node2, **kwargs ):
+        "See Link.__init__() for options"
+        self.isPatchLink = False
+        if ( isinstance( node1, OVSSwitch ) and
+             isinstance( node2, OVSSwitch ) and
+             getattr( node1, 'ovsdb', None ) ==
+             getattr( node2, 'ovsdb', None ) ):
+            self.isPatchLink = True
+            kwargs.update( cls1=OVSIntf, cls2=OVSIntf )
+        Link.__init__( self, node1, node2, **kwargs )
+
+switches = { 'ovsns': OVSSwitchNS, 'ovsm': OVSSwitchNS }
+
+links = { 'ovs': OVSLinkNS }
+
+def test():
+    "Test OVSNS switch"
+    setLogLevel( 'info' )
+    topo = TreeTopo( depth=4, fanout=2 )
+    net = Mininet( topo=topo, switch=OVSSwitchNS )
+    # Add connectivity to controller which is on LAN or in root NS
+    # net.addNAT().configDefault()
+    net.start()
+    CLI( net )
+    net.stop()
+
+
+if __name__ == '__main__':
+    test()