Statistics
| Branch: | Tag: | Revision:

mininet / mininet / test / test_hifi.py @ 4e76439c

History | View | Annotate | Download (6.48 KB)

1
#!/usr/bin/env python
2

    
3
"""Package: mininet
4
   Test creation and pings for topologies with link and/or CPU options."""
5

    
6
import unittest
7
from functools import partial
8

    
9
from mininet.net import Mininet
10
from mininet.node import OVSSwitch, UserSwitch, IVSSwitch
11
from mininet.node import CPULimitedHost
12
from mininet.link import TCLink
13
from mininet.topo import Topo
14
from mininet.log import setLogLevel
15
from mininet.util import quietRun
16

    
17
# Number of hosts for each test
18
N = 2
19

    
20

    
21
class 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
# Tell pylint not to complain about calls to other class
35
# pylint: disable=E1101
36

    
37
class testOptionsTopoCommon( object ):
38
    """Verify ability to create networks with host and link options
39
       (common code)."""
40

    
41
    switchClass = None # overridden in subclasses
42

    
43
    def runOptionsTopoTest( self, n, hopts=None, lopts=None ):
44
        "Generic topology-with-options test runner."
45
        mn = Mininet( topo=SingleSwitchOptionsTopo( n=n, hopts=hopts,
46
                                                    lopts=lopts ),
47
                      host=CPULimitedHost, link=TCLink,
48
                      switch=self.switchClass )
49
        dropped = mn.run( mn.ping )
50
        self.assertEqual( dropped, 0 )
51

    
52
    def assertWithinTolerance(self, measured, expected, tolerance_frac):
53
        """Check that a given value is within a tolerance of expected
54
        tolerance_frac: less-than-1.0 value; 0.8 would yield 20% tolerance.
55
        """
56
        self.assertGreaterEqual( float(measured),
57
                                 float(expected) * tolerance_frac )
58
        self.assertLess( float( measured ),
59
                                    float(expected) + (1-tolerance_frac) * float( expected ) )
60

    
61
    def testCPULimits( self ):
62
        "Verify topology creation with CPU limits set for both schedulers."
63
        CPU_FRACTION = 0.1
64
        CPU_TOLERANCE = 0.8  # CPU fraction below which test should fail
65
        hopts = { 'cpu': CPU_FRACTION }
66
        #self.runOptionsTopoTest( N, hopts=hopts )
67

    
68
        mn = Mininet( SingleSwitchOptionsTopo( n=N, hopts=hopts ),
69
                      host=CPULimitedHost, switch=self.switchClass )
70
        mn.start()
71
        results = mn.runCpuLimitTest( cpu=CPU_FRACTION )
72
        mn.stop()
73
        for cpu in results:
74
            #divide cpu by 100 to convert from percentage to fraction
75
            self.assertWithinTolerance( cpu/100, CPU_FRACTION, CPU_TOLERANCE )
76

    
77
    def testLinkBandwidth( self ):
78
        "Verify that link bandwidths are accurate within a bound."
79
        BW = .5  # Mbps
80
        BW_TOLERANCE = 0.8  # BW fraction below which test should fail
81
        # Verify ability to create limited-link topo first;
82
        lopts = { 'bw': BW, 'use_htb': True }
83
        # Also verify correctness of limit limitng within a bound.
84
        mn = Mininet( SingleSwitchOptionsTopo( n=N, lopts=lopts ),
85
                      link=TCLink, switch=self.switchClass )
86
        bw_strs = mn.run( mn.iperf, format='m' )
87
        for bw_str in bw_strs:
88
            bw = float( bw_str.split(' ')[0] )
89
            self.assertWithinTolerance( bw, BW, BW_TOLERANCE )
90

    
91
    def testLinkDelay( self ):
92
        "Verify that link delays are accurate within a bound."
93
        DELAY_MS = 15
94
        DELAY_TOLERANCE = 0.8  # Delay fraction below which test should fail
95
        lopts = { 'delay': '%sms' % DELAY_MS, 'use_htb': True }
96
        mn = Mininet( SingleSwitchOptionsTopo( n=N, lopts=lopts ),
97
                      link=TCLink, switch=self.switchClass )
98
        ping_delays = mn.run( mn.pingFull )
99
        test_outputs = ping_delays[0]
100
        # Ignore unused variables below
101
        # pylint: disable-msg=W0612
102
        node, dest, ping_outputs = test_outputs
103
        sent, received, rttmin, rttavg, rttmax, rttdev = ping_outputs
104
        self.assertEqual( sent, received )
105
        # pylint: enable-msg=W0612
106
        for rttval in [rttmin, rttavg, rttmax]:
107
            # Multiply delay by 8 to cover there & back on two links, for both the icmp packets and the arp packets
108
            self.assertWithinTolerance( rttval, DELAY_MS * 8.0, 
109
                                        DELAY_TOLERANCE)
110

    
111

    
112
    def testLinkLoss( self ):
113
        "Verify that we see packet drops with a high configured loss rate."
114
        LOSS_PERCENT = 99
115
        REPS = 1
116
        lopts = { 'loss': LOSS_PERCENT, 'use_htb': True }
117
        mn = Mininet( topo=SingleSwitchOptionsTopo( n=N, lopts=lopts ),
118
                      host=CPULimitedHost, link=TCLink,
119
                      switch=self.switchClass )
120
        # Drops are probabilistic, but the chance of no dropped packets is
121
        # 1 in 100 million with 4 hops for a link w/99% loss.
122
        dropped_total = 0
123
        mn.start()
124
        for _ in range(REPS):
125
            dropped_total += mn.ping(timeout='1')
126
        mn.stop()
127
        self.assertGreater( dropped_total, 0 )
128

    
129
    def testMostOptions( self ):
130
        "Verify topology creation with most link options and CPU limits."
131
        lopts = { 'bw': 10, 'delay': '5ms', 'use_htb': True }
132
        hopts = { 'cpu': 0.5 / N }
133
        self.runOptionsTopoTest( N, hopts=hopts, lopts=lopts )
134

    
135
# pylint: enable=E1101
136

    
137
class testOptionsTopoOVSKernel( testOptionsTopoCommon, unittest.TestCase ):
138
    """Verify ability to create networks with host and link options
139
       (OVS kernel switch)."""
140
    switchClass = OVSSwitch
141

    
142
@unittest.skip( 'Skipping OVS user switch test for now' )
143
class testOptionsTopoOVSUser( testOptionsTopoCommon, unittest.TestCase ):
144
    """Verify ability to create networks with host and link options
145
       (OVS user switch)."""
146
    switchClass = partial( OVSSwitch, datapath='user' )
147

    
148
@unittest.skipUnless( quietRun( 'which ivs-ctl' ), 'IVS is not installed' )
149
class testOptionsTopoIVS( testOptionsTopoCommon, unittest.TestCase ):
150
    "Verify ability to create networks with host and link options (IVS)."
151
    switchClass = IVSSwitch
152

    
153
@unittest.skipUnless( quietRun( 'which ofprotocol' ),
154
                     'Reference user switch is not installed' )
155
class testOptionsTopoUserspace( testOptionsTopoCommon, unittest.TestCase ):
156
    "Verify ability to create networks with host and link options (UserSwitch)."
157
    switchClass = UserSwitch
158

    
159
if __name__ == '__main__':
160
    setLogLevel( 'warning' )
161
    unittest.main()