Revision 63e61e90 test_code/olsr.py

View differences:

test_code/olsr.py
1 1

  
2 2
import sys
3
sys.path.append('../')
4 3
import os
5
sys.path.append('scripts/pop-routing/')
4
sys.path.append('../')
6 5
from network_builder import *
7 6
import random
8 7
import time
9
from dummyrouting import dummyRoutingRandomTest
10
from compute_theoretical_values import ComputeTheoreticalValues
11

  
12
import signal
13

  
14 8
from test_generic import *
15 9

  
16 10

  
17
class OLSRTest(dummyRoutingRandomTest):
11
class OLSRTest(MininetTest):
18 12

  
19 13
    def launch_sniffer(self, host):
14
        """ helper function """
20 15

  
21 16
        cmd = "tcpdump -i any -n -X -e "
22 17

  
......
47 42

  
48 43
    def launch_OLSR(self, host,  args):
49 44

  
50
        cmd = "../olsrd/olsrd " + args
45
        cmd = self.olsrd + " " + args 
51 46

  
52 47
        log_str = "Host " + host.name + " launching command:\n"
53 48
        info(log_str)
......
60 55

  
61 56
        return self.bgCmd(host, True, cmd,
62 57
                          *reduce(lambda x, y: x + y, params.items()))
63

  
64
    def runTest(self):
65

  
66
        info("*** Launching OLSR test\n")
67
        info("Data folder: "+self.prefix+"\n")
68

  
69
        self.stopNodeList = []
70
        if self.stopAllNodes:
71
            self.stopNodeList = self.getCentrality()[:self.stopAllNodes]
72
        elif self.stopList:
73
            self.stopNodeList = [[self.number_to_host(i) for i in self.stopList]]
74
        run_ids = range(len(self.stopNodeList))
75

  
76
        if not run_ids:
77
            # do at least one run
78
            run_ids = [0]
79
        for run_id in run_ids:
80
            info("\nStarting run " + str(run_id) + "\n")
81
            if self.stopNodeList:
82
                self.nodeCrashed = self.stopNodeList.pop(0)
83
            else:
84
                self.nodeCrashed = None
85

  
86
            if not self.startRun(run_id=run_id):
87
                # some times process are not killed in time, UDP
88
                # ports are still occupied and the next run can not
89
                # start correctly. I kill everything, wait some time, try
90
                # to restart. If something still goes wrong i stop
91
                # the emulation
92

  
93
                self.killAll()
94
                time.sleep(10)
95
                info("\nWARNING: run_id " + str(run_id) +
96
                     " could not start, retrying...\n")
97
                if not self.startRun(run_id):
98
                    error("\nERROR: run_id " + str(run_id) +
99
                          " could not start!" +
100
                          "please check the logs\n")
101
                    sys.exit(1)
102

  
103
            eventDict = {
104
                self.startLog: ["start/stop logging ",
105
                                self.sendSignal, {"sig": signal.SIGUSR1}
106
                                ],
107
                self.stopLog: ["Start/stop logging ",
108
                               self.sendSignal, {"sig": signal.SIGUSR1}
109
                               ]
110
                }
111

  
112
            if self.nodeCrashed:
113
                eventDict[self.stopTime] = ["Stopping node(s) " + str(self.nodeCrashed) +
114
                                " at time " + str(self.stopTime) + "\n", 
115
                                self.sendSignal,
116
                                {"sig": signal.SIGUSR2,
117
                                 "hostName": self.nodeCrashed}
118
                                ]
119

  
120

  
121
            eventList = []
122
            relativeTime = 0
123
            for e in sorted(eventDict.keys()):
124
                if e > 0:
125
                    data = eventDict[e]
126
                    eventList.append([e - relativeTime] + data)
127
                    relativeTime += (e - relativeTime)
128

  
129
            waitTime = self.duration - relativeTime
130

  
131
            for event in eventList:
132
                sleep(event[0])
133
                event[2](**event[3])
134
                info(event[1] + str(time.time()) + "\n")
135
            sleep(waitTime)
136
            for pid in self.pendingProc.keys():
137
                self.sendSig(pid, signal.SIGTERM)
138
            time.sleep(2)
139
            self.killAll()
140
            time.sleep(2)
141

  
142

  
143
    def getCentrality(self):
144

  
145
        node_centrality_posteriori = {}
146
        centrality = {}
147
        for n in self.graph.nodes():
148
            gg = self.graph.copy()
149
            edges = self.graph.edges([n]) 
150
            gg.remove_node(n)
151
            # compute the connected components
152
            # WARNING: connected_components should return a list 
153
            # sorted by size, largest first. It does not, so i resort them
154
            unsorted_comp = list(nx.connected_components(gg))
155
            comp = sorted(unsorted_comp, key = lambda x: -len(x))
156
            # re-add the node
157
            gg.add_node(n)
158
            # re-add the edges to nodes in the main component
159
            for (fr, to) in edges:
160
                if fr in comp[0]:
161
                    gg.add_edge(fr, n)
162
                if to in comp[0]:
