forked from hundeboll/riddler
/
riddler.py
executable file
·291 lines (248 loc) · 8.85 KB
/
riddler.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
#!/usr/bin/env python2
import sys
import argparse
import time
import riddler_interface as interface
import riddler_controller as controller
import riddler_client as client
import riddler_data as data
parser = argparse.ArgumentParser(description="Riddler Controller Application")
parser.add_argument("--config", default="riddler_defaults")
(args,dummy) = parser.parse_known_args()
try:
c = __import__(args.config)
defaults = dict((k, v) for k,v in c.__dict__.iteritems() if not k.startswith('__'))
except ImportError:
print("Unable to load config file: {0}".format(args.config))
sys.exit(1)
parser.add_argument("--rate_start", type=int)
parser.add_argument("--rate_stop", type=int)
parser.add_argument("--rate_step", type=int)
parser.add_argument("--ratio_start", type=int)
parser.add_argument("--ratio_stop", type=int)
parser.add_argument("--ratio_step", type=int)
parser.add_argument("--hold_time", type=int)
parser.add_argument("--hold_start", type=int)
parser.add_argument("--hold_stop", type=int)
parser.add_argument("--hold_step", type=int)
parser.add_argument("--symbols_start", type=int)
parser.add_argument("--symbols_stop", type=int)
parser.add_argument("--symbols_step", type=int)
parser.add_argument("--purge_time", type=int)
parser.add_argument("--rts_threshold", type=str)
parser.add_argument("--test_profile")
parser.add_argument("--test_time", type=int)
parser.add_argument("--test_sleep", type=int)
parser.add_argument("--test_loops", type=int)
parser.add_argument("--tcp_algos")
parser.add_argument("--tcp_window", type=int)
parser.add_argument("--tcp_algo")
parser.add_argument("--window_start", type=int)
parser.add_argument("--window_stop", type=int)
parser.add_argument("--window_step", type=int)
parser.add_argument("--sample_interval", type=int)
parser.add_argument("--nodes_file")
parser.add_argument("--data_file")
parser.add_argument("--client_port", type=int)
parser.add_argument("--client_host")
parser.add_argument("--codings", type=list)
parser.add_argument("--errors", type=list)
parser.add_argument("--gen_size", type=int)
parser.add_argument("--packet_size", type=int)
parser.add_argument("--iperf_len", type=int)
parser.add_argument("--fixed_overshoot", type=dict)
parser.add_argument("--encoders", type=list)
parser.add_argument("--encoder_timeout", type=float)
parser.add_argument("--decoder_timeout", type=float)
parser.add_argument("--recoder_timeout", type=float)
parser.add_argument("--helper_timeout", type=float)
parser.add_argument("--helper_overshoot", type=float)
parser.add_argument("--ack_timeout", type=list)
parser.add_argument("--req_timeout", type=list)
parser.add_argument("--systematic", type=bool)
parser.add_argument("--fox_verbose", type=int)
parser.add_argument("--helper_threshold", type=float)
parser.add_argument("--rlnc_rates", type=dict)
parser.add_argument("--fields", type=list) #RASP! ADD_ARG! FIELDS_EXAMPLE!
parser.add_argument("--max_tx", type=int)
parser.add_argument("--filename", type=str) #This is the filename for the datafile
parser.add_argument("--plot_enable", type=int) #1: Enables plotting. 0: Disable plotting
parser.add_argument("--plot_list", type=list)
parser.add_argument("--number_of_nodes", type=int)
parser.add_argument("--id", type=int)
parser.add_argument("--linkquality", type=str)
parser.set_defaults(**defaults)
args = parser.parse_args()
class riddler:
def __init__(self, args):
self.args = args
self.nodes = []
self.controller = None
self.data = None
# Start server thread to wait for clients
self.client = client.client(self.args)
self.client.set_riddler(self)
# Load node objects from network config
if not self.load_nodes():
self.quit()
return
# Connect to nodes
self.start_nodes()
def start(self):
# Create a data object for results and samples
#print "b"
#self.data = data.data(self.args) #FIX! RASP!
self.data = data.data_pandas(self.args)
self.data.add_nodes(self.nodes)
# Inform clients
self.client.export_event(interface.STARTED)
# Start test controller
#print(" Starting test controller ")
self.controller = controller.controller(self.args)
self.controller.nodes = self.nodes
self.controller.data = self.data
self.controller.start()
# Tell the controller to stop and wait for it
def stop_controller(self):
if self.controller:
self.controller.stop()
self.controller.join()
# Disconnect clients and wait for it
def stop_client(self):
if self.client:
self.client.stop()
self.client.join()
# Disconnect nodes
def stop_nodes(self):
# End nodes threads
for node in self.nodes:
node.stop()
# Wait for them to finish
for node in self.nodes:
node.join()
# Stop a running test
def stop_test(self):
if not self.controller:
return
# Tell controller to stop
print("Stopping test")
self.controller.stop()
# Inform clients
self.client.export_event(interface.STOPPED)
# Reconnect nodes to free controller
for node in self.nodes:
node.reconnect()
# Wait for controller to finish
self.controller.join()
# Stop everything and quit program
def quit(self):
print("Quitting. Please wait...")
print("Stopping nodes")
self.stop_nodes()
print("Stopping controller")
self.stop_controller()
print("Stopping client")
self.stop_client()
sys.exit(0)
# Load the nodes configuration and distribute node references
def load_nodes(self):
try:
c = __import__(self.args.nodes_file) #imports data from nodes file
self.nodes = c.node.nodes #Nodes are saved in class
except ImportError:
print("Unable to load nodes file: {0}".format(self.args.nodes_file))
return False
# Add client object to each node
for node in self.nodes:
node.client = self.client
# Add node objects to client server
for node in self.nodes:
self.client.export_node(node)
return True
# Start node thread and wait for information from each node
def start_nodes(self):
for node in self.nodes:
node.start()
try:
for node in self.nodes:
node.wait()
except KeyboardInterrupt:
print("Quit")
self.quit()
time.sleep(5)
def set_pause(self, pause):
if not self.controller:
return
self.controller.set_pause(pause)
for node in self.nodes:
node.pause()
if pause:
self.client.export_event(interface.PAUSED)
else:
self.client.export_event(interface.UNPAUSED)
# Clear the pause event in controller to pause current run
def toggle_pause(self):
if not self.controller:
return
print("Toggling pause")
if self.controller.toggle_pause():
self.client.export_event(interface.PAUSED)
else:
self.client.export_event(interface.UNPAUSED)
for node in self.nodes:
node.pause()
# Recover by reconnecting nodes
def recover(self):
if not self.controller:
return
print("Recovering")
self.controller.recover()
def save_data(self):
if not self.data:
return
# Read filename form console
path = raw_input("Filename: (Hit enter for '{0}')\n".format(self.args.data_file))
# If no name was entered, we use the configured one
if not path:
path = self.args.data_file
# Dump data to pickle file
data.dump_data(self.data, path)
print("Data saved to '{0}'".format(path))
def set_args(self, args):
self.args = args
self.controller.args = args
def print_help():
print("")
print(" t Start test")
print(" p Toggle pause")
print(" s Stop test")
print(" r Recover")
print(" d Save data")
print(" q Quit")
print(" h Help")
print("")
if __name__ == "__main__":
r = riddler(args)
try:
print_help()
while r:
# Get a key from user
c = interface.get_keypress()
# Select action based on key pressed
if c == 't':
r.start()
elif c == 'p':
r.toggle_pause()
elif c == 's':
r.stop_test()
elif c == 'r':
r.recover()
elif c == 'd':
r.save_data()
elif c == 'q':
r.quit()
else:
print_help()
except KeyboardInterrupt:
print("Quitting")
r.quit()