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