CI matrix build + 20.04 fixes (#990)
Ubuntu 20.04 fixes:
- fixes sshd test
- speeds up examples/{treeping64,tree1024}.py
- debugging hacks/output for testLinkChange
- removes cfs from examples/popen.py
- improves nat in nodelib (netplan fixes?)
- makes some tests executable
- waits for switches to connect in tests to
avoid race conditions
-- adds mn -w option and wait CLI command
Changes:
- REMOVES default "-v" argument for Controller()
and adds verbose(=False) option; avoiding logging
makes it faster
- CHANGES waitConnected to wait for 5 seconds
as documented; we may wish to implement an argument
to -w to set this timeout
Issues?
- There may still be an issue with the ovs-netplan-clean
service causing the boot to hang ;-(
This commit is contained in:
@@ -9,7 +9,7 @@ jobs:
|
|||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-18.04, ubuntu-16.04]
|
os: [ubuntu-20.04, ubuntu-18.04, ubuntu-16.04]
|
||||||
python-version: [3.x, 2.x]
|
python-version: [3.x, 2.x]
|
||||||
steps:
|
steps:
|
||||||
- name: Check out Mininet source
|
- name: Check out Mininet source
|
||||||
@@ -47,12 +47,10 @@ jobs:
|
|||||||
export sudo="sudo env PATH=$PATH"
|
export sudo="sudo env PATH=$PATH"
|
||||||
export PYTHON=`which python`
|
export PYTHON=`which python`
|
||||||
rm -f pexpect.out
|
rm -f pexpect.out
|
||||||
$sudo $PYTHON mininet/test/runner.py -v -quick || \
|
$sudo $PYTHON mininet/test/runner.py -v -quick
|
||||||
(cat pexpect.out && exit 1)
|
|
||||||
- name: Run examples tests (quick)
|
- name: Run examples tests (quick)
|
||||||
run: |
|
run: |
|
||||||
export sudo="sudo env PATH=$PATH"
|
export sudo="sudo env PATH=$PATH"
|
||||||
export PYTHON=`which python`
|
export PYTHON=`which python`
|
||||||
rm -f pexpect.out
|
rm -f pexpect.out
|
||||||
$sudo $PYTHON examples/test/runner.py -v -quick || \
|
$sudo $PYTHON examples/test/runner.py -v -quick
|
||||||
(cat pexpect.out && exit 1)
|
|
||||||
|
|||||||
@@ -132,4 +132,4 @@ Bob Lantz
|
|||||||
Mininet Core Team
|
Mininet Core Team
|
||||||
|
|
||||||
[1]: https://travis-ci.org/mininet/mininet.svg?branch=master
|
[1]: https://travis-ci.org/mininet/mininet.svg?branch=master
|
||||||
[2]: https://github.com/mininet/mininet/workflows/mininet%20tests/badge.svg
|
[2]: https://github.com/mininet/mininet/workflows/mininet-tests/badge.svg
|
||||||
|
|||||||
@@ -284,6 +284,8 @@ class MininetRunner( object ):
|
|||||||
" Mininet's IP subnet, see the --ipbase option." )
|
" Mininet's IP subnet, see the --ipbase option." )
|
||||||
opts.add_option( '--version', action='callback', callback=version,
|
opts.add_option( '--version', action='callback', callback=version,
|
||||||
help='prints the version and exits' )
|
help='prints the version and exits' )
|
||||||
|
opts.add_option( '--wait', '-w', action='store_true',
|
||||||
|
default=False, help='wait for switches to connect' )
|
||||||
opts.add_option( '--cluster', type='string', default=None,
|
opts.add_option( '--cluster', type='string', default=None,
|
||||||
metavar='server1,server2...',
|
metavar='server1,server2...',
|
||||||
help=( 'run on multiple servers (experimental!)' ) )
|
help=( 'run on multiple servers (experimental!)' ) )
|
||||||
@@ -385,6 +387,7 @@ class MininetRunner( object ):
|
|||||||
ipBase=opts.ipbase, inNamespace=opts.innamespace,
|
ipBase=opts.ipbase, inNamespace=opts.innamespace,
|
||||||
xterms=opts.xterms, autoSetMacs=opts.mac,
|
xterms=opts.xterms, autoSetMacs=opts.mac,
|
||||||
autoStaticArp=opts.arp, autoPinCpus=opts.pin,
|
autoStaticArp=opts.arp, autoPinCpus=opts.pin,
|
||||||
|
waitConnected=opts.wait,
|
||||||
listenPort=opts.listenport )
|
listenPort=opts.listenport )
|
||||||
|
|
||||||
if opts.ensure_value( 'nat', False ):
|
if opts.ensure_value( 'nat', False ):
|
||||||
|
|||||||
+1
-1
@@ -53,7 +53,7 @@ def testHostWithPrivateDirs():
|
|||||||
'/var/mn' ]
|
'/var/mn' ]
|
||||||
host = partial( Host,
|
host = partial( Host,
|
||||||
privateDirs=privateDirs )
|
privateDirs=privateDirs )
|
||||||
net = Mininet( topo=topo, host=host )
|
net = Mininet( topo=topo, host=host, waitConnected=True )
|
||||||
net.start()
|
net.start()
|
||||||
directories = [ directory[ 0 ] if isinstance( directory, tuple )
|
directories = [ directory[ 0 ] if isinstance( directory, tuple )
|
||||||
else directory for directory in privateDirs ]
|
else directory for directory in privateDirs ]
|
||||||
|
|||||||
+3
-2
@@ -875,7 +875,7 @@ class MininetCluster( Mininet ):
|
|||||||
|
|
||||||
def testNsTunnels( remote='ubuntu2', link=RemoteGRELink ):
|
def testNsTunnels( remote='ubuntu2', link=RemoteGRELink ):
|
||||||
"Test tunnels between nodes in namespaces"
|
"Test tunnels between nodes in namespaces"
|
||||||
net = Mininet( host=RemoteHost, link=link )
|
net = Mininet( host=RemoteHost, link=link, waitConnected=True )
|
||||||
h1 = net.addHost( 'h1')
|
h1 = net.addHost( 'h1')
|
||||||
h2 = net.addHost( 'h2', server=remote )
|
h2 = net.addHost( 'h2', server=remote )
|
||||||
net.addLink( h1, h2 )
|
net.addLink( h1, h2 )
|
||||||
@@ -891,7 +891,8 @@ def testNsTunnels( remote='ubuntu2', link=RemoteGRELink ):
|
|||||||
def testRemoteNet( remote='ubuntu2', link=RemoteGRELink ):
|
def testRemoteNet( remote='ubuntu2', link=RemoteGRELink ):
|
||||||
"Test remote Node classes"
|
"Test remote Node classes"
|
||||||
info( '*** Remote Node Test\n' )
|
info( '*** Remote Node Test\n' )
|
||||||
net = Mininet( host=RemoteHost, switch=RemoteOVSSwitch, link=link )
|
net = Mininet( host=RemoteHost, switch=RemoteOVSSwitch, link=link,
|
||||||
|
waitConnected=True )
|
||||||
c0 = net.addController( 'c0' )
|
c0 = net.addController( 'c0' )
|
||||||
# Make sure controller knows its non-loopback address
|
# Make sure controller knows its non-loopback address
|
||||||
Intf( 'eth0', node=c0 ).updateIP()
|
Intf( 'eth0', node=c0 ).updateIP()
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ from mininet.log import setLogLevel
|
|||||||
|
|
||||||
def perf(Link):
|
def perf(Link):
|
||||||
"Test connectivity nand performance over Link"
|
"Test connectivity nand performance over Link"
|
||||||
net = Mininet( host=RemoteHost, link=Link )
|
net = Mininet( host=RemoteHost, link=Link, waitConnected=True )
|
||||||
h1 = net.addHost( 'h1')
|
h1 = net.addHost( 'h1')
|
||||||
h2 = net.addHost( 'h2', server='ubuntu2' )
|
h2 = net.addHost( 'h2', server='ubuntu2' )
|
||||||
net.addLink( h1, h2 )
|
net.addLink( h1, h2 )
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ class MultiSwitch( OVSSwitch ):
|
|||||||
return OVSSwitch.start( self, [ cmap[ self.name ] ] )
|
return OVSSwitch.start( self, [ cmap[ self.name ] ] )
|
||||||
|
|
||||||
topo = TreeTopo( depth=2, fanout=2 )
|
topo = TreeTopo( depth=2, fanout=2 )
|
||||||
net = Mininet( topo=topo, switch=MultiSwitch, build=False )
|
net = Mininet( topo=topo, switch=MultiSwitch, build=False, waitConnected=True )
|
||||||
for c in [ c0, c1 ]:
|
for c in [ c0, c1 ]:
|
||||||
net.addController(c)
|
net.addController(c)
|
||||||
net.build()
|
net.build()
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ from mininet.log import setLogLevel, info
|
|||||||
def multiControllerNet():
|
def multiControllerNet():
|
||||||
"Create a network from semi-scratch with multiple controllers."
|
"Create a network from semi-scratch with multiple controllers."
|
||||||
|
|
||||||
net = Mininet( controller=Controller, switch=OVSSwitch )
|
net = Mininet( controller=Controller, switch=OVSSwitch,
|
||||||
|
waitConnected=True )
|
||||||
|
|
||||||
info( "*** Creating (reference) controllers\n" )
|
info( "*** Creating (reference) controllers\n" )
|
||||||
c1 = net.addController( 'c1', port=6633 )
|
c1 = net.addController( 'c1', port=6633 )
|
||||||
|
|||||||
@@ -123,7 +123,8 @@ def run():
|
|||||||
|
|
||||||
info( '* Creating Control Network\n' )
|
info( '* Creating Control Network\n' )
|
||||||
ctopo = ControlNetwork( n=4, dataController=DataController )
|
ctopo = ControlNetwork( n=4, dataController=DataController )
|
||||||
cnet = Mininet( topo=ctopo, ipBase='192.168.123.0/24', controller=None )
|
cnet = Mininet( topo=ctopo, ipBase='192.168.123.0/24',
|
||||||
|
controller=None, waitConnected=True )
|
||||||
info( '* Adding Control Network Controller\n')
|
info( '* Adding Control Network Controller\n')
|
||||||
cnet.addController( 'cc0', controller=Controller )
|
cnet.addController( 'cc0', controller=Controller )
|
||||||
info( '* Starting Control Network\n')
|
info( '* Starting Control Network\n')
|
||||||
@@ -133,7 +134,8 @@ def run():
|
|||||||
topo = TreeTopo( depth=2, fanout=2 )
|
topo = TreeTopo( depth=2, fanout=2 )
|
||||||
# UserSwitch so we can easily test failover
|
# UserSwitch so we can easily test failover
|
||||||
sw = partial( UserSwitch, opts='--inactivity-probe=1 --max-backoff=1' )
|
sw = partial( UserSwitch, opts='--inactivity-probe=1 --max-backoff=1' )
|
||||||
net = Mininet( topo=topo, switch=sw, controller=None )
|
net = Mininet( topo=topo, switch=sw, controller=None,
|
||||||
|
waitConnected=True )
|
||||||
info( '* Adding Controllers to Data Network\n' )
|
info( '* Adding Controllers to Data Network\n' )
|
||||||
for host in cnet.hosts:
|
for host in cnet.hosts:
|
||||||
if isinstance(host, Controller):
|
if isinstance(host, Controller):
|
||||||
|
|||||||
+1
-1
@@ -52,7 +52,7 @@ def bwtest( cpuLimits, period_us=100000, seconds=10 ):
|
|||||||
period_us=period_us,
|
period_us=period_us,
|
||||||
cpu=.5*cpu )
|
cpu=.5*cpu )
|
||||||
try:
|
try:
|
||||||
net = Mininet( topo=topo, host=host )
|
net = Mininet( topo=topo, host=host, waitConnected=True )
|
||||||
# pylint: disable=bare-except
|
# pylint: disable=bare-except
|
||||||
except:
|
except:
|
||||||
info( '*** Skipping scheduler %s and cleaning up\n' % sched )
|
info( '*** Skipping scheduler %s and cleaning up\n' % sched )
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ def emptyNet():
|
|||||||
|
|
||||||
"Create an empty network and add nodes to it."
|
"Create an empty network and add nodes to it."
|
||||||
|
|
||||||
net = Mininet( controller=Controller )
|
net = Mininet( controller=Controller, waitConnected=True )
|
||||||
|
|
||||||
info( '*** Adding controller\n' )
|
info( '*** Adding controller\n' )
|
||||||
net.addController( 'c0' )
|
net.addController( 'c0' )
|
||||||
|
|||||||
+1
-1
@@ -38,7 +38,7 @@ if __name__ == '__main__':
|
|||||||
checkIntf( intfName )
|
checkIntf( intfName )
|
||||||
|
|
||||||
info( '*** Creating network\n' )
|
info( '*** Creating network\n' )
|
||||||
net = Mininet( topo=TreeTopo( depth=1, fanout=2 ) )
|
net = Mininet( topo=TreeTopo( depth=1, fanout=2 ), waitConnected=True )
|
||||||
|
|
||||||
switch = net.switches[ 0 ]
|
switch = net.switches[ 0 ]
|
||||||
info( '*** Adding hardware interface', intfName, 'to switch',
|
info( '*** Adding hardware interface', intfName, 'to switch',
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ from mininet.link import TCLink
|
|||||||
|
|
||||||
def intfOptions():
|
def intfOptions():
|
||||||
"run various traffic control commands on a single interface"
|
"run various traffic control commands on a single interface"
|
||||||
net = Mininet( autoStaticArp=True )
|
net = Mininet( autoStaticArp=True, waitConnected=True )
|
||||||
net.addController( 'c0' )
|
net.addController( 'c0' )
|
||||||
h1 = net.addHost( 'h1' )
|
h1 = net.addHost( 'h1' )
|
||||||
h2 = net.addHost( 'h2' )
|
h2 = net.addHost( 'h2' )
|
||||||
|
|||||||
+2
-2
@@ -34,7 +34,7 @@ def limit( bw=10, cpu=.1 ):
|
|||||||
'Skipping this test\n' )
|
'Skipping this test\n' )
|
||||||
continue
|
continue
|
||||||
host = custom( CPULimitedHost, sched=sched, cpu=cpu )
|
host = custom( CPULimitedHost, sched=sched, cpu=cpu )
|
||||||
net = Mininet( topo=myTopo, intf=intf, host=host )
|
net = Mininet( topo=myTopo, intf=intf, host=host, waitConnected=True )
|
||||||
net.start()
|
net.start()
|
||||||
testLinkLimit( net, bw=bw )
|
testLinkLimit( net, bw=bw )
|
||||||
net.runCpuLimitTest( cpu=cpu )
|
net.runCpuLimitTest( cpu=cpu )
|
||||||
@@ -43,7 +43,7 @@ def limit( bw=10, cpu=.1 ):
|
|||||||
def verySimpleLimit( bw=150 ):
|
def verySimpleLimit( bw=150 ):
|
||||||
"Absurdly simple limiting test"
|
"Absurdly simple limiting test"
|
||||||
intf = custom( TCIntf, bw=bw )
|
intf = custom( TCIntf, bw=bw )
|
||||||
net = Mininet( intf=intf )
|
net = Mininet( intf=intf, waitConnected=True )
|
||||||
h1, h2 = net.addHost( 'h1' ), net.addHost( 'h2' )
|
h1, h2 = net.addHost( 'h1' ), net.addHost( 'h2' )
|
||||||
net.addLink( h1, h2 )
|
net.addLink( h1, h2 )
|
||||||
net.start()
|
net.start()
|
||||||
|
|||||||
@@ -83,10 +83,10 @@ def linearBandwidthTest( lengths ):
|
|||||||
info( "*** testing", datapath, "datapath\n" )
|
info( "*** testing", datapath, "datapath\n" )
|
||||||
Switch = switches[ datapath ]
|
Switch = switches[ datapath ]
|
||||||
results[ datapath ] = []
|
results[ datapath ] = []
|
||||||
link = partial( TCLink, delay='2ms', bw=10 )
|
link = partial( TCLink, delay='30ms', bw=100 )
|
||||||
net = Mininet( topo=topo, switch=Switch,
|
net = Mininet( topo=topo, switch=Switch,
|
||||||
controller=Controller, waitConnected=True,
|
controller=Controller, link=link,
|
||||||
link=link )
|
waitConnected=True )
|
||||||
net.start()
|
net.start()
|
||||||
info( "*** testing basic connectivity\n" )
|
info( "*** testing basic connectivity\n" )
|
||||||
for n in lengths:
|
for n in lengths:
|
||||||
@@ -99,7 +99,7 @@ def linearBandwidthTest( lengths ):
|
|||||||
src.cmd( 'telnet', dst.IP(), '5001' )
|
src.cmd( 'telnet', dst.IP(), '5001' )
|
||||||
info( "testing", src.name, "<->", dst.name, '\n' )
|
info( "testing", src.name, "<->", dst.name, '\n' )
|
||||||
# serverbw = received; _clientbw = buffered
|
# serverbw = received; _clientbw = buffered
|
||||||
serverbw, _clientbw = net.iperf( [ src, dst ], seconds=10 )
|
serverbw, _clientbw = net.iperf( [ src, dst ], seconds=5 )
|
||||||
info( serverbw, '\n' )
|
info( serverbw, '\n' )
|
||||||
flush()
|
flush()
|
||||||
results[ datapath ] += [ ( n, serverbw ) ]
|
results[ datapath ] += [ ( n, serverbw ) ]
|
||||||
@@ -117,6 +117,6 @@ def linearBandwidthTest( lengths ):
|
|||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
lg.setLogLevel( 'info' )
|
lg.setLogLevel( 'info' )
|
||||||
sizes = [ 1, 10, 20, 40, 60, 80 ]
|
sizes = [ 1, 2, 3, 4 ]
|
||||||
info( "*** Running linearBandwidthTest", sizes, '\n' )
|
info( "*** Running linearBandwidthTest", sizes, '\n' )
|
||||||
linearBandwidthTest( sizes )
|
linearBandwidthTest( sizes )
|
||||||
|
|||||||
@@ -79,7 +79,8 @@ class NetworkTopo( Topo ):
|
|||||||
def run():
|
def run():
|
||||||
"Test linux router"
|
"Test linux router"
|
||||||
topo = NetworkTopo()
|
topo = NetworkTopo()
|
||||||
net = Mininet( topo=topo ) # controller is used by s1-s3
|
net = Mininet( topo=topo,
|
||||||
|
waitConnected=True ) # controller is used by s1-s3
|
||||||
net.start()
|
net.start()
|
||||||
info( '*** Routing Table on Router:\n' )
|
info( '*** Routing Table on Router:\n' )
|
||||||
info( net[ 'r0' ].cmd( 'route' ) )
|
info( net[ 'r0' ].cmd( 'route' ) )
|
||||||
|
|||||||
@@ -107,7 +107,8 @@ def moveHost( host, oldSwitch, newSwitch, newPort=None ):
|
|||||||
def mobilityTest():
|
def mobilityTest():
|
||||||
"A simple test of mobility"
|
"A simple test of mobility"
|
||||||
info( '* Simple mobility test\n' )
|
info( '* Simple mobility test\n' )
|
||||||
net = Mininet( topo=LinearTopo( 3 ), switch=MobilitySwitch )
|
net = Mininet( topo=LinearTopo( 3 ), switch=MobilitySwitch,
|
||||||
|
waitConnected=True )
|
||||||
info( '* Starting network:\n' )
|
info( '* Starting network:\n' )
|
||||||
net.start()
|
net.start()
|
||||||
printConnections( net.switches )
|
printConnections( net.switches )
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ from mininet.topo import Topo
|
|||||||
def runMultiLink():
|
def runMultiLink():
|
||||||
"Create and run multiple link network"
|
"Create and run multiple link network"
|
||||||
topo = simpleMultiLinkTopo( n=2 )
|
topo = simpleMultiLinkTopo( n=2 )
|
||||||
net = Mininet( topo=topo )
|
net = Mininet( topo=topo, waitConnected=True )
|
||||||
net.start()
|
net.start()
|
||||||
CLI( net )
|
CLI( net )
|
||||||
net.stop()
|
net.stop()
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ def monitorFiles( outfiles, seconds, timeoutms ):
|
|||||||
def monitorTest( N=3, seconds=3 ):
|
def monitorTest( N=3, seconds=3 ):
|
||||||
"Run pings and monitor multiple hosts"
|
"Run pings and monitor multiple hosts"
|
||||||
topo = SingleSwitchTopo( N )
|
topo = SingleSwitchTopo( N )
|
||||||
net = Mininet( topo )
|
net = Mininet( topo, waitConnected=True )
|
||||||
net.start()
|
net.start()
|
||||||
hosts = net.hosts
|
hosts = net.hosts
|
||||||
info( "Starting test...\n" )
|
info( "Starting test...\n" )
|
||||||
|
|||||||
@@ -22,7 +22,8 @@ if __name__ == '__main__':
|
|||||||
info( "*** Initializing Mininet and kernel modules\n" )
|
info( "*** Initializing Mininet and kernel modules\n" )
|
||||||
OVSKernelSwitch.setup()
|
OVSKernelSwitch.setup()
|
||||||
info( "*** Creating network\n" )
|
info( "*** Creating network\n" )
|
||||||
network = Mininet( TreeTopo( depth=2, fanout=2 ), switch=OVSKernelSwitch )
|
network = Mininet( TreeTopo( depth=2, fanout=2), switch=OVSKernelSwitch,
|
||||||
|
waitConnected=True )
|
||||||
info( "*** Starting network\n" )
|
info( "*** Starting network\n" )
|
||||||
network.start()
|
network.start()
|
||||||
info( "*** Running ping test\n" )
|
info( "*** Running ping test\n" )
|
||||||
|
|||||||
+1
-1
@@ -12,7 +12,7 @@ from mininet.topolib import TreeNet
|
|||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
lg.setLogLevel( 'info')
|
lg.setLogLevel( 'info')
|
||||||
net = TreeNet( depth=1, fanout=4 )
|
net = TreeNet( depth=1, fanout=4, waitConnected=True )
|
||||||
# Add NAT connectivity
|
# Add NAT connectivity
|
||||||
net.addNAT().configDefault()
|
net.addNAT().configDefault()
|
||||||
net.start()
|
net.start()
|
||||||
|
|||||||
+1
-1
@@ -57,7 +57,7 @@ class InternetTopo(Topo):
|
|||||||
def run():
|
def run():
|
||||||
"Create network and run the CLI"
|
"Create network and run the CLI"
|
||||||
topo = InternetTopo()
|
topo = InternetTopo()
|
||||||
net = Mininet(topo=topo)
|
net = Mininet(topo=topo, waitConnected=True )
|
||||||
net.start()
|
net.start()
|
||||||
CLI(net)
|
CLI(net)
|
||||||
net.stop()
|
net.stop()
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ def testPortNumbering():
|
|||||||
mid-level API) and check that implicit and
|
mid-level API) and check that implicit and
|
||||||
explicit port numbering works as expected."""
|
explicit port numbering works as expected."""
|
||||||
|
|
||||||
net = Mininet( controller=Controller )
|
net = Mininet( controller=Controller, waitConnected=True )
|
||||||
|
|
||||||
info( '*** Adding controller\n' )
|
info( '*** Adding controller\n' )
|
||||||
net.addController( 'c0' )
|
net.addController( 'c0' )
|
||||||
|
|||||||
+3
-7
@@ -5,19 +5,15 @@ This example monitors a number of hosts using host.popen() and
|
|||||||
pmonitor()
|
pmonitor()
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
from mininet.net import Mininet
|
from mininet.net import Mininet
|
||||||
from mininet.node import CPULimitedHost
|
|
||||||
from mininet.topo import SingleSwitchTopo
|
from mininet.topo import SingleSwitchTopo
|
||||||
from mininet.log import setLogLevel, info
|
from mininet.log import setLogLevel, info
|
||||||
from mininet.util import custom, pmonitor
|
from mininet.util import pmonitor
|
||||||
|
|
||||||
def monitorhosts( hosts=5, sched='cfs' ):
|
def monitorhosts( hosts=5 ):
|
||||||
"Start a bunch of pings and monitor them using popen"
|
"Start a bunch of pings and monitor them using popen"
|
||||||
mytopo = SingleSwitchTopo( hosts )
|
mytopo = SingleSwitchTopo( hosts )
|
||||||
cpu = .5 / hosts
|
net = Mininet( topo=mytopo, waitConnected=True )
|
||||||
myhost = custom( CPULimitedHost, cpu=cpu, sched=sched )
|
|
||||||
net = Mininet( topo=mytopo, host=myhost )
|
|
||||||
net.start()
|
net.start()
|
||||||
# Start a bunch of pings
|
# Start a bunch of pings
|
||||||
popens = {}
|
popens = {}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ from signal import SIGINT
|
|||||||
def pmonitorTest( N=3, seconds=10 ):
|
def pmonitorTest( N=3, seconds=10 ):
|
||||||
"Run pings and monitor multiple hosts using pmonitor"
|
"Run pings and monitor multiple hosts using pmonitor"
|
||||||
topo = SingleSwitchTopo( N )
|
topo = SingleSwitchTopo( N )
|
||||||
net = Mininet( topo )
|
net = Mininet( topo, waitConnected=True )
|
||||||
net.start()
|
net.start()
|
||||||
hosts = net.hosts
|
hosts = net.hosts
|
||||||
info( "Starting test...\n" )
|
info( "Starting test...\n" )
|
||||||
|
|||||||
+1
-1
@@ -29,7 +29,7 @@ from mininet.util import waitListening
|
|||||||
def TreeNet( depth=1, fanout=2, **kwargs ):
|
def TreeNet( depth=1, fanout=2, **kwargs ):
|
||||||
"Convenience function for creating tree networks."
|
"Convenience function for creating tree networks."
|
||||||
topo = TreeTopo( depth, fanout )
|
topo = TreeTopo( depth, fanout )
|
||||||
return Mininet( topo, **kwargs )
|
return Mininet( topo, waitConnected=True, **kwargs )
|
||||||
|
|
||||||
def connectToRootNS( network, switch, ip, routes ):
|
def connectToRootNS( network, switch, ip, routes ):
|
||||||
"""Connect hosts to root namespace via switch. Starts network.
|
"""Connect hosts to root namespace via switch. Starts network.
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ class clusterSanityCheck( unittest.TestCase ):
|
|||||||
def testClusterPingAll( self ):
|
def testClusterPingAll( self ):
|
||||||
p = pexpect.spawn( 'python -m mininet.examples.clusterSanity' )
|
p = pexpect.spawn( 'python -m mininet.examples.clusterSanity' )
|
||||||
p.expect( self.prompt )
|
p.expect( self.prompt )
|
||||||
|
p.sendline( 'py net.waitConnected()' )
|
||||||
|
p.expect( self.prompt )
|
||||||
p.sendline( 'pingall' )
|
p.sendline( 'pingall' )
|
||||||
p.expect ( '(\d+)% dropped' )
|
p.expect ( '(\d+)% dropped' )
|
||||||
percent = int( p.match.group( 1 ) ) if p.match else -1
|
percent = int( p.match.group( 1 ) ) if p.match else -1
|
||||||
|
|||||||
Regular → Executable
Regular → Executable
@@ -16,7 +16,8 @@ class testSSHD( unittest.TestCase ):
|
|||||||
"Log into ssh server, check banner, then exit"
|
"Log into ssh server, check banner, then exit"
|
||||||
# Note: this test will fail if "Welcome" is not in the sshd banner
|
# Note: this test will fail if "Welcome" is not in the sshd banner
|
||||||
# and '#'' or '$'' are not in the prompt
|
# and '#'' or '$'' are not in the prompt
|
||||||
p = pexpect.spawn( 'ssh -i /tmp/ssh/test_rsa %s' % ip, timeout=10 )
|
ssh = 'ssh -o StrictHostKeyChecking=no -i /tmp/ssh/test_rsa ' + ip
|
||||||
|
p = pexpect.spawn( ssh, timeout=5 )
|
||||||
while True:
|
while True:
|
||||||
index = p.expect( self.opts )
|
index = p.expect( self.opts )
|
||||||
if index == 0:
|
if index == 0:
|
||||||
@@ -57,4 +58,3 @@ class testSSHD( unittest.TestCase ):
|
|||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
||||||
|
|||||||
Regular → Executable
@@ -9,10 +9,13 @@ and running sysctl -p. Check util/sysctl_addon.
|
|||||||
|
|
||||||
from mininet.cli import CLI
|
from mininet.cli import CLI
|
||||||
from mininet.log import setLogLevel
|
from mininet.log import setLogLevel
|
||||||
from mininet.node import OVSSwitch
|
from mininet.node import OVSSwitch, Host
|
||||||
from mininet.topolib import TreeNet
|
from mininet.topolib import TreeNet
|
||||||
|
from mininet.examples.treeping64 import HostV4, QuietController
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
setLogLevel( 'info' )
|
setLogLevel( 'info' )
|
||||||
network = TreeNet( depth=2, fanout=32, switch=OVSSwitch )
|
network = TreeNet( depth=2, fanout=32, host=HostV4,
|
||||||
|
switch=OVSSwitch, controller=QuietController,
|
||||||
|
waitConnected=True)
|
||||||
network.run( CLI, network )
|
network.run( CLI, network )
|
||||||
|
|||||||
+18
-5
@@ -4,21 +4,34 @@
|
|||||||
|
|
||||||
|
|
||||||
from mininet.log import setLogLevel, info
|
from mininet.log import setLogLevel, info
|
||||||
from mininet.node import UserSwitch, OVSKernelSwitch # , KernelSwitch
|
from mininet.node import UserSwitch, OVSKernelSwitch, Host, Controller
|
||||||
from mininet.topolib import TreeNet
|
from mininet.topolib import TreeNet
|
||||||
|
|
||||||
|
|
||||||
|
class HostV4( Host ):
|
||||||
|
"Try to IPv6 and its awful neighbor discovery"
|
||||||
|
def __init__( self, *args, **kwargs ):
|
||||||
|
super( HostV4, self ).__init__( *args, **kwargs )
|
||||||
|
cfgs = [ 'all.disable_ipv6=1', 'default.disable_ipv6=1',
|
||||||
|
'default.autoconf=0', 'lo.autoconf=0' ]
|
||||||
|
for cfg in cfgs:
|
||||||
|
self.cmd( 'sysctl -w net.ipv6.conf.' + cfg )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def treePing64():
|
def treePing64():
|
||||||
"Run ping test on 64-node tree networks."
|
"Run ping test on 64-node tree networks."
|
||||||
|
|
||||||
results = {}
|
results = {}
|
||||||
switches = { # 'reference kernel': KernelSwitch,
|
switches = { 'reference user': UserSwitch,
|
||||||
'reference user': UserSwitch,
|
'Open vSwitch kernel': OVSKernelSwitch }
|
||||||
'Open vSwitch kernel': OVSKernelSwitch }
|
|
||||||
|
|
||||||
for name in switches:
|
for name in switches:
|
||||||
info( "*** Testing", name, "datapath\n" )
|
info( "*** Testing", name, "datapath\n" )
|
||||||
switch = switches[ name ]
|
switch = switches[ name ]
|
||||||
network = TreeNet( depth=2, fanout=8, switch=switch )
|
network = TreeNet( depth=2, fanout=8, switch=switch,
|
||||||
|
waitConnected=True )
|
||||||
result = network.run( network.pingAll )
|
result = network.run( network.pingAll )
|
||||||
results[ name ] = result
|
results[ name ] = result
|
||||||
|
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ def exampleAllHosts( vlan ):
|
|||||||
|
|
||||||
# Start a basic network using our VLANHost
|
# Start a basic network using our VLANHost
|
||||||
topo = SingleSwitchTopo( k=2 )
|
topo = SingleSwitchTopo( k=2 )
|
||||||
net = Mininet( host=host, topo=topo )
|
net = Mininet( host=host, topo=topo, waitConnected=True )
|
||||||
net.start()
|
net.start()
|
||||||
CLI( net )
|
CLI( net )
|
||||||
net.stop()
|
net.stop()
|
||||||
@@ -96,7 +96,7 @@ class VLANStarTopo( Topo ):
|
|||||||
def exampleCustomTags():
|
def exampleCustomTags():
|
||||||
"""Simple example that exercises VLANStarTopo"""
|
"""Simple example that exercises VLANStarTopo"""
|
||||||
|
|
||||||
net = Mininet( topo=VLANStarTopo() )
|
net = Mininet( topo=VLANStarTopo(), waitConnected=True )
|
||||||
net.start()
|
net.start()
|
||||||
CLI( net )
|
CLI( net )
|
||||||
net.stop()
|
net.stop()
|
||||||
|
|||||||
@@ -399,6 +399,10 @@ class CLI( Cmd ):
|
|||||||
error( 'invalid command: '
|
error( 'invalid command: '
|
||||||
'switch <switch name> {start, stop}\n' )
|
'switch <switch name> {start, stop}\n' )
|
||||||
|
|
||||||
|
def do_wait( self, line ):
|
||||||
|
"Wait until all switches have connected to a controller"
|
||||||
|
self.mn.waitConnected()
|
||||||
|
|
||||||
def default( self, line ):
|
def default( self, line ):
|
||||||
"""Called on an input line when the command prefix is not recognized.
|
"""Called on an input line when the command prefix is not recognized.
|
||||||
Overridden to run shell commands when a node is the first
|
Overridden to run shell commands when a node is the first
|
||||||
|
|||||||
+1
-1
@@ -173,7 +173,7 @@ class Mininet( object ):
|
|||||||
if topo and build:
|
if topo and build:
|
||||||
self.build()
|
self.build()
|
||||||
|
|
||||||
def waitConnected( self, timeout=None, delay=.5 ):
|
def waitConnected( self, timeout=5, delay=.5 ):
|
||||||
"""wait for each switch to connect to a controller,
|
"""wait for each switch to connect to a controller,
|
||||||
up to 5 seconds
|
up to 5 seconds
|
||||||
timeout: time to wait, or None to wait indefinitely
|
timeout: time to wait, or None to wait indefinitely
|
||||||
|
|||||||
+4
-2
@@ -1382,10 +1382,12 @@ class Controller( Node ):
|
|||||||
OpenFlow controller."""
|
OpenFlow controller."""
|
||||||
|
|
||||||
def __init__( self, name, inNamespace=False, command='controller',
|
def __init__( self, name, inNamespace=False, command='controller',
|
||||||
cargs='-v ptcp:%d', cdir=None, ip="127.0.0.1",
|
cargs='ptcp:%d', cdir=None, ip="127.0.0.1",
|
||||||
port=6653, protocol='tcp', **params ):
|
port=6653, protocol='tcp', verbose=False, **params ):
|
||||||
self.command = command
|
self.command = command
|
||||||
self.cargs = cargs
|
self.cargs = cargs
|
||||||
|
if verbose:
|
||||||
|
cargs = '-v ' + cargs
|
||||||
self.cdir = cdir
|
self.cdir = cdir
|
||||||
# Accept 'ip:port' syntax as shorthand
|
# Accept 'ip:port' syntax as shorthand
|
||||||
if ':' in ip:
|
if ':' in ip:
|
||||||
|
|||||||
+24
-14
@@ -84,13 +84,35 @@ class NAT( Node ):
|
|||||||
self.flush = flush
|
self.flush = flush
|
||||||
self.forwardState = self.cmd( 'sysctl -n net.ipv4.ip_forward' ).strip()
|
self.forwardState = self.cmd( 'sysctl -n net.ipv4.ip_forward' ).strip()
|
||||||
|
|
||||||
|
def setManualConfig( self, intf ):
|
||||||
|
"""Prevent network-manager/networkd from messing with our interface
|
||||||
|
by specifying manual configuration in /etc/network/interfaces"""
|
||||||
|
cfile = '/etc/network/interfaces'
|
||||||
|
line = '\niface %s inet manual\n' % intf
|
||||||
|
try:
|
||||||
|
with open( cfile ) as f:
|
||||||
|
config = f.read()
|
||||||
|
except IOError:
|
||||||
|
config = ''
|
||||||
|
if ( line ) not in config:
|
||||||
|
info( '*** Adding "' + line.strip() + '" to ' + cfile + '\n' )
|
||||||
|
with open( cfile, 'a' ) as f:
|
||||||
|
f.write( line )
|
||||||
|
# Probably need to restart network manager to be safe -
|
||||||
|
# hopefully this won't disconnect you
|
||||||
|
self.cmd( 'service network-manager restart || netplan apply' )
|
||||||
|
|
||||||
def config( self, **params ):
|
def config( self, **params ):
|
||||||
"""Configure the NAT and iptables"""
|
"""Configure the NAT and iptables"""
|
||||||
super( NAT, self).config( **params )
|
|
||||||
|
|
||||||
if not self.localIntf:
|
if not self.localIntf:
|
||||||
self.localIntf = self.defaultIntf()
|
self.localIntf = self.defaultIntf()
|
||||||
|
|
||||||
|
self.setManualConfig( self.localIntf )
|
||||||
|
|
||||||
|
# Now we can configure manually without interference
|
||||||
|
super( NAT, self).config( **params )
|
||||||
|
|
||||||
if self.flush:
|
if self.flush:
|
||||||
self.cmd( 'sysctl net.ipv4.ip_forward=0' )
|
self.cmd( 'sysctl net.ipv4.ip_forward=0' )
|
||||||
self.cmd( 'iptables -F' )
|
self.cmd( 'iptables -F' )
|
||||||
@@ -114,19 +136,7 @@ class NAT( Node ):
|
|||||||
# Instruct the kernel to perform forwarding
|
# Instruct the kernel to perform forwarding
|
||||||
self.cmd( 'sysctl net.ipv4.ip_forward=1' )
|
self.cmd( 'sysctl net.ipv4.ip_forward=1' )
|
||||||
|
|
||||||
# Prevent network-manager from messing with our interface
|
|
||||||
# by specifying manual configuration in /etc/network/interfaces
|
|
||||||
intf = self.localIntf
|
|
||||||
cfile = '/etc/network/interfaces'
|
|
||||||
line = '\niface %s inet manual\n' % intf
|
|
||||||
config = open( cfile ).read()
|
|
||||||
if ( line ) not in config:
|
|
||||||
info( '*** Adding "' + line.strip() + '" to ' + cfile + '\n' )
|
|
||||||
with open( cfile, 'a' ) as f:
|
|
||||||
f.write( line )
|
|
||||||
# Probably need to restart network-manager to be safe -
|
|
||||||
# hopefully this won't disconnect you
|
|
||||||
self.cmd( 'service network-manager restart' )
|
|
||||||
|
|
||||||
def terminate( self ):
|
def terminate( self ):
|
||||||
"Stop NAT/forwarding between Mininet and external network"
|
"Stop NAT/forwarding between Mininet and external network"
|
||||||
|
|||||||
@@ -43,17 +43,18 @@ class testWalkthrough( unittest.TestCase ):
|
|||||||
tshark = pexpect.spawn( 'tshark -i lo -R of' )
|
tshark = pexpect.spawn( 'tshark -i lo -R of' )
|
||||||
else:
|
else:
|
||||||
tshark = pexpect.spawn( 'tshark -i lo -Y openflow_v1' )
|
tshark = pexpect.spawn( 'tshark -i lo -Y openflow_v1' )
|
||||||
tshark.expect( [ 'Capturing on lo', "Capturing on 'Loopback'" ] )
|
tshark.expect( [ 'Capturing on lo', "Capturing on 'Loopback" ] )
|
||||||
mn = pexpect.spawn( 'mn --test pingall' )
|
mn = pexpect.spawn( 'mn --test pingall' )
|
||||||
mn.expect( '0% dropped' )
|
mn.expect( '0% dropped' )
|
||||||
tshark.expect( [ '74 Hello', '74 of_hello', '74 Type: OFPT_HELLO' ] )
|
tshark.expect( [ '74 Hello', '74 of_hello', '74 Type: OFPT_HELLO' ] )
|
||||||
tshark.sendintr()
|
tshark.sendintr()
|
||||||
mn.expect( pexpect.EOF )
|
mn.expect( pexpect.EOF )
|
||||||
|
tshark.expect( 'aptured' ) # 'xx packets captured'
|
||||||
tshark.expect( pexpect.EOF )
|
tshark.expect( pexpect.EOF )
|
||||||
|
|
||||||
def testBasic( self ):
|
def testBasic( self ):
|
||||||
"Test basic CLI commands (help, nodes, net, dump)"
|
"Test basic CLI commands (help, nodes, net, dump)"
|
||||||
p = pexpect.spawn( 'mn' )
|
p = pexpect.spawn( 'mn -w' )
|
||||||
p.expect( self.prompt )
|
p.expect( self.prompt )
|
||||||
# help command
|
# help command
|
||||||
p.sendline( 'help' )
|
p.sendline( 'help' )
|
||||||
@@ -92,7 +93,7 @@ class testWalkthrough( unittest.TestCase ):
|
|||||||
|
|
||||||
def testHostCommands( self ):
|
def testHostCommands( self ):
|
||||||
"Test ifconfig and ps on h1 and s1"
|
"Test ifconfig and ps on h1 and s1"
|
||||||
p = pexpect.spawn( 'mn' )
|
p = pexpect.spawn( 'mn -w' )
|
||||||
p.expect( self.prompt )
|
p.expect( self.prompt )
|
||||||
# Third pattern is a local interface beginning with 'eth' or 'en'
|
# Third pattern is a local interface beginning with 'eth' or 'en'
|
||||||
interfaces = [ r'h1-eth0[:\s]', r's1-eth1[:\s]',
|
interfaces = [ r'h1-eth0[:\s]', r's1-eth1[:\s]',
|
||||||
@@ -144,7 +145,7 @@ class testWalkthrough( unittest.TestCase ):
|
|||||||
|
|
||||||
def testConnectivity( self ):
|
def testConnectivity( self ):
|
||||||
"Test ping and pingall"
|
"Test ping and pingall"
|
||||||
p = pexpect.spawn( 'mn' )
|
p = pexpect.spawn( 'mn -w' )
|
||||||
p.expect( self.prompt )
|
p.expect( self.prompt )
|
||||||
p.sendline( 'h1 ping -c 1 h2' )
|
p.sendline( 'h1 ping -c 1 h2' )
|
||||||
p.expect( '1 packets transmitted, 1 received' )
|
p.expect( '1 packets transmitted, 1 received' )
|
||||||
@@ -161,7 +162,7 @@ class testWalkthrough( unittest.TestCase ):
|
|||||||
httpserver = 'SimpleHTTPServer'
|
httpserver = 'SimpleHTTPServer'
|
||||||
else:
|
else:
|
||||||
httpserver = 'http.server'
|
httpserver = 'http.server'
|
||||||
p = pexpect.spawn( 'mn' )
|
p = pexpect.spawn( 'mn -w' )
|
||||||
p.expect( self.prompt )
|
p.expect( self.prompt )
|
||||||
p.sendline( 'h1 python -m %s 80 &' % httpserver )
|
p.sendline( 'h1 python -m %s 80 &' % httpserver )
|
||||||
# The walkthrough doesn't specify a delay here, and
|
# The walkthrough doesn't specify a delay here, and
|
||||||
@@ -213,7 +214,9 @@ class testWalkthrough( unittest.TestCase ):
|
|||||||
|
|
||||||
def testLinkChange( self ):
|
def testLinkChange( self ):
|
||||||
"Test TCLink bw and delay"
|
"Test TCLink bw and delay"
|
||||||
p = pexpect.spawn( 'mn --link tc,bw=10,delay=10ms' )
|
p = pexpect.spawn( 'mn -w --link tc,bw=10,delay=10ms' )
|
||||||
|
p.expect( self.prompt )
|
||||||
|
p.sendline( 'h1 route && ping -c1 h2' )
|
||||||
# test bw
|
# test bw
|
||||||
p.expect( self.prompt )
|
p.expect( self.prompt )
|
||||||
p.sendline( 'iperf' )
|
p.sendline( 'iperf' )
|
||||||
@@ -319,7 +322,7 @@ class testWalkthrough( unittest.TestCase ):
|
|||||||
# PART 3
|
# PART 3
|
||||||
def testPythonInterpreter( self ):
|
def testPythonInterpreter( self ):
|
||||||
"Test py and px by checking IP for h1 and adding h3"
|
"Test py and px by checking IP for h1 and adding h3"
|
||||||
p = pexpect.spawn( 'mn' )
|
p = pexpect.spawn( 'mn -w' )
|
||||||
p.expect( self.prompt )
|
p.expect( self.prompt )
|
||||||
# test host IP
|
# test host IP
|
||||||
p.sendline( 'py h1.IP()' )
|
p.sendline( 'py h1.IP()' )
|
||||||
@@ -341,7 +344,7 @@ class testWalkthrough( unittest.TestCase ):
|
|||||||
|
|
||||||
def testLink( self ):
|
def testLink( self ):
|
||||||
"Test link CLI command using ping"
|
"Test link CLI command using ping"
|
||||||
p = pexpect.spawn( 'mn' )
|
p = pexpect.spawn( 'mn -w' )
|
||||||
p.expect( self.prompt )
|
p.expect( self.prompt )
|
||||||
p.sendline( 'link s1 h1 down' )
|
p.sendline( 'link s1 h1 down' )
|
||||||
p.expect( self.prompt )
|
p.expect( self.prompt )
|
||||||
|
|||||||
Reference in New Issue
Block a user