예제 #1
0
 def setUp(self):
     self.log = structlog.get_logger()
     self.log.debug("do setup")
     self.device_id = '1'
     self._image_dnld = ImageDownload()
     self._image_dnld.id = '1'
     self._image_dnld.name = 'switchd_1012'
     # self._image_dnld.name = 'xgsont_4.4.4.006.img'
     self._image_dnld.url = 'http://192.168.100.222:9090/load/4.4.4.006.img'
     self._image_dnld.crc = 0
     self._image_dnld.local_dir = '/home/lcui/work/tmp'
     self._image_dnld.state = ImageDownload.DOWNLOAD_SUCCEEDED # ImageDownload.DOWNLOAD_UNKNOWN
     self._end_image_busy_try = 2
     self._act_image_busy_try = 0
     # self.image_file = '/home/lcui/work/tmp/v_change.txt'
     self.reactor = EPollReactor()
     self.defer = Deferred()
     self.adapter_agent = MockAdapterAgent(self.defer)
     self.defer.addCallback(self.cb_after_send_omci)
     pb2_dev = Device(id='1')
     self.adapter_agent.add_device(pb2_dev)
     self.core = self.adapter_agent.core
     self.omci_agent = OpenOMCIAgent(self.core, clock=self.reactor)
     self.device = self.omci_agent.add_device(self.device_id, self.adapter_agent)
     self.omci_agent.start()
     self.omci_agent.database.add('1')
     self.omci_agent.database.set('1', SoftwareImage.class_id, 0, {"is_committed": 1, "is_active": 1, "is_valid": 1})
     self.omci_agent.database.set('1', SoftwareImage.class_id, 1, {"is_committed": 0, "is_active": 0, "is_valid": 1})
예제 #2
0
 def omci_agent(self):
     if not hasattr(self, '_omci_agent') or self._omci_agent is None:
         self.log.debug('creating-omci-agent')
         self._omci_agent = OpenOMCIAgent(self.core_proxy,
                                          self.adapter_proxy,
                                          support_classes=self.broadcom_omci)
     return self._omci_agent
    def test_omci_agent_default_init(self):
        agent = OpenOMCIAgent(MockCore)

        self.assertTrue(isinstance(agent.core, type(MockCore)))
        self.assertTrue(isinstance(agent.database_class, type(MibDbExternal)))
        self.assertEqual(len(agent.device_ids()), 0)
        assert_raises(KeyError, agent.get_device, 'deadbeef')
예제 #4
0
    def __init__(self, core_proxy, adapter_proxy, config):
        self.log = structlog.get_logger()
        super(AdtranOnuAdapter, self).__init__(core_proxy=core_proxy,
                                               adapter_proxy=adapter_proxy,
                                               config=config,
                                               device_handler_class=AdtranOnuHandler,
                                               name='adtran_onu',
                                               vendor='ADTRAN, Inc.',
                                               version='2.0',
                                               device_type='adtran_onu',
                                               vendor_id='ADTN',
                                               accepts_bulk_flow_update=True,
                                               accepts_add_remove_flow_updates=False)  # TODO: Support flow-mods
        # Customize OpenOMCI for Adtran ONUs
        self.adtran_omci = deepcopy(OpenOmciAgentDefaults)

        from pyvoltha.adapters.extensions.omci.database.mib_db_dict import MibDbVolatileDict
        self.adtran_omci['mib-synchronizer']['database'] = MibDbVolatileDict

        self.adtran_omci['mib-synchronizer']['state-machine'] = AdtnMibSynchronizer
        self.adtran_omci['mib-synchronizer']['tasks']['get-mds'] = AdtnGetMdsTask
        self.adtran_omci['mib-synchronizer']['tasks']['mib-audit'] = AdtnGetMdsTask
        self.adtran_omci['mib-synchronizer']['tasks']['mib-resync'] = AdtnMibResyncTask
        self.adtran_omci['mib-synchronizer']['tasks']['mib-reconcile'] = AdtnMibReconcileTask
        self.adtran_omci['omci-capabilities']['tasks']['get-capabilities'] = AdtnCapabilitiesTask
        # TODO: Continue to customize adtran_omci here as needed

        self._omci_agent = OpenOMCIAgent(self.adapter_agent,
                                         support_classes=self.adtran_omci)
예제 #5
0
    def setUp(self):
        self.adapter_agent = MockAdapterAgent()

        custom = deepcopy(OpenOmciAgentDefaults)
        custom['mib-synchronizer']['database'] = MibDbVolatileDict

        self.omci_agent = OpenOMCIAgent(MockCore, support_classes=custom)
        self.omci_agent.start()
    def test_omci_agent_custom_mib_database(self):
        custom = deepcopy(OpenOmciAgentDefaults)
        custom['mib-synchronizer']['database'] = MibDbVolatileDict
        agent = OpenOMCIAgent(MockCore, support_classes=custom)

        self.assertTrue(isinstance(agent.core, type(MockCore)))
        self.assertTrue(
            isinstance(agent.database_class, type(MibDbVolatileDict)))
    def test_omci_agent_start_stop(self):
        agent = OpenOMCIAgent(MockCore)

        agent.start()
        agent.start()  # Should be a NOP, no side effects

        agent.stop()
        agent.stop()  # Should be a NOP, no side effects
