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>
25 from six import integer_types, string_types
27 class NetNSWrapper(object):
28 def __init__(self, loglevel = logging.INFO, enable_dump = False):
29 super(NetNSWrapper, self).__init__()
30 # holds reference to all C++ objects and variables in the simulation
31 self._objects = dict()
34 self._logger = logging.getLogger("netnswrapper")
35 self._logger.setLevel(loglevel)
37 # Object to dump instructions to reproduce and debug experiment
38 from nepi.resources.netns.netnswrapper_debug import NetNSWrapperDebuger
39 self._debuger = NetNSWrapperDebuger(enabled = enable_dump)
50 return "uuid%s" % uuid.uuid4()
52 def get_object(self, uuid):
53 return self._objects.get(uuid)
55 def create(self, clazzname, *args):
56 """ This method should be used to construct netns objects """
59 if clazzname not in ['open'] and not hasattr(netns, clazzname):
60 msg = "Type %s not supported" % (clazzname)
61 self.logger.error(msg)
63 uuid = self.make_uuid()
66 self.logger.debug("CREATE %s( %s )" % (clazzname, str(args)))
68 self.debuger.dump_create(uuid, clazzname, args)
71 if clazzname == "open":
74 # xxx Thierry: not sure where this gets closed
75 obj = open(path, mode)
77 clazz = getattr(netns, clazzname)
79 # arguments starting with 'uuid' identify ns-3 C++
80 # objects and must be replaced by the actual object
81 realargs = self.replace_args(args)
83 obj = clazz(*realargs)
85 self._objects[uuid] = obj
88 self.logger.debug("RET CREATE ( uuid %s ) %s = %s( %s )" % (str(uuid),
89 str(obj), clazzname, str(args)))
94 def invoke(self, uuid, operation, *args, **kwargs):
95 newuuid = self.make_uuid()
98 self.logger.debug("INVOKE %s -> %s( %s, %s ) " % (
99 uuid, operation, str(args), str(kwargs)))
101 self.debuger.dump_invoke(newuuid, uuid, operation, args, kwargs)
104 obj = self.get_object(uuid)
106 method = getattr(obj, operation)
108 # arguments starting with 'uuid' identify netns
109 # objects and must be replaced by the actual object
110 realargs = self.replace_args(args)
111 realkwargs = self.replace_kwargs(kwargs)
113 result = method(*realargs, **realkwargs)
115 # If the result is an object (not a base value),
116 # then keep track of the object and return the object
117 # reference (newuuid)
118 if result is not None \
119 and not isinstance(result, (bool, float) + integer_types + string_types):
120 self._objects[newuuid] = result
124 self.logger.debug("RET INVOKE %s%s = %s -> %s(%s, %s) " % (
125 "(uuid %s) " % str(newuuid) if newuuid else "", str(result), uuid,
126 operation, str(args), str(kwargs)))
131 def set(self, uuid, name, value):
133 self.logger.debug("SET %s %s %s" % (uuid, name, str(value)))
135 self.debuger.dump_set(uuid, name, value)
138 obj = self.get_object(uuid)
139 setattr(obj, name, value)
142 self.logger.debug("RET SET %s = %s -> set(%s, %s)" % (str(value), uuid, name,
148 def get(self, uuid, name):
150 self.logger.debug("GET %s %s" % (uuid, name))
152 self.debuger.dump_get(uuid, name)
155 obj = self.get_object(uuid)
156 result = getattr(obj, name)
159 self.logger.debug("RET GET %s = %s -> get(%s)" % (str(result), uuid, name))
166 self.debuger.dump_shutdown()
177 self.logger.debug("SHUTDOWN")
180 def replace_args(self, args):
181 realargs = [self.get_object(arg) if \
182 str(arg).startswith("uuid") else arg for arg in args]
186 def replace_kwargs(self, kwargs):
187 realkwargs = dict([(k, self.get_object(v) \
188 if str(v).startswith("uuid") else v) \
189 for k,v in kwargs.items()])