2 # -*- coding: utf-8 -*-
6 class ExperimentData(object):
11 return "%s(%r)" % (self.__class__, self.data)
14 from pprint import pformat
15 return "%s:%s" % (self.__class__, pformat(self.data))
19 return self.data.keys()
21 def add_testbed_data(self, guid, testbed_id, testbed_version):
23 testbed_data["testbed_id"] = testbed_id
24 testbed_data["testbed_version"] = testbed_version
25 self.data[guid] = testbed_data
27 def add_box_data(self, guid, testbed_guid, factory_id):
29 box_data["testbed_guid"] = testbed_guid
30 box_data["factory_id"] = factory_id
31 self.data[guid] = box_data
33 def add_graphical_info_data(self, guid, x, y, width, height):
34 data = self.data[guid]
35 if not "graphical_info" in data:
36 data["graphical_info"] = dict()
37 graphical_info_data = data["graphical_info"]
38 graphical_info_data["x"] = x
39 graphical_info_data["y"] = y
40 graphical_info_data["width"] = width
41 graphical_info_data["height"] = height
43 def add_factory_attribute_data(self, guid, name, value):
44 data = self.data[guid]
45 if not "factory_attributes" in data:
46 data["factory_attributes"] = dict()
47 factory_attributes_data = data["factory_attributes"]
48 factory_attributes_data[name] = value
50 def add_attribute_data(self, guid, name, value):
51 data = self.data[guid]
52 if not "attributes" in data:
53 data["attributes"] = dict()
54 attributes_data = data["attributes"]
55 attributes_data[name] = value
57 def add_trace_data(self, guid, trace_name):
58 data = self.data[guid]
59 if not "traces" in data:
60 data["traces"] = list()
61 traces_data = data["traces"]
62 traces_data.append(trace_name)
64 def add_connection_data(self, guid, connector_type_name, other_guid,
65 other_connector_type_name):
66 data = self.data[guid]
67 if not "connections" in data:
68 data["connections"] = dict()
69 connections_data = data["connections"]
70 if not connector_type_name in connections_data:
71 connections_data[connector_type_name] = dict()
72 connection_data = connections_data[connector_type_name]
73 connection_data[other_guid] = other_connector_type_name
75 def add_address_data(self, guid, address, netprefix,
77 data = self.data[guid]
78 if not "addresses" in data:
79 data["addresses"] = list()
80 addresses_data = data["addresses"]
83 address_data["Address"] = address
84 address_data["NetPrefix"] = netprefix
86 address_data["Broadcast"] = broadcast
87 addresses_data.append(address_data)
89 def add_route_data(self, guid, destination, netprefix, nexthop, metric):
90 data = self.data[guid]
91 if not "routes" in data:
92 data["routes"] = list()
93 routes_data = data["routes"]
95 "Destination": destination,
96 "NetPrefix": netprefix,
100 routes_data.append(route_data)
102 def is_testbed_data(self, guid):
103 return True if "testbed_id" in self.data[guid] else None
105 def get_testbed_data(self, guid):
106 testbed_data = self.data[guid]
107 return (testbed_data["testbed_id"], testbed_data["testbed_version"])
109 def get_box_data(self, guid):
110 box_data = self.data[guid]
111 return (box_data["testbed_guid"], box_data["factory_id"])
113 def get_graphical_info_data(self, guid):
114 data = self.data[guid]
115 if not "graphical_info" in data:
116 return (0, 0, 0, 0, "")
117 graphical_info_data = data["graphical_info"]
118 return (graphical_info_data["x"],
119 graphical_info_data["y"],
120 graphical_info_data["width"],
121 graphical_info_data["height"])
123 def get_factory_attribute_data(self, guid):
124 data = self.data[guid]
125 if not "factory_attributes" in data:
127 factory_attributes_data = data["factory_attributes"]
128 return [(name, value) for name, value \
129 in factory_attributes_data.iteritems()]
131 def get_attribute_data(self, guid, attribute=None, default=None):
132 data = self.data[guid]
133 if not "attributes" in data:
134 if attribute is None:
138 attributes_data = data["attributes"]
139 if attribute is None:
140 return [(name, value) for name, value \
141 in attributes_data.iteritems()]
143 return attributes_data.get(attribute, default)
145 def set_attribute_data(self, guid, attribute, value):
146 data = self.data[guid]
147 if not "attributes" in data:
148 raise KeyError, "No attributes in reference OBJECT %r" % (guid,)
149 attributes_data = data["attributes"]
150 attributes_data[attribute] = value
152 def get_trace_data(self, guid):
153 data = self.data[guid]
154 if not "traces" in data:
156 return data["traces"]
158 def get_connection_data(self, guid):
159 data = self.data[guid]
160 if not "connections" in data:
162 connections_data = data["connections"]
163 return [(connector_type_name, other_guid, other_connector_type_name) \
164 for connector_type_name, connection_data \
165 in connections_data.iteritems() \
166 for other_guid, other_connector_type_name \
167 in connection_data.iteritems()]
169 def get_address_data(self, guid):
170 data = self.data[guid]
171 if not "addresses" in data:
173 addresses_data = data["addresses"]
174 return [(data["Address"] if "Address" in data else None,
175 data["NetPrefix"] if "NetPrefix" in data else None,
176 data["Broadcast"] if "Broadcast" in data else None) \
177 for data in addresses_data]
179 def get_route_data(self, guid):
180 data = self.data[guid]
181 if not "routes" in data:
183 routes_data = data["routes"]
184 return [(data["Destination"],
188 for data in routes_data]
190 class ExperimentParser(object):
191 def to_data(self, experiment_description):
192 data = ExperimentData()
193 for testbed_description in experiment_description.testbed_descriptions:
194 guid = testbed_description.guid
195 testbed_id = testbed_description.provider.testbed_id
196 testbed_version = testbed_description.provider.testbed_version
197 data.add_testbed_data(guid, testbed_id, testbed_version)
198 self.graphical_info_to_data(data, guid,
199 testbed_description.graphical_info)
200 self.attributes_to_data(data, guid, testbed_description.attributes)
201 for box in testbed_description.boxes:
202 data.add_box_data(box.guid, guid, box.factory_id)
203 self.graphical_info_to_data(data, box.guid, box.graphical_info)
204 self.factory_attributes_to_data(data, box.guid,
205 box.factory_attributes)
206 self.attributes_to_data(data, box.guid, box.attributes)
207 self.traces_to_data(data, box.guid, box.traces)
208 self.connections_to_data(data, box.guid, box.connectors)
209 if hasattr(box, "addresses"):
210 self.addresses_to_data(data, box.guid, box.addresses)
211 if hasattr(box, "routes"):
212 self.routes_to_data(data, box.guid, box.routes)
215 def graphical_info_to_data(self, data, guid, g_info):
216 data.add_graphical_info_data(guid, g_info.x, g_info.y, g_info.width,
219 def factory_attributes_to_data(self, data, guid, factory_attributes):
220 factory_attributes = factory_attributes or dict()
221 for name, value in factory_attributes.iteritems():
222 data.add_factory_attribute_data(guid, name, value)
224 def attributes_to_data(self, data, guid, attributes):
225 for attribute in attributes:
226 if attribute.modified or attribute.has_no_default_value:
227 data.add_attribute_data(guid, attribute.name, attribute.value)
229 def traces_to_data(self, data, guid, traces):
232 data.add_trace_data(guid, trace.name)
234 def connections_to_data(self, data, guid, connectors):
235 for connector in connectors:
236 connector_type_name = connector.connector_type.name
237 for other_connector in connector.connections:
238 other_guid = other_connector.box.guid
239 other_connector_type_name = other_connector.connector_type.name
240 data.add_connection_data(guid, connector_type_name, other_guid,
241 other_connector_type_name)
243 def addresses_to_data(self, data, guid, addresses):
244 for addr in addresses:
245 address = addr.get_attribute_value("Address")
246 netprefix = addr.get_attribute_value("NetPrefix")
247 broadcast = addr.get_attribute_value("Broadcast") \
248 if addr.has_attribute("Broadcast") and \
249 addr.is_attribute_modified("Broadcast") else None
250 data.add_address_data(guid, address, netprefix, broadcast)
252 def routes_to_data(self, data, guid, routes):
254 destination = route.get_attribute_value("Destination")
255 netprefix = route.get_attribute_value("NetPrefix")
256 nexthop = route.get_attribute_value("NextHop")
257 metric = route.get_attribute_value("Metric")
258 data.add_route_data(guid, destination, netprefix, nexthop, metric)
260 def from_data(self, experiment_description, data):
262 for guid in sorted(data.guids):
263 if data.is_testbed_data(guid):
264 self.testbed_from_data(experiment_description, guid, data)
266 self.box_from_data(experiment_description, guid, data)
267 box_guids.append(guid)
268 self.connections_from_data(experiment_description, box_guids, data)
270 def testbed_from_data(self, experiment_description, guid, data):
271 from nepi.core.design import FactoriesProvider
272 (testbed_id, testbed_version) = data.get_testbed_data(guid)
273 provider = FactoriesProvider(testbed_id)
274 if provider.testbed_version != testbed_version:
275 raise RuntimeError("Bad testbed version on testbed %s. Asked for %s, got %s" % \
276 (testbed_id, testbed_version, provider.testbed_version))
277 experiment_description.add_testbed_description(provider, guid)
278 testbed_description = experiment_description.testbed_description(guid)
279 self.graphical_info_from_data(testbed_description, data)
280 self.attributes_from_data(testbed_description, data)
282 def box_from_data(self, experiment_description, guid, data):
283 (testbed_guid, factory_id) = data.get_box_data(guid)
284 testbed_description = experiment_description.testbed_description(
286 self.factory_attributes_from_data(testbed_description, factory_id,
288 box = testbed_description.create(factory_id, guid)
290 self.graphical_info_from_data(box, data)
291 self.attributes_from_data(box, data)
292 self.traces_from_data(box, data)
293 self.addresses_from_data(box, data)
294 self.routes_from_data(box, data)
296 def graphical_info_from_data(self, element, data):
297 (x, y, width, height) = data.get_graphical_info_data(
299 element.graphical_info.x = x
300 element.graphical_info.y = y
301 element.graphical_info.width = width
302 element.graphical_info.height = height
304 def factory_attributes_from_data(self, testbed_description, factory_id,
306 factory = testbed_description.provider.factory(factory_id)
307 for (name, value) in data.get_factory_attribute_data(guid):
308 factory.set_attribute_value(name, value)
310 def attributes_from_data(self, element, data):
311 for name, value in data.get_attribute_data(element.guid):
312 element.set_attribute_value(name, value)
314 def traces_from_data(self, box, data):
315 for name in data.get_trace_data(box.guid):
316 box.enable_trace(name)
318 def addresses_from_data(self, box, data):
319 for (address, netprefix, broadcast) in data.get_address_data(box.guid):
320 addr = box.add_address()
322 addr.set_attribute_value("Address", address)
323 if netprefix != None:
324 addr.set_attribute_value("NetPrefix", netprefix)
326 addr.set_attribute_value("Broadcast", broadcast)
328 def routes_from_data(self, box, data):
329 for (destination, netprefix, nexthop, metric) \
330 in data.get_route_data(box.guid):
331 addr = box.add_route()
332 addr.set_attribute_value("Destination", destination)
333 addr.set_attribute_value("NetPrefix", netprefix)
334 addr.set_attribute_value("NextHop", nexthop)
335 addr.set_attribute_value("Metric", metric)
337 def connections_from_data(self, experiment_description, guids, data):
339 box = experiment_description.box(guid)
340 for (connector_type_name, other_guid, other_connector_type_name) \
341 in data.get_connection_data(guid):
342 other_box = experiment_description.box(other_guid)
343 connector = box.connector(connector_type_name)
344 other_connector = other_box.connector(
345 other_connector_type_name)
346 if not connector.is_connected(other_connector):
347 connector.connect(other_connector)