예제 #8
0
class BrcmOpenomciOnuAdapter(object):

    name = 'brcm_openomci_onu'

    supported_device_types = [
        DeviceType(
            id=name,
            vendor_ids=['OPEN', 'ALCL', 'BRCM', 'TWSH', 'ALPH', 'ISKT', 'SFAA', 'BBSM', 'SCOM', 'ARPX', 'DACM', 'ERSN', 'HWTC', 'CIGG'],
            adapter=name,
            accepts_bulk_flow_update=False,
            accepts_add_remove_flow_updates=True
        )
    ]

    def __init__(self, core_proxy, adapter_proxy, config, build_info):
        self.log = structlog.get_logger()
        self.log.debug('starting-adapter', config=config)

        self.core_proxy = core_proxy
        self.adapter_proxy = adapter_proxy
        self.config = config
        self.descriptor = Adapter(
            id=self.name,
            vendor='VOLTHA OpenONU',
            version=build_info.version,
            config=AdapterConfig()
        )
        self.devices_handlers = dict()
        self.device_handler_class = BrcmOpenomciOnuHandler

        # Customize OpenOMCI for Broadcom ONUs
        self.broadcom_omci = deepcopy(OpenOmciAgentDefaults)

        self.broadcom_omci['mib-synchronizer']['audit-delay'] = 0  # disable audits as brcm onu wont upload once provisioned
        self.broadcom_omci['mib-synchronizer']['database'] = MibDbVolatileDict
        self.broadcom_omci['alarm-synchronizer']['database'] = MibDbVolatileDict
        self.broadcom_omci['omci-capabilities']['tasks']['get-capabilities'] = BrcmCapabilitiesTask

        # Defer creation of omci agent to a lazy init that allows subclasses to override support classes

    def custom_me_entities(self):
        return None

    @property
    def omci_agent(self):
        if not hasattr(self, '_omci_agent') or self._omci_agent is None:
            self.log.debug('creating-omci-agent')
            self._omci_agent = OpenOMCIAgent(self.core_proxy,
                                             self.adapter_proxy,
                                             support_classes=self.broadcom_omci)
        return self._omci_agent

    def start(self):
        self.log.debug('starting')
        self.omci_agent.start()
        self.log.info('started')

    def stop(self):
        self.log.debug('stopping')

        omci, self._omci_agent = self._omci_agent, None
        if omci is not None:
            self._omci_agent.stop()

        self.log.info('stopped')

    def adapter_descriptor(self):
        return self.descriptor

    def device_types(self):
        return DeviceTypes(items=self.supported_device_types)

    def health(self):
        return HealthStatus(state=HealthStatus.HealthState.HEALTHY)

    def change_master_state(self, master):
        raise NotImplementedError()

    def adopt_device(self, device):
        self.log.info('adopt-device', device_id=device.id)
        self.devices_handlers[device.id] = BrcmOpenomciOnuHandler(self, device.id)
        reactor.callLater(0, self.devices_handlers[device.id].activate, device)
        return device

    def reconcile_device(self, device):
        self.log.info('reconcile-device', device_id=device.id)
        self.devices_handlers[device.id] = BrcmOpenomciOnuHandler(self, device.id)
        reactor.callLater(0, self.devices_handlers[device.id].reconcile, device)

    def abandon_device(self, device):
        raise NotImplementedError()

    def disable_device(self, device):
        self.log.info('disable-onu-device', device_id=device.id)
        if device.id in self.devices_handlers:
            handler = self.devices_handlers[device.id]
            if handler is not None:
                handler.disable(device)

    def reenable_device(self, device):
        self.log.info('reenable-onu-device', device_id=device.id)
        if device.id in self.devices_handlers:
            handler = self.devices_handlers[device.id]
            if handler is not None:
                handler.reenable(device)

    def reboot_device(self, device):
        self.log.info('reboot-device', device_id=device.id)
        if device.id in self.devices_handlers:
            handler = self.devices_handlers[device.id]
            if handler is not None:
                handler.reboot()

    def download_image(self, device, request):
        raise NotImplementedError()

    def get_image_download_status(self, device, request):
        raise NotImplementedError()

    def cancel_image_download(self, device, request):
        raise NotImplementedError()

    def activate_image_update(self, device, request):
        raise NotImplementedError()

    def revert_image_update(self, device, request):
        raise NotImplementedError()

    def enable_port(self, device_id, port):
        raise NotImplementedError()

    def disable_port(self, device_id, port):
        raise NotImplementedError()

    def self_test_device(self, device):
        """
        This is called to Self a device based on a NBI call.
        :param device: A Voltha.Device object.
        :return: Will return result of self test
        """
        self.log.info('self-test-device - Not implemented yet', device_id=device.id, serial_number=device.serial_number)
        raise NotImplementedError()

    def delete_device(self, device):
        self.log.info('delete-device', device_id=device.id)
        if device.id in self.devices_handlers:
            handler = self.devices_handlers[device.id]
            if handler is not None:
                handler.delete(device)
            del self.devices_handlers[device.id]
        return

    def get_device_details(self, device):
        raise NotImplementedError()

    # TODO(smbaker): When BrcmOpenomciOnuAdapter is updated to inherit from OnuAdapter, this function can be deleted
    def update_pm_config(self, device, pm_config):
        self.log.info("adapter-update-pm-config", device_id=device.id, serial_number=device.serial_number,
                 pm_config=pm_config)
        handler = self.devices_handlers[device.id]
        handler.update_pm_config(device, pm_config)

    def update_flows_bulk(self, device, flows, groups):
        '''
        log.info('bulk-flow-update', device_id=device.id,
                  flows=flows, groups=groups)
        '''
        assert len(groups.items) == 0
        handler = self.devices_handlers[device.id]
        return handler.update_flow_table(device, flows.items)

    def update_flows_incrementally(self, device, flow_changes, group_changes):
        self.log.info('incremental-flow-update', device_id=device.id,
                 flows=flow_changes, groups=group_changes)
        # For now, there is no support for group changes
        assert len(group_changes.to_add.items) == 0
        assert len(group_changes.to_remove.items) == 0

        handler = self.devices_handlers[device.id]
        # Remove flows
        if len(flow_changes.to_remove.items) != 0:
            handler.remove_onu_flows(device, flow_changes.to_remove.items)

        # Add flows
        if len(flow_changes.to_add.items) != 0:
            handler.add_onu_flows(device, flow_changes.to_add.items)

    def send_proxied_message(self, proxy_address, msg):
        self.log.debug('send-proxied-message', proxy_address=proxy_address, msg=msg)

    @inlineCallbacks
    def receive_proxied_message(self, proxy_address, msg):
        self.log.debug('receive-proxied-message', proxy_address=proxy_address,
                 device_id=proxy_address.device_id, msg=hexify(msg))
        # Device_id from the proxy_address is the olt device id. We need to
        # get the onu device id using the port number in the proxy_address
        device = self.core_proxy. \
            get_child_device_with_proxy_address(proxy_address)
        if device:
            handler = self.devices_handlers[device.id]
            handler.receive_message(msg)

    def receive_packet_out(self, logical_device_id, egress_port_no, msg):
        self.log.debug('packet-out', logical_device_id=logical_device_id,
                 egress_port_no=egress_port_no, msg_len=len(msg))

    @inlineCallbacks
    def receive_inter_adapter_message(self, msg):
        self.log.debug('receive-inter-adapter-message', msg=msg)
        proxy_address = msg['proxy_address']
        assert proxy_address is not None
        # Device_id from the proxy_address is the olt device id. We need to
        # get the onu device id using the port number in the proxy_address
        device = self.core_proxy. \
            get_child_device_with_proxy_address(proxy_address)
        if device:
            handler = self.devices_handlers[device.id]
            handler.event_messages.put(msg)
        else:
            self.log.error("device-not-found")

    def get_ofp_port_info(self, device, port_no):
        ofp_port_info = self.devices_handlers[device.id].get_ofp_port_info(device, port_no)
        self.log.debug('get-ofp-port-info', device_id=device.id,
                  port_name=ofp_port_info.port.ofp_port.name, port_no=ofp_port_info.port.device_port_no)
        return ofp_port_info

    def process_inter_adapter_message(self, msg):
        # Unpack the header to know which device needs to handle this message
        if msg.header:
            self.log.debug('process-inter-adapter-message', type=msg.header.type, from_topic=msg.header.from_topic,
                      to_topic=msg.header.to_topic, to_device_id=msg.header.to_device_id)
            handler = self.devices_handlers[msg.header.to_device_id]
            handler.process_inter_adapter_message(msg)

    def start_omci_test(self, device, uuid):
        """

        :param device:
        :return:
        """
        self.log.info('Omci-test-action-request-On', request=device)
        handler = self.devices_handlers[device.id]
        result = handler.start_omci_test_action(device, uuid)
        return result