163
                    gg.add_edge(n, to)
164
            # now compute the centrality. This tells how important is the node
165
            # for the main connected component. If this is 0, it is not worth
166
            # to remove this node
167
            cent = nx.betweenness_centrality(gg)[n]
168
            isolated_nodes = [x for component in comp[1:] for x in component]
169
            node_centrality_posteriori[n] = [cent, [n] + isolated_nodes]
170
            centrality[n] = cent
171
        betw = [x for x in nx.betweenness_centrality(self.graph).items()\
172
                if x[1] > 0 and node_centrality_posteriori[x[0]][0] > 0]
173

  
174
        return [node_centrality_posteriori[k[0]][1] for k in sorted(betw, key=lambda x: -x[1])]
175

  
176
    def startRun(self, run_id=0):
177

  
178
        rNode = ""
179
        host_list = self.getAllHosts()
180

  
181
        # default values
182
        hello_timer = self.HelloInterval
183
        tc_timer = self.TcInterval
184

  
185
        if rNode:
186
            info("\nChosen node " + str(rNode) + " to fail\n")
187

  
188
        if self.popRouting:
189
            c = ComputeTheoreticalValues(graph_file=None, graph=self.graph,
190
                    cH=hello_timer, cTC=tc_timer)
191
            cent = nx.betweenness_centrality(self.graph)
192
            deg = nx.degree(self.graph)
193
            for (h, cc) in sorted(cent.items(), key = lambda x: -x[1]):
194
                print deg[h],",", cent[h], ",", c.Hi[h], ",", c.TCi[h]
195

  
196
        # h_load_pop = 0
197
        # h_load_nopop = 0
198
        # tc_load_pop = 0
199
        # tc_load_nopop = 0
200
        #for h in host_list:
201
        #    h_load_pop += len(self.graph[h.name])/c.Hi[h.name]
202
        #    h_load_nopop += len(self.graph[h.name])/hello_timer
203
        #    tc_load_pop += len(self.graph.edges())/c.TCi[h.name]
204
        #    tc_load_nopop += len(self.graph.edges())/tc_timer
205
        #print "XXXXXXXXX POP, h,tc", h_load_pop, tc_load_pop
206
        #print "XXXXXXXXX NOPOP, h,tc", h_load_nopop, tc_load_nopop
207
        for idx, h in enumerate(host_list):
208
            intf = h.intfList()
209
            intf_list = ' '.join(["\"" + i.name + "\"" for i in intf])
210

  
211
            # set the main IP of the host to the one ending with .1
212
            main_ip = ""
213

  
214
            log_folder = self.logPrefix + "OLSR-log-" + str(self.runId) + "/"
215
            try:
216
                os.makedirs(log_folder)
217
            except:
218
                pass
219
            olsr_conf_file = self.prefix + h.name + ".conf"
220
            olsr_json_file = log_folder + h.name
221
            olsr_lock_file = "/var/run/" + h.name + str(time.time()) + ".lock"
222
            f = open(olsr_conf_file, "w")
223
            if self.popRouting:
224
                hello_timer = c.Hi[h.name]
225
                tc_timer = c.TCi[h.name]
226
            hello_validity = hello_timer * 3
227
            tc_validity = tc_timer * 3
228
            print >> f, self.conf_file % (olsr_lock_file, run_id,
229
                                          olsr_json_file, intf_list,
230
                                          hello_timer, hello_validity,
231
                                          tc_timer, tc_validity)
232
            f.close()
233
            args = "-f " + os.path.abspath(olsr_conf_file)
234

  
235
            launch_pid = self.launch_OLSR(h, args)
236

  
237
            if self.dump:
238
                self.launch_sniffer(h)
239

  
240
        if not self.nodeCrashed and rNode:
241
            self.nodeCrashed = [rNode]
242
        return launch_pid
243

  
244 58
    def start_ping(self, exclude=[], number=1, run_id=0):
245 59

  
246
        print exclude
247 60
        host_list = self.getAllHosts()
248 61
        exclude_ips = []
249 62
        destinations = {}
250 63

  
251 64
        for h in host_list:
252
            if h.name in exclude:
253
                exclude_ips.append(h.intfList()[0].ip)
254
            else:
255
                destinations[h] = []
65
            destinations[h] = []
256 66

  
257 67
        for h in destinations:
258 68
            intf = h.intfList()
......
272 82
        for (h, ip_list) in destinations.items():
273 83
                self.launch_ping(h, ip_list, run_id=run_id)
274 84

  
275
    def number_to_host(self, host_number):
276

  
277
        host_list = self.getAllHosts()
278
        for host in host_list:
279
            number = int(host.name.split("_")[0][1:])
280
            if host_number == number:
281
                return host.name
282
        print "ERROR: no host number", host_number, "in host_list:"
283
        print "  ", self.getAllHosts()
284
        return None
285

  
286 85
    def get_random_destination(self):
287 86

  
288 87
        host_list = self.getAllHosts()
......
290 89
        dest_ip = d.intfList()[0].ip
