Revision b672166b

View differences:

wcn_simulator.py
11 11
from mininet.link import TCLink
12 12

  
13 13
import networkx as nx
14
from time import sleep, time
15
from os import kill, path, makedirs
16
from psutil import Process
17
import signal
14 18
from matplotlib.pyplot import ion
19
from random import sample
20

  
15 21
from gengraphs import loadGraph
16 22
from misclibs import showGraph
17 23

  
......
79 85
        for e in self.gg.edges(data=True):
80 86
            # 10 Mbps, 5ms delay, 10% loss, 1000 packet queue
81 87
            # htp: Hierarchical Token Bucket rate limiter
82
            quality_params = {"bw":10,"delay":'5ms', "loss":100-100.0/e[2]['weight'], "max_queue_size":1000, "use_htb":True}
88
#            quality_params = {"bw":10,"delay":'5ms', "loss":100-100.0/e[2]['weight'], "use_htb":True}
89
            quality_params = {}
90
#            quality_params["bw"] = 10
91
#            quality_params["delay"] = '5ms'
92
#            quality_params["loss"] = 100-100.0/e[2]['weight']
93
#            quality_params["use_htb"] = True
83 94
            self.insertLink(self.get(e[0]),self.get(e[1]),quality_params)
84 95

  
85 96
        if draw:
......
104 115
                )
105 116

  
106 117
    def setShortestRoutes(self):
107
        self.setNeighboursRoutes()
108 118
        paths = nx.shortest_path(self.gg,weight='weight')
109 119
        for node1 in paths.keys():
120
            host1 = self.get(node1)
110 121
            debug("Starting node: "+node1+'\n')
111 122
            debug("\tpaths: "+str(paths[node1])+'\n')
112 123
            for node2 in paths[node1].keys():
113
                if node2 != node1 and len(paths[node1][node2])>2:
114
                    debug("\tDestination node: "+node2+'\n')
115
                    nextHop = self.get(paths[node1][node2][1])
116
                    debug("\tNextHop node: "+nextHop.name+'\n')
117
                    dsts = self.getNodeAddrs(self.get(node2))
118
                    intfs = self.get(node1).connectionsTo(nextHop)
119
                    nextAddrs = [ couple[1].ip for couple in intfs ]
120
                    for dst in dsts:
121
                        for addr in nextAddrs:
122
                            self.get(node1).cmd("ip route add "+dst+" via "+addr)
123
                            debug("\tip route add "+dst+" via "+addr+'\n')
124
                
124
                if node2 != node1 :
125
                    if len(paths[node1][node2])>2:
126
                        debug("\tDestination node: "+node2+'\n')
127
                        nextHop = self.get(paths[node1][node2][1])
128
                        debug("\tNextHop node: "+nextHop.name+'\n')
129
                        dsts = self.getNodeAddrs(self.get(node2))
130
                        intfs = host1.connectionsTo(nextHop)
131
                        nextAddrs = [ couple[1].ip for couple in intfs ]
132
                        rintf = intfs[0][0] # WARNING we just consider one link
133
                        for dst in dsts:
134
                            for addr in nextAddrs:
135
                                host1.cmd("ip route add "+dst+" via "+addr+" dev "+rintf.name)
136
                                debug("\tip route add "+dst+" via "+addr+'\n')
137
                    else :
138
                        host2 = self.get(node2)
139
                        intfs = [ couple[0] for couple in host1.connectionsTo(host2) ]
140
                        rintf = intfs[0] # WARNING we just consider one link
141
                        raddrs = self.getNodeAddrs(host2)
142
                        for addr in raddrs:
143
                            host1.setHostRoute(addr,rintf.name)
144

  
145

  
146
class MininetTest(object):
147
    def __init__(self,mininet):
148
        self.net = mininet
149
        self.pendingProc = {} 
150
    
151
    def getHostSample(self,num):
152
        hosts = sample(self.net.values(),num)
153
        return hosts[:num]
154

  
155
    def bgCmd(self,host,*args):
156
        # here it's a little workaround for tracing the resulting pid
157
        # it launch the new process using the mininet interface
158
        # but it check the newly created process id using psutil
159
        host_proc = Process(host.pid)
160
        host_ps = set(host_proc.get_children())
161
        host.sendCmd(*(args+("&",)))
162
        sleep(0.5)
163
        pid = (set(host_proc.get_children()).difference(host_ps)).pop().pid
164
        info("BGProcess: "+str(pid)+"; ")
165
        self.pendingProc[pid] = host
166
        return pid
167

  
168
    def sendSig(self,pid,sig=signal.SIGTERM):
