1 # -*- coding: utf-8 -*-
5 class ExperimentData(object):
10 return "%s(%r)" % (self.__class__, self.data)
13 from pprint import pformat
14 return "%s:%s" % (self.__class__, pformat(self.data))
18 return self.data.keys()
20 def add_testbed_data(self, guid, testbed_id, testbed_version):
22 testbed_data["testbed_id"] = testbed_id
23 testbed_data["testbed_version"] = testbed_version
24 self.data[guid] = testbed_data
26 def add_box_data(self, guid, testbed_guid, factory_id):
28 box_data["testbed_guid"] = testbed_guid
29 box_data["factory_id"] = factory_id
30 self.data[guid] = box_data
32 def add_graphical_info_data(self, guid, x, y, width, height):
33 data = self.data[guid]
34 if not "graphical_info" in data:
35 data["graphical_info"] = dict()
36 graphical_info_data = data["graphical_info"]
37 graphical_info_data["x"] = x
38 graphical_info_data["y"] = y
39 graphical_info_data["width"] = width
40 graphical_info_data["height"] = height
42 def add_factory_attribute_data(self, guid, name, value):
43 data = self.data[guid]
44 if not "factory_attributes" in data:
45 data["factory_attributes"] = dict()
46 factory_attributes_data = data["factory_attributes"]
47 factory_attributes_data[name] = value
49 def add_attribute_data(self, guid, name, value):
50 data = self.data[guid]
51 if not "attributes" in data:
52 data["attributes"] = dict()
53 attributes_data = data["attributes"]
54 attributes_data[name] = value
56 def add_trace_data(self, guid, trace_name):
57 data = self.data[guid]
58 if not "traces" in data:
59 data["traces"] = list()
60 traces_data = data["traces"]
61 traces_data.append(trace_name)
63 def add_connection_data(self, guid, connector_type_name, other_guid,
64 other_connector_type_name):
65 data = self.data[guid]
66 if not "connections" in data:
67 data["connections"] = dict()
68 connections_data = data["connections"]
69 if not connector_type_name in connections_data:
70 connections_data[connector_type_name] = dict()
71 connection_data = connections_data[connector_type_name]
72 connection_data[other_guid] = other_connector_type_name
74 def add_address_data(self, guid, address, netprefix,
76 data = self.data[guid]
77 if not "addresses" in data:
78 data["addresses"] = list()
79 addresses_data = data["addresses"]
82 address_data["Address"] = address
83 address_data["NetPrefix"] = netprefix
85 address_data["Broadcast"] = broadcast
86 addresses_data.append(address_data)
88 def add_route_data(self, guid, destination, netprefix, nexthop, metric):
89 data = self.data[guid]
90 if not "routes" in data:
91 data["routes"] = list()
92 routes_data = data["routes"]
94 "Destination": destination,
95 "NetPrefix": netprefix,
99 routes_data.append(route_data)
101 def is_testbed_data(self, guid):
102 return True if "testbed_id" in self.data[guid] else None
104 def get_testbed_data(self, guid):
105 testbed_data = self.data[guid]
106 return (testbed_data["testbed_id"], testbed_data["testbed_version"])
108 def get_box_data(self, guid):
109 box_data = self.data[guid]
110 return (box_data["testbed_guid"], box_data["factory_id"])
112 def get_graphical_info_data(self, guid):
113 data = self.data[guid]
114 if not "graphical_info" in data:
115 return (0, 0, 0, 0, "")
116 graphical_info_data = data["graphical_info"]
117 return (graphical_info_data["x"],
118 graphical_info_data["y"],
119 graphical_info_data["width"],
120 graphical_info_data["height"])
122 def get_factory_attribute_data(self, guid):
123 data = self.data[guid]
124 if not "factory_attributes" in data:
126 factory_attributes_data = data["factory_attributes"]
127 return [(name, value) for name, value \
128 in factory_attributes_data.iteritems()]
130 def get_attribute_data(self, guid, attribute=None, default=None):
131 data = self.data[guid]
132 if not "attributes" in data:
133 if attribute is None:
137 attributes_data = data["attributes"]
138 if attribute is None:
139 return [(name, value) for name, value \
140 in attributes_data.iteritems()]
142 return attributes_data.get(attribute, default)
144 def set_attribute_data(self, guid, attribute, value):
145 data = self.data[guid]
146 if not "attributes" in data:
147 raise KeyError, "No attributes in reference OBJECT %r" % (guid,)
148 attributes_data = data["attributes"]
149 attributes_data[attribute] = value
151 def get_trace_data(self, guid):
152 data = self.data[guid]
153 if not "traces" in data:
155 return data["traces"]
157 def get_connection_data(self, guid):
158 data = self.data[guid]
159 if not "connections" in data:
161 connections_data = data["connections"]
162 return [(connector_type_name, other_guid, other_connector_type_name) \
163 for connector_type_name, connection_data \
164 in connections_data.iteritems() \
165 for other_guid, other_connector_type_name \
166 in connection_data.iteritems()]
168 def get_address_data(self, guid):
169 data = self.data[guid]
170 if not "addresses" in data:
172 addresses_data = data["addresses"]
173 return [(data["Address"] if "Address" in data else None,
174 data["NetPrefix"] if "NetPrefix" in data else None,
175 data["Broadcast"] if "Broadcast" in data else None) \
176 for data in addresses_data]
178 def get_route_data(self, guid):
179 data = self.data[guid]
180 if not "routes" in data:
182 routes_data = data["routes"]
183 return [(data["Destination"],
187 for data in routes_data]
189 class ExperimentParser(object):
190 def to_data(self, experiment_description):
191 data = ExperimentData()
192 for testbed_description in experiment_description.testbed_descriptions:
193 guid = testbed_description.guid
194 testbed_id = testbed_description.provider.testbed_id
195 testbed_version = testbed_description.provider.testbed_version
196 data.add_testbed_data(guid, testbed_id, testbed_version)
197 self.graphical_info_to_data(data, guid,
198 testbed_description.graphical_info)
199 self.attributes_to_data(data, guid, testbed_description.attributes)
200 for box in testbed_description.boxes:
201 data.add_box_data(box.guid, guid, box.factory_id)
202 self.graphical_info_to_data(data, box.guid, box.graphical_info)
203 self.factory_attributes_to_data(data, box.guid,
204 box.factory_attributes)
205 self.attributes_to_data(data, box.guid, box.attributes)
206 self.traces_to_data(data, box.guid, box.traces)
207 self.connections_to_data(data, box.guid, box.connectors)
208 if hasattr(box, "addresses"):
209 self.addresses_to_data(data, box.guid, box.addresses)
210 if hasattr(box, "routes"):
211 self.routes_to_data(data, box.guid, box.routes)
214 def graphical_info_to_data(self, data, guid, g_info):
215 data.add_graphical_info_data(guid, g_info.x, g_info.y, g_info.width,
218 def factory_attributes_to_data(self, data, guid, factory_attributes):
219 factory_attributes = factory_attributes or dict()
220 for name, value in factory_attributes.iteritems():
221 data.add_factory_attribute_data(guid, name, value)
223 def attributes_to_data(self, data, guid, attributes):
224 for attribute in attributes:
225 if attribute.modified or attribute.has_no_default_value:
226 data.add_attribute_data(guid, attribute.name, attribute.value)
228 def traces_to_data(self, data, guid, traces):
231 data.add_trace_data(guid, trace.name)
233 def connections_to_data(self, data, guid, connectors):
234 for connector in connectors:
235 connector_type_name = connector.connector_type.name
236 for other_connector in connector.connections:
237 other_guid = other_connector.box.guid
238 other_connector_type_name = other_connector.connector_type.name
239 data.add_connection_data(guid, connector_type_name, other_guid,
240 other_connector_type_name)
242 def addresses_to_data(self, data, guid, addresses):
243 for addr in addresses:
244 address = addr.get_attribute_value("Address")
245 netprefix = addr.get_attribute_value("NetPrefix")
246 broadcast = addr.get_attribute_value("Broadcast") \
247 if addr.has_attribute("Broadcast") and \
248 addr.is_attribute_modified("Broadcast") else None
249 data.add_address_data(guid, address, netprefix, broadcast)
251 def routes_to_data(self, data, guid, routes):
253 destination = route.get_attribute_value("Destination")
254 netprefix = route.get_attribute_value("NetPrefix")
255 nexthop = route.get_attribute_value("NextHop")
256 metric = route.get_attribute_value("Metric")
257 data.add_route_data(guid, destination, netprefix, nexthop, metric)
259 def from_data(self, experiment_description, data):
261 for guid in sorted(data.guids):
262 if data.is_testbed_data(guid):
263 self.testbed_from_data(experiment_description, guid, data)
265 self.box_from_data(experiment_description, guid, data)
266 box_guids.append(guid)
267 self.connections_from_data(experiment_description, box_guids, data)
269 def testbed_from_data(self, experiment_description, guid, data):
270 from nepi.core.design import FactoriesProvider
271 (testbed_id, testbed_version) = data.get_testbed_data(guid)
272 provider = FactoriesProvider(testbed_id)
273 if provider.testbed_version != testbed_version:
274 raise RuntimeError("Bad testbed version on testbed %s. Asked for %s, got %s" % \
275 (testbed_id, testbed_version, provider.testbed_version))
276 experiment_description.add_testbed_description(provider, guid)
277 testbed_description = experiment_description.testbed_description(guid)
278 self.graphical_info_from_data(testbed_description, data)
279 self.attributes_from_data(testbed_description, data)
281 def box_from_data(self, experiment_description, guid, data):
282 (testbed_guid, factory_id) = data.get_box_data(guid)
283 testbed_description = experiment_description.testbed_description(
285 self.factory_attributes_from_data(testbed_description, factory_id,
287 box = testbed_description.create(factory_id, guid)
289 self.graphical_info_from_data(box, data)
290 self.attributes_from_data(box, data)
291 self.traces_from_data(box, data)
292 self.addresses_from_data(box, data)
293 self.routes_from_data(box, data)
295 def graphical_info_from_data(self, element, data):
296 (x, y, width, height) = data.get_graphical_info_data(
298 element.graphical_info.x = x
299 element.graphical_info.y = y
300 element.graphical_info.width = width
301 element.graphical_info.height = height
303 def factory_attributes_from_data(self, testbed_description, factory_id,
305 factory = testbed_description.provider.factory(factory_id)
306 for (name, value) in data.get_factory_attribute_data(guid):
307 factory.set_attribute_value(name, value)
309 def attributes_from_data(self, element, data):
310 for name, value in data.get_attribute_data(element.guid):
311 element.set_attribute_value(name, value)
313 def traces_from_data(self, box, data):
314 for name in data.get_trace_data(box.guid):
315 box.enable_trace(name)
317 def addresses_from_data(self, box, data):
318 for (address, netprefix, broadcast) in data.get_address_data(box.guid):
319 addr = box.add_address()
321 addr.set_attribute_value("Address", address)
322 if netprefix != None:
323 addr.set_attribute_value("NetPrefix", netprefix)
325 addr.set_attribute_value("Broadcast", broadcast)
327 def routes_from_data(self, box, data):
328 for (destination, netprefix, nexthop, metric) \
329 in data.get_route_data(box.guid):
330 addr = box.add_route()
331 addr.set_attribute_value("Destination", destination)
332 addr.set_attribute_value("NetPrefix", netprefix)
333 addr.set_attribute_value("NextHop", nexthop)
334 addr.set_attribute_value("Metric", metric)
336 def connections_from_data(self, experiment_description, guids, data):
338 box = experiment_description.box(guid)
339 for (connector_type_name, other_guid, other_connector_type_name) \
340 in data.get_connection_data(guid):
341 other_box = experiment_description.box(other_guid)
342 connector = box.connector(connector_type_name)
343 other_connector = other_box.connector(
344 other_connector_type_name)
345 if not connector.is_connected(other_connector):
346 connector.connect(other_connector)