blob: ace7bb5198bf498181e2d5bc3075290136c32367 [file] [log] [blame]
carlosmscabralf40ecd12013-02-01 18:15:58 -02001#!/usr/bin/env python
2
3"""Package: mininet
4 Test creation and pings for topologies with link and/or CPU options."""
5
6import unittest
7
8from mininet.net import Mininet
9from mininet.node import OVSKernelSwitch
10from mininet.node import CPULimitedHost
11from mininet.link import TCLink
12from mininet.topo import Topo
13from mininet.log import setLogLevel
14
15
16SWITCH = OVSKernelSwitch
17# Number of hosts for each test
18N = 2
19
20
21class SingleSwitchOptionsTopo(Topo):
22 "Single switch connected to n hosts."
23 def __init__(self, n=2, hopts=None, lopts=None):
24 if not hopts:
25 hopts = {}
26 if not lopts:
27 lopts = {}
28 Topo.__init__(self, hopts=hopts, lopts=lopts)
29 switch = self.addSwitch('s1')
30 for h in range(n):
31 host = self.addHost('h%s' % (h + 1))
32 self.addLink(host, switch)
33
34
35class testOptionsTopo( unittest.TestCase ):
36 "Verify ability to create networks with host and link options."
37
38 def runOptionsTopoTest( self, n, hopts=None, lopts=None ):
39 "Generic topology-with-options test runner."
40 mn = Mininet( topo=SingleSwitchOptionsTopo( n=n, hopts=hopts,
41 lopts=lopts ),
42 host=CPULimitedHost, link=TCLink )
43 dropped = mn.run( mn.ping )
44 self.assertEqual( dropped, 0 )
45
46 def assertWithinTolerance(self, measured, expected, tolerance_frac):
47 """Check that a given value is within a tolerance of expected
48 tolerance_frac: less-than-1.0 value; 0.8 would yield 20% tolerance.
49 """
50 self.assertTrue( float(measured) >= float(expected) * tolerance_frac )
51 self.assertTrue( float(measured) >= float(expected) * tolerance_frac )
52
53 def testCPULimits( self ):
54 "Verify topology creation with CPU limits set for both schedulers."
55 CPU_FRACTION = 0.1
56 CPU_TOLERANCE = 0.8 # CPU fraction below which test should fail
57 hopts = { 'cpu': CPU_FRACTION }
58 #self.runOptionsTopoTest( N, hopts=hopts )
59
60 mn = Mininet( SingleSwitchOptionsTopo( n=N, hopts=hopts ),
61 host=CPULimitedHost )
62 mn.start()
63 results = mn.runCpuLimitTest( cpu=CPU_FRACTION )
64 mn.stop()
65 for cpu in results:
66 self.assertWithinTolerance( cpu, CPU_FRACTION, CPU_TOLERANCE )
67
68 def testLinkBandwidth( self ):
69 "Verify that link bandwidths are accurate within a bound."
70 BW = 5 # Mbps
71 BW_TOLERANCE = 0.8 # BW fraction below which test should fail
72 # Verify ability to create limited-link topo first;
73 lopts = { 'bw': BW, 'use_htb': True }
74 # Also verify correctness of limit limitng within a bound.
75 mn = Mininet( SingleSwitchOptionsTopo( n=N, lopts=lopts ),
76 link=TCLink )
77 bw_strs = mn.run( mn.iperf )
78 for bw_str in bw_strs:
79 bw = float( bw_str.split(' ')[0] )
80 self.assertWithinTolerance( bw, BW, BW_TOLERANCE )
81
82 def testLinkDelay( self ):
83 "Verify that link delays are accurate within a bound."
84 DELAY_MS = 15
85 DELAY_TOLERANCE = 0.8 # Delay fraction below which test should fail
86 lopts = { 'delay': '%sms' % DELAY_MS, 'use_htb': True }
87 mn = Mininet( SingleSwitchOptionsTopo( n=N, lopts=lopts ),
88 link=TCLink )
89 ping_delays = mn.run( mn.pingFull )
90 test_outputs = ping_delays[0]
91 # Ignore unused variables below
92 # pylint: disable-msg=W0612
93 node, dest, ping_outputs = test_outputs
94 sent, received, rttmin, rttavg, rttmax, rttdev = ping_outputs
95 self.assertEqual( sent, received )
96 # pylint: enable-msg=W0612
97 for rttval in [rttmin, rttavg, rttmax]:
98 # Multiply delay by 4 to cover there & back on two links
99 self.assertWithinTolerance( rttval, DELAY_MS * 4.0,
100 DELAY_TOLERANCE)
101
102 def testLinkLoss( self ):
103 "Verify that we see packet drops with a high configured loss rate."
104 LOSS_PERCENT = 99
105 REPS = 1
106 lopts = { 'loss': LOSS_PERCENT, 'use_htb': True }
107 mn = Mininet( topo=SingleSwitchOptionsTopo( n=N, lopts=lopts ),
108 host=CPULimitedHost, link=TCLink )
109 # Drops are probabilistic, but the chance of no dropped packets is
110 # 1 in 100 million with 4 hops for a link w/99% loss.
111 dropped_total = 0
112 mn.start()
113 for _ in range(REPS):
114 dropped_total += mn.ping(timeout='1')
115 mn.stop()
116 self.assertTrue(dropped_total > 0)
117
118 def testMostOptions( self ):
119 "Verify topology creation with most link options and CPU limits."
120 lopts = { 'bw': 10, 'delay': '5ms', 'use_htb': True }
121 hopts = { 'cpu': 0.5 / N }
122 self.runOptionsTopoTest( N, hopts=hopts, lopts=lopts )
123
124
125if __name__ == '__main__':
126 setLogLevel( 'warning' )
127 unittest.main()