2 # NEPI, a framework to manage network experiments
3 # Copyright (C) 2013 INRIA
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
21 ############ METHODS DEBUG NETNSWRAPPER EXECUTION
23 ## The netnswrapper works in ditributed mode, receiving instructions from
24 ## a remote client. This makes it very hard to debug scripting errors
25 ## in the client side. To simplify error debugging, when set to debug mode,
26 ## the ns3wrapper dumps every executed line to a script that can be then
27 ## executed locally to reproduce and debug the experiment.
29 ###########################################################################
33 class NetNSWrapperDebuger(object):
34 def __init__(self, enabled):
35 super(NetNSWrapperDebuger, self).__init__()
36 self._enabled = enabled
37 self._script_path = "debug.py"
46 def script_path(self):
47 return self._script_path
49 def dump_to_script(self, command):
50 f = open(self.script_path, "a")
51 f.write("%s" % command)
54 def dump_header(self):
59 from netnswrapper import NetNSWrapper
61 wrapper = NS3Wrapper()
64 self.dump_to_script(header)
66 def dump_factory(self, uuid, type_name, kwargs):
70 command = ("kwargs = %(kwargs)s\n"
71 "%(uuid)s = wrapper.factory(%(type_name)s, **kwargs)\n\n"
73 "uuid": self.format_value(uuid),
74 "type_name": self.format_value(type_name),
75 "kwargs": self.format_kwargs(kwargs)
78 self.dump_to_script(command)
80 def dump_create(self, uuid, clazzname, args):
84 command = ("args = %(args)s\n"
85 "%(uuid)s = wrapper.create(%(clazzname)s, *args)\n\n"
87 "uuid": self.format_value(uuid),
88 "clazzname": self.format_value(clazzname),
89 "args": self.format_args(args),
92 self.dump_to_script(command)
94 def dump_invoke(self, newuuid, uuid, operation, args, kwargs):
98 command = ("args = %(args)s\n"
99 "kwargs = %(kwargs)s\n"
100 "%(newuuid)s = wrapper.invoke(%(uuid)s, %(operation)s, *args, **kwargs)\n\n"
102 "newuuid": self.format_value(newuuid) if newuuid else "nothing",
103 "uuid": self.format_value(uuid),
104 "operation": self.format_value(operation),
105 "args": self.format_args(args),
106 "kwargs": self.format_kwargs(kwargs),
109 self.dump_to_script(command)
111 def dump_set(self, uuid, name, value):
115 command = ("wrapper.set(%(uuid)s, %(name)s, %(value)s)\n\n"
117 "uuid": self.format_value(uuid),
118 "name": self.format_value(name),
119 "value": self.format_value(value),
122 self.dump_to_script(command)
124 def dump_get(self, uuid, name):
128 command = ("wrapper.get(%(uuid)s, %(name)s)\n\n"
130 "uuid": self.format_value(uuid),
131 "name": self.format_value(name),
134 self.dump_to_script(command)
136 def dump_start(self):
140 command = "wrapper.start()\n\n"
141 self.dump_to_script(command)
143 def dump_stop(self, time = None):
147 command = ("wrapper.stop(time=%(time)s)\n\n"
149 "time": self.format_value(time) if time else "None",
152 self.dump_to_script(command)
154 def dump_shutdown(self):
158 command = "wrapper.shutdown()\n\n"
159 self.dump_to_script(command)
161 def dump_add_static_route(self, uuid, args):
165 command = ("args = %(args)s\n"
166 "wrapper._add_static_route(%(uuid)s, *args)\n\n"
168 "uuid": self.format_value(uuid),
169 "args": self.format_args(args),
172 self.dump_to_script(command)
174 def format_value(self, value):
175 if isinstance(value, str) and value.startswith("uuid"):
176 return value.replace("-", "")
179 return pprint.pformat(value)
181 def format_args(self, args):
182 fargs = map(self.format_value, args)
183 return "[%s]" % ",".join(fargs)
185 def format_kwargs(self, kwargs):
186 fkwargs = map(lambda (k,w):
187 "%s: %s" % (self.format_value(k), self.format_value(w)),
190 return "dict({%s})" % ",".join(fkwargs)