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)
예제 #2
0
    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)
예제 #3
0
    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)
예제 #4
0
    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)
예제 #6
0
    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
예제 #7
0
    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)
예제 #9
0
    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
예제 #10
0
    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
예제 #11
0
    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)
예제 #12
0
    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
예제 #13
0
    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
예제 #14
0
    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)