예제 #9
0
class TestOmciDownload(TestCase):
    # def __init__(self, device_id='1', image_file='/home/lcui/work/tmp/v_change.txt', **kwargs):
    #     self.device_id = device_id
    #     self.image_file = image_file
    #     super(TestOmciDownload, self).__init__(**kwargs)
    sw_dwld_resp = {
        'tid': '0001',
        'mid': '33',
        'did': '0A',
        'entity_class': '0007',
        'entity_id'   : '0000',
        'reason'      : '0000',
        'window_size' : '001F',
        'inst_num'    : '0001',
        'inst_id'     : '0000',
        'trailer'     : '00000028',
        'mic'         : '00000000'
    }
    
    # sw_dwld_resp = '0001330A000700000000001f010000'
     
    ### Test Functions ###
    def sim_receive_start_sw_download_resp(self, tid, eid, r=0):
        msg = OmciFrame(
                    transaction_id=tid,
                    message_type=OmciStartSoftwareDownloadResponse.message_id,
                    omci_message=OmciStartSoftwareDownloadResponse(
                        entity_class=0x7,
                        entity_id=eid,
                        result=r,
                        window_size=0x1F,
                        image_number=1,
                        instance_id=eid
                    )
              )
        self.device.omci_cc.receive_message(msg)

    def sim_receive_download_section_resp(self, tid, eid, section, r=0):
        msg = OmciFrame(
                    transaction_id=tid,
                    message_type=OmciDownloadSectionResponse.message_id,
                    omci_message=OmciDownloadSectionResponse(
                        entity_class=0x7,
                        entity_id=eid,
                        result=r,
                        section_number=section
                    )
              )
        self.device.omci_cc.receive_message(msg)

    def sim_receive_end_sw_download_resp(self, tid, eid, r=0):
        msg = OmciFrame(
                    transaction_id=tid,
                    message_type=OmciEndSoftwareDownloadResponse.message_id,
                    omci_message=OmciEndSoftwareDownloadResponse(
                        entity_class=0x7,
                        entity_id=eid,
                        result=r,
                        image_number=0x1,
                        instance_id=eid,
                        result0=0x0
                    )
              )
        self.device.omci_cc.receive_message(msg)

    def sim_receive_activate_image_resp(self, tid, eid, r=0):
        msg = OmciFrame(
                    transaction_id=tid,
                    message_type=OmciActivateImageResponse.message_id,
                    omci_message=OmciActivateImageResponse(
                        entity_class=0x7,
                        entity_id=eid,
                        result = r
                    ))
        self.device.omci_cc.receive_message(msg)

    def sim_receive_commit_image_resp(self, tid, eid, r=0):
        msg = OmciFrame(
                    transaction_id=tid,
                    message_type=OmciCommitImageResponse.message_id,
                    omci_message=OmciCommitImageResponse(
                        entity_class=0x7,
                        entity_id=eid,
                        result = r
                    ))
        self.device.omci_cc.receive_message(msg)
        
    def cb_after_send_omci(self, msg):
        self.log.debug("cb_after_send_omci")
        dmsg = OmciFrame(binascii.unhexlify(msg))
        tid = dmsg.fields['transaction_id']
        mid = dmsg.fields['message_type']
        dmsg_body = dmsg.fields['omci_message']
        eid = dmsg_body.fields['entity_id']

        # print("%X" % dmsg.fields['transaction_id'])
        # print("%X" % dmsg.fields['message_type'])
        # print("%X" % OmciActivateImage.message_id)
        # print("%X" % dmsg_body.fields['entity_id'])

        if mid == OmciStartSoftwareDownload.message_id:
            self.log.debug("response start download")
            self.reactor.callLater(0, self.sim_receive_start_sw_download_resp, tid, eid)
        elif mid == OmciEndSoftwareDownload.message_id:
            self.log.debug("response end download")
            if self._end_image_busy_try > 0:
                self.reactor.callLater(0, self.sim_receive_end_sw_download_resp, tid, eid, r=6)
                self._end_image_busy_try -= 1
            else:
                self.reactor.callLater(0, self.sim_receive_end_sw_download_resp, tid, eid)
        elif mid == OmciDownloadSection.message_id:
            self.log.debug("receive download section, not respond")
        elif mid == OmciDownloadSectionLast.message_id:
            self.log.debug("response download last section")
            self.reactor.callLater(0, self.sim_receive_download_section_resp, tid, eid, 
                                   section=dmsg_body.fields["section_number"])
        elif mid == OmciActivateImage.message_id:
            self.log.debug("response activate image")
            if self._act_image_busy_try > 0:
                self.reactor.callLater(0, self.sim_receive_activate_image_resp, tid, eid, r=6)
                self._act_image_busy_try -= 1
            else:
                self.reactor.callLater(0, self.sim_receive_activate_image_resp, tid, eid)
                self.reactor.callLater(2, self.device.image_agent.onu_bootup)
        elif mid == OmciCommitImage.message_id:
            self.log.debug("response commit image")
            self.reactor.callLater(0, self.sim_receive_commit_image_resp, tid, eid)
        else:
            self.log.debug("Unsupported message type", message_type=mid)
            
        self.defer = Deferred()
        self.defer.addCallback(self.cb_after_send_omci)
        self.adapter_agent.send_omci_defer = self.defer
        
    def setUp(self):
        self.log = structlog.get_logger()
        self.log.debug("do setup")
        self.device_id = '1'
        self._image_dnld = ImageDownload()
        self._image_dnld.id = '1'
        self._image_dnld.name = 'switchd_1012'
        # self._image_dnld.name = 'xgsont_4.4.4.006.img'
        self._image_dnld.url = 'http://192.168.100.222:9090/load/4.4.4.006.img'
        self._image_dnld.crc = 0
        self._image_dnld.local_dir = '/home/lcui/work/tmp'
        self._image_dnld.state = ImageDownload.DOWNLOAD_SUCCEEDED # ImageDownload.DOWNLOAD_UNKNOWN
        self._end_image_busy_try = 2
        self._act_image_busy_try = 0
        # self.image_file = '/home/lcui/work/tmp/v_change.txt'
        self.reactor = EPollReactor()
        self.defer = Deferred()
        self.adapter_agent = MockAdapterAgent(self.defer)
        self.defer.addCallback(self.cb_after_send_omci)
        pb2_dev = Device(id='1')
        self.adapter_agent.add_device(pb2_dev)
        self.core = self.adapter_agent.core
        self.omci_agent = OpenOMCIAgent(self.core, clock=self.reactor)
        self.device = self.omci_agent.add_device(self.device_id, self.adapter_agent)
        self.omci_agent.start()
        self.omci_agent.database.add('1')
        self.omci_agent.database.set('1', SoftwareImage.class_id, 0, {"is_committed": 1, "is_active": 1, "is_valid": 1})
        self.omci_agent.database.set('1', SoftwareImage.class_id, 1, {"is_committed": 0, "is_active": 0, "is_valid": 1})
        
    def tearDown(self):
        self.log.debug("Test is Done")
        self.omci_agent.database.remove('1')
        self.device = None

    def stop(self):
        self.reactor.stop()
        self.log.debug("stopped");

    def get_omci_msg(self, *args, **kargs):
        m = ''
        for s in args:
            m += s
        m = m.ljust(80, '0')
        return m + kargs['trailer'] + kargs['mic']

    def sim_receive_sw_download_resp2(self):
        r = self.get_omci_msg(self.sw_dwld_resp['tid'], self.sw_dwld_resp['mid'], 
                              self.sw_dwld_resp['did'], self.sw_dwld_resp['entity_class'], 
                              self.sw_dwld_resp['entity_id'], self.sw_dwld_resp['reason'], 
                              self.sw_dwld_resp['window_size'], self.sw_dwld_resp['inst_num'], self.sw_dwld_resp['inst_id'], 
                              trailer=self.sw_dwld_resp['trailer'], mic=self.sw_dwld_resp['mic'])
        data = binascii.unhexlify(r)
        #msg = OmciFrame(data)
        #print(msg.fields['transaction_id'])
        #print(msg.fields['omci'])
        self.device.omci_cc.receive_message(data)

    def sw_action_success(self, instance_id, device_id):
        self.log.debug("Action Success", device_id=device_id, entity_id=instance_id)
        self.reactor.callLater(0, self.onu_do_activate)
        
    def sw_action2_success(self, instance_id, device_id):
        self.log.debug("Action2 Success", device_id=device_id, entity_id=instance_id)

    def sw_action_fail(self, fail, device_id):
        self.log.debug("Finally Failed", device_id=device_id)
        self.log.debug(fail)
        
    # def test_onu_do_activate(self):
    def onu_do_activate(self):
        self.log.debug("do test_onu_do_activate") 
        self.defer = self.device.do_onu_image_activate(self._image_dnld.name)
        self.defer.addCallbacks(self.sw_action2_success, self.sw_action_fail, callbackArgs=(self.device_id,), errbackArgs=(self.device_id,))
        self.reactor.callLater(100, self.stop)
        # self.reactor.run()
        
    @skip("for Jenkins Verification")
    def test_onu_do_software_upgrade(self):
        self.log.debug("do test_onu_do_software_upgrade", download=self._image_dnld)
        dr = self.omci_agent.database.query('1', SoftwareImage.class_id, 0, "is_committed")
        self.defer = self.device.do_onu_software_download(self._image_dnld)
        self.defer.addCallbacks(self.sw_action_success, self.sw_action_fail, callbackArgs=(self.device_id,), errbackArgs=(self.device_id,))
        # self.defer.addCallbacks(self.sw_action_success, self.sw_action_fail) #, errbackArgs=(self.device_id,))
        # self.reactor.callLater(1, self.sim_receive_start_sw_download_resp)
        # self.reactor.callLater(12, self.stop)
        self.reactor.run()
        
    @skip("Not used")
    def test_omci_message(self):
        self.log.debug("do test_omci_message") 
        r = self.get_omci_msg(self.sw_dwld_resp['tid'], self.sw_dwld_resp['mid'], 
                              self.sw_dwld_resp['did'], self.sw_dwld_resp['entity_class'], 
                              self.sw_dwld_resp['entity_id'], self.sw_dwld_resp['reason'], 
                              self.sw_dwld_resp['window_size'], self.sw_dwld_resp['inst_num'], self.sw_dwld_resp['inst_id'], 
                              trailer=self.sw_dwld_resp['trailer'], mic=self.sw_dwld_resp['mic'])
        data = binascii.unhexlify(r)
        msg = OmciFrame(data)
        self.log.debug(binascii.hexlify(str(msg)))
        # print("%04X" % msg.fields['transaction_id'])
        # print("%02X" % msg.fields['message_type'])
        # print("%02X" % msg.fields['omci'])
        # print("%X" % msg.fields['omci_message'])

    @skip("Not used")
    def test_omci_message2(self):
        self.log.debug("do test_omci_message2") 
        msg = OmciFrame(
                    transaction_id=0x0001,
                    message_type=OmciStartSoftwareDownloadResponse.message_id,
                    omci_message=OmciStartSoftwareDownloadResponse(
                        entity_class=0x7,
                        entity_id=0x0,
                        result=0x0,
                        window_size=0x1F,
                        image_number=1,
                        instance_id=0
                    )
              )
        self.log.debug(binascii.hexlify(str(msg)))
