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()
class TestOpenOmciAgent(TestCase): """ Test the Open OMCI Agent """ def setUp(self): self.adapter_agent = MockAdapterAgent() def tearDown(self): if self.adapter_agent is not None: self.adapter_agent.tearDown() def test_omci_agent_defaults(self): # Make sure someone does not check in bad default values mib_sync = OpenOmciAgentDefaults.get('mib-synchronizer') self.assertIsNotNone(mib_sync) self.assertTrue(isinstance(mib_sync['state-machine'], type(MibSynchronizer))) self.assertTrue(isinstance(mib_sync['database'], type(MibDbExternal))) mib_sync_tasks = mib_sync.get('tasks') self.assertIsNotNone(mib_sync_tasks) self.assertTrue(isinstance(mib_sync_tasks['mib-upload'], type(MibUploadTask))) self.assertTrue(isinstance(mib_sync_tasks['get-mds'], type(GetMdsTask))) self.assertTrue(isinstance(mib_sync_tasks['mib-audit'], type(GetMdsTask))) self.assertTrue(isinstance(mib_sync_tasks['mib-resync'], type(MibResyncTask))) self.assertTrue(isinstance(mib_sync_tasks['mib-reconcile'], type(MibReconcileTask))) # caps = OpenOmciAgentDefaults.get('onu-capabilities') # # self.assertIsNotNone(caps) 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') 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
class TestMibSync(TestCase): """ Test the MIB Synchronizer State Machine """ def setUp(self): self.adapter_agent = MockAdapterAgent() def tearDown(self): if self.adapter_agent is not None: self.adapter_agent.tearDown()
class TestMibUpload(TestCase): """ Test the MIB Upload Task """ def setUp(self): self.adapter_agent = MockAdapterAgent() def tearDown(self): if self.adapter_agent is not None: self.adapter_agent.tearDown()
def setUp(self): self.adapter_agent = MockAdapterAgent() self.adapter_agent.add_device( MockDevice(_DEVICE_ID)) # For Entity class lookups self.onu_db = OnuDB(self.adapter_agent) self.olt_db = OltDB(self.adapter_agent) self.onu_db.start() self.olt_db.start() self.olt_db.add(_DEVICE_ID) self.onu_db.add(_DEVICE_ID) self.task = MibResyncTask(self.adapter_agent, _DEVICE_ID)
def setUp(self): self.adapter_agent = MockAdapterAgent() self.adapter_agent.add_device( MockDevice(_DEVICE_ID)) # For Entity class lookups self.db = MibDbExternal(self.adapter_agent)
class TestOmciMibDbExt(TestCase): def setUp(self): self.adapter_agent = MockAdapterAgent() self.adapter_agent.add_device( MockDevice(_DEVICE_ID)) # For Entity class lookups self.db = MibDbExternal(self.adapter_agent) def tearDown(self): self.db.stop() def test_start_stop(self): # Simple start stop self.assertFalse(self.db.active) self.db.start() self.assertTrue(self.db.active) self.db.stop() self.assertFalse(self.db.active) # Start after start still okay self.db.start() self.db.start() self.assertTrue(self.db.active) self.db.stop() self.db.stop() self.assertFalse(self.db.active) @raises(DatabaseStateError) def test_bad_state_add(self): self.db.add(_DEVICE_ID) @raises(DatabaseStateError) def test_bad_state_remove(self): self.db.remove(_DEVICE_ID) @raises(DatabaseStateError) def test_bad_state_query_1(self): self.db.query(_DEVICE_ID, 0) @raises(DatabaseStateError) def test_bad_state_query_2(self): self.db.query(_DEVICE_ID, 0, 0) @raises(DatabaseStateError) def test_bad_state_query_3(self): self.db.query(_DEVICE_ID, 0, 0, 'test') @raises(DatabaseStateError) def test_bad_state_set(self): self.db.set(_DEVICE_ID, 0, 0, {'test': 123}) @raises(DatabaseStateError) def test_bad_state_delete(self): self.db.delete(_DEVICE_ID, 0, 0) @raises(KeyError) def test_no_device_query(self): self.db.start() self.db.query(_DEVICE_ID) def test_no_device_last_sync(self): self.db.start() # Returns None, not a KeyError value = self.db.get_last_sync(_DEVICE_ID) self.assertIsNone(value) def test_no_device_mds(self): self.db.start() # Returns None, not a KeyError value = self.db.get_mib_data_sync(_DEVICE_ID) self.assertIsNone(value) @raises(KeyError) def test_no_device_save_last_sync(self): self.db.start() self.db.save_last_sync(_DEVICE_ID, datetime.utcnow()) @raises(KeyError) def test_no_device_save_mds(self): self.db.start() self.db.save_mib_data_sync(_DEVICE_ID, 123) def test_param_types(self): self.db.start() assert_raises(TypeError, self.db.add, 123) assert_raises(TypeError, self.db.remove, 123) assert_raises(TypeError, self.db.query, 123) assert_raises(TypeError, self.db.get_mib_data_sync, 123) assert_raises(TypeError, self.db.save_mib_data_sync, 123, 0) assert_raises(TypeError, self.db.save_mib_data_sync, _DEVICE_ID, 'zero') assert_raises(TypeError, self.db.get_last_sync, 123) assert_raises(TypeError, self.db.save_last_sync, 123, datetime.utcnow()) assert_raises(TypeError, self.db.save_last_sync, _DEVICE_ID, 'bad-date') assert_raises(TypeError, self.db.set, 123, 0, 0, {'test': 0}) assert_raises(TypeError, self.db.set, None, 0, 0, {'test': 0}) assert_raises(ValueError, self.db.set, _DEVICE_ID, None, 0, {'test': 0}) assert_raises(ValueError, self.db.set, _DEVICE_ID, 0, None, {'test': 0}) assert_raises(TypeError, self.db.set, _DEVICE_ID, 0, 0, None) assert_raises(TypeError, self.db.set, _DEVICE_ID, 0, 0, 'not-a-dict') assert_raises(ValueError, self.db.set, _DEVICE_ID, -1, 0, {'test': 0}) assert_raises(ValueError, self.db.set, _DEVICE_ID, 0x10000, 0, {'test': 0}) assert_raises(ValueError, self.db.set, _DEVICE_ID, 0, -1, {'test': 0}) assert_raises(ValueError, self.db.set, _DEVICE_ID, 0, 0x10000, {'test': 0}) assert_raises(TypeError, self.db.delete, 123, 0, 0) assert_raises(ValueError, self.db.delete, _DEVICE_ID, -1, 0) assert_raises(ValueError, self.db.delete, _DEVICE_ID, 0x10000, 0) assert_raises(ValueError, self.db.delete, _DEVICE_ID, 0, -1) assert_raises(ValueError, self.db.delete, _DEVICE_ID, 0, 0x10000) def test_add_remove_device(self): self.db.start() # Remove of non-existent device is not an error assert_raises(KeyError, self.db.query, _DEVICE_ID) self.db.remove(_DEVICE_ID) start_time = datetime.utcnow() self.db.add(_DEVICE_ID) dev_data = self.db.query(_DEVICE_ID) self.assertEqual(dev_data[DEVICE_ID_KEY], _DEVICE_ID) self.assertEquals(dev_data[MDS_KEY], 0) self.assertIsNone(dev_data[LAST_SYNC_KEY]) self.assertEqual(dev_data[VERSION_KEY], MibDbExternal.CURRENT_VERSION) self.assertGreaterEqual(self.db.created, start_time) # Remove it self.db.remove(_DEVICE_ID) assert_raises(KeyError, self.db.query, _DEVICE_ID) # Remove of non-existant dev okay self.db.remove(_DEVICE_ID + 'abcd') # Overwrite tests self.db.add(_DEVICE_ID) assert_raises(KeyError, self.db.add, _DEVICE_ID) self.db.add(_DEVICE_ID, overwrite=True) # This is okay def test_mib_data_sync(self): self.db.start() self.db.add(_DEVICE_ID) self.assertEquals(self.db.get_mib_data_sync(_DEVICE_ID), 0) self.db.save_mib_data_sync(_DEVICE_ID, 100) self.assertEqual(self.db.get_mib_data_sync(_DEVICE_ID), 100) assert_raises(ValueError, self.db.save_mib_data_sync, _DEVICE_ID, -1) assert_raises(ValueError, self.db.save_mib_data_sync, _DEVICE_ID, 256) def test_last_sync(self): self.db.start() self.assertIsNone(self.db.get_last_sync(_DEVICE_ID)) self.db.add(_DEVICE_ID) self.assertIsNone(self.db.get_last_sync(_DEVICE_ID)) now = datetime.utcnow() self.db.save_last_sync(_DEVICE_ID, now) self.assertEqual(self.db.get_last_sync(_DEVICE_ID), now) assert_raises(TypeError, self.db.save_last_sync, _DEVICE_ID, 'hello') def test_set_and_query(self): self.db.start() self.db.add(_DEVICE_ID) # Base device DB created here time.sleep(0.1) class_id = OntG.class_id inst_id = 0 attributes = {'vendor_id': 'ABCD'} start_time = datetime.utcnow() set_occurred = self.db.set(_DEVICE_ID, class_id, inst_id, attributes) self.assertTrue(set_occurred) end_time = datetime.utcnow() dev_data = self.db.query(_DEVICE_ID) self.assertEqual(dev_data[DEVICE_ID_KEY], _DEVICE_ID) dev_classes = [v for k, v in dev_data.items() if isinstance(k, int)] self.assertEqual(len(dev_classes), 1) class_data = dev_classes[0] self.assertEqual(class_data[CLASS_ID_KEY], class_id) class_insts = [v for k, v in class_data.items() if isinstance(k, int)] self.assertEqual(len(class_insts), 1) inst_data = class_insts[0] self.assertEqual(inst_data[INSTANCE_ID_KEY], inst_id) self.assertGreaterEqual(inst_data[MODIFIED_KEY], start_time) self.assertLessEqual(inst_data[MODIFIED_KEY], end_time) self.assertLessEqual(inst_data[CREATED_KEY], inst_data[MODIFIED_KEY]) inst_attributes = inst_data[ATTRIBUTES_KEY] self.assertEqual(len(inst_attributes), 1) self.assertTrue('vendor_id' in inst_attributes) self.assertEqual(inst_attributes['vendor_id'], attributes['vendor_id']) ######################################## # Query with device and class. Should be same as from full device query cls_2_data = self.db.query(_DEVICE_ID, class_id) self.assertEqual(class_data[CLASS_ID_KEY], cls_2_data[CLASS_ID_KEY]) cl2_insts = {k: v for k, v in cls_2_data.items() if isinstance(k, int)} self.assertEqual(len(cl2_insts), len(class_insts)) # Bad class id query cls_no_data = self.db.query(_DEVICE_ID, class_id + 1) self.assertTrue(isinstance(cls_no_data, dict)) self.assertEqual(len(cls_no_data), 0) ######################################## # Query with device, class, instance inst_2_data = self.db.query(_DEVICE_ID, class_id, inst_id) self.assertEqual(inst_data[INSTANCE_ID_KEY], inst_2_data[INSTANCE_ID_KEY]) self.assertEqual(inst_data[MODIFIED_KEY], inst_2_data[MODIFIED_KEY]) self.assertEqual(inst_data[CREATED_KEY], inst_2_data[CREATED_KEY]) inst2_attr = inst_2_data[ATTRIBUTES_KEY] self.assertEqual(len(inst2_attr), len(inst_attributes)) # Bad instance id query inst_no_data = self.db.query(_DEVICE_ID, class_id, inst_id + 100) self.assertTrue(isinstance(inst_no_data, dict)) self.assertEqual(len(inst_no_data), 0) ######################################## # Attribute queries attr_2_data = self.db.query(_DEVICE_ID, class_id, inst_id, 'vendor_id') self.assertEqual(attr_2_data['vendor_id'], attributes['vendor_id']) attr_3_data = self.db.query(_DEVICE_ID, class_id, inst_id, ['vendor_id']) self.assertEqual(attr_3_data['vendor_id'], attributes['vendor_id']) attr_4_data = self.db.query(_DEVICE_ID, class_id, inst_id, {'vendor_id'}) self.assertEqual(attr_4_data['vendor_id'], attributes['vendor_id']) attr_no_data = self.db.query(_DEVICE_ID, class_id, inst_id, 'no_such_thing') self.assertTrue(isinstance(attr_no_data, dict)) self.assertEqual(len(attr_no_data), 0) # Set to same value does not change modified data. The modified is # at the instance level class_id = OntG.class_id inst_id = 0 attributes = {'vendor_id': 'ABCD'} set_occurred = self.db.set(_DEVICE_ID, class_id, inst_id, attributes) self.assertFalse(set_occurred) inst_3_data = self.db.query(_DEVICE_ID, class_id, inst_id) self.assertEqual(inst_data[MODIFIED_KEY], inst_3_data[MODIFIED_KEY]) self.assertEqual(inst_data[CREATED_KEY], inst_3_data[CREATED_KEY]) # But set to new value does time.sleep(0.1) attributes = {'vendor_id': 'WXYZ'} set_occurred = self.db.set(_DEVICE_ID, class_id, inst_id, attributes) self.assertTrue(set_occurred) inst_4_data = self.db.query(_DEVICE_ID, class_id, inst_id) self.assertLess(inst_3_data[MODIFIED_KEY], inst_4_data[MODIFIED_KEY]) self.assertEqual(inst_3_data[CREATED_KEY], inst_4_data[CREATED_KEY]) def test_delete_instances(self): self.db.start() self.db.add(_DEVICE_ID) create_time = datetime.utcnow() class_id = GalEthernetProfile.class_id inst_id_1 = 0x100 inst_id_2 = 0x200 attributes = {'max_gem_payload_size': 1500} self.db.set(_DEVICE_ID, class_id, inst_id_1, attributes) self.db.set(_DEVICE_ID, class_id, inst_id_2, attributes) time.sleep(0.1) dev_data = self.db.query(_DEVICE_ID) cls_data = self.db.query(_DEVICE_ID, class_id) inst_data = {k: v for k, v in cls_data.items() if isinstance(k, int)} self.assertEqual(len(inst_data), 2) self.assertLessEqual(dev_data[CREATED_KEY], create_time) self.assertLessEqual(self.db.created, create_time) # Delete one instance time.sleep(0.1) result = self.db.delete(_DEVICE_ID, class_id, inst_id_1) self.assertTrue(result) # True returned if a del actually happened dev_data = self.db.query(_DEVICE_ID) cls_data = self.db.query(_DEVICE_ID, class_id) inst_data = {k: v for k, v in cls_data.items() if isinstance(k, int)} self.assertEqual(len(inst_data), 1) self.assertLessEqual(dev_data[CREATED_KEY], create_time) self.assertLessEqual(self.db.created, create_time) # Delete remaining instance time.sleep(0.1) result = self.db.delete(_DEVICE_ID, class_id, inst_id_2) self.assertTrue(result) # True returned if a del actually happened dev_data = self.db.query(_DEVICE_ID) cls_data = {k: v for k, v in dev_data.items() if isinstance(k, int)} self.assertEqual(len(cls_data), 0) self.assertLessEqual(dev_data[CREATED_KEY], create_time) # Delete returns false if not instance self.assertFalse(self.db.delete(_DEVICE_ID, class_id, inst_id_1)) self.assertFalse(self.db.delete(_DEVICE_ID, class_id, inst_id_2)) def test_on_mib_reset_listener(self): self.db.start() self.db.add(_DEVICE_ID) time.sleep(0.1) class_id = OntG.class_id inst_id = 0 attributes = {'vendor_id': 'ABCD'} set_time = datetime.utcnow() self.db.set(_DEVICE_ID, class_id, inst_id, attributes) time.sleep(0.1) self.db.on_mib_reset(_DEVICE_ID) dev_data = self.db.query(_DEVICE_ID) self.assertEqual(dev_data[DEVICE_ID_KEY], _DEVICE_ID) self.assertLessEqual(dev_data[CREATED_KEY], set_time) self.assertLessEqual(self.db.created, set_time) self.assertFalse( any(isinstance(cls, int) for cls in dev_data.iterkeys())) def test_str_field_serialization(self): self.db.start() self.db.add(_DEVICE_ID) class_id = OltG.class_id inst_id = 0 attributes = { 'olt_vendor_id': 'ABCD', # StrFixedLenField(4) } self.db.set(_DEVICE_ID, class_id, inst_id, attributes) data = self.db.query(_DEVICE_ID, class_id, inst_id, attributes.keys()) self.assertTrue( all(isinstance(data[k], basestring) for k in attributes.keys())) self.assertTrue( all(data[k] == attributes[k] for k in attributes.keys())) def test_mac_address_ip_field_serialization(self): self.db.start() self.db.add(_DEVICE_ID) class_id = IpHostConfigData.class_id inst_id = 0 attributes = { 'mac_address': '00:01:02:03:04:05', # MACField 'ip_address': '1.2.3.4', # IPField } self.db.set(_DEVICE_ID, class_id, inst_id, attributes) data = self.db.query(_DEVICE_ID, class_id, inst_id, attributes.keys()) self.assertTrue( all(isinstance(data[k], basestring) for k in attributes.keys())) self.assertTrue( all(data[k] == attributes[k] for k in attributes.keys())) def test_byte_and_short_field_serialization(self): self.db.start() self.db.add(_DEVICE_ID) class_id = UniG.class_id inst_id = 0 attributes = { 'administrative_state': int(1), # ByteField 'non_omci_management_identifier': int(12345) # IPField } self.db.set(_DEVICE_ID, class_id, inst_id, attributes) data = self.db.query(_DEVICE_ID, class_id, inst_id, attributes.keys()) self.assertTrue( all( isinstance(data[k], type(attributes[k])) for k in attributes.keys())) self.assertTrue( all(data[k] == attributes[k] for k in attributes.keys())) def test_int_field_serialization(self): self.db.start() self.db.add(_DEVICE_ID) class_id = PriorityQueueG.class_id inst_id = 0 attributes = { 'related_port': int(1234567) # IntField } self.db.set(_DEVICE_ID, class_id, inst_id, attributes) data = self.db.query(_DEVICE_ID, class_id, inst_id, attributes.keys()) self.assertTrue( all( isinstance(data[k], type(attributes[k])) for k in attributes.keys())) self.assertTrue( all(data[k] == attributes[k] for k in attributes.keys())) def test_long_field_serialization(self): self.db.start() self.db.add(_DEVICE_ID) class_id = PriorityQueueG.class_id inst_id = 0 attributes = { 'packet_drop_queue_thresholds': int(0x1234) # LongField } self.db.set(_DEVICE_ID, class_id, inst_id, attributes) data = self.db.query(_DEVICE_ID, class_id, inst_id, attributes.keys()) self.assertTrue( all( isinstance(data[k], type(attributes[k])) for k in attributes.keys())) self.assertTrue( all(data[k] == attributes[k] for k in attributes.keys())) def test_bit_field_serialization(self): self.db.start() self.db.add(_DEVICE_ID) class_id = OntG.class_id inst_id = 0 attributes = { 'extended_tc_layer_options': long(0x1234), # BitField(16) } self.db.set(_DEVICE_ID, class_id, inst_id, attributes) data = self.db.query(_DEVICE_ID, class_id, inst_id, attributes.keys()) self.assertTrue( all( isinstance(data[k], type(attributes[k])) for k in attributes.keys())) self.assertTrue( all(data[k] == attributes[k] for k in attributes.keys())) def test_list_field_serialization(self): self.db.start() self.db.add(_DEVICE_ID) class_id = VlanTaggingFilterData.class_id inst_id = 0 vlan_filter_list = [0] * 12 vlan_filter_list[0] = 0x1234 attributes = { 'vlan_filter_list': vlan_filter_list, # FieldListField 'forward_operation': 0, 'number_of_entries': 1 } self.db.set(_DEVICE_ID, class_id, inst_id, attributes) data = self.db.query(_DEVICE_ID, class_id, inst_id, attributes.keys()) self.assertTrue( all( isinstance(data[k], type(attributes[k])) for k in attributes.keys())) self.assertTrue( all(data[k] == attributes[k] for k in attributes.keys())) def test_complex_json_serialization(self): self.db.start() self.db.add(_DEVICE_ID) class_id = ExtendedVlanTaggingOperationConfigurationData.class_id inst_id = 0x202 table_data = VlanTaggingOperation(filter_outer_priority=15, filter_inner_priority=8, filter_inner_vid=1024, filter_inner_tpid_de=5, filter_ether_type=0, treatment_tags_to_remove=1, pad3=2, treatment_outer_priority=15, treatment_inner_priority=8, treatment_inner_vid=1024, treatment_inner_tpid_de=4) attributes = dict( received_frame_vlan_tagging_operation_table=table_data) self.db.set(_DEVICE_ID, class_id, inst_id, attributes) data = self.db.query(_DEVICE_ID, class_id, inst_id, attributes.keys()) table_as_dict = json.loads(table_data.to_json()) self.assertTrue( all( isinstance( data['received_frame_vlan_tagging_operation_table'][k], type(attributes[ 'received_frame_vlan_tagging_operation_table']. fields[k])) for k in attributes['received_frame_vlan_tagging_operation_table']. fields.keys())) self.assertTrue( all(data['received_frame_vlan_tagging_operation_table'][k] == attributes['received_frame_vlan_tagging_operation_table']. fields[k] for k in attributes['received_frame_vlan_tagging_operation_table']. fields.keys())) self.assertTrue( all(data['received_frame_vlan_tagging_operation_table'][k] == table_as_dict[k] for k in table_as_dict.keys())) def test_unknown_me_serialization(self): self.db.start() self.db.add(_DEVICE_ID) blob = '00010000000c0000000000000000000000000000000000000000' class_id = 0xff78 inst_id = 0x101 attributes = {UNKNOWN_CLASS_ATTRIBUTE_KEY: blob} self.db.set(_DEVICE_ID, class_id, inst_id, attributes) data = self.db.query(_DEVICE_ID, class_id, inst_id, attributes.keys()) self.assertTrue(isinstance(UNKNOWN_CLASS_ATTRIBUTE_KEY, basestring)) self.assertTrue( all( isinstance(attributes[k], basestring) for k in attributes.keys())) self.assertTrue( all(data[k] == attributes[k] for k in attributes.keys()))
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
def setUp(self): self.adapter_agent = MockAdapterAgent()
class TestOmciCc(TestCase): """ Test the Open OMCI Communication channels Note also added some testing of MockOnu behaviour since its behaviour during more complicated unit/integration tests may be performed in the future. """ def setUp(self): self.adapter_agent = MockAdapterAgent() def tearDown(self): 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 _is_omci_frame(self, results): assert isinstance(results, OmciFrame), 'Not OMCI Frame' return results def _check_status(self, results, value): status = results.fields['omci_message'].fields['success_code'] assert status == value,\ 'Unexpected Status Code. Got {}, Expected: {}'.format(status, value) return results def _check_mib_sync(self, results, value): assert self.onu_device.mib_data_sync == value, \ 'Unexpected MIB DATA Sync value. Got {}, Expected: {}'.format( self.onu_device.mib_data_sync, value) return results def _check_stats(self, results, snapshot, stat, expected): assert snapshot[stat] == expected, \ 'Invalid statistic "{}". Got {}, Expected: {}'.format(stat, snapshot[stat], expected) return results def _check_value_equal(self, results, name, value, expected): assert value == expected, \ 'Value "{}" not equal. Got {}, Expected: {}'.format(name, value, expected) return results def _default_errback(self, _failure): assert False def _snapshot_stats(self): omci_cc = self.onu_handler.omci_cc return { 'tx_frames': omci_cc.tx_frames, 'rx_frames': omci_cc.rx_frames, 'rx_unknown_tid': omci_cc.rx_unknown_tid, 'rx_onu_frames': omci_cc.rx_onu_frames, 'rx_alarm_overflow': omci_cc.rx_alarm_overflow, 'rx_avc_overflow': omci_cc.rx_avc_overflow, 'rx_onu_discards': omci_cc.rx_onu_discards, 'rx_timeouts': omci_cc.rx_timeouts, 'rx_unknown_me': omci_cc.rx_unknown_me, 'tx_errors': omci_cc.tx_errors, 'consecutive_errors': omci_cc.consecutive_errors, 'reply_min': omci_cc.reply_min, 'reply_max': omci_cc.reply_max, 'reply_average': omci_cc.reply_average } def test_default_init(self): self.setup_one_of_each() # Test default construction of OMCI_CC as well as # various other parameter settings omci_cc = self.onu_handler.omci_cc # No device directly associated self.assertIsNotNone(omci_cc._adapter_agent) self.assertIsNone(omci_cc._proxy_address) # No outstanding requests self.assertEqual(len(omci_cc._requests), 0) # Flags/properties self.assertFalse(omci_cc.enabled) # Statistics self.assertEqual(omci_cc.tx_frames, 0) self.assertEqual(omci_cc.rx_frames, 0) self.assertEqual(omci_cc.rx_unknown_tid, 0) self.assertEqual(omci_cc.rx_onu_frames, 0) self.assertEqual(omci_cc.rx_alarm_overflow, 0) self.assertEqual(omci_cc.rx_avc_overflow, 0) self.assertEqual(omci_cc.rx_onu_discards, 0) self.assertEqual(omci_cc.rx_unknown_me, 0) self.assertEqual(omci_cc.rx_timeouts, 0) self.assertEqual(omci_cc.tx_errors, 0) self.assertEqual(omci_cc.consecutive_errors, 0) self.assertNotEquals(omci_cc.reply_min, 0.0) self.assertEqual(omci_cc.reply_max, 0.0) self.assertEqual(omci_cc.reply_average, 0.0) def test_enable_disable(self): self.setup_one_of_each() # Test enable property omci_cc = self.onu_handler.omci_cc # Initially disabled self.assertFalse(omci_cc.enabled) omci_cc.enabled = False self.assertFalse(omci_cc.enabled) omci_cc.enabled = True self.assertTrue(omci_cc.enabled) self.assertIsNotNone(omci_cc._proxy_address) self.assertEqual(len(omci_cc._requests), 0) omci_cc.enabled = True # Should be a NOP self.assertTrue(omci_cc.enabled) self.assertIsNotNone(omci_cc._proxy_address) self.assertEqual(len(omci_cc._requests), 0) omci_cc.enabled = False self.assertFalse(omci_cc.enabled) self.assertIsNone(omci_cc._proxy_address) def test_rx_discard_if_disabled(self): # ME without a known decoder self.setup_one_of_each() omci_cc = self.onu_handler.omci_cc omci_cc.enabled = False snapshot = self._snapshot_stats() msg = '00fc2e0a00020000ff780000e00000010000000c' \ '0000000000000000000000000000000000000000' \ '00000028105a86ef' omci_cc.receive_message(hex2raw(msg)) # Note: No counter increments self.assertEqual(omci_cc.rx_frames, snapshot['rx_frames']) self.assertEqual(omci_cc.rx_unknown_me, snapshot['rx_unknown_me']) self.assertEqual(omci_cc.rx_unknown_tid, snapshot['rx_unknown_tid']) self.assertEqual(omci_cc.rx_onu_frames, snapshot['rx_onu_frames']) self.assertEqual(omci_cc.rx_unknown_tid, snapshot['rx_unknown_tid']) def test_message_send_get(self): # Various tests of sending an OMCI message and it either # getting a response or send catching some errors of # importance self.setup_one_of_each() omci_cc = self.onu_handler.omci_cc omci_cc.enabled = True snapshot = self._snapshot_stats() mib_data_sync = self.onu_device.mib_data_sync # GET # d = omci_cc.send() # TODO: Implement # # d.addCallbacks(self._is_omci_frame, self._default_errback) # d.addCallback(self._check_status, RC.Success.value) # d.addCallback(self._check_mib_sync, mib_data_sync) # # d.addCallback(self._check_stats, snapshot, 'tx_frames', snapshot['tx_frames'] + 1) # d.addCallback(self._check_stats, snapshot, 'rx_frames', snapshot['rx_frames'] + 1) # d.addCallback(self._check_stats, snapshot, 'rx_unknown_tid', snapshot['rx_unknown_tid']) # d.addCallback(self._check_stats, snapshot, 'rx_onu_frames', snapshot['rx_onu_frames']) # d.addCallback(self._check_stats, snapshot, 'rx_alarm_overflow', snapshot['rx_alarm_overflow']) # d.addCallback(self._check_stats, snapshot, 'rx_avc_overflow', snapshot['rx_avc_overflow']) # d.addCallback(self._check_stats, snapshot, 'rx_onu_discards', snapshot['rx_onu_discards']) # d.addCallback(self._check_stats, snapshot, 'rx_unknown_me', snapshot['rx_unknown_me']) # d.addCallback(self._check_stats, snapshot, 'rx_timeouts', snapshot['rx_timeouts']) # d.addCallback(self._check_stats, snapshot, 'tx_errors', snapshot['tx_errors']) # d.addCallback(self._check_value_equal, 'consecutive_errors', 0, omci_cc.consecutive_errors) # return d def test_message_send_set(self): # Various tests of sending an OMCI message and it either # getting a response or send catching some errors of # importance self.setup_one_of_each() omci_cc = self.onu_handler.omci_cc omci_cc.enabled = True snapshot = self._snapshot_stats() mib_data_sync = self.onu_device.mib_data_sync # SET # d = omci_cc.send() # TODO: Implement # # d.addCallbacks(self._is_omci_frame, self._default_errback) # d.addCallback(self._check_status, RC.Success.value) # d.addCallback(self._check_mib_sync, mib_data_sync + 1 if mib_data_sync < 255 else 1) # # d.addCallback(self._check_stats, snapshot, 'tx_frames', snapshot['tx_frames'] + 1) # d.addCallback(self._check_stats, snapshot, 'rx_frames', snapshot['rx_frames'] + 1) # d.addCallback(self._check_stats, snapshot, 'rx_unknown_tid', snapshot['rx_unknown_tid']) # d.addCallback(self._check_stats, snapshot, 'rx_onu_frames', snapshot['rx_onu_frames']) # d.addCallback(self._check_stats, snapshot, 'rx_alarm_overflow', snapshot['rx_alarm_overflow']) # d.addCallback(self._check_stats, snapshot, 'rx_avc_overflow', snapshot['rx_avc_overflow']) # d.addCallback(self._check_stats, snapshot, 'rx_onu_discards', snapshot['rx_onu_discards']) # d.addCallback(self._check_stats, snapshot, 'rx_unknown_me', snapshot['rx_unknown_me']) # d.addCallback(self._check_stats, snapshot, 'rx_timeouts', snapshot['rx_timeouts']) # d.addCallback(self._check_stats, snapshot, 'tx_errors', snapshot['tx_errors']) # d.addCallback(self._check_value_equal, 'consecutive_errors', 0, omci_cc.consecutive_errors) # return d # # # Also test mib_data_sync rollover. 255 -> 1 (zero reserved) # # self.onu_device.mib_data_sync = 255 # # SET # self.assertTrue(True) # TODO: Implement (copy previous one here) # self.assertEqual(1, self.onu_device.mib_data_sync) def test_message_send_create(self): # Various tests of sending an OMCI message and it either # getting a response or send catching some errors of # importance self.setup_one_of_each() omci_cc = self.onu_handler.omci_cc omci_cc.enabled = True snapshot = self._snapshot_stats() mib_data_sync = self.onu_device.mib_data_sync # Create # d = omci_cc.send() # TODO: Implement # # d.addCallbacks(self._is_omci_frame, self._default_errback) # d.addCallback(self._check_status, RC.Success.value) # d.addCallback(self._check_mib_sync, mib_data_sync + 1 if mib_data_sync < 255 else 1) # # d.addCallback(self._check_stats, snapshot, 'tx_frames', snapshot['tx_frames'] + 1) # d.addCallback(self._check_stats, snapshot, 'rx_frames', snapshot['rx_frames'] + 1) # d.addCallback(self._check_stats, snapshot, 'rx_unknown_tid', snapshot['rx_unknown_tid']) # d.addCallback(self._check_stats, snapshot, 'rx_onu_frames', snapshot['rx_onu_frames']) # d.addCallback(self._check_stats, snapshot, 'rx_alarm_overflow', snapshot['rx_alarm_overflow']) # d.addCallback(self._check_stats, snapshot, 'rx_avc_overflow', snapshot['rx_avc_overflow']) # d.addCallback(self._check_stats, snapshot, 'rx_onu_discards', snapshot['rx_onu_discards']) # d.addCallback(self._check_stats, snapshot, 'rx_unknown_me', snapshot['rx_unknown_me']) # d.addCallback(self._check_stats, snapshot, 'rx_timeouts', snapshot['rx_timeouts']) # d.addCallback(self._check_stats, snapshot, 'tx_errors', snapshot['tx_errors']) # d.addCallback(self._check_value_equal, 'consecutive_errors', 0, omci_cc.consecutive_errors) # return d def test_message_send_delete(self): # Various tests of sending an OMCI message and it either # getting a response or send catching some errors of # importance self.setup_one_of_each() omci_cc = self.onu_handler.omci_cc omci_cc.enabled = True snapshot = self._snapshot_stats() mib_data_sync = self.onu_device.mib_data_sync # Delete # d = omci_cc.send() # TODO: Implement # # d.addCallbacks(self._is_omci_frame, self._default_errback) # d.addCallback(self._check_status, RC.Success.value) # d.addCallback(self._check_mib_sync, mib_data_sync + 1 if mib_data_sync < 255 else 1) # # d.addCallback(self._check_stats, snapshot, 'tx_frames', snapshot['tx_frames'] + 1) # d.addCallback(self._check_stats, snapshot, 'rx_frames', snapshot['rx_frames'] + 1) # d.addCallback(self._check_stats, snapshot, 'rx_unknown_tid', snapshot['rx_unknown_tid']) # d.addCallback(self._check_stats, snapshot, 'rx_onu_frames', snapshot['rx_onu_frames']) # d.addCallback(self._check_stats, snapshot, 'rx_alarm_overflow', snapshot['rx_alarm_overflow']) # d.addCallback(self._check_stats, snapshot, 'rx_avc_overflow', snapshot['rx_avc_overflow']) # d.addCallback(self._check_stats, snapshot, 'rx_onu_discards', snapshot['rx_onu_discards']) # d.addCallback(self._check_stats, snapshot, 'rx_unknown_me', snapshot['rx_unknown_me']) # d.addCallback(self._check_stats, snapshot, 'rx_timeouts', snapshot['rx_timeouts']) # d.addCallback(self._check_stats, snapshot, 'tx_errors', snapshot['tx_errors']) # d.addCallback(self._check_value_equal, 'consecutive_errors', 0, omci_cc.consecutive_errors) # return d def test_message_send_mib_reset(self): self.setup_one_of_each() omci_cc = self.onu_handler.omci_cc omci_cc.enabled = True self.onu_device.mib_data_sync = 10 snapshot = self._snapshot_stats() # Successful MIB Reset d = omci_cc.send_mib_reset(timeout=1.0) d.addCallbacks(self._is_omci_frame, self._default_errback) d.addCallback(self._check_status, RC.Success) d.addCallback(self._check_mib_sync, 0) d.addCallback(self._check_stats, snapshot, 'tx_frames', snapshot['tx_frames'] + 1) d.addCallback(self._check_stats, snapshot, 'rx_frames', snapshot['rx_frames'] + 1) d.addCallback(self._check_stats, snapshot, 'rx_unknown_tid', snapshot['rx_unknown_tid']) d.addCallback(self._check_stats, snapshot, 'rx_onu_frames', snapshot['rx_onu_frames']) d.addCallback(self._check_stats, snapshot, 'rx_alarm_overflow', snapshot['rx_alarm_overflow']) d.addCallback(self._check_stats, snapshot, 'rx_avc_overflow', snapshot['rx_avc_overflow']) d.addCallback(self._check_stats, snapshot, 'rx_onu_discards', snapshot['rx_onu_discards']) d.addCallback(self._check_stats, snapshot, 'rx_unknown_me', snapshot['rx_unknown_me']) d.addCallback(self._check_stats, snapshot, 'rx_timeouts', snapshot['rx_timeouts']) d.addCallback(self._check_stats, snapshot, 'tx_errors', snapshot['tx_errors']) d.addCallback(self._check_value_equal, 'consecutive_errors', 0, omci_cc.consecutive_errors) return d def test_message_send_mib_upload(self): self.setup_one_of_each() omci_cc = self.onu_handler.omci_cc omci_cc.enabled = True snapshot = self._snapshot_stats() mib_data_sync = self.onu_device.mib_data_sync # MIB Upload d = omci_cc.send_mib_upload(timeout=1.0) d.addCallbacks(self._is_omci_frame, self._default_errback) d.addCallback(self._check_status, RC.Success) d.addCallback(self._check_mib_sync, mib_data_sync) # TODO: MIB Upload Results specific tests here d.addCallback(self._check_stats, snapshot, 'tx_frames', snapshot['tx_frames'] + 1) d.addCallback(self._check_stats, snapshot, 'rx_frames', snapshot['rx_frames'] + 1) d.addCallback(self._check_stats, snapshot, 'rx_unknown_tid', snapshot['rx_unknown_tid']) d.addCallback(self._check_stats, snapshot, 'rx_onu_frames', snapshot['rx_onu_frames']) d.addCallback(self._check_stats, snapshot, 'rx_alarm_overflow', snapshot['rx_alarm_overflow']) d.addCallback(self._check_stats, snapshot, 'rx_avc_overflow', snapshot['rx_avc_overflow']) d.addCallback(self._check_stats, snapshot, 'rx_onu_discards', snapshot['rx_onu_discards']) d.addCallback(self._check_stats, snapshot, 'rx_unknown_me', snapshot['rx_unknown_me']) d.addCallback(self._check_stats, snapshot, 'rx_timeouts', snapshot['rx_timeouts']) d.addCallback(self._check_stats, snapshot, 'tx_errors', snapshot['tx_errors']) d.addCallback(self._check_value_equal, 'consecutive_errors', 0, omci_cc.consecutive_errors) return d def test_message_send_mib_upload_next(self): self.setup_one_of_each() omci_cc = self.onu_handler.omci_cc omci_cc.enabled = True snapshot = self._snapshot_stats() mib_data_sync = self.onu_device.mib_data_sync # # MIB Upload Next # d = omci_cc.send_mib_upload_next(0, timeout=1.0) # # d.addCallbacks(self._is_omci_frame, self._default_errback) # d.addCallback(self._check_status, RC.Success) # d.addCallback(self._check_mib_sync, mib_data_sync) # # # TODO: MIB Upload Next Results specific tests here # # d.addCallback(self._check_stats, snapshot, 'tx_frames', snapshot['tx_frames'] + 1) # d.addCallback(self._check_stats, snapshot, 'rx_frames', snapshot['rx_frames'] + 1) # d.addCallback(self._check_stats, snapshot, 'rx_unknown_tid', snapshot['rx_unknown_tid']) # d.addCallback(self._check_stats, snapshot, 'rx_onu_frames', snapshot['rx_onu_frames']) # d.addCallback(self._check_stats, snapshot, 'rx_alarm_overflow', snapshot['rx_alarm_overflow']) # d.addCallback(self._check_stats, snapshot, 'rx_avc_overflow', snapshot['rx_avc_overflow']) # d.addCallback(self._check_stats, snapshot, 'rx_onu_discards', snapshot['rx_onu_discards']) # d.addCallback(self._check_stats, snapshot, 'rx_unknown_me', snapshot['rx_unknown_me']) # d.addCallback(self._check_stats, snapshot, 'rx_timeouts', snapshot['rx_timeouts']) # d.addCallback(self._check_stats, snapshot, 'tx_errors', snapshot['tx_errors']) # d.addCallback(self._check_value_equal, 'consecutive_errors', 0, omci_cc.consecutive_errors) # return d def test_message_send_reboot(self): self.setup_one_of_each() omci_cc = self.onu_handler.omci_cc omci_cc.enabled = True snapshot = self._snapshot_stats() # ONU Reboot d = omci_cc.send_reboot(timeout=1.0) d.addCallbacks(self._is_omci_frame, self._default_errback) d.addCallback(self._check_status, RC.Success) d.addCallback(self._check_stats, snapshot, 'tx_frames', snapshot['tx_frames'] + 1) d.addCallback(self._check_stats, snapshot, 'rx_frames', snapshot['rx_frames'] + 1) d.addCallback(self._check_stats, snapshot, 'rx_unknown_tid', snapshot['rx_unknown_tid']) d.addCallback(self._check_stats, snapshot, 'rx_onu_frames', snapshot['rx_onu_frames']) d.addCallback(self._check_stats, snapshot, 'rx_alarm_overflow', snapshot['rx_alarm_overflow']) d.addCallback(self._check_stats, snapshot, 'rx_avc_overflow', snapshot['rx_avc_overflow']) d.addCallback(self._check_stats, snapshot, 'rx_onu_discards', snapshot['rx_onu_discards']) d.addCallback(self._check_stats, snapshot, 'rx_unknown_me', snapshot['rx_unknown_me']) d.addCallback(self._check_stats, snapshot, 'rx_timeouts', snapshot['rx_timeouts']) d.addCallback(self._check_stats, snapshot, 'tx_errors', snapshot['tx_errors']) d.addCallback(self._check_value_equal, 'consecutive_errors', 0, omci_cc.consecutive_errors) return d def test_message_send_with_omci_disabled(self): self.setup_one_of_each() omci_cc = self.onu_handler.omci_cc self.assertFalse(omci_cc.enabled) # Successful MIB Reset d = omci_cc.send_mib_reset(timeout=1.0) def success_is_bad(_results): assert False, 'This test should throw a failure/error' def fail_fast(_failure): pass return None d.addCallbacks(success_is_bad, fail_fast) return d def test_message_send_get_with_latency(self): # Various tests of sending an OMCI message and it either # getting a response or send catching some errors of # importance self.setup_one_of_each() self.olt_handler.latency = 0.500 # 1/2 second omci_cc = self.onu_handler.omci_cc omci_cc.enabled = True # Successful MIB Reset d = omci_cc.send_mib_reset(timeout=1.0) d.addCallbacks(self._is_omci_frame, self._default_errback) d.addCallback(self._check_status, RC.Success) def check_latency_values(_): self.assertGreaterEqual(omci_cc.reply_min, self.olt_handler.latency) self.assertGreaterEqual(omci_cc.reply_max, self.olt_handler.latency) self.assertGreaterEqual(omci_cc.reply_average, self.olt_handler.latency) d.addCallback(check_latency_values) return d def test_message_failures(self): # Various tests of sending an OMCI message and it fails self.setup_one_of_each() omci_cc = self.onu_handler.omci_cc omci_cc.enabled = True snapshot = self._snapshot_stats() self.assertEqual(omci_cc.tx_frames, 0) self.assertEqual(omci_cc.rx_frames, 0) self.assertEqual(omci_cc.rx_unknown_tid, 0) self.assertEqual(omci_cc.rx_timeouts, 0) self.assertEqual(omci_cc.tx_errors, 0) # # Class ID not found # d = omci_cc.send_mib_reset(timeout=1.0) # self.assertTrue(True) # TODO: Implement # todo: Test non-zero consecutive errors # # # Instance ID not found # d = omci_cc.send_mib_reset(timeout=1.0) # self.assertTrue(True) # TODO: Implement # todo: Test non-zero consecutive errors # # # PON is disabled # d = omci_cc.send_mib_reset(timeout=1.0) # self.assertTrue(True) # TODO: Implement # todo: Test non-zero consecutive errors # # # ONU is disabled # d = omci_cc.send_mib_reset(timeout=1.0) # self.assertTrue(True) # TODO: Implement # todo: Test non-zero consecutive errors # # # ONU is not activated # d = omci_cc.send_mib_reset(timeout=1.0) # self.assertTrue(True) # TODO: Implement # todo: Test non-zero consecutive errors # TODO: make OLT send back an unknown TID ( # todo: Test non-zero consecutive errors # todo: Send a good frame # todo: Test zero consecutive errors # d.addCallback(self._check_value_equal, 'consecutive_errors', 0, omci_cc.consecutive_errors) def test_rx_unknown_me(self): # ME without a known decoder self.setup_one_of_each() omci_cc = self.onu_handler.omci_cc omci_cc.enabled = True snapshot = self._snapshot_stats() # This is the ID ------+ # v msg = '00fc2e0a00020000ff780000e00000010000000c' \ '0000000000000000000000000000000000000000' \ '00000028' omci_cc.receive_message(hex2raw(msg)) # Note: After successful frame decode, a lookup of the corresponding request by # TID is performed. None should be found, so we should see the Rx Unknown TID # increment. self.assertEqual(omci_cc.rx_frames, snapshot['rx_frames']) self.assertEqual(omci_cc.rx_unknown_me, snapshot['rx_unknown_me'] + 1) self.assertEqual(omci_cc.rx_unknown_tid, snapshot['rx_unknown_tid'] + 1) self.assertEqual(omci_cc.rx_onu_frames, snapshot['rx_onu_frames']) self.assertEqual(omci_cc.consecutive_errors, 0) def test_rx_decode_unknown_me(self): # ME without a known decoder self.setup_one_of_each() omci_cc = self.onu_handler.omci_cc omci_cc.enabled = True snapshot = self._snapshot_stats() # This is a MIB Upload Next Response. Where we would probably first see an # unknown Class ID # # This is the ID ------+ # v msg = '00fc2e0a00020000ff780001e000' blob = '00010000000c0000000000000000000000000000000000000000' msg += blob + '00000028' # Dig into the internal method so we can get the returned frame frame = omci_cc._decode_unknown_me(hex2raw(msg)) self.assertEqual(frame.fields['transaction_id'], 0x00fc) self.assertEqual(frame.fields['message_type'], 0x2e) omci_fields = frame.fields['omci_message'].fields self.assertEqual(omci_fields['entity_class'], 0x0002) self.assertEqual(omci_fields['entity_id'], 0x00) self.assertEqual(omci_fields['object_entity_class'], 0x0ff78) self.assertEqual(omci_fields['object_entity_id'], 0x01) self.assertEqual(omci_fields['object_attributes_mask'], 0xe000) data_fields = omci_fields['object_data'] decoded_blob = data_fields.get(UNKNOWN_CLASS_ATTRIBUTE_KEY) self.assertIsNotNone(decoded_blob) self.assertEqual(decoded_blob, blob) def test_flush(self): # Test flush of autonomous ONU queues self.setup_one_of_each() omci_cc = self.onu_handler.omci_cc omci_cc.enabled = True snapshot = self._snapshot_stats() # TODO: add more self.assertTrue(True) # TODO: Implement def test_avc_rx(self): # Test flush of autonomous ONU queues self.setup_one_of_each() omci_cc = self.onu_handler.omci_cc omci_cc.enabled = True snapshot = self._snapshot_stats() # TODO: add more self.assertTrue(True) # TODO: Implement
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
class TestOmciMibResyncTask(TestCase): def setUp(self): self.adapter_agent = MockAdapterAgent() self.adapter_agent.add_device( MockDevice(_DEVICE_ID)) # For Entity class lookups self.onu_db = OnuDB(self.adapter_agent) self.olt_db = OltDB(self.adapter_agent) self.onu_db.start() self.olt_db.start() self.olt_db.add(_DEVICE_ID) self.onu_db.add(_DEVICE_ID) self.task = MibResyncTask(self.adapter_agent, _DEVICE_ID) def tearDown(self): self.onu_db.stop() self.olt_db.stop() def test_not_same_type_dbs(self): # # OLT DB is a copy of the 'external' DB, ONU is a volatile DB # self.assertNotEqual(type(self.olt_db), type(self.onu_db)) def test_db_same_format_str_field_serialization(self): class_id = OltG.class_id inst_id = 0 attributes = { 'olt_vendor_id': 'ABCD', # StrFixedLenField(4) } self.onu_db.set(_DEVICE_ID, class_id, inst_id, attributes) self.olt_db.set(_DEVICE_ID, class_id, inst_id, attributes) db_copy = self.olt_db.query(_DEVICE_ID) db_active = self.onu_db.query(_DEVICE_ID) olt_only, onu_only, attr_diffs = self.task.compare_mibs( db_copy, db_active) self.assertEqual(len(olt_only), 0) self.assertEqual(len(onu_only), 0) self.assertEqual(len(attr_diffs), 0) def test_db_same_format_mac_address_ip_field_serialization(self): class_id = IpHostConfigData.class_id inst_id = 0 attributes = { 'mac_address': '00:01:02:03:04:05', # MACField 'ip_address': '1.2.3.4', # IPField } self.onu_db.set(_DEVICE_ID, class_id, inst_id, attributes) self.olt_db.set(_DEVICE_ID, class_id, inst_id, attributes) db_copy = self.olt_db.query(_DEVICE_ID) db_active = self.onu_db.query(_DEVICE_ID) olt_only, onu_only, attr_diffs = self.task.compare_mibs( db_copy, db_active) self.assertEqual(len(olt_only), 0) self.assertEqual(len(onu_only), 0) self.assertEqual(len(attr_diffs), 0) def test_db_same_format_byte_and_short_field_serialization(self): class_id = UniG.class_id inst_id = 0 attributes = { 'administrative_state': int(1), # ByteField 'non_omci_management_identifier': int(12345) # IPField } self.onu_db.set(_DEVICE_ID, class_id, inst_id, attributes) self.olt_db.set(_DEVICE_ID, class_id, inst_id, attributes) db_copy = self.olt_db.query(_DEVICE_ID) db_active = self.onu_db.query(_DEVICE_ID) olt_only, onu_only, attr_diffs = self.task.compare_mibs( db_copy, db_active) self.assertEqual(len(olt_only), 0) self.assertEqual(len(onu_only), 0) self.assertEqual(len(attr_diffs), 0) def test_db_same_format_int_field_serialization(self): class_id = PriorityQueueG.class_id inst_id = 0 attributes = { 'related_port': int(1234567) # IntField } self.onu_db.set(_DEVICE_ID, class_id, inst_id, attributes) self.olt_db.set(_DEVICE_ID, class_id, inst_id, attributes) db_copy = self.olt_db.query(_DEVICE_ID) db_active = self.onu_db.query(_DEVICE_ID) olt_only, onu_only, attr_diffs = self.task.compare_mibs( db_copy, db_active) self.assertEqual(len(olt_only), 0) self.assertEqual(len(onu_only), 0) self.assertEqual(len(attr_diffs), 0) def test_db_same_format_long_field_serialization(self): class_id = PriorityQueueG.class_id inst_id = 0 attributes = { 'packet_drop_queue_thresholds': int(0x1234) # LongField } self.onu_db.set(_DEVICE_ID, class_id, inst_id, attributes) self.olt_db.set(_DEVICE_ID, class_id, inst_id, attributes) db_copy = self.olt_db.query(_DEVICE_ID) db_active = self.onu_db.query(_DEVICE_ID) olt_only, onu_only, attr_diffs = self.task.compare_mibs( db_copy, db_active) self.assertEqual(len(olt_only), 0) self.assertEqual(len(onu_only), 0) self.assertEqual(len(attr_diffs), 0) def test_db_same_format_bit_field_serialization(self): class_id = OntG.class_id inst_id = 0 attributes = { 'extended_tc_layer_options': long(0x1234), # BitField(16) } self.onu_db.set(_DEVICE_ID, class_id, inst_id, attributes) self.olt_db.set(_DEVICE_ID, class_id, inst_id, attributes) db_copy = self.olt_db.query(_DEVICE_ID) db_active = self.onu_db.query(_DEVICE_ID) olt_only, onu_only, attr_diffs = self.task.compare_mibs( db_copy, db_active) self.assertEqual(len(olt_only), 0) self.assertEqual(len(onu_only), 0) self.assertEqual(len(attr_diffs), 0) def test_db_same_format_list_field_serialization(self): class_id = VlanTaggingFilterData.class_id inst_id = 0 vlan_filter_list = [0] * 12 vlan_filter_list[0] = 0x1234 attributes = { 'vlan_filter_list': vlan_filter_list, # FieldListField 'forward_operation': 0, 'number_of_entries': 1 } self.onu_db.set(_DEVICE_ID, class_id, inst_id, attributes) self.olt_db.set(_DEVICE_ID, class_id, inst_id, attributes) db_copy = self.olt_db.query(_DEVICE_ID) db_active = self.onu_db.query(_DEVICE_ID) olt_only, onu_only, attr_diffs = self.task.compare_mibs( db_copy, db_active) self.assertEqual(len(olt_only), 0) self.assertEqual(len(onu_only), 0) self.assertEqual(len(attr_diffs), 0) def test_db_same_format_complex_json_serialization(self): class_id = ExtendedVlanTaggingOperationConfigurationData.class_id inst_id = 0x202 table_data = VlanTaggingOperation(filter_outer_priority=15, filter_inner_priority=8, filter_inner_vid=1024, filter_inner_tpid_de=5, filter_ether_type=0, treatment_tags_to_remove=1, pad3=2, treatment_outer_priority=15, treatment_inner_priority=8, treatment_inner_vid=1024, treatment_inner_tpid_de=4) attributes = dict( received_frame_vlan_tagging_operation_table=table_data) self.onu_db.set(_DEVICE_ID, class_id, inst_id, attributes) self.olt_db.set(_DEVICE_ID, class_id, inst_id, attributes) db_copy = self.olt_db.query(_DEVICE_ID) db_active = self.onu_db.query(_DEVICE_ID) olt_only, onu_only, attr_diffs = self.task.compare_mibs( db_copy, db_active) self.assertEqual(len(olt_only), 0) self.assertEqual(len(onu_only), 0) self.assertEqual(len(attr_diffs), 0) def test_on_olt_only(self): class_id = GemInterworkingTp.class_id inst_id = 0 attributes = {'gal_loopback_configuration': int(1)} self.olt_db.set(_DEVICE_ID, class_id, inst_id, attributes) db_copy = self.olt_db.query(_DEVICE_ID) db_active = self.onu_db.query(_DEVICE_ID) olt_only, onu_only, attr_diffs = self.task.compare_mibs( db_copy, db_active) self.assertEqual(len(olt_only), 1) self.assertEqual(len(onu_only), 0) self.assertEqual(len(attr_diffs), 0) self.assertEqual(olt_only, [(class_id, inst_id)]) # Now a little more complex (extra instance on the OLT self.olt_db.set(_DEVICE_ID, class_id, inst_id + 1, attributes) self.onu_db.set(_DEVICE_ID, class_id, inst_id, attributes) db_copy = self.olt_db.query(_DEVICE_ID) db_active = self.onu_db.query(_DEVICE_ID) olt_only, onu_only, attr_diffs = self.task.compare_mibs( db_copy, db_active) self.assertEqual(len(olt_only), 1) self.assertEqual(len(onu_only), 0) self.assertEqual(len(attr_diffs), 0) self.assertEqual(olt_only, [(class_id, inst_id + 1)]) def test_on_onu_only(self): class_id = PriorityQueueG.class_id inst_id = 0 attributes = { 'related_port': int(1234567) # IntField } self.onu_db.set(_DEVICE_ID, class_id, inst_id, attributes) db_copy = self.olt_db.query(_DEVICE_ID) db_active = self.onu_db.query(_DEVICE_ID) olt_only, onu_only, attr_diffs = self.task.compare_mibs( db_copy, db_active) self.assertEqual(len(olt_only), 0) self.assertEqual(len(onu_only), 1) self.assertEqual(len(attr_diffs), 0) self.assertEqual( onu_only, [(class_id, inst_id)]) # Test contents of what was returned # Now a little more complex (extra instance on the ONU self.olt_db.set(_DEVICE_ID, class_id, inst_id, attributes) self.onu_db.set(_DEVICE_ID, class_id, inst_id + 1, attributes) db_copy = self.olt_db.query(_DEVICE_ID) db_active = self.onu_db.query(_DEVICE_ID) olt_only, onu_only, attr_diffs = self.task.compare_mibs( db_copy, db_active) self.assertEqual(len(olt_only), 0) self.assertEqual(len(onu_only), 1) self.assertEqual(len(attr_diffs), 0) self.assertEqual( onu_only, [(class_id, inst_id + 1)]) # Test contents of what was returned def test_on_attr_different_value(self): class_id = PriorityQueueG.class_id inst_id = 0 attributes_olt = { 'weight': int(12) # ByteField } attributes_onu = { 'weight': int(34) # ByteField } self.onu_db.set(_DEVICE_ID, class_id, inst_id, attributes_onu) self.olt_db.set(_DEVICE_ID, class_id, inst_id, attributes_olt) db_copy = self.olt_db.query(_DEVICE_ID) db_active = self.onu_db.query(_DEVICE_ID) olt_only, onu_only, attr_diffs = self.task.compare_mibs( db_copy, db_active) self.assertEqual(len(olt_only), 0) self.assertEqual(len(onu_only), 0) self.assertEqual(len(attr_diffs), 1) self.assertEqual(attr_diffs, [(class_id, inst_id, 'weight')]) def test_ignore_read_only_attribute_differences(self): class_id = PriorityQueueG.class_id inst_id = 0 attributes_olt = { 'related_port': int(1234), # IntField (R/O) 'maximum_queue_size': int(222) # Only on OLT but read-only } attributes_onu = { 'related_port': int(5678) # IntField (R/O) } self.onu_db.set(_DEVICE_ID, class_id, inst_id, attributes_onu) self.olt_db.set(_DEVICE_ID, class_id, inst_id, attributes_olt) db_copy = self.olt_db.query(_DEVICE_ID) db_active = self.onu_db.query(_DEVICE_ID) olt_only, onu_only, attr_diffs = self.task.compare_mibs( db_copy, db_active) self.assertEqual(len(olt_only), 0) self.assertEqual(len(onu_only), 0) self.assertEqual(len(attr_diffs), 0) def test_on_attr_more_on_olt(self): class_id = PriorityQueueG.class_id inst_id = 0 attributes_olt = { 'related_port': int(1234), # IntField 'back_pressure_time': int(1234) # IntField } attributes_onu = { 'related_port': int(1234) # IntField } self.onu_db.set(_DEVICE_ID, class_id, inst_id, attributes_onu) self.olt_db.set(_DEVICE_ID, class_id, inst_id, attributes_olt) db_copy = self.olt_db.query(_DEVICE_ID) db_active = self.onu_db.query(_DEVICE_ID) olt_only, onu_only, attr_diffs = self.task.compare_mibs( db_copy, db_active) self.assertEqual(len(olt_only), 0) self.assertEqual(len(onu_only), 0) self.assertEqual(len(attr_diffs), 1) self.assertEqual(attr_diffs, [(class_id, inst_id, 'back_pressure_time')]) def test_on_attr_more_on_onu(self): class_id = PriorityQueueG.class_id inst_id = 0 attributes_olt = { 'related_port': int(1234) # IntField } attributes_onu = { 'related_port': int(1234), # IntField 'back_pressure_time': int(5678) # IntField } self.onu_db.set(_DEVICE_ID, class_id, inst_id, attributes_onu) self.olt_db.set(_DEVICE_ID, class_id, inst_id, attributes_olt) db_copy = self.olt_db.query(_DEVICE_ID) db_active = self.onu_db.query(_DEVICE_ID) olt_only, onu_only, attr_diffs = self.task.compare_mibs( db_copy, db_active) self.assertEqual(len(olt_only), 0) self.assertEqual(len(onu_only), 0) self.assertEqual(len(attr_diffs), 1) self.assertEqual(attr_diffs, [(class_id, inst_id, 'back_pressure_time')])
class TestOmciCc(TestCase): """ Test the Open OMCI Communication channels Note also added some testing of MockOnu behaviour since its behaviour during more complicated unit/integration tests may be performed in the future. """ def setUp(self): self.adapter_agent = MockAdapterAgent() def tearDown(self): 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 _is_omci_frame(self, results, omci_msg_type): assert isinstance(results, OmciFrame), 'Not OMCI Frame' assert 'omci_message' in results.fields, 'Not OMCI Frame' if omci_msg_type is not None: assert isinstance(results.fields['omci_message'], omci_msg_type) return results def _check_status(self, results, value): if value is not None: assert results is not None, 'unexpected emtpy message' status = results.fields['omci_message'].fields['success_code'] assert status == value,\ 'Unexpected Status Code. Got {}, Expected: {}'.format(status, value) return results def _check_mib_sync(self, results, value): assert self.onu_device.mib_data_sync == value, \ 'Unexpected MIB DATA Sync value. Got {}, Expected: {}'.format( self.onu_device.mib_data_sync, value) return results def _check_stats(self, results, _, stat, expected): snapshot = self._snapshot_stats() assert snapshot[stat] == expected, \ 'Invalid statistic "{}". Got {}, Expected: {}'.format(stat, snapshot[stat], expected) return results def _check_value_equal(self, results, name, value, expected): assert value == expected, \ 'Value "{}" not equal. Got {}, Expected: {}'.format(name, value, expected) return results def _default_errback(self, failure): from twisted.internet.defer import TimeoutError assert isinstance(failure.type, type(TimeoutError)) return None def _snapshot_stats(self): omci_cc = self.onu_handler.omci_cc return { 'tx_frames': omci_cc.tx_frames, 'rx_frames': omci_cc.rx_frames, 'rx_unknown_tid': omci_cc.rx_unknown_tid, 'rx_onu_frames': omci_cc.rx_onu_frames, 'rx_onu_discards': omci_cc.rx_onu_discards, 'rx_timeouts': omci_cc.rx_timeouts, 'rx_unknown_me': omci_cc.rx_unknown_me, 'tx_errors': omci_cc.tx_errors, 'consecutive_errors': omci_cc.consecutive_errors, 'reply_min': omci_cc.reply_min, 'reply_max': omci_cc.reply_max, 'reply_average': omci_cc.reply_average } def test_default_init(self): self.setup_one_of_each() # Test default construction of OMCI_CC as well as # various other parameter settings omci_cc = self.onu_handler.omci_cc # No device directly associated self.assertIsNotNone(omci_cc._adapter_agent) self.assertIsNone(omci_cc._proxy_address) # No outstanding requests self.assertEqual(len(omci_cc._requests), 0) # Flags/properties self.assertFalse(omci_cc.enabled) # Statistics self.assertEqual(omci_cc.tx_frames, 0) self.assertEqual(omci_cc.rx_frames, 0) self.assertEqual(omci_cc.rx_unknown_tid, 0) self.assertEqual(omci_cc.rx_onu_frames, 0) self.assertEqual(omci_cc.rx_onu_discards, 0) self.assertEqual(omci_cc.rx_unknown_me, 0) self.assertEqual(omci_cc.rx_timeouts, 0) self.assertEqual(omci_cc.tx_errors, 0) self.assertEqual(omci_cc.consecutive_errors, 0) self.assertNotEquals(omci_cc.reply_min, 0.0) self.assertEqual(omci_cc.reply_max, 0.0) self.assertEqual(omci_cc.reply_average, 0.0) def test_enable_disable(self): self.setup_one_of_each() # Test enable property omci_cc = self.onu_handler.omci_cc # Initially disabled self.assertFalse(omci_cc.enabled) omci_cc.enabled = False self.assertFalse(omci_cc.enabled) omci_cc.enabled = True self.assertTrue(omci_cc.enabled) self.assertIsNotNone(omci_cc._proxy_address) self.assertEqual(len(omci_cc._requests), 0) omci_cc.enabled = True # Should be a NOP self.assertTrue(omci_cc.enabled) self.assertIsNotNone(omci_cc._proxy_address) self.assertEqual(len(omci_cc._requests), 0) omci_cc.enabled = False self.assertFalse(omci_cc.enabled) self.assertIsNone(omci_cc._proxy_address) def test_rx_discard_if_disabled(self): # ME without a known decoder self.setup_one_of_each() omci_cc = self.onu_handler.omci_cc omci_cc.enabled = False snapshot = self._snapshot_stats() msg = '00fc2e0a00020000ff780000e00000010000000c' \ '0000000000000000000000000000000000000000' \ '00000028105a86ef' omci_cc.receive_message(hex2raw(msg)) # Note: No counter increments self.assertEqual(omci_cc.rx_frames, snapshot['rx_frames']) self.assertEqual(omci_cc.rx_unknown_me, snapshot['rx_unknown_me']) self.assertEqual(omci_cc.rx_unknown_tid, snapshot['rx_unknown_tid']) self.assertEqual(omci_cc.rx_onu_frames, snapshot['rx_onu_frames']) self.assertEqual(omci_cc.rx_unknown_tid, snapshot['rx_unknown_tid']) def test_message_send_get(self): # Various tests of sending an OMCI message and it either # getting a response or send catching some errors of # importance self.setup_one_of_each() omci_cc = self.onu_handler.omci_cc omci_cc.enabled = True snapshot = self._snapshot_stats() mib_data_sync = self.onu_device.mib_data_sync # GET # d = omci_cc.send() # TODO: Implement # # d.addCallbacks(self._is_omci_frame, self._default_errback) # d.addCallback(self._check_status, RC.Success.value) # d.addCallback(self._check_mib_sync, mib_data_sync) # # d.addCallback(self._check_stats, snapshot, 'tx_frames', snapshot['tx_frames'] + 1) # d.addCallback(self._check_stats, snapshot, 'rx_frames', snapshot['rx_frames'] + 1) # d.addCallback(self._check_stats, snapshot, 'rx_unknown_tid', snapshot['rx_unknown_tid']) # d.addCallback(self._check_stats, snapshot, 'rx_onu_frames', snapshot['rx_onu_frames']) # d.addCallback(self._check_stats, snapshot, 'rx_onu_discards', snapshot['rx_onu_discards']) # d.addCallback(self._check_stats, snapshot, 'rx_unknown_me', snapshot['rx_unknown_me']) # d.addCallback(self._check_stats, snapshot, 'rx_timeouts', snapshot['rx_timeouts']) # d.addCallback(self._check_stats, snapshot, 'tx_errors', snapshot['tx_errors']) # d.addCallback(self._check_value_equal, 'consecutive_errors', 0, omci_cc.consecutive_errors) # return d def test_message_send_set(self): # Various tests of sending an OMCI message and it either # getting a response or send catching some errors of # importance self.setup_one_of_each() omci_cc = self.onu_handler.omci_cc omci_cc.enabled = True snapshot = self._snapshot_stats() mib_data_sync = self.onu_device.mib_data_sync # SET # d = omci_cc.send() # TODO: Implement # # d.addCallbacks(self._is_omci_frame, self._default_errback) # d.addCallback(self._check_status, RC.Success.value) # d.addCallback(self._check_mib_sync, mib_data_sync + 1 if mib_data_sync < 255 else 1) # # d.addCallback(self._check_stats, snapshot, 'tx_frames', snapshot['tx_frames'] + 1) # d.addCallback(self._check_stats, snapshot, 'rx_frames', snapshot['rx_frames'] + 1) # d.addCallback(self._check_stats, snapshot, 'rx_unknown_tid', snapshot['rx_unknown_tid']) # d.addCallback(self._check_stats, snapshot, 'rx_onu_frames', snapshot['rx_onu_frames']) # d.addCallback(self._check_stats, snapshot, 'rx_onu_discards', snapshot['rx_onu_discards']) # d.addCallback(self._check_stats, snapshot, 'rx_unknown_me', snapshot['rx_unknown_me']) # d.addCallback(self._check_stats, snapshot, 'rx_timeouts', snapshot['rx_timeouts']) # d.addCallback(self._check_stats, snapshot, 'tx_errors', snapshot['tx_errors']) # d.addCallback(self._check_value_equal, 'consecutive_errors', 0, omci_cc.consecutive_errors) # return d # # # Also test mib_data_sync rollover. 255 -> 1 (zero reserved) # # self.onu_device.mib_data_sync = 255 # # SET # self.assertTrue(True) # TODO: Implement (copy previous one here) # self.assertEqual(1, self.onu_device.mib_data_sync) def test_message_send_create(self): # Various tests of sending an OMCI message and it either # getting a response or send catching some errors of # importance self.setup_one_of_each() omci_cc = self.onu_handler.omci_cc omci_cc.enabled = True snapshot = self._snapshot_stats() mib_data_sync = self.onu_device.mib_data_sync # Create # d = omci_cc.send() # TODO: Implement # # d.addCallbacks(self._is_omci_frame, self._default_errback) # d.addCallback(self._check_status, RC.Success.value) # d.addCallback(self._check_mib_sync, mib_data_sync + 1 if mib_data_sync < 255 else 1) # # d.addCallback(self._check_stats, snapshot, 'tx_frames', snapshot['tx_frames'] + 1) # d.addCallback(self._check_stats, snapshot, 'rx_frames', snapshot['rx_frames'] + 1) # d.addCallback(self._check_stats, snapshot, 'rx_unknown_tid', snapshot['rx_unknown_tid']) # d.addCallback(self._check_stats, snapshot, 'rx_onu_frames', snapshot['rx_onu_frames']) # d.addCallback(self._check_stats, snapshot, 'rx_onu_discards', snapshot['rx_onu_discards']) # d.addCallback(self._check_stats, snapshot, 'rx_unknown_me', snapshot['rx_unknown_me']) # d.addCallback(self._check_stats, snapshot, 'rx_timeouts', snapshot['rx_timeouts']) # d.addCallback(self._check_stats, snapshot, 'tx_errors', snapshot['tx_errors']) # d.addCallback(self._check_value_equal, 'consecutive_errors', 0, omci_cc.consecutive_errors) # return d def test_message_send_delete(self): # Various tests of sending an OMCI message and it either # getting a response or send catching some errors of # importance self.setup_one_of_each() omci_cc = self.onu_handler.omci_cc omci_cc.enabled = True snapshot = self._snapshot_stats() mib_data_sync = self.onu_device.mib_data_sync # Delete # d = omci_cc.send() # TODO: Implement # # d.addCallbacks(self._is_omci_frame, self._default_errback) # d.addCallback(self._check_status, RC.Success.value) # d.addCallback(self._check_mib_sync, mib_data_sync + 1 if mib_data_sync < 255 else 1) # # d.addCallback(self._check_stats, snapshot, 'tx_frames', snapshot['tx_frames'] + 1) # d.addCallback(self._check_stats, snapshot, 'rx_frames', snapshot['rx_frames'] + 1) # d.addCallback(self._check_stats, snapshot, 'rx_unknown_tid', snapshot['rx_unknown_tid']) # d.addCallback(self._check_stats, snapshot, 'rx_onu_frames', snapshot['rx_onu_frames']) # d.addCallback(self._check_stats, snapshot, 'rx_onu_discards', snapshot['rx_onu_discards']) # d.addCallback(self._check_stats, snapshot, 'rx_unknown_me', snapshot['rx_unknown_me']) # d.addCallback(self._check_stats, snapshot, 'rx_timeouts', snapshot['rx_timeouts']) # d.addCallback(self._check_stats, snapshot, 'tx_errors', snapshot['tx_errors']) # d.addCallback(self._check_value_equal, 'consecutive_errors', 0, omci_cc.consecutive_errors) # return d def test_message_send_mib_reset(self): self.setup_one_of_each() omci_cc = self.onu_handler.omci_cc omci_cc.enabled = True self.onu_device.mib_data_sync = 10 snapshot = self._snapshot_stats() # Successful MIB Reset d = omci_cc.send_mib_reset(timeout=1.0) d.addCallbacks(self._is_omci_frame, self._default_errback) d.addCallback(self._check_status, RC.Success) d.addCallback(self._check_mib_sync, 0) d.addCallback(self._check_stats, snapshot, 'tx_frames', snapshot['tx_frames'] + 1) d.addCallback(self._check_stats, snapshot, 'rx_frames', snapshot['rx_frames'] + 1) d.addCallback(self._check_stats, snapshot, 'rx_unknown_tid', snapshot['rx_unknown_tid']) d.addCallback(self._check_stats, snapshot, 'rx_onu_frames', snapshot['rx_onu_frames']) d.addCallback(self._check_stats, snapshot, 'rx_onu_discards', snapshot['rx_onu_discards']) d.addCallback(self._check_stats, snapshot, 'rx_unknown_me', snapshot['rx_unknown_me']) d.addCallback(self._check_stats, snapshot, 'rx_timeouts', snapshot['rx_timeouts']) d.addCallback(self._check_stats, snapshot, 'tx_errors', snapshot['tx_errors']) d.addCallback(self._check_value_equal, 'consecutive_errors', 0, omci_cc.consecutive_errors) return d def test_message_send_mib_upload(self): self.setup_one_of_each() omci_cc = self.onu_handler.omci_cc omci_cc.enabled = True snapshot = self._snapshot_stats() mib_data_sync = self.onu_device.mib_data_sync # MIB Upload d = omci_cc.send_mib_upload(timeout=1.0) d.addCallbacks(self._is_omci_frame, self._default_errback) d.addCallback(self._check_status, RC.Success) d.addCallback(self._check_mib_sync, mib_data_sync) # TODO: MIB Upload Results specific tests here d.addCallback(self._check_stats, snapshot, 'tx_frames', snapshot['tx_frames'] + 1) d.addCallback(self._check_stats, snapshot, 'rx_frames', snapshot['rx_frames'] + 1) d.addCallback(self._check_stats, snapshot, 'rx_unknown_tid', snapshot['rx_unknown_tid']) d.addCallback(self._check_stats, snapshot, 'rx_onu_frames', snapshot['rx_onu_frames']) d.addCallback(self._check_stats, snapshot, 'rx_onu_discards', snapshot['rx_onu_discards']) d.addCallback(self._check_stats, snapshot, 'rx_unknown_me', snapshot['rx_unknown_me']) d.addCallback(self._check_stats, snapshot, 'rx_timeouts', snapshot['rx_timeouts']) d.addCallback(self._check_stats, snapshot, 'tx_errors', snapshot['tx_errors']) d.addCallback(self._check_value_equal, 'consecutive_errors', 0, omci_cc.consecutive_errors) return d def test_message_send_mib_upload_next(self): self.setup_one_of_each() omci_cc = self.onu_handler.omci_cc omci_cc.enabled = True snapshot = self._snapshot_stats() mib_data_sync = self.onu_device.mib_data_sync # # MIB Upload Next # d = omci_cc.send_mib_upload_next(0, timeout=1.0) # # d.addCallbacks(self._is_omci_frame, self._default_errback) # d.addCallback(self._check_status, RC.Success) # d.addCallback(self._check_mib_sync, mib_data_sync) # # # TODO: MIB Upload Next Results specific tests here # # d.addCallback(self._check_stats, snapshot, 'tx_frames', snapshot['tx_frames'] + 1) # d.addCallback(self._check_stats, snapshot, 'rx_frames', snapshot['rx_frames'] + 1) # d.addCallback(self._check_stats, snapshot, 'rx_unknown_tid', snapshot['rx_unknown_tid']) # d.addCallback(self._check_stats, snapshot, 'rx_onu_frames', snapshot['rx_onu_frames']) # d.addCallback(self._check_stats, snapshot, 'rx_onu_discards', snapshot['rx_onu_discards']) # d.addCallback(self._check_stats, snapshot, 'rx_unknown_me', snapshot['rx_unknown_me']) # d.addCallback(self._check_stats, snapshot, 'rx_timeouts', snapshot['rx_timeouts']) # d.addCallback(self._check_stats, snapshot, 'tx_errors', snapshot['tx_errors']) # d.addCallback(self._check_value_equal, 'consecutive_errors', 0, omci_cc.consecutive_errors) # return d def test_message_send_reboot(self): self.setup_one_of_each() omci_cc = self.onu_handler.omci_cc omci_cc.enabled = True snapshot = self._snapshot_stats() # ONU Reboot d = omci_cc.send_reboot(timeout=1.0) d.addCallbacks(self._is_omci_frame, self._default_errback) d.addCallback(self._check_status, RC.Success) d.addCallback(self._check_stats, snapshot, 'tx_frames', snapshot['tx_frames'] + 1) d.addCallback(self._check_stats, snapshot, 'rx_frames', snapshot['rx_frames'] + 1) d.addCallback(self._check_stats, snapshot, 'rx_unknown_tid', snapshot['rx_unknown_tid']) d.addCallback(self._check_stats, snapshot, 'rx_onu_frames', snapshot['rx_onu_frames']) d.addCallback(self._check_stats, snapshot, 'rx_onu_discards', snapshot['rx_onu_discards']) d.addCallback(self._check_stats, snapshot, 'rx_unknown_me', snapshot['rx_unknown_me']) d.addCallback(self._check_stats, snapshot, 'rx_timeouts', snapshot['rx_timeouts']) d.addCallback(self._check_stats, snapshot, 'tx_errors', snapshot['tx_errors']) d.addCallback(self._check_value_equal, 'consecutive_errors', 0, omci_cc.consecutive_errors) return d def test_message_send_with_omci_disabled(self): self.setup_one_of_each() omci_cc = self.onu_handler.omci_cc self.assertFalse(omci_cc.enabled) # Successful MIB Reset d = omci_cc.send_mib_reset(timeout=1.0) def success_is_bad(_results): assert False, 'This test should throw a failure/error' def fail_fast(_failure): pass return None d.addCallbacks(success_is_bad, fail_fast) return d def test_message_send_get_with_latency(self): # Various tests of sending an OMCI message and it either # getting a response or send catching some errors of # importance self.setup_one_of_each() self.olt_handler.latency = 0.500 # 1/2 second omci_cc = self.onu_handler.omci_cc omci_cc.enabled = True # Successful MIB Reset d = omci_cc.send_mib_reset(timeout=1.0) d.addCallbacks(self._is_omci_frame, self._default_errback) d.addCallback(self._check_status, RC.Success) def check_latency_values(_): self.assertGreaterEqual(omci_cc.reply_min, self.olt_handler.latency) self.assertGreaterEqual(omci_cc.reply_max, self.olt_handler.latency) self.assertGreaterEqual(omci_cc.reply_average, self.olt_handler.latency) d.addCallback(check_latency_values) return d def test_message_failures(self): # Various tests of sending an OMCI message and it fails self.setup_one_of_each() omci_cc = self.onu_handler.omci_cc omci_cc.enabled = True snapshot = self._snapshot_stats() self.assertEqual(omci_cc.tx_frames, 0) self.assertEqual(omci_cc.rx_frames, 0) self.assertEqual(omci_cc.rx_unknown_tid, 0) self.assertEqual(omci_cc.rx_timeouts, 0) self.assertEqual(omci_cc.tx_errors, 0) # # Class ID not found # d = omci_cc.send_mib_reset(timeout=1.0) # self.assertTrue(True) # TODO: Implement # todo: Test non-zero consecutive errors # # # Instance ID not found # d = omci_cc.send_mib_reset(timeout=1.0) # self.assertTrue(True) # TODO: Implement # todo: Test non-zero consecutive errors # # # PON is disabled # d = omci_cc.send_mib_reset(timeout=1.0) # self.assertTrue(True) # TODO: Implement # todo: Test non-zero consecutive errors # # # ONU is disabled # d = omci_cc.send_mib_reset(timeout=1.0) # self.assertTrue(True) # TODO: Implement # todo: Test non-zero consecutive errors # # # ONU is not activated # d = omci_cc.send_mib_reset(timeout=1.0) # self.assertTrue(True) # TODO: Implement # todo: Test non-zero consecutive errors # TODO: make OLT send back an unknown TID ( # todo: Test non-zero consecutive errors # todo: Send a good frame # todo: Test zero consecutive errors # d.addCallback(self._check_value_equal, 'consecutive_errors', 0, omci_cc.consecutive_errors) def test_rx_unknown_me(self): # ME without a known decoder self.setup_one_of_each() omci_cc = self.onu_handler.omci_cc omci_cc.enabled = True snapshot = self._snapshot_stats() # This is the ID ------+ # v msg = '00fc2e0a00020000ff780000e00000010000000c' \ '0000000000000000000000000000000000000000' \ '00000028' omci_cc.receive_message(hex2raw(msg)) # Note: After successful frame decode, a lookup of the corresponding request by # TID is performed. None should be found, so we should see the Rx Unknown TID # increment. self.assertEqual(omci_cc.rx_frames, snapshot['rx_frames']) self.assertEqual(omci_cc.rx_unknown_me, snapshot['rx_unknown_me'] + 1) self.assertEqual(omci_cc.rx_unknown_tid, snapshot['rx_unknown_tid'] + 1) self.assertEqual(omci_cc.rx_onu_frames, snapshot['rx_onu_frames']) self.assertEqual(omci_cc.consecutive_errors, 0) def test_rx_decode_unknown_me(self): # ME without a known decoder self.setup_one_of_each() omci_cc = self.onu_handler.omci_cc omci_cc.enabled = True snapshot = self._snapshot_stats() # This is a MIB Upload Next Response. Where we would probably first see an # unknown Class ID # # This is the ID ------+ # v msg = '00fc2e0a00020000ff780001e000' blob = '00010000000c0000000000000000000000000000000000000000' msg += blob + '00000028' # Dig into the internal method so we can get the returned frame frame = omci_cc._decode_unknown_me(hex2raw(msg)) self.assertEqual(frame.fields['transaction_id'], 0x00fc) self.assertEqual(frame.fields['message_type'], 0x2e) omci_fields = frame.fields['omci_message'].fields self.assertEqual(omci_fields['entity_class'], 0x0002) self.assertEqual(omci_fields['entity_id'], 0x00) self.assertEqual(omci_fields['object_entity_class'], 0x0ff78) self.assertEqual(omci_fields['object_entity_id'], 0x01) self.assertEqual(omci_fields['object_attributes_mask'], 0xe000) data_fields = omci_fields['object_data'] decoded_blob = data_fields.get(UNKNOWN_CLASS_ATTRIBUTE_KEY) self.assertIsNotNone(decoded_blob) self.assertEqual(decoded_blob, blob) def test_flush(self): # Test flush of autonomous ONU queues self.setup_one_of_each() omci_cc = self.onu_handler.omci_cc omci_cc.enabled = True snapshot = self._snapshot_stats() # TODO: add more self.assertTrue(True) # TODO: Implement def test_avc_rx(self): # Test flush of autonomous ONU queues self.setup_one_of_each() omci_cc = self.onu_handler.omci_cc omci_cc.enabled = True snapshot = self._snapshot_stats() # TODO: add more self.assertTrue(True) # TODO: Implement def test_rx_discard_if_disabled(self): # ME without a known decoder self.setup_one_of_each() omci_cc = self.onu_handler.omci_cc omci_cc.enabled = False snapshot = self._snapshot_stats() msg = '00fc2e0a00020000ff780000e00000010000000c' \ '0000000000000000000000000000000000000000' \ '00000028105a86ef' omci_cc.receive_message(hex2raw(msg)) # Note: No counter increments self.assertEqual(omci_cc.rx_frames, snapshot['rx_frames']) self.assertEqual(omci_cc.rx_unknown_me, snapshot['rx_unknown_me']) self.assertEqual(omci_cc.rx_unknown_tid, snapshot['rx_unknown_tid']) self.assertEqual(omci_cc.rx_onu_frames, snapshot['rx_onu_frames']) self.assertEqual(omci_cc.rx_unknown_tid, snapshot['rx_unknown_tid']) def test_omci_alarm_decode(self): """ This test covers an issue discovered in Sept 2018 (JIRA-1213). It was an exception during frame decode. """ self.setup_one_of_each() omci_cc = self.onu_handler.omci_cc omci_cc.enabled = True # Frame from the JIRA issue msg = '0000100a000b0102800000000000000000000000' \ '0000000000000000000000000000000000000015' \ '000000282d3ae0a6' results = omci_cc.receive_message(hex2raw(msg)) self.assertTrue(True, 'Truth is the truth') def test_rx_decode_onu_g(self): self.setup_one_of_each() omci_cc = self.onu_handler.omci_cc omci_cc.enabled = True snapshot = self._snapshot_stats() msg = '001e2e0a0002000001000000e000424657530000' \ '0000000000000000000000324246575300107496' \ '00000028e7fb4a91' omci_cc.receive_message(hex2raw(msg)) # Note: No counter increments self.assertEqual(omci_cc.rx_frames, snapshot['rx_frames'] + 1) self.assertEqual(omci_cc.rx_unknown_me, snapshot['rx_unknown_me']) self.assertEqual(omci_cc.rx_unknown_tid, snapshot['rx_unknown_tid'] + 1) self.assertEqual(omci_cc.rx_onu_frames, snapshot['rx_onu_frames']) def test_rx_decode_extvlantagging(self): self.setup_one_of_each() omci_cc = self.onu_handler.omci_cc omci_cc.enabled = True snapshot = self._snapshot_stats() msg = '030a290a00ab0201000d00000000001031323334' \ '3536373839303132333435363738393031323334' \ '000000281166d283' omci_cc.receive_message(hex2raw(msg)) self.assertEqual(omci_cc.rx_frames, snapshot['rx_frames'] + 1) self.assertEqual(omci_cc.rx_unknown_me, snapshot['rx_unknown_me']) self.assertEqual(omci_cc.rx_unknown_tid, snapshot['rx_unknown_tid'] + 1) self.assertEqual(omci_cc.rx_onu_frames, snapshot['rx_onu_frames']) def _check_vlan_tag_op(self, results, attr, expected): omci_msg = results.fields['omci_message'] data = omci_msg.fields['data'] val = data[attr] self.assertEqual(expected, val) return results @skip('for unknow omci failure') #@deferred() def test_rx_table_get_extvlantagging(self): self.setup_one_of_each() onu = self.onu_handler.onu_mock entity_id = 1 vlan_tag_op1 = VlanTaggingOperation( filter_outer_priority=15, filter_outer_vid=4096, filter_outer_tpid_de=2, filter_inner_priority=15, filter_inner_vid=4096, filter_inner_tpid_de=0, filter_ether_type=0, treatment_tags_to_remove=0, treatment_outer_priority=15, treatment_outer_vid=1234, treatment_outer_tpid_de=0, treatment_inner_priority=0, treatment_inner_vid=4091, treatment_inner_tpid_de=4, ) vlan_tag_op2 = VlanTaggingOperation( filter_outer_priority=14, filter_outer_vid=1234, filter_outer_tpid_de=5, filter_inner_priority=1, filter_inner_vid=2345, filter_inner_tpid_de=1, filter_ether_type=0, treatment_tags_to_remove=1, treatment_outer_priority=15, treatment_outer_vid=2222, treatment_outer_tpid_de=1, treatment_inner_priority=1, treatment_inner_vid=3333, treatment_inner_tpid_de=5, ) vlan_tag_op3 = VlanTaggingOperation( filter_outer_priority=13, filter_outer_vid=55, filter_outer_tpid_de=1, filter_inner_priority=7, filter_inner_vid=4567, filter_inner_tpid_de=1, filter_ether_type=0, treatment_tags_to_remove=1, treatment_outer_priority=2, treatment_outer_vid=1111, treatment_outer_tpid_de=1, treatment_inner_priority=1, treatment_inner_vid=3131, treatment_inner_tpid_de=5, ) tbl = [vlan_tag_op1, vlan_tag_op2, vlan_tag_op3] tblstr = str(vlan_tag_op1) + str(vlan_tag_op2) + str(vlan_tag_op3) onu._omci_response[OP.Get.value][ ExtendedVlanTaggingOperationConfigurationData.class_id] = { entity_id: OmciFrame( transaction_id=0, message_type=OmciGetResponse.message_id, omci_message=OmciGetResponse( entity_class= ExtendedVlanTaggingOperationConfigurationData.class_id, entity_id=1, success_code=RC.Success.value, attributes_mask= ExtendedVlanTaggingOperationConfigurationData.mask_for( 'received_frame_vlan_tagging_operation_table'), data={ 'received_frame_vlan_tagging_operation_table': 16 * len(tbl) })) } rsp1 = binascii.a2b_hex(hexify(tblstr[0:OmciTableField.PDU_SIZE])) rsp2 = binascii.a2b_hex(hexify(tblstr[OmciTableField.PDU_SIZE:])) onu._omci_response[OP.GetNext.value][ ExtendedVlanTaggingOperationConfigurationData.class_id] = { entity_id: { 0: { 'failures': 2, 'frame': OmciFrame( transaction_id=0, message_type=OmciGetNextResponse.message_id, omci_message=OmciGetNextResponse( entity_class= ExtendedVlanTaggingOperationConfigurationData. class_id, entity_id=1, success_code=RC.Success.value, attributes_mask= ExtendedVlanTaggingOperationConfigurationData. mask_for( 'received_frame_vlan_tagging_operation_table' ), data={ 'received_frame_vlan_tagging_operation_table': rsp1 })) }, 1: OmciFrame( transaction_id=0, message_type=OmciGetNextResponse.message_id, omci_message=OmciGetNextResponse( entity_class= ExtendedVlanTaggingOperationConfigurationData. class_id, entity_id=1, success_code=RC.Success.value, attributes_mask= ExtendedVlanTaggingOperationConfigurationData. mask_for( 'received_frame_vlan_tagging_operation_table'), data={ 'received_frame_vlan_tagging_operation_table': rsp2 })) } } omci_cc = self.onu_handler.omci_cc omci_cc.enabled = True msg = ExtendedVlanTaggingOperationConfigurationDataFrame( entity_id, attributes={'received_frame_vlan_tagging_operation_table': True}) snapshot = self._snapshot_stats() frame = msg.get() d = omci_cc.send(frame, timeout=5.0) d.addCallbacks(self._is_omci_frame, self._default_errback, [OmciGetResponse]) d.addCallback(self._check_status, RC.Success) d.addCallback(self._check_stats, snapshot, 'tx_frames', snapshot['tx_frames'] + 5) d.addCallback(self._check_stats, snapshot, 'rx_frames', snapshot['rx_frames'] + 3) d.addCallback(self._check_stats, snapshot, 'rx_unknown_tid', snapshot['rx_unknown_tid']) d.addCallback(self._check_stats, snapshot, 'rx_onu_frames', snapshot['rx_onu_frames']) d.addCallback(self._check_stats, snapshot, 'rx_onu_discards', snapshot['rx_onu_discards']) d.addCallback(self._check_stats, snapshot, 'rx_unknown_me', snapshot['rx_unknown_me']) d.addCallback(self._check_stats, snapshot, 'rx_timeouts', snapshot['rx_timeouts'] + 2) d.addCallback(self._check_stats, snapshot, 'tx_errors', snapshot['tx_errors']) d.addCallback(self._check_stats, snapshot, 'consecutive_errors', 0) d.addCallback(self._check_vlan_tag_op, 'received_frame_vlan_tagging_operation_table', tbl) return d