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 version 2 as
7 # published by the Free Software Foundation;
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
17 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
20 ############ METHODS DEBUG NETNSWRAPPER EXECUTION
22 ## The netnswrapper works in ditributed mode, receiving instructions from
23 ## a remote client. This makes it very hard to debug scripting errors
24 ## in the client side. To simplify error debugging, when set to debug mode,
25 ## the ns3wrapper dumps every executed line to a script that can be then
26 ## executed locally to reproduce and debug the experiment.
28 ###########################################################################
32 class NetNSWrapperDebuger(object):
33 def __init__(self, enabled):
34 super(NetNSWrapperDebuger, self).__init__()
35 self._enabled = enabled
36 self._script_path = "debug.py"
45 def script_path(self):
46 return self._script_path
48 def dump_to_script(self, command):
49 f = open(self.script_path, "a")
50 f.write("%s" % command)
53 def dump_header(self):
58 from netnswrapper import NetNSWrapper
60 wrapper = NS3Wrapper()
63 self.dump_to_script(header)
65 def dump_factory(self, uuid, type_name, kwargs):
69 command = ("kwargs = %(kwargs)s\n"
70 "%(uuid)s = wrapper.factory(%(type_name)s, **kwargs)\n\n"
72 "uuid": self.format_value(uuid),
73 "type_name": self.format_value(type_name),
74 "kwargs": self.format_kwargs(kwargs)
77 self.dump_to_script(command)
79 def dump_create(self, uuid, clazzname, args):
83 command = ("args = %(args)s\n"
84 "%(uuid)s = wrapper.create(%(clazzname)s, *args)\n\n"
86 "uuid": self.format_value(uuid),
87 "clazzname": self.format_value(clazzname),
88 "args": self.format_args(args),
91 self.dump_to_script(command)
93 def dump_invoke(self, newuuid, uuid, operation, args, kwargs):
97 command = ("args = %(args)s\n"
98 "kwargs = %(kwargs)s\n"
99 "%(newuuid)s = wrapper.invoke(%(uuid)s, %(operation)s, *args, **kwargs)\n\n"
101 "newuuid": self.format_value(newuuid) if newuuid else "nothing",
102 "uuid": self.format_value(uuid),
103 "operation": self.format_value(operation),
104 "args": self.format_args(args),
105 "kwargs": self.format_kwargs(kwargs),
108 self.dump_to_script(command)
110 def dump_set(self, uuid, name, value):
114 command = ("wrapper.set(%(uuid)s, %(name)s, %(value)s)\n\n"
116 "uuid": self.format_value(uuid),
117 "name": self.format_value(name),
118 "value": self.format_value(value),
121 self.dump_to_script(command)
123 def dump_get(self, uuid, name):
127 command = ("wrapper.get(%(uuid)s, %(name)s)\n\n"
129 "uuid": self.format_value(uuid),
130 "name": self.format_value(name),
133 self.dump_to_script(command)
135 def dump_shutdown(self):
139 command = "wrapper.shutdown()\n\n"
140 self.dump_to_script(command)
142 def format_value(self, value):
143 if isinstance(value, str) and value.startswith("uuid"):
144 return value.replace("-", "")
147 return pprint.pformat(value)
149 def format_args(self, args):
150 fargs = map(self.format_value, args)
151 return "[%s]" % ",".join(fargs)
153 def format_kwargs(self, kwargs):
154 fkwargs = map(lambda (k,w):
155 "%s: %s" % (self.format_value(k), self.format_value(w)),
158 return "dict({%s})" % ",".join(fkwargs)