예제 #10
0
class BrcmOpenomciOnuAdapter(object):

    name = 'brcm_openomci_onu'

    supported_device_types = [
        DeviceType(id=name,
                   vendor_ids=[
                       'OPEN', 'ALCL', 'BRCM', 'TWSH', 'ALPH', 'ISKT', 'SFAA',
                       'BBSM'
                   ],
                   adapter=name,
                   accepts_bulk_flow_update=True)
    ]

    def __init__(self, core_proxy, adapter_proxy, config):
        log.debug('function-entry', config=config)
        self.core_proxy = core_proxy
        self.adapter_proxy = adapter_proxy
        self.config = config
        self.descriptor = Adapter(
            id=self.name,
            vendor='Voltha project',
            version='2.0',
            config=AdapterConfig(log_level=LogLevel.INFO))
        self.devices_handlers = dict()
        self.device_handler_class = BrcmOpenomciOnuHandler

        # Customize OpenOMCI for Broadcom ONUs
        self.broadcom_omci = deepcopy(OpenOmciAgentDefaults)

        self.broadcom_omci['mib-synchronizer'][
            'state-machine'] = BrcmMibSynchronizer
        self.broadcom_omci['mib-synchronizer']['database'] = MibDbExternal
        self.broadcom_omci['omci-capabilities']['tasks'][
            'get-capabilities'] = BrcmCapabilitiesTask

        # Defer creation of omci agent to a lazy init that allows subclasses to override support classes

    def custom_me_entities(self):
        return None

    @property
    def omci_agent(self):
        if not hasattr(self, '_omci_agent') or self._omci_agent is None:
            log.debug('creating-omci-agent')
            self._omci_agent = OpenOMCIAgent(
                self.core_proxy,
                self.adapter_proxy,
                support_classes=self.broadcom_omci)
        return self._omci_agent

    def start(self):
        log.debug('starting')
        self.omci_agent.start()
        log.info('started')

    def stop(self):
        log.debug('stopping')

        omci, self._omci_agent = self._omci_agent, None
        if omci is not None:
            self._omci_agent.stop()

        log.info('stopped')

    def adapter_descriptor(self):
        return self.descriptor

    def device_types(self):
        return DeviceTypes(items=self.supported_device_types)

    def health(self):
        return HealthStatus(state=HealthStatus.HealthState.HEALTHY)

    def change_master_state(self, master):
        raise NotImplementedError()

    def adopt_device(self, device):
        log.info('adopt_device', device_id=device.id)
        self.devices_handlers[device.id] = BrcmOpenomciOnuHandler(
            self, device.id)
        reactor.callLater(0, self.devices_handlers[device.id].activate, device)
        return device

    def reconcile_device(self, device):
        log.info('reconcile-device', device_id=device.id)
        self.devices_handlers[device.id] = BrcmOpenomciOnuHandler(
            self, device.id)
        reactor.callLater(0, self.devices_handlers[device.id].reconcile,
                          device)

    def abandon_device(self, device):
        raise NotImplementedError()

    def disable_device(self, device):
        log.info('disable-onu-device', device_id=device.id)
        if device.id in self.devices_handlers:
            handler = self.devices_handlers[device.id]
            if handler is not None:
                handler.disable(device)

    def reenable_device(self, device):
        log.info('reenable-onu-device', device_id=device.id)
        if device.id in self.devices_handlers:
            handler = self.devices_handlers[device.id]
            if handler is not None:
                handler.reenable(device)

    def reboot_device(self, device):
        log.info('reboot-device', device_id=device.id)
        if device.id in self.devices_handlers:
            handler = self.devices_handlers[device.id]
            if handler is not None:
                handler.reboot()

    def download_image(self, device, request):
        raise NotImplementedError()

    def get_image_download_status(self, device, request):
        raise NotImplementedError()

    def cancel_image_download(self, device, request):
        raise NotImplementedError()

    def activate_image_update(self, device, request):
        raise NotImplementedError()

    def revert_image_update(self, device, request):
        raise NotImplementedError()

    def self_test_device(self, device):
        """
        This is called to Self a device based on a NBI call.
        :param device: A Voltha.Device object.
        :return: Will return result of self test
        """
        log.info('self-test-device - Not implemented yet', device=device.id)
        raise NotImplementedError()

    def delete_device(self, device):
        log.info('delete-device', device_id=device.id)
        if device.id in self.devices_handlers:
            handler = self.devices_handlers[device.id]
            if handler is not None:
                handler.delete(device)
            del self.devices_handlers[device.id]
        return

    def get_device_details(self, device):
        raise NotImplementedError()

    # TODO(smbaker): When BrcmOpenomciOnuAdapter is updated to inherit from OnuAdapter, this function can be deleted
    def update_pm_config(self, device, pm_config):
        log.info("adapter-update-pm-config",
                 device=device,
                 pm_config=pm_config)
        handler = self.devices_handlers[device.id]
        handler.update_pm_config(device, pm_config)

    def update_flows_bulk(self, device, flows, groups):
        '''
        log.info('bulk-flow-update', device_id=device.id,
                  flows=flows, groups=groups)
        '''
        assert len(groups.items) == 0
        handler = self.devices_handlers[device.id]
        return handler.update_flow_table(device, flows.items)

    def update_flows_incrementally(self, device, flow_changes, group_changes):
        raise NotImplementedError()

    def send_proxied_message(self, proxy_address, msg):
        log.debug('send-proxied-message', proxy_address=proxy_address, msg=msg)

    @inlineCallbacks
    def receive_proxied_message(self, proxy_address, msg):
        log.debug('receive-proxied-message',
                  proxy_address=proxy_address,
                  device_id=proxy_address.device_id,
                  msg=hexify(msg))
        # Device_id from the proxy_address is the olt device id. We need to
        # get the onu device id using the port number in the proxy_address
        device = self.core_proxy. \
            get_child_device_with_proxy_address(proxy_address)
        if device:
            handler = self.devices_handlers[device.id]
            handler.receive_message(msg)

    def receive_packet_out(self, logical_device_id, egress_port_no, msg):
        log.info('packet-out',
                 logical_device_id=logical_device_id,
                 egress_port_no=egress_port_no,
                 msg_len=len(msg))

    @inlineCallbacks
    def receive_inter_adapter_message(self, msg):
        log.debug('receive_inter_adapter_message', msg=msg)
        proxy_address = msg['proxy_address']
        assert proxy_address is not None
        # Device_id from the proxy_address is the olt device id. We need to
        # get the onu device id using the port number in the proxy_address
        device = self.core_proxy. \
            get_child_device_with_proxy_address(proxy_address)
        if device:
            handler = self.devices_handlers[device.id]
            handler.event_messages.put(msg)
        else:
            log.error("device-not-found")

    def get_ofp_port_info(self, device, port_no):
        ofp_port_info = self.devices_handlers[device.id].get_ofp_port_info(
            device, port_no)
        log.debug('get_ofp_port_info',
                  device_id=device.id,
                  ofp_port_info=ofp_port_info)
        return ofp_port_info

    def process_inter_adapter_message(self, msg):
        log.debug('process-inter-adapter-message', msg=msg)
        # Unpack the header to know which device needs to handle this message
        if msg.header:
            handler = self.devices_handlers[msg.header.to_device_id]
            handler.process_inter_adapter_message(msg)

    def create_interface(self, device, data):
        log.debug('create-interface', device_id=device.id)
        if device.id in self.devices_handlers:
            handler = self.devices_handlers[device.id]
            if handler is not None:
                handler.create_interface(data)

    def update_interface(self, device, data):
        log.debug('update-interface', device_id=device.id)
        if device.id in self.devices_handlers:
            handler = self.devices_handlers[device.id]
            if handler is not None:
                handler.update_interface(data)

    def remove_interface(self, device, data):
        log.debug('remove-interface', device_id=device.id)
        if device.id in self.devices_handlers:
            handler = self.devices_handlers[device.id]
            if handler is not None:
                handler.remove_interface(data)

    def receive_onu_detect_state(self, device_id, state):
        raise NotImplementedError()

    def create_tcont(self, device, tcont_data, traffic_descriptor_data):
        log.debug('create-tcont', device_id=device.id)
        if device.id in self.devices_handlers:
            handler = self.devices_handlers[device.id]
            if handler is not None:
                handler.create_tcont(tcont_data, traffic_descriptor_data)

    def update_tcont(self, device, tcont_data, traffic_descriptor_data):
        raise NotImplementedError()

    def remove_tcont(self, device, tcont_data, traffic_descriptor_data):
        log.debug('remove-tcont', device_id=device.id)
        if device.id in self.devices_handlers:
            handler = self.devices_handlers[device.id]
            if handler is not None:
                handler.remove_tcont(tcont_data, traffic_descriptor_data)

    def create_gemport(self, device, data):
        log.debug('create-gemport', device_id=device.id)
        if device.id in self.devices_handlers:
            handler = self.devices_handlers[device.id]
            if handler is not None:
                handler.create_gemport(data)

    def update_gemport(self, device, data):
        raise NotImplementedError()

    def remove_gemport(self, device, data):
        log.debug('remove-gemport', device_id=device.id)
        if device.id in self.devices_handlers:
            handler = self.devices_handlers[device.id]
            if handler is not None:
                handler.remove_gemport(data)

    def create_multicast_gemport(self, device, data):
        log.debug('create-multicast-gemport', device_id=device.id)
        if device.id in self.devices_handlers:
            handler = self.devices_handlers[device.id]
            if handler is not None:
                handler.create_multicast_gemport(data)

    def update_multicast_gemport(self, device, data):
        raise NotImplementedError()

    def remove_multicast_gemport(self, device, data):
        raise NotImplementedError()

    def create_multicast_distribution_set(self, device, data):
        raise NotImplementedError()

    def update_multicast_distribution_set(self, device, data):
        raise NotImplementedError()

    def remove_multicast_distribution_set(self, device, data):
        raise NotImplementedError()

    def suppress_alarm(self, filter):
        raise NotImplementedError()

    def unsuppress_alarm(self, filter):
        raise NotImplementedError()
