17ae1f26f789640e4c63c0f285f96cca29f5b40c
[nepi.git] / src / nepi / resources / netns / netnswrapper_debug.py
1 #
2 #    NEPI, a framework to manage network experiments
3 #    Copyright (C) 2013 INRIA
4 #
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;
8 #
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.
13 #
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/>.
16 #
17 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
18
19
20 ############ METHODS DEBUG NETNSWRAPPER EXECUTION
21 ##
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.
27 ##
28 ###########################################################################
29
30 import logging
31
32 class NetNSWrapperDebuger(object):
33     def __init__(self, enabled):
34         super(NetNSWrapperDebuger, self).__init__()
35         self._enabled = enabled
36         self._script_path = "debug.py"
37
38         self.dump_header()
39
40     @property
41     def enabled(self):
42         return self._enabled
43
44     @property
45     def script_path(self):
46         return self._script_path
47
48     def dump_to_script(self, command):
49         f = open(self.script_path, "a")
50         f.write("%s" % command)
51         f.close()
52
53     def dump_header(self):
54         if not self.enabled:
55             return
56
57         header = """
58 from netnswrapper import NetNSWrapper
59
60 wrapper = NS3Wrapper()
61
62 """
63         self.dump_to_script(header)
64
65     def dump_factory(self, uuid, type_name, kwargs):
66         if not self.enabled:
67             return
68
69         command = ("kwargs = %(kwargs)s\n"
70                 "%(uuid)s = wrapper.factory(%(type_name)s, **kwargs)\n\n" 
71                 ) % dict({
72                  "uuid": self.format_value(uuid),
73                  "type_name": self.format_value(type_name),
74                  "kwargs": self.format_kwargs(kwargs)
75                 })
76
77         self.dump_to_script(command)
78
79     def dump_create(self, uuid, clazzname, args):
80         if not self.enabled:
81             return
82
83         command = ("args = %(args)s\n"
84                 "%(uuid)s = wrapper.create(%(clazzname)s, *args)\n\n" 
85                 ) % dict({
86                  "uuid": self.format_value(uuid),
87                  "clazzname": self.format_value(clazzname),
88                  "args": self.format_args(args),
89                 })
90
91         self.dump_to_script(command)
92
93     def dump_invoke(self, newuuid, uuid, operation, args, kwargs):
94         if not self.enabled:
95             return
96
97         command = ("args = %(args)s\n"
98                    "kwargs = %(kwargs)s\n"
99                    "%(newuuid)s = wrapper.invoke(%(uuid)s, %(operation)s, *args, **kwargs)\n\n" 
100                 ) % dict({
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),
106                 })
107
108         self.dump_to_script(command)
109
110     def dump_set(self, uuid, name, value):
111         if not self.enabled:
112             return
113
114         command = ("wrapper.set(%(uuid)s, %(name)s, %(value)s)\n\n" 
115                 ) % dict({
116                  "uuid": self.format_value(uuid),
117                  "name": self.format_value(name),
118                  "value": self.format_value(value),
119                 })
120
121         self.dump_to_script(command)
122
123     def dump_get(self, uuid, name):
124         if not self.enabled:
125             return
126
127         command = ("wrapper.get(%(uuid)s, %(name)s)\n\n" 
128                 ) % dict({
129                  "uuid": self.format_value(uuid),
130                  "name": self.format_value(name),
131                 })
132         
133         self.dump_to_script(command)
134
135     def dump_shutdown(self):
136         if not self.enabled:
137             return
138
139         command = "wrapper.shutdown()\n\n"
140         self.dump_to_script(command)
141
142     def format_value(self, value):
143         if isinstance(value, str) and value.startswith("uuid"):
144             return value.replace("-", "")
145
146         import pprint 
147         return pprint.pformat(value)
148
149     def format_args(self, args):
150         fargs = map(self.format_value, args)
151         return "[%s]" % ",".join(fargs)
152
153     def format_kwargs(self, kwargs):
154         fkwargs = map(lambda (k,w): 
155                "%s: %s" % (self.format_value(k), self.format_value(w)), 
156             kwargs.iteritems())
157         
158         return  "dict({%s})" % ",".join(fkwargs)
159