Statistics
| Branch: | Revision:

wcn_emulator / scripts / run_batch_simulations.py @ 2f8f6071

History | View | Annotate | Download (5.7 KB)

1
#! /usr/bin/env python
2

    
3
import sys
4
import os
5
import time
6
import argparse
7
import glob
8
import matplotlib.pyplot as plt
9
from subprocess import check_output, CalledProcessError, call
10

    
11
import json
12

    
13
from measure_breakage_time import resultParser
14

    
15
class EmulationRunner():
16

    
17
    def __init__(self):
18
        self.path_prefix = ""
19
        self.args = None
20

    
21
    def parse_args(self):
22
        parser = argparse.ArgumentParser(description = "batch simulation launcher"+ \
23
            " and analyser")
24
        parser.add_argument("-r", dest="runs", help="number of runs",
25
            default=1, type=int)
26
        parser.add_argument("-f", dest="confile", help="configuration file",
27
            default="conf/dummyrouting.ini", type=str)
28
        parser.add_argument("-t", dest="stanza", required=True,
29
                help="name of the configuration to run", type=str)
30
        parser.add_argument("-p", dest="parseonly", action="store_true",
31
                help="do not run the simulation, only parse results")
32
        self.args = parser.parse_args()
33

    
34

    
35
    def run_and_parse(self):
36
        if not self.args.parseonly and os.getuid() != 0:
37
            print "You should run this script as root"
38
            sys.exit(1)
39
        p = resultParser()
40
        self.path_prefix = "/tmp/dummyrouting-log"
41
        ret_value = {}
42
        for i in range(self.args.runs):
43
            if not self.args.parseonly and i == 0:
44
                self.clean_environment()
45
            elif i != 0:
46
                self.clean_environment(auto=True)
47
            command = ["./wcn_simulator.py", "-f", str(self.args.confile), \
48
                    "-t", str(self.args.stanza)]
49
            self.command = command
50
            if not self.args.parseonly:
51
                self.execute_run(command)
52
            jsonRt, nodeSet, failedNodes, signallingSent = \
53
                    p.readTopology(self.path_prefix)
54
            results = p.parseAllRuns(jsonRt, nodeSet, failedNodes)
55
            failures = 0
56
            for tt in sorted(results):
57
                failures += sum(results[tt][1:])
58
            ret_value[i] = {}
59
            ret_value[i]["results"] = results
60
            ret_value[i]["signalling"] = signallingSent
61
            ret_value[i]["failures"] = failures
62
            ret_value[i]["failed_nodes"] = failedNodes
63
        return ret_value
64

    
65
    def save_results(self, results):
66
        results["time"] = time.time()
67
        results["command"] = " ".join(self.command)
68
        out_string = json.dumps(results, indent=1)
69
        out_file_name = "/tmp/"+self.args.stanza+"_"+str(int(time.time()))+".results"
70
        try:
71
            out_file = open(out_file_name, 'w')
72
        except:
73
            print "Error: could not open file " + out_file
74
            raise
75
        print >> out_file, out_string
76
        out_file.close()
77

    
78
    def summarise_results(self, results):
79
        signalling_messages = 0
80
        failed_routes = 0
81
        for k,v in results.items():
82
            if k in ["time", "command"]:
83
                continue
84
            signalling_messages += v["signalling"]
85
            failed_routes += v["failures"]
86
        ret_value = {}
87
        ret_value["signalling"] = signalling_messages
88
        ret_value["failures"] = failed_routes
89
        return ret_value
90

    
91
    def plot_results(self, results, title=""):
92
        x = []
93
        y = []
94
        xlabel = "Experiment Time"
95
        ylabel = "Broken Paths"
96
        run_number = 0
97
        for runId,v in results.items():
98
            if runId in ["time", "command"]:
99
                continue
100
            run_x = []
101
            run_y = []
102
            print v
103
            for tt,vv in (sorted(v["results"].items(),
104
                key = lambda x: x[0])):
105
                run_x.append(tt)
106
                run_y.append(vv[1] + vv[2])
107
            run_number += 1
108
            x.append(run_x)
109
            y.append(run_y)
110
        for runId in range(run_number):
111
            plt.plot(x[runId],y[runId], label="Failed node:")
112
        plt.xlabel(xlabel)
113
        plt.ylabel(ylabel)
114
        title += " runs:" + str(run_number)
115
        plt.title(title)
116
        plt.savefig("/tmp/pp.png")
117
        plt.show()
118

    
119

    
120
    def clean_environment(self, auto=False):
121
        commands = []
122
        log_files = glob.glob(self.path_prefix+"*")
123
        dump_files = glob.glob("../"+self.args.stanza+"*")
124
        c = []
125
        if log_files:
126
            commands.append(["rm", "-rf"]+log_files)
127
        if dump_files:
128
            commands.append(["rm", "-rf"]+dump_files)
129
        if not auto:
130
            inputString = "I'm about to run:\n"
131
            for c in commands:
132
                inputString += " ".join(c) + "\n"
133
            inputString += "[y/n]:"
134
            user_input = raw_input(inputString)
135
        if auto or user_input == 'y':
136
            for c in commands:
137
                call(c)
138
        elif user_input != 'n' and not auto:
139
            user_input = raw_input("please choose y/n:")
140
            if user_input == 'y':
141
                for c in commands:
142
                    call(c)
143
            elif user_input != 'n':
144
                print "seems you're too dumb to choose between y/n, erasing nothing"
145

    
146

    
147
    def execute_run(self, command):
148

    
149
        if not command:
150
            print "Please give me a command to run"
151
            sys.exit(1)
152
        try:
153
            output = check_output(command, cwd="../")
154
        except CalledProcessError:
155
            print "command: ", command , " exited with non-zero value"
156
            raise
157
        except:
158
            print "Could not run command ", command
159
            raise
160

    
161
if __name__ == "__main__":
162
    e = EmulationRunner()
163
    e.parse_args()
164
    results = e.run_and_parse()
165
    e.save_results(results)
166
    r = e.summarise_results(results)
167
    e.plot_results(results, title = "Tot failures " + str(r["failures"]) + \
168
            ", tot signalling " + str(r["signalling"]))
169
    print r