예제 #11
0
class TestOmciConfiguration(TestCase):
    """
    Test the OMCI read-only Configuration library methods
    """
    def setUp(self):
        self.adapter_agent = MockAdapterAgent()

        custom = deepcopy(OpenOmciAgentDefaults)
        custom['mib-synchronizer']['database'] = MibDbVolatileDict

        self.omci_agent = OpenOMCIAgent(MockCore, support_classes=custom)
        self.omci_agent.start()

    def tearDown(self):
        if self.omci_agent is not None:
            self.omci_agent.stop()

        if self.adapter_agent is not None:
            self.adapter_agent.tearDown()

    def setup_mock_olt(self, device_id=DEFAULT_OLT_DEVICE_ID):
        handler = MockOltHandler(self.adapter_agent, device_id)
        self.adapter_agent.add_device(handler.device)
        return handler

    def setup_mock_onu(self,
                       parent_id=DEFAULT_OLT_DEVICE_ID,
                       device_id=DEFAULT_ONU_DEVICE_ID,
                       pon_id=DEFAULT_PON_ID,
                       onu_id=DEFAULT_ONU_ID,
                       serial_no=DEFAULT_ONU_SN):
        handler = MockOnuHandler(self.adapter_agent, parent_id, device_id,
                                 pon_id, onu_id)
        handler.serial_number = serial_no
        onu = MockOnu(serial_no, self.adapter_agent, handler.device_id) \
            if serial_no is not None else None
        handler.onu_mock = onu
        return handler

    def setup_one_of_each(self):
        # Most tests will use at lease one or more OLT and ONU
        self.olt_handler = self.setup_mock_olt()
        self.onu_handler = self.setup_mock_onu(
            parent_id=self.olt_handler.device_id)
        self.onu_device = self.onu_handler.onu_mock

        self.adapter_agent.add_child_device(self.olt_handler.device,
                                            self.onu_handler.device)
        # Add device to OpenOMCI
        self.onu_device = self.omci_agent.add_device(DEFAULT_ONU_DEVICE_ID,
                                                     self.adapter_agent)

        # Allow timeout trigger support while in disabled state for mib sync
        # to make tests run cleanly while profiling.
        self.onu_device.mib_synchronizer.machine.add_transition(
            'timeout', 'disabled', 'disabled')

    def not_called(self, _reason):
        assert False, 'Should never be called'

    def _stuff_database(self, entries):
        """
        Stuff the MIB database with some entries that we will use during tests
        """
        database = self.onu_device.mib_synchronizer._database

        # Stuff a value into last in sync. This makes it look like
        # the ONU has been in in-sync at least once.
        self.onu_device.mib_synchronizer.last_mib_db_sync = datetime.utcnow()

        # Entry is a tuple of (class_id, instance_id, {attributes})
        for entry in entries:
            database.set(DEFAULT_ONU_DEVICE_ID, entry[0], entry[1], entry[2])

    def test_OMCCVersion(self):
        for key, value in OMCCVersion.__members__.items():
            self.assertEqual(OMCCVersion.to_enum(OMCCVersion[key].value),
                             value)

        self.assertEqual(OMCCVersion.to_enum(-1), OMCCVersion.Unknown)

    @deferred(timeout=50000)
    def test_defaults(self):
        self.setup_one_of_each()
        self.assertEqual(len(self.omci_agent.device_ids()), 1)

        @raises(AssertionError)
        def do_my_tests(_results):
            config = self.onu_device.configuration
            # Should raise assertion if never been synchronized
            config.version

        # No capabilities available until started
        self.assertIsNone(self.onu_device.configuration)

        # Yield context so that MIB Database callLater runs. This is a waiting
        # Async task from when the OpenOMCIAgent was started. But also start the
        # device so that it's queued async state machines can run as well
        self.onu_device.start()
        d = asleep(0.2)
        d.addCallbacks(do_my_tests, self.not_called)
        return d

    @deferred(timeout=5)
    def test_in_sync_but_empty(self):
        self.setup_one_of_each()
        self.assertEqual(len(self.omci_agent.device_ids()), 1)

        def stuff_db(_results):
            self._stuff_database([])

        def do_my_tests(_results):
            config = self.onu_device.configuration

            # On no Class ID for requested property, None should be
            # returned
            self.assertIsNone(config.version)
            self.assertIsNone(config.traffic_management_option)
            self.assertIsNone(config.onu_survival_time)
            self.assertIsNone(config.equipment_id)
            self.assertIsNone(config.omcc_version)
            self.assertIsNone(config.vendor_product_code)
            self.assertIsNone(config.total_priority_queues)
            self.assertIsNone(config.total_traffic_schedulers)
            self.assertIsNone(config.total_gem_ports)
            self.assertIsNone(config.uptime)
            self.assertIsNone(config.connectivity_capability)
            self.assertIsNone(config.qos_configuration_flexibility)
            self.assertIsNone(config.priority_queue_scale_factor)
            self.assertIsNone(config.cardholder_entities)
            self.assertIsNone(config.circuitpack_entities)
            self.assertIsNone(config.software_images)
            self.assertIsNone(config.ani_g_entities)
            self.assertIsNone(config.uni_g_entities)

        # No capabilities available until started
        self.assertIsNone(self.onu_device.configuration)

        # Yield context so that MIB Database callLater runs.
        self.onu_device.start()
        d = asleep(0.2)
        d.addCallbacks(stuff_db, self.not_called)
        d.addCallbacks(do_my_tests, self.not_called)
        return d

    @deferred(timeout=5)
    def test_in_sync_with_ont_g_values(self):
        self.setup_one_of_each()
        self.assertEqual(len(self.omci_agent.device_ids()), 1)

        version = 'abcDEF'
        tm_opt = 2
        onu_survival = 123

        def stuff_db(_results):
            self._stuff_database([(OntG.class_id, 0, {
                'version': version,
                'traffic_management_options': tm_opt,
                'ont_survival_time': onu_survival
            })])

        def do_my_tests(_results):
            config = self.onu_device.configuration

            # On no Class ID for requested property, None should be
            # returned
            self.assertEqual(config.version, version)
            self.assertEqual(config.traffic_management_option, tm_opt)
            self.assertEqual(config.onu_survival_time, onu_survival)

        # No capabilities available until started
        self.assertIsNone(self.onu_device.configuration)

        # Yield context so that MIB Database callLater runs.
        self.onu_device.start()
        d = asleep(0.2)
        d.addCallbacks(stuff_db, self.not_called)
        d.addCallbacks(do_my_tests, self.not_called)
        return d

    @deferred(timeout=5)
    def test_in_sync_with_ont_2g_values(self):
        self.setup_one_of_each()
        self.assertEqual(len(self.omci_agent.device_ids()), 1)

        equip_id = 'br-549'
        omcc_ver = OMCCVersion.G_988_2012
        vend_code = 0x1234
        queues = 64
        scheds = 8
        gem_ports = 24
        uptime = 12345
        conn_capp = 0x00aa
        qos_flex = 0x001b
        queue_scale = 1

        def stuff_db(_results):
            self._stuff_database([(Ont2G.class_id, 0, {
                'equipment_id': equip_id,
                'omcc_version': omcc_ver.value,
                'vendor_product_code': vend_code,
                'total_priority_queue_number': queues,
                'total_traffic_scheduler_number': scheds,
                'total_gem_port_id_number': gem_ports,
                'sys_uptime': uptime,
                'connectivity_capability': conn_capp,
                'qos_configuration_flexibility': qos_flex,
                'priority_queue_scale_factor': queue_scale
            })])

        def do_my_tests(_results):
            config = self.onu_device.configuration

            self.assertEqual(config.equipment_id, equip_id)
            self.assertEqual(config.omcc_version, omcc_ver)
            self.assertEqual(config.vendor_product_code, vend_code)
            self.assertEqual(config.total_priority_queues, queues)
            self.assertEqual(config.total_traffic_schedulers, scheds)
            self.assertEqual(config.total_gem_ports, gem_ports)
            self.assertEqual(config.uptime, uptime)
            self.assertEqual(config.connectivity_capability, conn_capp)
            self.assertEqual(config.qos_configuration_flexibility, qos_flex)
            self.assertEqual(config.priority_queue_scale_factor, queue_scale)

        # No capabilities available until started
        self.assertIsNone(self.onu_device.configuration)

        # Yield context so that MIB Database callLater runs.
        self.onu_device.start()
        d = asleep(0.2)
        d.addCallbacks(stuff_db, self.not_called)
        d.addCallbacks(do_my_tests, self.not_called)
        return d

    @deferred(timeout=5)
    def test_in_sync_with_cardholder_values(self):
        self.setup_one_of_each()
        self.assertEqual(len(self.omci_agent.device_ids()), 1)

        ch_entity = 0x102
        unit_type = 255
        clie_code = 'abc123'
        prot_ptr = 0

        def stuff_db(_results):
            self._stuff_database([(Cardholder.class_id, ch_entity, {
                'actual_plugin_unit_type': unit_type,
                'actual_equipment_id': clie_code,
                'protection_profile_pointer': prot_ptr,
            })])

        def do_my_tests(_results):
            config = self.onu_device.configuration

            cardholder = config.cardholder_entities
            self.assertTrue(isinstance(cardholder, dict))
            self.assertEqual(len(cardholder), 1)
            self.assertEqual(cardholder[ch_entity]['entity-id'], ch_entity)
            self.assertEqual(cardholder[ch_entity]['is-single-piece'],
                             ch_entity >= 256)
            self.assertEqual(cardholder[ch_entity]['slot-number'],
                             ch_entity & 0xFF)
            self.assertEqual(cardholder[ch_entity]['actual-plug-in-type'],
                             unit_type)
            self.assertEqual(cardholder[ch_entity]['actual-equipment-id'],
                             clie_code)
            self.assertEqual(cardholder[ch_entity]['protection-profile-ptr'],
                             prot_ptr)

        # No capabilities available until started
        self.assertIsNone(self.onu_device.configuration)

        # Yield context so that MIB Database callLater runs.
        self.onu_device.start()
        d = asleep(0.2)
        d.addCallbacks(stuff_db, self.not_called)
        d.addCallbacks(do_my_tests, self.not_called)
        return d

    @deferred(timeout=5)
    def test_in_sync_with_circuitpack_values(self):
        self.setup_one_of_each()
        self.assertEqual(len(self.omci_agent.device_ids()), 1)

        cp_entity = 0x100
        num_ports = 1
        serial_num = 'ABCD01234'
        cp_version = '1234ABCD'
        vendor_id = 'AB-9876'
        tconts = 2
        pqueues = 64
        sched_count = 8

        def stuff_db(_results):
            self._stuff_database([(CircuitPack.class_id, cp_entity, {
                'number_of_ports':
                num_ports,
                'serial_number':
                serial_num,
                'version':
                cp_version,
                'vendor_id':
                vendor_id,
                'total_tcont_buffer_number':
                tconts,
                'total_priority_queue_number':
                pqueues,
                'total_traffic_scheduler_number':
                sched_count,
            })])

        def do_my_tests(_results):
            config = self.onu_device.configuration

            circuitpack = config.circuitpack_entities
            self.assertTrue(isinstance(circuitpack, dict))
            self.assertEqual(len(circuitpack), 1)
            self.assertEqual(circuitpack[cp_entity]['entity-id'], cp_entity)
            self.assertEqual(circuitpack[cp_entity]['number-of-ports'],
                             num_ports)
            self.assertEqual(circuitpack[cp_entity]['serial-number'],
                             serial_num)
            self.assertEqual(circuitpack[cp_entity]['version'], cp_version)
            self.assertEqual(circuitpack[cp_entity]['vendor-id'], vendor_id)
            self.assertEqual(circuitpack[cp_entity]['total-tcont-count'],
                             tconts)
            self.assertEqual(
                circuitpack[cp_entity]['total-priority-queue-count'], pqueues)
            self.assertEqual(
                circuitpack[cp_entity]['total-traffic-sched-count'],
                sched_count)

        # No capabilities available until started
        self.assertIsNone(self.onu_device.configuration)

        # Yield context so that MIB Database callLater runs.
        self.onu_device.start()
        d = asleep(0.2)
        d.addCallbacks(stuff_db, self.not_called)
        d.addCallbacks(do_my_tests, self.not_called)
        return d

    @deferred(timeout=5)
    def test_in_sync_with_software_values(self):
        self.setup_one_of_each()
        self.assertEqual(len(self.omci_agent.device_ids()), 1)

        sw_entity = 0x200
        sw_version = 'Beta-0.0.2'
        sw_hash = md5("just_a_test").hexdigest()
        prod_code = 'MySoftware'
        sw_active = True
        sw_committed = True
        sw_valid = True

        def stuff_db(_results):
            self._stuff_database([(SoftwareImage.class_id, sw_entity, {
                'version': sw_version,
                'is_committed': sw_committed,
                'is_active': sw_active,
                'is_valid': sw_valid,
                'product_code': prod_code,
                'image_hash': sw_hash,
            })])

        def do_my_tests(_results):
            config = self.onu_device.configuration

            images = config.software_images
            self.assertTrue(isinstance(images, list))
            self.assertEqual(len(images), 1)
            self.assertEqual(
                images[0].name,
                'running-revision' if sw_active else 'candidate-revision')
            self.assertEqual(images[0].version, sw_version)
            self.assertEqual(images[0].is_active, 1 if sw_active else 0)
            self.assertEqual(images[0].is_committed, 1 if sw_committed else 0)
            self.assertEqual(images[0].is_valid, 1 if sw_valid else 0)
            self.assertEqual(images[0].hash, sw_hash)

        # No capabilities available until started
        self.assertIsNone(self.onu_device.configuration)

        # Yield context so that MIB Database callLater runs.
        self.onu_device.start()
        d = asleep(0.2)
        d.addCallbacks(stuff_db, self.not_called)
        d.addCallbacks(do_my_tests, self.not_called)
        return d

    @deferred(timeout=5)
    def test_in_sync_with_ani_g_values(self):
        self.setup_one_of_each()
        self.assertEqual(len(self.omci_agent.device_ids()), 1)

        entity_id = 0x0106
        tconts = 4
        dba_report = 4

        def stuff_db(_results):
            self._stuff_database([(AniG.class_id, entity_id, {
                'total_tcont_number': tconts,
                'piggyback_dba_reporting': dba_report
            })])

        def do_my_tests(_results):
            config = self.onu_device.configuration

            anig = config.ani_g_entities
            self.assertTrue(isinstance(anig, dict))
            self.assertEqual(len(anig), 1)

            self.assertEqual(anig[entity_id]['entity-id'], entity_id)
            self.assertEqual(anig[entity_id]['slot-number'],
                             (entity_id >> 8) & 0xff)
            self.assertEqual(anig[entity_id]['port-number'], entity_id & 0xff)
            self.assertEqual(anig[entity_id]['total-tcont-count'], tconts)
            self.assertEqual(anig[entity_id]['piggyback-dba-reporting'],
                             dba_report)

        # No capabilities available until started
        self.assertIsNone(self.onu_device.configuration)

        # Yield context so that MIB Database callLater runs.
        self.onu_device.start()
        d = asleep(0.2)
        d.addCallbacks(stuff_db, self.not_called)
        d.addCallbacks(do_my_tests, self.not_called)
        return d

    @deferred(timeout=5)
    def test_in_sync_with_uni_g_values(self):
        self.setup_one_of_each()
        self.assertEqual(len(self.omci_agent.device_ids()), 1)

        entity_id = 0x4321
        mgmt_cap = 0

        def stuff_db(_results):
            self._stuff_database([(UniG.class_id, entity_id, {
                'management_capability': mgmt_cap
            })])

        def do_my_tests(_results):
            config = self.onu_device.configuration

            unig = config.uni_g_entities
            self.assertTrue(isinstance(unig, dict))
            self.assertEqual(len(unig), 1)

            self.assertEqual(unig[entity_id]['entity-id'], entity_id)
            self.assertEqual(unig[entity_id]['management-capability'],
                             mgmt_cap)

        # No capabilities available until started
        self.assertIsNone(self.onu_device.configuration)

        # Yield context so that MIB Database callLater runs.
        self.onu_device.start()
        d = asleep(0.2)
        d.addCallbacks(stuff_db, self.not_called)
        d.addCallbacks(do_my_tests, self.not_called)
        return d