291 90
        return dest_ip
292 91

  
293
    def sendSignal(self, sig, hostName=""):
294
        for pid, h in self.pendingProc.items():
295
            if hostName:
296
                for host in hostName:
297
                    if host == h.name:
298
                        print "sending signal to host:", host, ", pid", pid
299
                        self.sendSig(pid, sig)
300
            # send to all
301
            else:
302
                print "sending signal to all hosts:", sig
303
                self.sendSig(pid, sig)
92
    def runTest(self, run_id=0):
93

  
94
        host_list = self.getAllHosts()
95

  
96
        # default values
97
        hello_timer = self.HelloInterval
98
        tc_timer = self.TcInterval
99

  
100
        for idx, h in enumerate(host_list):
101
            intf = h.intfList()
102
            intf_list = ' '.join(["\"" + i.name + "\"" for i in intf])
103

  
104
            try:
105
                os.makedirs(self.conf_folder)
106
            except:
107
                pass
108
            olsr_conf_file = self.conf_folder + h.name + ".conf"
109
            olsr_lock_file = "/var/run/" + h.name + str(time.time()) + ".lock"
110
            f = open(olsr_conf_file, "w")
111
            hello_validity = hello_timer * 3
112
            tc_validity = tc_timer * 3
113
            print >> f, self.conf_file % (olsr_lock_file, intf_list,
114
                                          hello_timer, hello_validity,
115
                                          tc_timer, tc_validity)
116
            f.close()
117
            args = "-f " + os.path.abspath(olsr_conf_file)
118

  
119
            launch_pid = self.launch_OLSR(h, args)
120

  
121
            if self.dump:
122
                self.launch_sniffer(h)
123
            #if self.numPing:
124

  
125
        info("Waiting completion...\n")
126
        self.wait(self.duration, log_resources={'net': 'netusage.csv',
127
                                                'cpu': 'cpuusage.csv',
128
                                                'mem': 'memusage.csv'})
129
        self.killAll()
130
        return launch_pid
131

  
132

  
304 133

  
305 134
    def __init__(self, mininet, name, args):
306 135

  
......
323 152
        Hna6
324 153
        {
325 154
        }
326
        LoadPlugin "../olsrd/lib/dumprt/olsrd_dumprt.so.0.0"{
327
        PlParam "run_id" "%d"
328
        PlParam "log_file" "%s"
329
        PlParam "log_interval_msec" "300"
330
        }
331 155

  
332 156
        InterfaceDefaults {
333 157
        }
334 158

  
159
        LoadPlugin "../olsrd/lib/txtinfo/olsrd_txtinfo.so.1.1"
160
        {
161
        }
162

  
163
        LoadPlugin "../olsrd/lib/jsoninfo/olsrd_jsoninfo.so.1.1"
164
        {
165
        PlParam "accept" "0.0.0.0"
166
        }
167

  
335 168
        Interface %s
336 169
        {
337 170
        HelloInterval       %f
......
340 173
        TcValidityTime      %f
341 174
        }
342 175
        """
343
        if "logPrefix" in args.keys():
344
            self.logPrefix = args["logPrefix"]
345
        else:
346
            self.logPrefix = "/tmp/"
347 176

  
348
        if "runId" in args.keys():
349
            self.runId = args["runId"]
350
        else:
351
            self.runId = 0
352 177

  
353
        if "popRouting" in args.keys() and\
354
                args['popRouting'] == 'True':
355
            self.popRouting = True
178
        if not "olsrPath" in args.keys():
179
            print "ERROR: you must set olsrPath config option, " + \
180
                  "specifying where the OLSR binary is"
181
            exit()
356 182
        else:
357
            self.popRouting = False
183
            self.olsrd = args['olsrPath']
358 184

  
359 185
        if "NumPing" in args.keys():
360 186
            self.NumPing = int(args["NumPing"])
......
371 197
        else:
372 198
            self.TcInterval = 5
373 199

  
374
        if "stopAllNodes" in args.keys():
375
            self.stopAllNodes = int(args["stopAllNodes"])
200
        if "dumpTraffic" in args.keys():
201
            self.dump = True
376 202
        else:
377
            self.stopAllNodes = []
203
            self.dump = False
378 204

  
379
        if "stopList" in args.keys():
380
            self.stopList = map(int, args["stopList"].split(","))
205
        if "duration" in args.keys():
206
            self.duration = float(args["duration"])
381 207
        else:
382
            self.stopList = []
383

  
384
        # TODO import parseTime from dummyrouting
385
        if "stopTime" in args.keys():
386
            self.stopTime = float(args["stopTime"])
387
        elif self.stopAllNodes or self.stopList:
388
            print "ERROR: you set one of stopAllNodes/stopList" +\
389
                  "but did not set stopTime"
390
            exit()
391
        else:
392
            self.stopTime = 0
208
            self.duration = 60
209

  
210
        self.setPrefix(name)
211
        self.conf_folder = self.prefix + "OLSR-conf/"
212
        print "XXX", self.duration

Also available in: Unified diff