169
        try:
170
            info("Killing BGProcess: "+str(pid)+"; ")
171
            kill( pid, sig )
172
        except OSError:
173
            error("Error while killing process "+str(pid))
174
            pass
175

  
176
    def killAll(self):
177
        for pid in self.pendingProc.keys():
178
            self.sendSig(pid,signal.SIGKILL)
179
            self.pendingProc[pid].monitor() # wait exiting
180
        self.pendingProc.clear()
181

  
182
class PSTest(MininetTest):
183
    def __init__(self,mininet,duration=300):
184
        super(PSTest,self).__init__(mininet)
185
        self.source = None
186
        self.hosts = []
187
        self.duration = duration
188
        self.prefix = ''
189

  
190
    def setPrefix(self,name):
191
        self.prefix = str(name)+'_'+str(self.duration)+'_'+str(len(self.hosts)+1)+'hosts/' 
192
        if not path.exists(self.prefix):
193
                makedirs(self.prefix)
194

  
195
    def launchPS(self,host,params):
196
        cmd = "./streamer"
197
        self.bgCmd(host,cmd,*reduce(lambda x, y: x + y, params.items()))
198

  
199
    def launchPeer(self,host,source,source_port=7000):
200
        logfile = self.prefix+host.name.split('_')[0]+"_peerstreamer_normal_$(date +%s).log"
201
        params = {}
202
        params['-i'] = source.defaultIntf().ip
203
        params['-p'] = str(source_port)
204
        params['-c'] = '38'
205
        params['--chunk_log'] = ''
206
        params['>'] = '/dev/null'
207
        params['2>'] = logfile
208
        self.launchPS(host,params)
209

  
210
    def launchSource(self,host,chunk_mult=1,source_port=7000):
211
        video_file = "bunny.ts,loop=1"
212
        logfile = self.prefix+host.name.split('_')[0]+"_source_normal_$(date +%s).log"
213
        params = {}
214
        params['-I'] = host.defaultIntf().name
215
        params['-P'] = str(source_port)
216
        params['-m'] = str(chunk_mult)
217
        params['-f'] = video_file
218
        params['-c'] = '38'
219
        params['--chunk_log'] = ''
220
        params['>'] = '/dev/null'
221
        params['2>'] = logfile
222
        self.launchPS(host,params)
223

  
224
    def runTest(self):
225
        info("*** Launching PeerStreamer test\n")
226
        info("Data folder: "+self.prefix+"\n")
227
        if self.source:
228
            self.launchSource(self.source)
229

  
230
        for h in self.hosts:
231
            self.launchPeer(h,self.source)
232
        info("Waiting completion...\n")
233
        sleep(self.duration)
234

  
235
        self.killAll()
236

  
237
class PSHostsTest(PSTest):
238
    def __init__(self,mininet,source_name,peer_names,duration=300,name=None):
239
        super(PSHostsTest,self).__init__(mininet,duration=duration)
240
        self.source = mininet.get(source_name)
241
        for n in peer_names:
242
            self.hosts.append(mininet.get(n))
243
        self.setPrefix(name)
244

  
245
class PSRandomTest(PSTest):
246
    def __init__(self,mininet,duration=300,num_peers=5,name=None):
247
        super(PSRandomTest,self).__init__(mininet,duration)
248
        self.hosts = self.getHostSample(num_peers)
249
        if len(self.hosts) > 0:
250
            self.source = self.hosts.pop()
251
        self.setPrefix(name)
125 252

  
126 253
if __name__ == '__main__':
127 254
    setLogLevel('info')
128
    net = GraphNet("test.edges")
255
    net = GraphNet("LeoNets/FFGraz0.edges",draw=True)
129 256
    net.start()
130 257
    net.enableForwarding()
131 258
    net.setShortestRoutes()
132
    CLI(net)
259
    test_name = "FFGRAZ0_parameterless_"+str(int(time()))
260
    for i in range(1):
261
        info( "+++++++ Round: "+str(i+1) + '\n')
262
        #test = PSTest(net,duration=600,name=test_name,num_peers=(10-i))
263
        test = PSHostsTest(net,'h46_46',['h121_121','h28_28'],duration=30,name=test_name)
264
        test.runTest()
265
      #  sleep(60)
133 266
    net.stop()
134

  
135
#    setLogLevel('info')
136
#    topo = TopoFactory("minitest.edges")
137
#    net = Mininet(topo,controller = OVSController,host=CPULimitedHost, link=TCLink)
138
#    net.start()
139
#    CLI(net)
140
#    net.stop()

Also available in: Unified diff