예제 #12
0
class TestOnuDeviceEntry(TestCase):
    """
    Test the ONU Device Entry methods
    """
    def setUp(self):
        self.adapter_agent = MockAdapterAgent()

        custom = deepcopy(OpenOmciAgentDefaults)
        custom['mib-synchronizer']['database'] = MibDbVolatileDict

        self.agent = OpenOMCIAgent(MockCore, support_classes=custom)
        self.agent.start()

    def tearDown(self):
        if self.agent is not None:
            self.agent.stop()

        if self.adapter_agent is not None:
            self.adapter_agent.tearDown()

    def setup_mock_olt(self, device_id=DEFAULT_OLT_DEVICE_ID):
        handler = MockOltHandler(self.adapter_agent, device_id)
        self.adapter_agent.add_device(handler.device)
        return handler

    def setup_mock_onu(self,
                       parent_id=DEFAULT_OLT_DEVICE_ID,
                       device_id=DEFAULT_ONU_DEVICE_ID,
                       pon_id=DEFAULT_PON_ID,
                       onu_id=DEFAULT_ONU_ID,
                       serial_no=DEFAULT_ONU_SN):
        handler = MockOnuHandler(self.adapter_agent, parent_id, device_id,
                                 pon_id, onu_id)
        handler.serial_number = serial_no
        onu = MockOnu(serial_no, self.adapter_agent, handler.device_id) \
            if serial_no is not None else None
        handler.onu_mock = onu
        return handler

    def setup_one_of_each(self):
        # Most tests will use at lease one or more OLT and ONU
        self.olt_handler = self.setup_mock_olt()
        self.onu_handler = self.setup_mock_onu(
            parent_id=self.olt_handler.device_id)
        self.onu_device = self.onu_handler.onu_mock

        self.adapter_agent.add_child_device(self.olt_handler.device,
                                            self.onu_handler.device)

    def test_add_remove_device(self):
        self.setup_one_of_each()
        self.assertEqual(len(self.agent.device_ids()), 0)

        onu_device = self.agent.add_device(DEFAULT_ONU_DEVICE_ID,
                                           self.adapter_agent)
        self.assertIsNotNone(onu_device)
        self.assertEqual(len(self.agent.device_ids()), 1)
        self.assertEqual(self.agent.get_device(DEFAULT_ONU_DEVICE_ID),
                         onu_device)

        # No MIB if not started
        assert_raises(KeyError, onu_device.query_mib)

        self.agent.remove_device(DEFAULT_ONU_DEVICE_ID)
        self.assertEqual(len(self.agent.device_ids()), 1)

    def test_delete_device(self):
        self.setup_one_of_each()
        self.assertEqual(len(self.agent.device_ids()), 0)

        onu_device = self.agent.add_device(DEFAULT_ONU_DEVICE_ID,
                                           self.adapter_agent)
        self.assertIsNotNone(onu_device)
        self.assertEqual(len(self.agent.device_ids()), 1)
        self.assertEqual(self.agent.get_device(DEFAULT_ONU_DEVICE_ID),
                         onu_device)
        # Can delete if it was not started
        onu_device.delete()
        self.assertEqual(len(self.agent.device_ids()), 0)

        ##########################################
        # Delete of ONU device okay if it is started
        onu_device = self.agent.add_device(DEFAULT_ONU_DEVICE_ID,
                                           self.adapter_agent)
        self.assertIsNotNone(onu_device)
        self.assertEqual(len(self.agent.device_ids()), 1)
        self.assertEqual(self.agent.get_device(DEFAULT_ONU_DEVICE_ID),
                         onu_device)

        # Start it and then delete it
        onu_device.start()
        onu_device.delete()
        self.assertEqual(len(self.agent.device_ids()), 0)

    @deferred(timeout=5)
    def test_mib_query_fails_if_dev_not_started(self):
        self.setup_one_of_each()

        onu_device = self.agent.add_device(DEFAULT_ONU_DEVICE_ID,
                                           self.adapter_agent)
        self.assertIsNotNone(onu_device)
        self.assertEqual(len(self.agent.device_ids()), 1)
        self.assertEqual(self.agent.get_device(DEFAULT_ONU_DEVICE_ID),
                         onu_device)

        def not_called(_reason):
            assert False, 'Should never be called'

        def check_status(_results):
            # Device not yet started. Query should fail with KeyError since
            # ONU is not in database yet
            assert_raises(KeyError, onu_device.query_mib)

        # Yield context so that MIB Database callLater runs. This is a waiting
        # Async task from when the OpenOMCIAgent was started.
        d = asleep(0.2)
        d.addCallbacks(check_status, not_called)

        return d

    @deferred(timeout=5)
    def test_mib_query_ok_if_dev_started(self):
        self.setup_one_of_each()

        onu_device = self.agent.add_device(DEFAULT_ONU_DEVICE_ID,
                                           self.adapter_agent)
        self.assertIsNotNone(onu_device)
        self.assertEqual(len(self.agent.device_ids()), 1)
        self.assertEqual(self.agent.get_device(DEFAULT_ONU_DEVICE_ID),
                         onu_device)

        def not_called(_reason):
            onu_device.stop()
            assert False, 'Should never be called'

        def check_status(_results):
            # Device started. Query will succeed but nothing should be populated
            # but the most basic items

            results = onu_device.query_mib()
            self.assertTrue(isinstance(results, dict))
            self.assertEqual(results.get(DEVICE_ID_KEY), DEFAULT_ONU_DEVICE_ID)

            self.assertIsNotNone(results.get(VERSION_KEY))
            self.assertIsNotNone(results.get(CREATED_KEY))
            self.assertIsNone(
                results.get(MODIFIED_KEY))  # Created! but not yet modified

            self.assertEqual(results.get(MDS_KEY), 0)
            self.assertIsNone(results.get(LAST_SYNC_KEY))

            self.assertIsNone(results.get(CLASS_ID_KEY))

            # Stopping still allows a query.  Note you just delete a device
            # to clean up any associated databases
            onu_device.stop()
            results = onu_device.query_mib()
            self.assertTrue(isinstance(results, dict))

        # Yield context so that MIB Database callLater runs. This is a waiting
        # Async task from when the OpenOMCIAgent was started. But also start the
        # device so that it's queued async state machines can run as well
        onu_device.start()
        d = asleep(0.2)
        d.addCallbacks(check_status, not_called)

        return d

    @deferred(timeout=5)
    def test_delete_scrubs_mib(self):
        self.setup_one_of_each()

        onu_device = self.agent.add_device(DEFAULT_ONU_DEVICE_ID,
                                           self.adapter_agent)
        self.assertIsNotNone(onu_device)
        self.assertEqual(len(self.agent.device_ids()), 1)
        self.assertEqual(self.agent.get_device(DEFAULT_ONU_DEVICE_ID),
                         onu_device)

        def not_called(_reason):
            onu_device.stop()
            assert False, 'Should never be called'

        def check_status(_results):
            # Device started. Query will succeed but nothing should be populated
            # but the most basic items

            results = onu_device.query_mib()
            self.assertTrue(isinstance(results, dict))
            self.assertEqual(results.get(DEVICE_ID_KEY), DEFAULT_ONU_DEVICE_ID)

            # Delete should wipe out any MIB data. Note that a delete of a started
            # or stopped ONU device is allowed.  In this case we are deleting a
            # started ONU Device

            onu_device.delete()
            assert_raises(Exception, onu_device.query_mib)
            # TODO: When capabilities are supported, make sure capabilities get cleared as well

        # Yield context so that MIB Database callLater runs. This is a waiting
        # Async task from when the OpenOMCIAgent was started. But also start the
        # device so that it's queued async state machines can run as well
        onu_device.start()
        d = asleep(0.2)
        d.addCallbacks(check_status, not_called)

        return d
