def testLinkBandwidth(self): "Verify that link bandwidths are accurate within a bound." if self.switchClass is UserSwitch: self.skipTest('UserSwitch has very poor performance -' ' skipping for now') BW = 5 # Mbps BW_TOLERANCE = 0.8 # BW fraction below which test should fail # Verify ability to create limited-link topo first; lopts = {'bw': BW, 'use_htb': True} # Also verify correctness of limit limitng within a bound. mn = Mininet(SingleSwitchOptionsTopo(n=N, lopts=lopts), link=TCLink, switch=self.switchClass, waitConnected=True) bw_strs = mn.run(mn.iperf, fmt='m') loptsStr = ', '.join('%s: %s' % (opt, value) for opt, value in lopts.items()) msg = ('\nTesting link bandwidth limited to %d Mbps per link\n' 'iperf results[ client, server ]: %s\n' 'Topo = SingleSwitchTopo, %s hosts\n' 'Link = TCLink\n' 'lopts = %s\n' 'host = default\n' 'switch = %s\n' % (BW, bw_strs, N, loptsStr, self.switchClass)) # On the client side, iperf doesn't wait for ACKs - it simply # reports how long it took to fill up the TCP send buffer. # As long as the kernel doesn't wait a long time before # delivering bytes to the iperf server, its reported data rate # should be close to the actual receive rate. serverRate, _clientRate = bw_strs bw = float(serverRate.split(' ')[0]) self.assertWithinTolerance(bw, BW, BW_TOLERANCE, msg)
def __init__( self, *args, **kwargs ): """servers: a list of servers to use (note: include localhost or None to use local system as well) user: user name for server ssh placement: Placer() subclass""" params = { 'host': RemoteHost, 'switch': RemoteOVSSwitch, 'link': RemoteLink, 'precheck': True } params.update( kwargs ) servers = params.pop( 'servers', [ 'localhost' ] ) servers = [ s if s else 'localhost' for s in servers ] self.servers = servers self.serverIP = params.pop( 'serverIP', {} ) if not self.serverIP: self.serverIP = { server: RemoteMixin.findServerIP( server ) for server in self.servers } self.user = params.pop( 'user', findUser() ) if params.pop( 'precheck' ): self.precheck() self.connections = {} self.placement = params.pop( 'placement', SwitchBinPlacer ) # Make sure control directory exists self.cdir = os.environ[ 'HOME' ] + '/.ssh/mn' errRun( [ 'mkdir', '-p', self.cdir ] ) Mininet.__init__( self, *args, **params )
def testRemoteTopo(): "Test remote Node classes using Mininet()/Topo() API" topo = LinearTopo( 2 ) net = Mininet( topo=topo, host=HostPlacer, switch=SwitchPlacer, link=RemoteLink, controller=ClusterController ) net.start() net.pingAll() net.stop()
def testActualDpidAssignment(self): """Verify that Switch dpid is the actual dpid assigned if dpid is passed in switch creation.""" dpid = self.dpidFrom(0xABCD) switch = Mininet(Topo(), self.switchClass, Host, Controller).addSwitch('s1', dpid=dpid) self.assertEqual(switch.dpid, dpid)
def perfTest(lossy=True): "Create network and run simple performance test" topo = SingleSwitchTopo(n=4, lossy=lossy) net = Mininet(topo=topo, host=CPULimitedHost, link=TCLink, autoStaticArp=True) net.start() print "Dumping host connections" dumpNodeConnections(net.hosts) print "Testing bandwidth between h1 and h4" h1, h4 = net.getNodeByName('h1', 'h4') net.iperf((h1, h4), l4Type='UDP') net.stop()
def testCPULimits(self): "Verify topology creation with CPU limits set for both schedulers." CPU_FRACTION = 0.1 CPU_TOLERANCE = 0.8 # CPU fraction below which test should fail hopts = {'cpu': CPU_FRACTION} #self.runOptionsTopoTest( N, hopts=hopts ) mn = Mininet(SingleSwitchOptionsTopo(n=N, hopts=hopts), host=CPULimitedHost, switch=self.switchClass, waitConnected=True) mn.start() results = mn.runCpuLimitTest(cpu=CPU_FRACTION) mn.stop() hostUsage = '\n'.join('h%s: %s' % (n + 1, results[(n - 1) * 5:(n * 5) - 1]) for n in range(N)) hoptsStr = ', '.join('%s: %s' % (opt, value) for opt, value in hopts.items()) msg = ('\nTesting cpu limited to %d%% of cpu per host\n' 'cpu usage percent per host:\n%s\n' 'Topo = SingleSwitchTopo, %s hosts\n' 'hopts = %s\n' 'host = CPULimitedHost\n' 'Switch = %s\n' % (CPU_FRACTION * 100, hostUsage, N, hoptsStr, self.switchClass)) for pct in results: #divide cpu by 100 to convert from percentage to fraction self.assertWithinTolerance(pct / 100, CPU_FRACTION, CPU_TOLERANCE, msg)
def testLinkLoss(self): "Verify that we see packet drops with a high configured loss rate." LOSS_PERCENT = 99 REPS = 1 lopts = {'loss': LOSS_PERCENT, 'use_htb': True} mn = Mininet(topo=SingleSwitchOptionsTopo(n=N, lopts=lopts), host=CPULimitedHost, link=TCLink, switch=self.switchClass, waitConnected=True) # Drops are probabilistic, but the chance of no dropped packets is # 1 in 100 million with 4 hops for a link w/99% loss. dropped_total = 0 mn.start() for _ in range(REPS): dropped_total += mn.ping(timeout='1') mn.stop() loptsStr = ', '.join('%s: %s' % (opt, value) for opt, value in lopts.items()) msg = ('\nTesting packet loss with %d%% loss rate\n' 'number of dropped pings during mininet.ping(): %s\n' 'expected number of dropped packets: 1\n' 'Topo = SingleSwitchTopo, %s hosts\n' 'Link = TCLink\n' 'lopts = %s\n' 'host = default\n' 'switch = %s\n' % (LOSS_PERCENT, dropped_total, N, loptsStr, self.switchClass)) self.assertGreater(dropped_total, 0, msg)
def testDefaultDpidLen(self): """Verify that Default dpid length is 16 characters consisting of 16 - len(hex of first string of contiguous digits passed in switch name) 0's followed by hex of first string of contiguous digits passed in switch name.""" switch = Mininet(Topo(), self.switchClass, Host, Controller).addSwitch('s123') self.assertEqual(switch.dpid, self.dpidFrom(123))
def addController( self, *args, **kwargs ): "Patch to update IP address to global IP address" controller = Mininet.addController( self, *args, **kwargs ) # Update IP address for controller that may not be local if ( isinstance( controller, Controller) and controller.IP() == '127.0.0.1' and ' eth0:' in controller.cmd( 'ip link show' ) ): Intf( 'eth0', node=controller ).updateIP() return controller
def testDefaultDpidAssignmentFailure(self): """Verify that Default dpid assignment raises an Exception if the name of the switch does not contin a digit. Also verify the exception message.""" with self.assertRaises(Exception) as raises_cm: Mininet(Topo(), self.switchClass, Host, Controller).addSwitch('A') self.assertEqual( raises_cm.exception.message, 'Unable to derive ' 'default datapath ID - please either specify a dpid ' 'or use a canonical switch name such as s23.')
def run(): "Create network and run the CLI" topo = InternetTopo() net = Mininet(topo=topo) net.start() CLI(net) net.stop()
def runMultiLink(): "Create and run multiple link network" topo = simpleMultiLinkTopo(n=2) net = Mininet(topo=topo) net.start() CLI(net) net.stop()
def monitorTest(N=3, seconds=3): "Run pings and monitor multiple hosts" topo = SingleSwitchTopo(N) net = Mininet(topo) net.start() hosts = net.hosts print "Starting test..." server = hosts[0] outfiles, errfiles = {}, {} for h in hosts: # Create and/or erase output files outfiles[h] = '/tmp/%s.out' % h.name errfiles[h] = '/tmp/%s.err' % h.name h.cmd('echo >', outfiles[h]) h.cmd('echo >', errfiles[h]) # Start pings h.cmdPrint('ping', server.IP(), '>', outfiles[h], '2>', errfiles[h], '&') print "Monitoring output for", seconds, "seconds" for h, line in monitorFiles(outfiles, seconds, timeoutms=500): if h: print '%s: %s' % (h.name, line) for h in hosts: h.cmd('kill %ping') net.stop()
def exampleCustomTags(): """Simple example that exercises VLANStarTopo""" net = Mininet(topo=VLANStarTopo()) net.start() CLI(net) net.stop()
def runOptionsTopoTest(self, n, msg, hopts=None, lopts=None): "Generic topology-with-options test runner." mn = Mininet(topo=SingleSwitchOptionsTopo(n=n, hopts=hopts, lopts=lopts), host=CPULimitedHost, link=TCLink, switch=self.switchClass, waitConnected=True) dropped = mn.run(mn.ping) hoptsStr = ', '.join('%s: %s' % (opt, value) for opt, value in hopts.items()) loptsStr = ', '.join('%s: %s' % (opt, value) for opt, value in lopts.items()) msg += ('%s%% of pings were dropped during mininet.ping().\n' 'Topo = SingleSwitchTopo, %s hosts\n' 'hopts = %s\n' 'lopts = %s\n' 'host = CPULimitedHost\n' 'link = TCLink\n' 'Switch = %s\n' % (dropped, n, hoptsStr, loptsStr, self.switchClass)) self.assertEqual(dropped, 0, msg=msg)
def exampleAllHosts(vlan): """Simple example of how VLANHost can be used in a script""" # This is where the magic happens... host = partial(VLANHost, vlan=vlan) # vlan (type: int): VLAN ID to be used by all hosts # Start a basic network using our VLANHost topo = SingleSwitchTopo(k=2) net = Mininet(host=host, topo=topo) net.start() CLI(net) net.stop()
def bwtest(cpuLimits, period_us=100000, seconds=5): """Example/test of link and CPU bandwidth limits cpu: cpu limit as fraction of overall CPU time""" topo = TreeTopo(depth=1, fanout=2) results = {} for sched in 'rt', 'cfs': print '*** Testing with', sched, 'bandwidth limiting' for cpu in cpuLimits: host = custom(CPULimitedHost, sched=sched, period_us=period_us, cpu=cpu) try: net = Mininet(topo=topo, host=host) # pylint: disable=bare-except except: info('*** Skipping host %s\n' % sched) break net.start() net.pingAll() hosts = [net.getNodeByName(h) for h in topo.hosts()] client, server = hosts[0], hosts[-1] server.cmd('iperf -s -p 5001 &') waitListening(client, server, 5001) result = client.cmd('iperf -yc -t %s -c %s' % (seconds, server.IP())).split(',') bps = float(result[-1]) server.cmdPrint('kill %iperf') net.stop() updated = results.get(sched, []) updated += [(cpu, bps)] results[sched] = updated return results
def limit(bw=10, cpu=.1): """Example/test of link and CPU bandwidth limits bw: interface bandwidth limit in Mbps cpu: cpu limit as fraction of overall CPU time""" intf = custom(TCIntf, bw=bw) myTopo = TreeTopo(depth=1, fanout=2) for sched in 'rt', 'cfs': info('*** Testing with', sched, 'bandwidth limiting\n') if sched == 'rt': release = quietRun('uname -r').strip('\r\n') output = quietRun('grep CONFIG_RT_GROUP_SCHED /boot/config-%s' % release) if output == '# CONFIG_RT_GROUP_SCHED is not set\n': info('*** RT Scheduler is not enabled in your kernel. ' 'Skipping this test\n') continue host = custom(CPULimitedHost, sched=sched, cpu=cpu) net = Mininet(topo=myTopo, intf=intf, host=host) net.start() testLinkLimit(net, bw=bw) net.runCpuLimitTest(cpu=cpu) net.stop()
def testHostWithPrivateDirs(): "Test bind mounts" topo = SingleSwitchTopo( 10 ) privateDirs = [ ( '/var/log', '/tmp/%(name)s/var/log' ), ( '/var/run', '/tmp/%(name)s/var/run' ), '/var/mn' ] host = partial( Host, privateDirs=privateDirs ) net = Mininet( topo=topo, host=host ) net.start() directories = [ directory[ 0 ] if isinstance( directory, tuple ) else directory for directory in privateDirs ] info( 'Private Directories:', directories, '\n' ) CLI( net ) net.stop()
def testLinkDelay(self): "Verify that link delays are accurate within a bound." DELAY_MS = 15 DELAY_TOLERANCE = 0.8 # Delay fraction below which test should fail REPS = 3 lopts = {'delay': '%sms' % DELAY_MS, 'use_htb': True} mn = Mininet(SingleSwitchOptionsTopo(n=N, lopts=lopts), link=TCLink, switch=self.switchClass, autoStaticArp=True, waitConnected=True) mn.start() for _ in range(REPS): ping_delays = mn.pingFull() mn.stop() test_outputs = ping_delays[0] # Ignore unused variables below # pylint: disable=W0612 node, dest, ping_outputs = test_outputs sent, received, rttmin, rttavg, rttmax, rttdev = ping_outputs pingFailMsg = 'sent %s pings, only received %s' % (sent, received) self.assertEqual(sent, received, msg=pingFailMsg) # pylint: enable=W0612 loptsStr = ', '.join('%s: %s' % (opt, value) for opt, value in lopts.items()) msg = ('\nTesting Link Delay of %s ms\n' 'ping results across 4 links:\n' '(Sent, Received, rttmin, rttavg, rttmax, rttdev)\n' '%s\n' 'Topo = SingleSwitchTopo, %s hosts\n' 'Link = TCLink\n' 'lopts = %s\n' 'host = default' 'switch = %s\n' % (DELAY_MS, ping_outputs, N, loptsStr, self.switchClass)) for rttval in [rttmin, rttavg, rttmax]: # Multiply delay by 4 to cover there & back on two links self.assertWithinTolerance(rttval, DELAY_MS * 4.0, DELAY_TOLERANCE, msg)
def monitorhosts(hosts=5, sched='cfs'): "Start a bunch of pings and monitor them using popen" mytopo = SingleSwitchTopo(hosts) cpu = .5 / hosts myhost = custom(CPULimitedHost, cpu=cpu, sched=sched) net = Mininet(topo=mytopo, host=myhost) net.start() # Start a bunch of pings popens = {} last = net.hosts[-1] for host in net.hosts: popens[host] = host.popen("ping -c5 %s" % last.IP()) last = host # Monitor them and print output for host, line in pmonitor(popens): if host: print "<%s>: %s" % (host.name, line.strip()) # Done net.stop()
def pmonitorTest(N=3, seconds=10): "Run pings and monitor multiple hosts using pmonitor" topo = SingleSwitchTopo(N) net = Mininet(topo) net.start() hosts = net.hosts print "Starting test..." server = hosts[0] popens = {} for h in hosts: popens[h] = h.popen('ping', server.IP()) print "Monitoring output for", seconds, "seconds" endTime = time() + seconds for h, line in pmonitor(popens, timeoutms=500): if h: print '<%s>: %s' % (h.name, line), if time() >= endTime: for p in popens.values(): p.send_signal(SIGINT) net.stop()
def testRemoteNet( remote='ubuntu2' ): "Test remote Node classes" print '*** Remote Node Test' net = Mininet( host=RemoteHost, switch=RemoteOVSSwitch, link=RemoteLink ) c0 = net.addController( 'c0' ) # Make sure controller knows its non-loopback address Intf( 'eth0', node=c0 ).updateIP() print "*** Creating local h1" h1 = net.addHost( 'h1' ) print "*** Creating remote h2" h2 = net.addHost( 'h2', server=remote ) print "*** Creating local s1" s1 = net.addSwitch( 's1' ) print "*** Creating remote s2" s2 = net.addSwitch( 's2', server=remote ) print "*** Adding links" net.addLink( h1, s1 ) net.addLink( s1, s2 ) net.addLink( h2, s2 ) net.start() print 'Mininet is running on', quietRun( 'hostname' ).strip() for node in c0, h1, h2, s1, s2: print 'Node', node, 'is running on', node.cmd( 'hostname' ).strip() net.pingAll() CLI( net ) net.stop()
def testNsTunnels(): "Test tunnels between nodes in namespaces" net = Mininet( host=RemoteHost, link=RemoteLink ) h1 = net.addHost( 'h1' ) h2 = net.addHost( 'h2', server='ubuntu2' ) net.addLink( h1, h2 ) net.start() net.pingAll() net.stop()
def buildFromTopo( self, *args, **kwargs ): "Start network" info( '*** Placing nodes\n' ) self.placeNodes() info( '\n' ) Mininet.buildFromTopo( self, *args, **kwargs )
def modifiedaddHost( self, *args, **kwargs ): "Slightly modify addHost" assert self # please pylint kwargs[ 'splitInit' ] = True return Mininet.addHost( *args, **kwargs )
def TreeNet(depth=1, fanout=2, **kwargs): "Convenience function for creating tree networks." topo = TreeTopo(depth, fanout) return Mininet(topo, **kwargs)
def testPortNumbering(): """Test port numbering: Create a network with 5 hosts (using Mininet's mid-level API) and check that implicit and explicit port numbering works as expected.""" net = Mininet(controller=Controller) info('*** Adding controller\n') net.addController('c0') info('*** Adding hosts\n') h1 = net.addHost('h1', ip='10.0.0.1') h2 = net.addHost('h2', ip='10.0.0.2') h3 = net.addHost('h3', ip='10.0.0.3') h4 = net.addHost('h4', ip='10.0.0.4') h5 = net.addHost('h5', ip='10.0.0.5') info('*** Adding switch\n') s1 = net.addSwitch('s1') info('*** Creating links\n') # host 1-4 connect to ports 1-4 on the switch net.addLink(h1, s1) net.addLink(h2, s1) net.addLink(h3, s1) net.addLink(h4, s1) # specify a different port to connect host 5 to on the switch. net.addLink(h5, s1, port1=1, port2=9) info('*** Starting network\n') net.start() # print the interfaces and their port numbers info('\n*** printing and validating the ports ' 'running on each interface\n') for intfs in s1.intfList(): if not intfs.name == "lo": info(intfs, ': ', s1.ports[intfs], '\n') info('Validating that', intfs, 'is actually on port', s1.ports[intfs], '... ') if validatePort(s1, intfs): info('Validated.\n') print '\n' # test the network with pingall net.pingAll() print '\n' info('*** Stopping network') net.stop()
from src.mininet.cli import CLI from src.mininet.log import lg, info from src.mininet.net import Mininet from src.mininet.node import OVSKernelSwitch from src.mininet.topolib import TreeTopo def ifconfigTest(net): "Run ifconfig on all hosts in net." hosts = net.hosts for host in hosts: info(host.cmd('ifconfig')) if __name__ == '__main__': lg.setLogLevel('info') info("*** Initializing Mininet and kernel modules\n") OVSKernelSwitch.setup() info("*** Creating network\n") network = Mininet(TreeTopo(depth=2, fanout=2), switch=OVSKernelSwitch) info("*** Starting network\n") network.start() info("*** Running ping test\n") network.pingAll() info("*** Running ifconfig test\n") ifconfigTest(network) info("*** Starting CLI (type 'exit' to exit)\n") CLI(network) info("*** Stopping network\n") network.stop()
def testDefaultDpid(self): """Verify that the default dpid is assigned using a valid provided canonical switchname if no dpid is passed in switch creation.""" switch = Mininet(Topo(), self.switchClass, Host, Controller).addSwitch('s1') self.assertEqual(switch.defaultDpid(), switch.dpid)