Statistics
| Branch: | Tag: | Revision:

mininet / mininet / test / test_hifi.py @ 54932125

History | View | Annotate | Download (6.08 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

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

    
38
    switchClass = None # overridden in subclasses
39

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

    
48
    def assertWithinTolerance(self, measured, expected, tolerance_frac):
49
        """Check that a given value is within a tolerance of expected
50
        tolerance_frac: less-than-1.0 value; 0.8 would yield 20% tolerance.
51
        """
52
        self.assertTrue( float(measured) >= float(expected) * tolerance_frac )
53
        self.assertTrue( float(measured) >= float(expected) * tolerance_frac )
54

    
55
    def testCPULimits( self ):
56
        "Verify topology creation with CPU limits set for both schedulers."
57
        CPU_FRACTION = 0.1
58
        CPU_TOLERANCE = 0.8  # CPU fraction below which test should fail
59
        hopts = { 'cpu': CPU_FRACTION }
60
        #self.runOptionsTopoTest( N, hopts=hopts )
61

    
62
        mn = Mininet( SingleSwitchOptionsTopo( n=N, hopts=hopts ),
63
                      host=CPULimitedHost, switch=self.switchClass )
64
        mn.start()
65
        results = mn.runCpuLimitTest( cpu=CPU_FRACTION )
66
        mn.stop()
67
        for cpu in results:
68
            self.assertWithinTolerance( cpu, CPU_FRACTION, CPU_TOLERANCE )
69

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

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

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

    
120
    def testMostOptions( self ):
121
        "Verify topology creation with most link options and CPU limits."
122
        lopts = { 'bw': 10, 'delay': '5ms', 'use_htb': True }
123
        hopts = { 'cpu': 0.5 / N }
124
        self.runOptionsTopoTest( N, hopts=hopts, lopts=lopts )
125

    
126
class testOptionsTopoOVSKernel( testOptionsTopoCommon, unittest.TestCase ):
127
    "Verify ability to create networks with host and link options (OVS kernel switch)."
128
    switchClass = OVSSwitch
129

    
130
@unittest.skip( 'Skipping OVS user switch test for now' )
131
class testOptionsTopoOVSUser( testOptionsTopoCommon, unittest.TestCase ):
132
    "Verify ability to create networks with host and link options (OVS user switch)."
133
    switchClass = partial( OVSSwitch, datapath='user' )
134

    
135
@unittest.skipUnless( quietRun( 'which ivs-ctl' ), 'IVS is not installed' )
136
class testOptionsTopoIVS( testOptionsTopoCommon, unittest.TestCase ):
137
    "Verify ability to create networks with host and link options (IVS switch)."
138
    switchClass = IVSSwitch
139

    
140
@unittest.skipUnless( quietRun( 'which ofprotocol' ),
141
                     'Reference user switch is not installed' )
142
class testOptionsTopoUserspace( testOptionsTopoCommon, unittest.TestCase ):
143
    "Verify ability to create networks with host and link options (Userspace switch)."
144
    switchClass = UserSwitch
145

    
146
if __name__ == '__main__':
147
    setLogLevel( 'warning' )
148
    unittest.main()