def test_serialization_deserialization(self): # create NetworkDefinition object by de-serializing the simulated network: ndef = NetworkUtil.deserialize_network_definition( file('mi/platform/rsn/simulator/network.yml')) # serialize object to string serialization = NetworkUtil.serialize_network_definition(ndef) # recreate object by de-serializing the string: ndef2 = NetworkUtil.deserialize_network_definition(serialization) # verify the objects are equal: diff = ndef.diff(ndef2) self.assertIsNone(diff, "deserialized version must be equal to original." " DIFF=\n%s" % diff)
def test_serialization_deserialization(self): # create NetworkDefinition object by de-serializing the simulated network: ndef = NetworkUtil.deserialize_network_definition( file('mi/platform/rsn/simulator/network.yml')) # serialize object to string serialization = NetworkUtil.serialize_network_definition(ndef) # recreate object by de-serializing the string: ndef2 = NetworkUtil.deserialize_network_definition(serialization) # verify the objects are equal: diff = ndef.diff(ndef2) self.assertIsNone( diff, "deserialized version must be equal to original." " DIFF=\n%s" % diff)
def __init__(self, pnode, event_callback, create_event_subscriber, destroy_event_subscriber): """ Creates a PlatformDriver instance. @param pnode Root PlatformNode defining the platform network rooted at this platform. @param event_callback Callback to notify platform agent about events generated by this driver. This is captured in self._send_event for this class and subclasses to call as needed. @param create_event_subscriber @param destroy_event_subscriber functions to create/destroy any needed EventSubscriber's, in particular regarding the Managed Endpoint API. """ # # NOTE the "pnode" parameter may be not very "standard" but it is the # current convenient mechanism that captures the overall definition # of the corresponding platform (most of which coming from configuration) # self._pnode = pnode self._send_event = event_callback self._create_event_subscriber = create_event_subscriber self._destroy_event_subscriber = destroy_event_subscriber self._platform_id = self._pnode.platform_id if self._pnode.parent: self._parent_platform_id = self._pnode.parent.platform_id else: self._parent_platform_id = None self._platform_attributes = \ dict((a.attr_id, a.defn) for a in self._pnode.attrs.itervalues()) if log.isEnabledFor(logging.DEBUG): log.debug("%r: PlatformDriver constructor called: pnode:\n%s\n" "_platform_attributes=%s", self._platform_id, NetworkUtil._dump_pnode(self._pnode, include_subplatforms=False), self._platform_attributes) self._driver_config = None self._resource_schema = {} # The parameter dictionary. self._param_dict = {} # construct FSM and start it with initial state UNCONFIGURED: self._construct_fsm() self._fsm.start(PlatformDriverState.UNCONFIGURED)
def test_create_network_definition_from_ci_config_bad(self): CFG = DotDict({ 'device_type': "bad_device_type", }) # device_type with self.assertRaises(NetworkDefinitionException): NetworkUtil.create_network_definition_from_ci_config(CFG) CFG = DotDict({ 'device_type': "PlatformDevice", }) # missing platform_id with self.assertRaises(NetworkDefinitionException): NetworkUtil.create_network_definition_from_ci_config(CFG) CFG = DotDict({ 'device_type': "PlatformDevice", 'platform_config': { 'platform_id': 'Node1D' }, }) # missing driver_config with self.assertRaises(NetworkDefinitionException): NetworkUtil.create_network_definition_from_ci_config(CFG)
def test_create_network_definition_from_ci_config_bad(self): CFG = DotDict({ 'device_type' : "bad_device_type", }) # device_type with self.assertRaises(NetworkDefinitionException): NetworkUtil.create_network_definition_from_ci_config(CFG) CFG = DotDict({ 'device_type' : "PlatformDevice", }) # missing platform_id with self.assertRaises(NetworkDefinitionException): NetworkUtil.create_network_definition_from_ci_config(CFG) CFG = DotDict({ 'device_type' : "PlatformDevice", 'platform_config': { 'platform_id': 'Node1D' }, }) # missing driver_config with self.assertRaises(NetworkDefinitionException): NetworkUtil.create_network_definition_from_ci_config(CFG)
def __init__(self, yaml_filename='mi/platform/rsn/simulator/network.yml'): self._ndef = NetworkUtil.deserialize_network_definition(file(yaml_filename)) self._platform_types = self._ndef.platform_types self._pnodes = self._ndef.pnodes # registered event listeners: {url: reg_time, ...}, # where reg_time is the NTP time of (latest) registration. # NOTE: for simplicity, we don't keep info about unregistered listeners self._reg_event_listeners = {} self._event_notifier = EventNotifier() # EventGenerator only kept while there are listeners registered self._event_generator = None
def __init__(self, yaml_filename='mi/platform/rsn/simulator/network.yml'): self._ndef = NetworkUtil.deserialize_network_definition(file(yaml_filename)) self._platform_types = self._ndef.platform_types self._pnodes = self._ndef.pnodes self._mission_flags = ['pause', 'returntohome', 'returntodock'] # registered event listeners: {url: reg_time, ...}, # where reg_time is the NTP time of (latest) registration. # NOTE: for simplicity, we don't keep info about unregistered listeners self._reg_event_listeners = {} self._event_notifier = EventNotifier() # EventGenerator only kept while there are listeners registered self._event_generator = None
def setUp(self): DVR_CONFIG['oms_uri'] = self._dispatch_simulator(oms_uri) log.debug("DVR_CONFIG['oms_uri'] = %s", DVR_CONFIG['oms_uri']) # Use the network definition provided by RSN OMS directly. rsn_oms = CIOMSClientFactory.create_instance(DVR_CONFIG['oms_uri']) network_definition = RsnOmsUtil.build_network_definition(rsn_oms) CIOMSClientFactory.destroy_instance(rsn_oms) if log.isEnabledFor(logging.DEBUG): network_definition_ser = NetworkUtil.serialize_network_definition(network_definition) log.debug("NetworkDefinition serialization:\n%s", network_definition_ser) platform_id = self.PLATFORM_ID pnode = network_definition.pnodes[platform_id] self._plat_driver = RSNPlatformDriver(pnode, self.evt_recv)
def _configure(self, config): """ Configures this driver. In this base class it basically calls validate_driver_configuration and then assigns the given config to self._driver_config. @param driver_config Driver configuration. """ # # NOTE the "pnode" parameter may be not very "standard" but it is the # current convenient mechanism that captures the overall definition # of the corresponding platform (most of which coming from configuration) # # Use the network definition provided by RSN OMS directly. rsn_oms = CIOMSClientFactory.create_instance() network_definition = RsnOmsUtil.build_network_definition(rsn_oms) CIOMSClientFactory.destroy_instance(rsn_oms) platform_id = 'LJ01D' self._pnode = network_definition.pnodes[platform_id] #self._pnode = config.get('pnode') self._platform_id = self._pnode.platform_id if self._pnode.parent: self._parent_platform_id = self._pnode.parent.platform_id else: self._parent_platform_id = None self._platform_attributes = \ dict((a.attr_id, a.defn) for a in self._pnode.attrs.itervalues()) log.debug("%r: PlatformDriver constructor called: pnode:\n%s\n" "_platform_attributes=%s", self._platform_id, NetworkUtil._dump_pnode(self._pnode, include_subplatforms=False), self._platform_attributes) self.validate_driver_configuration(config) self._driver_config = config
def _check_sync(self): """ This will be the main operation related with checking that the information on this platform agent (and sub-platforms) is consistent with the information in the external network rooted at the corresponding platform, then publishing relevant notification events. For the moment, it only reports the value of the external checksum and the value of the local checksum. @todo complete implementation @return {'external_checksum': string, 'local_checksum': string} """ log.debug("%r: _check_sync: getting external checksum...", self._platform_id) external_checksum = self.get_external_checksum() local_checksum = self._pnode.compute_checksum() if log.isEnabledFor(logging.DEBUG): # pragma: no cover filename = "logs/checksum_check_from_driver.yml" try: from mi.platform.util.network_util import NetworkUtil open(filename, "w").write(NetworkUtil.serialize_pnode(self._pnode)) except Exception as e: log.debug("%r: cannot write %s: %s", self._platform_id, filename, e) result = { 'external_checksum': external_checksum, 'local_checksum': local_checksum } log.debug("%r: _check_sync: result: %s", self._platform_id, result) # TODO - if checksums are different, determine what sub-components are # in disagreement; publish relevant event(s), etc. return result
def __init__(self, host, port, inactivity_period=None): """ Creates a SimpleXMLRPCServer and starts a Thread where serve_forever is called on the server. @param host Hostname for the service @param port Port for the service """ self._running = True self._sim = CIOMSSimulatorWithExit(self) if log.isEnabledFor(logging.DEBUG): ser = NetworkUtil.serialize_network_definition(self._sim._ndef) log.debug("network serialization:\n %s" % ser.replace('\n', '\n ')) log.debug("network.get_map() = %s\n" % self._sim.config.get_platform_map()) self._server = SimpleXMLRPCServer((host, port), allow_none=True) actual_port = self._server.socket.getsockname()[1] uri = "http://%s:%s/" % (host, actual_port) # write the URI to a file for launching process to see it: with open("logs/rsn_oms_simulator.yml", 'w') as f: f.write("rsn_oms_simulator_uri=%s\n" % uri) self._server.register_introspection_functions() self._server.register_instance(self._sim, allow_dotted_names=True) log.info("Methods:\n\t%s", "\n\t".join(self._server.system_listMethods())) self._check_pyon() runnable = Thread(target=self._server.serve_forever) runnable.setDaemon(True) runnable.start() log.info("OMS simulator xmlrpc server listening on %s" % uri) if inactivity_period: self._sim.x_exit_inactivity(inactivity_period)
def _check_sync(self): """ This will be the main operation related with checking that the information on this platform agent (and sub-platforms) is consistent with the information in the external network rooted at the corresponding platform, then publishing relevant notification events. For the moment, it only reports the value of the external checksum and the value of the local checksum. @todo complete implementation @return {'external_checksum': string, 'local_checksum': string} """ log.debug("%r: _check_sync: getting external checksum...", self._platform_id) external_checksum = self.get_external_checksum() local_checksum = self._pnode.compute_checksum() if log.isEnabledFor(logging.DEBUG): # pragma: no cover filename = "logs/checksum_check_from_driver.yml" try: from mi.platform.util.network_util import NetworkUtil open(filename, "w").write(NetworkUtil.serialize_pnode(self._pnode)) except Exception as e: log.debug("%r: cannot write %s: %s", self._platform_id, filename, e) result = {'external_checksum': external_checksum, 'local_checksum': local_checksum} log.debug("%r: _check_sync: result: %s", self._platform_id, result) # TODO - if checksums are different, determine what sub-components are # in disagreement; publish relevant event(s), etc. return result
def build_network_definition(rsn_oms): """ Creates and returns a NetworkDefinition object reflecting the platform network definition reported by the RSN OMS Client object. The returned object will have as root the PlatformNode corresponding to the actual root of the whole newtork. You can use the `pnodes` property to access any node. @param rsn_oms RSN OMS Client object. @return NetworkDefinition object """ if log.isEnabledFor(logging.DEBUG): log.debug("build_network_definition. rsn_oms class: %s", rsn_oms.__class__.__name__) # platform types: platform_types = rsn_oms.config.get_platform_types() if log.isEnabledFor(logging.DEBUG): log.debug("got platform_types %s", str(platform_types)) # platform map: map = rsn_oms.config.get_platform_map() if log.isEnabledFor(logging.DEBUG): log.debug("got platform map %s", str(map)) # build topology: pnodes = NetworkUtil.create_node_network(map) dummy_root = pnodes[''] root_pnode = pnodes[dummy_root.subplatforms.keys()[0]] if log.isEnabledFor(logging.DEBUG): log.debug("topology's root platform_id=%r", root_pnode.platform_id) # now, populate the attributes and ports for the platforms def build_attributes_and_ports(pnode): """ Recursive routine to call set_attributes and set_ports on each pnode. """ set_attributes(pnode) set_ports(pnode) for sub_platform_id, sub_pnode in pnode.subplatforms.iteritems(): build_attributes_and_ports(sub_pnode) def set_attributes(pnode): platform_id = pnode.platform_id attr_infos = rsn_oms.attr.get_platform_attributes(platform_id) if not isinstance(attr_infos, dict): raise PlatformDriverException( "%r: get_platform_attributes returned: %s" % ( platform_id, attr_infos)) if log.isEnabledFor(logging.TRACE): log.trace("%r: attr_infos: %s", platform_id, attr_infos) if not platform_id in attr_infos: raise PlatformDriverException( "%r: get_platform_attributes response does not " "include entry for platform_id: %s" %( platform_id, attr_infos)) ret_infos = attr_infos[platform_id] for attrName, attr_defn in ret_infos.iteritems(): attr = AttrNode(attrName, attr_defn) pnode.add_attribute(attr) def set_ports(pnode): platform_id = pnode.platform_id port_infos = rsn_oms.port.get_platform_ports(platform_id) if not isinstance(port_infos, dict): raise PlatformDriverException( "%r: get_platform_ports response is not a dict: %s" % ( platform_id, port_infos)) if log.isEnabledFor(logging.TRACE): log.trace("%r: port_infos: %s", platform_id, port_infos) if not platform_id in port_infos: raise PlatformDriverException( "%r: get_platform_ports response does not include " "platform_id: %s" % (platform_id, port_infos)) ports = port_infos[platform_id] if not isinstance(ports, dict): raise PlatformDriverException( "%r: get_platform_ports: entry for platform_id is " "not a dict: %s" % (platform_id, ports)) for port_id, dic in ports.iteritems(): port = PortNode(port_id) port.set_state(dic['state']) pnode.add_port(port) # add connected instruments: instrs_res = rsn_oms.instr.get_connected_instruments(platform_id, port_id) if not isinstance(instrs_res, dict): log.warn("%r: port_id=%r: get_connected_instruments " "response is not a dict: %s" % (platform_id, port_id, instrs_res)) continue if log.isEnabledFor(logging.TRACE): log.trace("%r: port_id=%r: get_connected_instruments " "returned: %s" % (platform_id, port_id, instrs_res)) if not platform_id in instrs_res: raise PlatformDriverException( "%r: port_id=%r: get_connected_instruments response" "does not have entry for platform_id: %s" % ( platform_id, ports)) if not port_id in instrs_res[platform_id]: raise PlatformDriverException( "%r: port_id=%r: get_connected_instruments response " "for platform_id does not have entry for port_id: %s" % ( platform_id, port_id, instrs_res[platform_id])) instr = instrs_res[platform_id][port_id] for instrument_id, attrs in instr.iteritems(): port.add_instrument(InstrumentNode(instrument_id, attrs)) # call the recursive routine build_attributes_and_ports(root_pnode) # we got our whole network including platform attributes and ports. # and finally create and return NetworkDefinition: ndef = NetworkDefinition() ndef._platform_types = platform_types ndef._pnodes = pnodes ndef._dummy_root = dummy_root return ndef
def test_create_network_definition_from_ci_config(self): CFG = DotDict({ 'device_type': "PlatformDevice", 'platform_config': { 'platform_id': 'Node1D' }, 'driver_config': { 'attributes': { 'MVPC_pressure_1': { 'attr_id': 'MVPC_pressure_1', 'group': 'pressure', 'max_val': 33.8, 'min_val': -3.8, 'monitor_cycle_seconds': 10, 'precision': 0.04, 'read_write': 'read', 'type': 'float', 'units': 'PSI' }, 'MVPC_temperature': { 'attr_id': 'MVPC_temperature', 'group': 'temperature', 'max_val': 58.5, 'min_val': -1.5, 'monitor_cycle_seconds': 10, 'precision': 0.06, 'read_write': 'read', 'type': 'float', 'units': 'Degrees C' }, 'input_bus_current': { 'attr_id': 'input_bus_current', 'group': 'power', 'max_val': 50, 'min_val': -50, 'monitor_cycle_seconds': 5, 'precision': 0.1, 'read_write': 'write', 'type': 'float', 'units': 'Amps' }, 'input_voltage': { 'attr_id': 'input_voltage', 'group': 'power', 'max_val': 500, 'min_val': -500, 'monitor_cycle_seconds': 5, 'precision': 1, 'read_write': 'read', 'type': 'float', 'units': 'Volts' } }, 'dvr_cls': 'RSNPlatformDriver', 'dvr_mod': 'ion.agents.platform.rsn.rsn_platform_driver', 'oms_uri': 'embsimulator', 'ports': { 'Node1D_port_1': { 'port_id': 'Node1D_port_1' }, 'Node1D_port_2': { 'port_id': 'Node1D_port_2' } }, }, 'children': { 'd7877d832cf94c388089b141043d60de': { 'agent': { 'resource_id': 'd7877d832cf94c388089b141043d60de' }, 'device_type': 'PlatformDevice', 'platform_config': { 'platform_id': 'MJ01C' }, 'driver_config': { 'attributes': { 'MJ01C_attr_1': { 'attr_id': 'MJ01C_attr_1', 'group': 'power', 'max_val': 10, 'min_val': -2, 'monitor_cycle_seconds': 5, 'read_write': 'read', 'type': 'int', 'units': 'xyz' }, 'MJ01C_attr_2': { 'attr_id': 'MJ01C_attr_2', 'group': 'power', 'max_val': 10, 'min_val': -2, 'monitor_cycle_seconds': 5, 'read_write': 'write', 'type': 'int', 'units': 'xyz' } }, 'dvr_cls': 'RSNPlatformDriver', 'dvr_mod': 'ion.agents.platform.rsn.rsn_platform_driver', 'oms_uri': 'embsimulator', 'ports': { 'MJ01C_port_1': { 'port_id': 'MJ01C_port_1' }, 'MJ01C_port_2': { 'port_id': 'MJ01C_port_2' } } }, 'children': { 'd0203cb9eb844727b7a8eea77db78e89': { 'agent': { 'resource_id': 'd0203cb9eb844727b7a8eea77db78e89' }, 'platform_config': { 'platform_id': 'LJ01D' }, 'device_type': 'PlatformDevice', 'driver_config': { 'attributes': { 'MVPC_pressure_1': { 'attr_id': 'MVPC_pressure_1', 'group': 'pressure', 'max_val': 33.8, 'min_val': -3.8, 'monitor_cycle_seconds': 10, 'precision': 0.04, 'read_write': 'read', 'type': 'float', 'units': 'PSI' }, 'MVPC_temperature': { 'attr_id': 'MVPC_temperature', 'group': 'temperature', 'max_val': 58.5, 'min_val': -1.5, 'monitor_cycle_seconds': 10, 'precision': 0.06, 'read_write': 'read', 'type': 'float', 'units': 'Degrees C' }, 'input_bus_current': { 'attr_id': 'input_bus_current', 'group': 'power', 'max_val': 50, 'min_val': -50, 'monitor_cycle_seconds': 5, 'precision': 0.1, 'read_write': 'write', 'type': 'float', 'units': 'Amps' }, 'input_voltage': { 'attr_id': 'input_voltage', 'group': 'power', 'max_val': 500, 'min_val': -500, 'monitor_cycle_seconds': 5, 'precision': 1, 'read_write': 'read', 'type': 'float', 'units': 'Volts' } }, 'dvr_cls': 'RSNPlatformDriver', 'dvr_mod': 'ion.agents.platform.rsn.rsn_platform_driver', 'oms_uri': 'embsimulator', 'ports': { 'LJ01D_port_1': { 'port_id': '1' }, 'LJ01D_port_2': { 'port_id': '2' } } }, 'children': {}, } } } } }) ndef = NetworkUtil.create_network_definition_from_ci_config(CFG) if log.isEnabledFor(logging.TRACE): serialization = NetworkUtil.serialize_network_definition(ndef) log.trace("serialization = \n%s", serialization) self.assertIn('Node1D', ndef.pnodes) Node1D = ndef.pnodes['Node1D'] common_attr_names = [ 'MVPC_pressure_1|0', 'MVPC_temperature|0', 'input_bus_current|0', 'input_voltage|0', ] for attr_name in common_attr_names: self.assertIn(attr_name, Node1D.attrs) #todo complete the network definition: align ports defintion with internal representation. #for port_name in ['Node1D_port_1', 'Node1D_port_2']: # self.assertIn(port_name, Node1D.ports) for subplat_name in [ 'MJ01C', ]: self.assertIn(subplat_name, Node1D.subplatforms) MJ01C = Node1D.subplatforms['MJ01C'] for subplat_name in [ 'LJ01D', ]: self.assertIn(subplat_name, MJ01C.subplatforms) LJ01D = MJ01C.subplatforms['LJ01D'] for attr_name in common_attr_names: self.assertIn(attr_name, LJ01D.attrs)
def test_create_network_definition_from_ci_config(self): CFG = DotDict({ 'device_type' : "PlatformDevice", 'platform_config': { 'platform_id': 'Node1D' }, 'driver_config': {'attributes': {'MVPC_pressure_1': {'attr_id': 'MVPC_pressure_1', 'group': 'pressure', 'max_val': 33.8, 'min_val': -3.8, 'monitor_cycle_seconds': 10, 'precision': 0.04, 'read_write': 'read', 'type': 'float', 'units': 'PSI'}, 'MVPC_temperature': {'attr_id': 'MVPC_temperature', 'group': 'temperature', 'max_val': 58.5, 'min_val': -1.5, 'monitor_cycle_seconds': 10, 'precision': 0.06, 'read_write': 'read', 'type': 'float', 'units': 'Degrees C'}, 'input_bus_current': {'attr_id': 'input_bus_current', 'group': 'power', 'max_val': 50, 'min_val': -50, 'monitor_cycle_seconds': 5, 'precision': 0.1, 'read_write': 'write', 'type': 'float', 'units': 'Amps'}, 'input_voltage': {'attr_id': 'input_voltage', 'group': 'power', 'max_val': 500, 'min_val': -500, 'monitor_cycle_seconds': 5, 'precision': 1, 'read_write': 'read', 'type': 'float', 'units': 'Volts'}}, 'dvr_cls': 'RSNPlatformDriver', 'dvr_mod': 'ion.agents.platform.rsn.rsn_platform_driver', 'oms_uri': 'embsimulator', 'ports': {'Node1D_port_1': {'port_id': 'Node1D_port_1'}, 'Node1D_port_2': {'port_id': 'Node1D_port_2'}}, }, 'children': {'d7877d832cf94c388089b141043d60de': {'agent': {'resource_id': 'd7877d832cf94c388089b141043d60de'}, 'device_type': 'PlatformDevice', 'platform_config': {'platform_id': 'MJ01C'}, 'driver_config': {'attributes': {'MJ01C_attr_1': {'attr_id': 'MJ01C_attr_1', 'group': 'power', 'max_val': 10, 'min_val': -2, 'monitor_cycle_seconds': 5, 'read_write': 'read', 'type': 'int', 'units': 'xyz'}, 'MJ01C_attr_2': {'attr_id': 'MJ01C_attr_2', 'group': 'power', 'max_val': 10, 'min_val': -2, 'monitor_cycle_seconds': 5, 'read_write': 'write', 'type': 'int', 'units': 'xyz'}}, 'dvr_cls': 'RSNPlatformDriver', 'dvr_mod': 'ion.agents.platform.rsn.rsn_platform_driver', 'oms_uri': 'embsimulator', 'ports': {'MJ01C_port_1': {'port_id': 'MJ01C_port_1'}, 'MJ01C_port_2': {'port_id': 'MJ01C_port_2'}}}, 'children': {'d0203cb9eb844727b7a8eea77db78e89': {'agent': {'resource_id': 'd0203cb9eb844727b7a8eea77db78e89'}, 'platform_config': {'platform_id': 'LJ01D'}, 'device_type': 'PlatformDevice', 'driver_config': {'attributes': {'MVPC_pressure_1': {'attr_id': 'MVPC_pressure_1', 'group': 'pressure', 'max_val': 33.8, 'min_val': -3.8, 'monitor_cycle_seconds': 10, 'precision': 0.04, 'read_write': 'read', 'type': 'float', 'units': 'PSI'}, 'MVPC_temperature': {'attr_id': 'MVPC_temperature', 'group': 'temperature', 'max_val': 58.5, 'min_val': -1.5, 'monitor_cycle_seconds': 10, 'precision': 0.06, 'read_write': 'read', 'type': 'float', 'units': 'Degrees C'}, 'input_bus_current': {'attr_id': 'input_bus_current', 'group': 'power', 'max_val': 50, 'min_val': -50, 'monitor_cycle_seconds': 5, 'precision': 0.1, 'read_write': 'write', 'type': 'float', 'units': 'Amps'}, 'input_voltage': {'attr_id': 'input_voltage', 'group': 'power', 'max_val': 500, 'min_val': -500, 'monitor_cycle_seconds': 5, 'precision': 1, 'read_write': 'read', 'type': 'float', 'units': 'Volts'}}, 'dvr_cls': 'RSNPlatformDriver', 'dvr_mod': 'ion.agents.platform.rsn.rsn_platform_driver', 'oms_uri': 'embsimulator', 'ports': {'LJ01D_port_1': {'port_id': '1'}, 'LJ01D_port_2': {'port_id': '2'}}}, 'children': {}, } } } } }) ndef = NetworkUtil.create_network_definition_from_ci_config(CFG) if log.isEnabledFor(logging.TRACE): serialization = NetworkUtil.serialize_network_definition(ndef) log.trace("serialization = \n%s", serialization) self.assertIn('Node1D', ndef.pnodes) Node1D = ndef.pnodes['Node1D'] common_attr_names = ['MVPC_pressure_1|0', 'MVPC_temperature|0', 'input_bus_current|0', 'input_voltage|0', ] for attr_name in common_attr_names: self.assertIn(attr_name, Node1D.attrs) #todo complete the network definition: align ports defintion with internal representation. #for port_name in ['Node1D_port_1', 'Node1D_port_2']: # self.assertIn(port_name, Node1D.ports) for subplat_name in ['MJ01C', ]: self.assertIn(subplat_name, Node1D.subplatforms) MJ01C = Node1D.subplatforms['MJ01C'] for subplat_name in ['LJ01D', ]: self.assertIn(subplat_name, MJ01C.subplatforms) LJ01D = MJ01C.subplatforms['LJ01D'] for attr_name in common_attr_names: self.assertIn(attr_name, LJ01D.attrs)