예제 #13
0
class AdtranOnuAdapter(OnuAdapter):
    def __init__(self, core_proxy, adapter_proxy, config):
        self.log = structlog.get_logger()
        super(AdtranOnuAdapter, self).__init__(core_proxy=core_proxy,
                                               adapter_proxy=adapter_proxy,
                                               config=config,
                                               device_handler_class=AdtranOnuHandler,
                                               name='adtran_onu',
                                               vendor='ADTRAN, Inc.',
                                               version='2.0',
                                               device_type='adtran_onu',
                                               vendor_id='ADTN',
                                               accepts_bulk_flow_update=True,
                                               accepts_add_remove_flow_updates=False)  # TODO: Support flow-mods
        # Customize OpenOMCI for Adtran ONUs
        self.adtran_omci = deepcopy(OpenOmciAgentDefaults)

        from pyvoltha.adapters.extensions.omci.database.mib_db_dict import MibDbVolatileDict
        self.adtran_omci['mib-synchronizer']['database'] = MibDbVolatileDict

        self.adtran_omci['mib-synchronizer']['state-machine'] = AdtnMibSynchronizer
        self.adtran_omci['mib-synchronizer']['tasks']['get-mds'] = AdtnGetMdsTask
        self.adtran_omci['mib-synchronizer']['tasks']['mib-audit'] = AdtnGetMdsTask
        self.adtran_omci['mib-synchronizer']['tasks']['mib-resync'] = AdtnMibResyncTask
        self.adtran_omci['mib-synchronizer']['tasks']['mib-reconcile'] = AdtnMibReconcileTask
        self.adtran_omci['omci-capabilities']['tasks']['get-capabilities'] = AdtnCapabilitiesTask
        # TODO: Continue to customize adtran_omci here as needed

        self._omci_agent = OpenOMCIAgent(self.adapter_agent,
                                         support_classes=self.adtran_omci)

    @property
    def omci_agent(self):
        return self._omci_agent

    def start(self):
        super(AdtranOnuAdapter, self).start()
        self._omci_agent.start()

    def stop(self):
        omci, self._omci_agent = self._omci_agent, None
        if omci is not None:
            omci.stop()

        super(AdtranOnuAdapter, self).stop()

    def download_image(self, device, request):
        raise NotImplementedError()

    def activate_image_update(self, device, request):
        raise NotImplementedError()

    def cancel_image_download(self, device, request):
        raise NotImplementedError()

    def revert_image_update(self, device, request):
        raise NotImplementedError()

    def get_image_download_status(self, device, request):
        raise NotImplementedError()

    def process_inter_adapter_message(self, msg):
        # Currently the only OLT Device adapter that uses this is the EdgeCore

        self.log.info('receive_inter_adapter_message', msg=msg)
        proxy_address = msg['proxy_address']
        assert proxy_address is not None
        # Device_id from the proxy_address is the olt device id. We need to
        # get the onu device id using the port number in the proxy_address
        device = self.adapter_agent.get_child_device_with_proxy_address(proxy_address)
        if device is not None:
            handler = self.devices_handlers[device.id]
            handler.event_messages.put(msg)
        else:
            self.log.error("device-not-found")

    def receive_proxied_message(self, proxy_address, msg):
        self.log.debug('receive-proxied-message', proxy_address=proxy_address,
                       device_id=proxy_address.device_id, msg=binascii.hexlify(msg))
        # Device_id from the proxy_address is the olt device id. We need to
        # get the onu device id using the port number in the proxy_address
        device = self.adapter_agent.get_child_device_with_proxy_address(proxy_address)

        if device is not None:
            handler = self.devices_handlers[device.id]
            if handler is not None:
                handler.receive_message(msg)