From a559828bae4a5f46dc26d216564dc0eebf66f5a1 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Fri, 15 Feb 2019 13:59:46 -0800 Subject: [PATCH] Enable overriding interface counters OIDs (#98) * Add test for interface IN_OCTETS * Add OverlayAdpaterMIBEntry class * Refine * InterfacesMIB supports counter override * (reformat) * Add missing test data * Remvoe unused code * Refactor * (reformat) * InterfaceMIBObjects supports counter override --- src/ax_interface/mib.py | 62 ++++++++++++++---- src/sonic_ax_impl/mibs/__init__.py | 56 ++++++++++++++++ src/sonic_ax_impl/mibs/ietf/rfc1213.py | 91 ++++++++++++++++++-------- src/sonic_ax_impl/mibs/ietf/rfc2863.py | 89 +++++++++++++++++-------- tests/mock_tables/counters_db.json | 4 +- tests/mock_tables/dbconnector.py | 2 + tests/mock_tables/snmp_overlay_db.json | 10 +++ tests/test_hc_interfaces.py | 40 ++++++++++- tests/test_interfaces.py | 40 +++++++++++ 9 files changed, 324 insertions(+), 70 deletions(-) create mode 100644 tests/mock_tables/snmp_overlay_db.json diff --git a/src/ax_interface/mib.py b/src/ax_interface/mib.py index 8512f8199394..ce3f718ce4f5 100644 --- a/src/ax_interface/mib.py +++ b/src/ax_interface/mib.py @@ -86,22 +86,16 @@ def __new__(mcs, name, bases, attributes, prefix=None): for me in vars(cls).values(): if isinstance(me, MIBEntry): setattr(me, MIBEntry.PREFIXLEN, _prefix_len + len(me.subtree)) + setattr(me, MIBEntry.PREFIX, _prefix + me.subtree) sub_ids = {} - # gather all static MIB entries. - static_entries = (v for v in vars(cls).values() if type(v) is MIBEntry) - for me in static_entries: + # gather all MIB entries. + mib_entries = (v for v in vars(cls).values() if isinstance(v, MIBEntry)) + for me in mib_entries: sub_ids.update({_prefix + me.subtree: me}) prefixes.append(_prefix + me.subtree) - # gather all subtree IDs - # to support dynamic sub_id in the subtree, not to pour leaves into dictionary - subtree_entries = (v for v in vars(cls).values() if type(v) is SubtreeMIBEntry) - for sme in subtree_entries: - sub_ids.update({_prefix + sme.subtree: sme}) - prefixes.append(_prefix + sme.subtree) - # gather all updater instances updaters = set(v for k, v in vars(cls).items() if isinstance(v, MIBUpdater)) @@ -134,6 +128,7 @@ def __init__(cls, name, bases, attributes, prefix=None): class MIBEntry: PREFIXLEN = '__prefixlen__' + PREFIX = '__prefix__' def __init__(self, subtree, value_type, callable_, *args): """ @@ -155,7 +150,7 @@ def __init__(self, subtree, value_type, callable_, *args): raise ValueError("Third argument must be a callable object--got literal instead.") self._callable_ = callable_ self._callable_args = args - self.subtree = subtree + self.subtree_str = subtree self.value_type = value_type self.subtree = util.oid2tuple(subtree, dot_prefix=False) @@ -174,8 +169,11 @@ def replace_sub_id(self, oid_key, sub_id): def get_next(self, sub_id): return None + def get_prefix(self): + return getattr(self, MIBEntry.PREFIX) + class SubtreeMIBEntry(MIBEntry): - def __init__(self, subtree, iterator, value_type, callable_, *args, updater=None): + def __init__(self, subtree, iterator, value_type, callable_, *args): super().__init__(subtree, value_type, callable_, *args) self.iterator = iterator @@ -209,6 +207,46 @@ def get_next(self, sub_id): logger.exception("SubtreeMIBEntry.get_next() caught an unexpected exception during iterator.get_next()") return None +# Define MIB entry (subtree) with a callable, which accepts a starndard OID tuple as a paramter +class OidMIBEntry(MIBEntry): + def __init__(self, subtree, value_type, callable_): + super().__init__(subtree, value_type, callable_) + + def __iter__(self): + raise NotImplementedError + + def __call__(self, sub_id): + return self._callable_.__call__(self.get_prefix() + sub_id) + +class OverlayAdpaterMIBEntry(MIBEntry): + def __init__(self, underlay_mibentry, overlay_mibentry): + assert underlay_mibentry.value_type == overlay_mibentry.value_type + assert underlay_mibentry.subtree == overlay_mibentry.subtree + + super().__init__(underlay_mibentry.subtree_str, underlay_mibentry.value_type, underlay_mibentry._callable_) + self.underlay_mibentry = underlay_mibentry + self.overlay_mibentry = overlay_mibentry + + def __setattr__(self, name, value): + super().__setattr__(name, value) + if name.startswith('__') and name.endswith('__'): + setattr(self.underlay_mibentry, name, value) + setattr(self.overlay_mibentry, name, value) + + def __iter__(self): + return self.underlay_mibentry.__iter__() + + def __call__(self, sub_id=None): + overlay_val = self.overlay_mibentry(sub_id) + if overlay_val is not None: + return overlay_val + + underlay_val = self.underlay_mibentry(sub_id) + return underlay_val + + def get_next(self, sub_id): + return self.underlay_mibentry.get_next(sub_id) + class MIBTable(dict): """ Simplistic LUT for Get/GetNext OID. Interprets iterables as keys and implements the same interfaces as dict's. diff --git a/src/sonic_ax_impl/mibs/__init__.py b/src/sonic_ax_impl/mibs/__init__.py index d6f183c52b82..6fc5286690ce 100644 --- a/src/sonic_ax_impl/mibs/__init__.py +++ b/src/sonic_ax_impl/mibs/__init__.py @@ -4,6 +4,8 @@ from swsssdk import SonicV2Connector from swsssdk import port_util from swsssdk.port_util import get_index, get_index_from_str +from ax_interface.mib import MIBUpdater +from ax_interface.util import oid2tuple from sonic_ax_impl import logger COUNTERS_PORT_NAME_MAP = b'COUNTERS_PORT_NAME_MAP' @@ -16,6 +18,7 @@ COUNTERS_DB = 'COUNTERS_DB' CONFIG_DB = 'CONFIG_DB' STATE_DB = 'STATE_DB' +SNMP_OVERLAY_DB = 'SNMP_OVERLAY_DB' TABLE_NAME_SEPARATOR_COLON = ':' TABLE_NAME_SEPARATOR_VBAR = '|' @@ -363,3 +366,56 @@ def get_transceiver_sensor_sub_id(ifindex, sensor): transceiver_oid, = get_transceiver_sub_id(ifindex) return (transceiver_oid + SENSOR_PART_ID_MAP[sensor], ) + +class RedisOidTreeUpdater(MIBUpdater): + def __init__(self, prefix_str): + super().__init__() + + self.db_conn = init_db() + if prefix_str.startswith('.'): + prefix_str = prefix_str[1:] + self.prefix_str = prefix_str + + def get_next(self, sub_id): + """ + :param sub_id: The 1-based sub-identifier query. + :return: the next sub id. + """ + raise NotImplementedError + + def reinit_data(self): + """ + Subclass update loopback information + """ + pass + + def update_data(self): + """ + Update redis (caches config) + Pulls the table references for each interface. + """ + self.oid_list = [] + self.oid_map = {} + + self.db_conn.connect(SNMP_OVERLAY_DB) + keys = self.db_conn.keys(SNMP_OVERLAY_DB, self.prefix_str + '*') + # TODO: fix db_conn.keys to return empty list instead of None if there is no match + if keys is None: + keys = [] + + for key in keys: + key = key.decode() + oid = oid2tuple(key, dot_prefix=False) + self.oid_list.append(oid) + value = self.db_conn.get_all(SNMP_OVERLAY_DB, key) + if value[b'type'] in [b'COUNTER_32', b'COUNTER_64']: + self.oid_map[oid] = int(value[b'data']) + else: + raise ValueError("Invalid value type") + + self.oid_list.sort() + + def get_oidvalue(self, oid): + if oid not in self.oid_map: + return None + return self.oid_map[oid] diff --git a/src/sonic_ax_impl/mibs/ietf/rfc1213.py b/src/sonic_ax_impl/mibs/ietf/rfc1213.py index 8f2a98ded2c3..b69fe39fc5bb 100644 --- a/src/sonic_ax_impl/mibs/ietf/rfc1213.py +++ b/src/sonic_ax_impl/mibs/ietf/rfc1213.py @@ -4,11 +4,10 @@ from bisect import bisect_right from sonic_ax_impl import mibs -from ax_interface import MIBMeta, ValueType, MIBUpdater, MIBEntry, SubtreeMIBEntry +from ax_interface.mib import MIBMeta, ValueType, MIBUpdater, MIBEntry, SubtreeMIBEntry, OverlayAdpaterMIBEntry, OidMIBEntry from ax_interface.encodings import ObjectIdentifier from ax_interface.util import mac_decimals, ip2tuple_v4 - @unique class DbTables(int, Enum): """ @@ -271,6 +270,7 @@ def get_counter(self, sub_id, table_name): :param table_name: the redis table (either IntEnum or string literal) to query. :return: the counter for the respective sub_id/table. """ + oid = self.get_oid(sub_id) if not oid: return @@ -423,7 +423,6 @@ def get_if_type(self, sub_id): else: return IfTypes.ethernetCsmacd - class InterfacesMIB(metaclass=MIBMeta, prefix='.1.3.6.1.2.1.2'): """ 'interfaces' https://tools.ietf.org/html/rfc1213#section-3.5 @@ -431,6 +430,8 @@ class InterfacesMIB(metaclass=MIBMeta, prefix='.1.3.6.1.2.1.2'): if_updater = InterfacesUpdater() + oidtree_updater = mibs.RedisOidTreeUpdater(prefix_str='1.3.6.1.2.1.2') + # (subtree, value_type, callable_, *args, handler=None) ifNumber = MIBEntry('1', ValueType.INTEGER, if_updater.get_if_number) @@ -467,52 +468,88 @@ class InterfacesMIB(metaclass=MIBMeta, prefix='.1.3.6.1.2.1.2'): SubtreeMIBEntry('2.1.9', if_updater, ValueType.TIME_TICKS, lambda sub_id: 0) ifInOctets = \ - SubtreeMIBEntry('2.1.10', if_updater, ValueType.COUNTER_32, if_updater.get_counter, - DbTables(10)) + OverlayAdpaterMIBEntry( + SubtreeMIBEntry('2.1.10', if_updater, ValueType.COUNTER_32, if_updater.get_counter, + DbTables(10)), + OidMIBEntry('2.1.10', ValueType.COUNTER_32, oidtree_updater.get_oidvalue) + ) ifInUcastPkts = \ - SubtreeMIBEntry('2.1.11', if_updater, ValueType.COUNTER_32, if_updater.get_counter, - DbTables(11)) + OverlayAdpaterMIBEntry( + SubtreeMIBEntry('2.1.11', if_updater, ValueType.COUNTER_32, if_updater.get_counter, + DbTables(11)), + OidMIBEntry('2.1.11', ValueType.COUNTER_32, oidtree_updater.get_oidvalue) + ) ifInNUcastPkts = \ - SubtreeMIBEntry('2.1.12', if_updater, ValueType.COUNTER_32, if_updater.get_counter, - DbTables(12)) + OverlayAdpaterMIBEntry( + SubtreeMIBEntry('2.1.12', if_updater, ValueType.COUNTER_32, if_updater.get_counter, + DbTables(12)), + OidMIBEntry('2.1.12', ValueType.COUNTER_32, oidtree_updater.get_oidvalue) + ) ifInDiscards = \ - SubtreeMIBEntry('2.1.13', if_updater, ValueType.COUNTER_32, if_updater.get_counter, - DbTables(13)) + OverlayAdpaterMIBEntry( + SubtreeMIBEntry('2.1.13', if_updater, ValueType.COUNTER_32, if_updater.get_counter, + DbTables(13)), + OidMIBEntry('2.1.13', ValueType.COUNTER_32, oidtree_updater.get_oidvalue) + ) ifInErrors = \ - SubtreeMIBEntry('2.1.14', if_updater, ValueType.COUNTER_32, if_updater.get_counter, - DbTables(14)) + OverlayAdpaterMIBEntry( + SubtreeMIBEntry('2.1.14', if_updater, ValueType.COUNTER_32, if_updater.get_counter, + DbTables(14)), + OidMIBEntry('2.1.14', ValueType.COUNTER_32, oidtree_updater.get_oidvalue) + ) ifInUnknownProtos = \ - SubtreeMIBEntry('2.1.15', if_updater, ValueType.COUNTER_32, if_updater.get_counter, - DbTables(15)) + OverlayAdpaterMIBEntry( + SubtreeMIBEntry('2.1.15', if_updater, ValueType.COUNTER_32, if_updater.get_counter, + DbTables(15)), + OidMIBEntry('2.1.15', ValueType.COUNTER_32, oidtree_updater.get_oidvalue) + ) ifOutOctets = \ - SubtreeMIBEntry('2.1.16', if_updater, ValueType.COUNTER_32, if_updater.get_counter, - DbTables(16)) + OverlayAdpaterMIBEntry( + SubtreeMIBEntry('2.1.16', if_updater, ValueType.COUNTER_32, if_updater.get_counter, + DbTables(16)), + OidMIBEntry('2.1.16', ValueType.COUNTER_32, oidtree_updater.get_oidvalue) + ) ifOutUcastPkts = \ - SubtreeMIBEntry('2.1.17', if_updater, ValueType.COUNTER_32, if_updater.get_counter, - DbTables(17)) + OverlayAdpaterMIBEntry( + SubtreeMIBEntry('2.1.17', if_updater, ValueType.COUNTER_32, if_updater.get_counter, + DbTables(17)), + OidMIBEntry('2.1.17', ValueType.COUNTER_32, oidtree_updater.get_oidvalue) + ) ifOutNUcastPkts = \ - SubtreeMIBEntry('2.1.18', if_updater, ValueType.COUNTER_32, if_updater.get_counter, - DbTables(18)) + OverlayAdpaterMIBEntry( + SubtreeMIBEntry('2.1.18', if_updater, ValueType.COUNTER_32, if_updater.get_counter, + DbTables(18)), + OidMIBEntry('2.1.18', ValueType.COUNTER_32, oidtree_updater.get_oidvalue) + ) ifOutDiscards = \ - SubtreeMIBEntry('2.1.19', if_updater, ValueType.COUNTER_32, if_updater.get_counter, - DbTables(19)) + OverlayAdpaterMIBEntry( + SubtreeMIBEntry('2.1.19', if_updater, ValueType.COUNTER_32, if_updater.get_counter, + DbTables(19)), + OidMIBEntry('2.1.19', ValueType.COUNTER_32, oidtree_updater.get_oidvalue) + ) ifOutErrors = \ - SubtreeMIBEntry('2.1.20', if_updater, ValueType.COUNTER_32, if_updater.get_counter, - DbTables(20)) + OverlayAdpaterMIBEntry( + SubtreeMIBEntry('2.1.20', if_updater, ValueType.COUNTER_32, if_updater.get_counter, + DbTables(20)), + OidMIBEntry('2.1.20', ValueType.COUNTER_32, oidtree_updater.get_oidvalue) + ) ifOutQLen = \ - SubtreeMIBEntry('2.1.21', if_updater, ValueType.GAUGE_32, if_updater.get_counter, - DbTables(21)) + OverlayAdpaterMIBEntry( + SubtreeMIBEntry('2.1.21', if_updater, ValueType.GAUGE_32, if_updater.get_counter, + DbTables(21)), + OidMIBEntry('2.1.21', ValueType.GAUGE_32, oidtree_updater.get_oidvalue) + ) # FIXME Placeholder ifSpecific = \ diff --git a/src/sonic_ax_impl/mibs/ietf/rfc2863.py b/src/sonic_ax_impl/mibs/ietf/rfc2863.py index 0c704e52d9e7..f584bc2dc465 100644 --- a/src/sonic_ax_impl/mibs/ietf/rfc2863.py +++ b/src/sonic_ax_impl/mibs/ietf/rfc2863.py @@ -2,8 +2,7 @@ from bisect import bisect_right from sonic_ax_impl import mibs -from ax_interface import MIBMeta, MIBUpdater, ValueType, SubtreeMIBEntry - +from ax_interface.mib import MIBMeta, MIBUpdater, ValueType, SubtreeMIBEntry, OverlayAdpaterMIBEntry, OidMIBEntry @unique class DbTables32(int, Enum): @@ -239,6 +238,8 @@ class InterfaceMIBObjects(metaclass=MIBMeta, prefix='.1.3.6.1.2.1.31.1'): """ if_updater = InterfaceMIBUpdater() + oidtree_updater = mibs.RedisOidTreeUpdater(prefix_str='1.3.6.1.2.1.31.1') + # ifXTable = '1' # ifXEntry = '1.1' @@ -246,52 +247,88 @@ class InterfaceMIBObjects(metaclass=MIBMeta, prefix='.1.3.6.1.2.1.31.1'): SubtreeMIBEntry('1.1.1', if_updater, ValueType.OCTET_STRING, if_updater.interface_name) ifInMulticastPkts = \ - SubtreeMIBEntry('1.1.2', if_updater, ValueType.COUNTER_32, if_updater.get_counter32, - DbTables32(2)) + OverlayAdpaterMIBEntry( + SubtreeMIBEntry('1.1.2', if_updater, ValueType.COUNTER_32, if_updater.get_counter32, + DbTables32(2)), + OidMIBEntry('1.1.2', ValueType.COUNTER_32, oidtree_updater.get_oidvalue) + ) ifInBroadcastPkts = \ - SubtreeMIBEntry('1.1.3', if_updater, ValueType.COUNTER_32, if_updater.get_counter32, - DbTables32(3)) + OverlayAdpaterMIBEntry( + SubtreeMIBEntry('1.1.3', if_updater, ValueType.COUNTER_32, if_updater.get_counter32, + DbTables32(3)), + OidMIBEntry('1.1.3', ValueType.COUNTER_32, oidtree_updater.get_oidvalue) + ) ifOutMulticastPkts = \ - SubtreeMIBEntry('1.1.4', if_updater, ValueType.COUNTER_32, if_updater.get_counter32, - DbTables32(4)) + OverlayAdpaterMIBEntry( + SubtreeMIBEntry('1.1.4', if_updater, ValueType.COUNTER_32, if_updater.get_counter32, + DbTables32(4)), + OidMIBEntry('1.1.4', ValueType.COUNTER_32, oidtree_updater.get_oidvalue) + ) ifOutBroadcastPkts = \ - SubtreeMIBEntry('1.1.5', if_updater, ValueType.COUNTER_32, if_updater.get_counter32, - DbTables32(5)) + OverlayAdpaterMIBEntry( + SubtreeMIBEntry('1.1.5', if_updater, ValueType.COUNTER_32, if_updater.get_counter32, + DbTables32(5)), + OidMIBEntry('1.1.5', ValueType.COUNTER_32, oidtree_updater.get_oidvalue) + ) ifHCInOctets = \ - SubtreeMIBEntry('1.1.6', if_updater, ValueType.COUNTER_64, if_updater.get_counter64, - DbTables64(6)) + OverlayAdpaterMIBEntry( + SubtreeMIBEntry('1.1.6', if_updater, ValueType.COUNTER_64, if_updater.get_counter64, + DbTables64(6)), + OidMIBEntry('1.1.6', ValueType.COUNTER_64, oidtree_updater.get_oidvalue) + ) ifHCInUcastPkts = \ - SubtreeMIBEntry('1.1.7', if_updater, ValueType.COUNTER_64, if_updater.get_counter64, - DbTables64(7)) + OverlayAdpaterMIBEntry( + SubtreeMIBEntry('1.1.7', if_updater, ValueType.COUNTER_64, if_updater.get_counter64, + DbTables64(7)), + OidMIBEntry('1.1.7', ValueType.COUNTER_64, oidtree_updater.get_oidvalue) + ) ifHCInMulticastPkts = \ - SubtreeMIBEntry('1.1.8', if_updater, ValueType.COUNTER_64, if_updater.get_counter64, - DbTables64(8)) + OverlayAdpaterMIBEntry( + SubtreeMIBEntry('1.1.8', if_updater, ValueType.COUNTER_64, if_updater.get_counter64, + DbTables64(8)), + OidMIBEntry('1.1.8', ValueType.COUNTER_64, oidtree_updater.get_oidvalue) + ) ifHCInBroadcastPkts = \ - SubtreeMIBEntry('1.1.9', if_updater, ValueType.COUNTER_64, if_updater.get_counter64, - DbTables64(9)) + OverlayAdpaterMIBEntry( + SubtreeMIBEntry('1.1.9', if_updater, ValueType.COUNTER_64, if_updater.get_counter64, + DbTables64(9)), + OidMIBEntry('1.1.9', ValueType.COUNTER_64, oidtree_updater.get_oidvalue) + ) ifHCOutOctets = \ - SubtreeMIBEntry('1.1.10', if_updater, ValueType.COUNTER_64, if_updater.get_counter64, - DbTables64(10)) + OverlayAdpaterMIBEntry( + SubtreeMIBEntry('1.1.10', if_updater, ValueType.COUNTER_64, if_updater.get_counter64, + DbTables64(10)), + OidMIBEntry('1.1.10', ValueType.COUNTER_64, oidtree_updater.get_oidvalue) + ) ifHCOutUcastPkts = \ - SubtreeMIBEntry('1.1.11', if_updater, ValueType.COUNTER_64, if_updater.get_counter64, - DbTables64(11)) + OverlayAdpaterMIBEntry( + SubtreeMIBEntry('1.1.11', if_updater, ValueType.COUNTER_64, if_updater.get_counter64, + DbTables64(11)), + OidMIBEntry('1.1.11', ValueType.COUNTER_64, oidtree_updater.get_oidvalue) + ) ifHCOutMulticastPkts = \ - SubtreeMIBEntry('1.1.12', if_updater, ValueType.COUNTER_64, if_updater.get_counter64, - DbTables64(12)) + OverlayAdpaterMIBEntry( + SubtreeMIBEntry('1.1.12', if_updater, ValueType.COUNTER_64, if_updater.get_counter64, + DbTables64(12)), + OidMIBEntry('1.1.12', ValueType.COUNTER_64, oidtree_updater.get_oidvalue) + ) ifHCOutBroadcastPkts = \ - SubtreeMIBEntry('1.1.13', if_updater, ValueType.COUNTER_64, if_updater.get_counter64, - DbTables64(13)) + OverlayAdpaterMIBEntry( + SubtreeMIBEntry('1.1.13', if_updater, ValueType.COUNTER_64, if_updater.get_counter64, + DbTables64(13)), + OidMIBEntry('1.1.13', ValueType.COUNTER_64, oidtree_updater.get_oidvalue) + ) """ ifLinkUpDownTrapEnable OBJECT-TYPE diff --git a/tests/mock_tables/counters_db.json b/tests/mock_tables/counters_db.json index ae0a6a49f73c..8aba20750127 100644 --- a/tests/mock_tables/counters_db.json +++ b/tests/mock_tables/counters_db.json @@ -1086,7 +1086,7 @@ "SAI_PORT_STAT_ETHER_IN_PKTS_2048_TO_4095_OCTETS": "0", "SAI_PORT_STAT_IP_OUT_NON_UCAST_PKTS": "0", "SAI_PORT_STAT_ETHER_STATS_JABBERS": "0", - "SAI_PORT_STAT_IF_IN_OCTETS": "0", + "SAI_PORT_STAT_IF_IN_OCTETS": "4321", "SAI_PORT_STAT_IPV6_IN_MCAST_PKTS": "0", "SAI_PORT_STAT_ETHER_STATS_PKTS_65_TO_127_OCTETS": "0", "SAI_PORT_STAT_IF_OUT_QLEN": "0", @@ -3262,7 +3262,7 @@ "SAI_PORT_STAT_ETHER_IN_PKTS_2048_TO_4095_OCTETS": "0", "SAI_PORT_STAT_IP_OUT_NON_UCAST_PKTS": "0", "SAI_PORT_STAT_ETHER_STATS_JABBERS": "0", - "SAI_PORT_STAT_IF_IN_OCTETS": "0", + "SAI_PORT_STAT_IF_IN_OCTETS": "40321", "SAI_PORT_STAT_IPV6_IN_MCAST_PKTS": "0", "SAI_PORT_STAT_ETHER_STATS_PKTS_65_TO_127_OCTETS": "0", "SAI_PORT_STAT_IF_OUT_QLEN": "0", diff --git a/tests/mock_tables/dbconnector.py b/tests/mock_tables/dbconnector.py index 073ed293dbf6..6662168f0040 100644 --- a/tests/mock_tables/dbconnector.py +++ b/tests/mock_tables/dbconnector.py @@ -44,6 +44,8 @@ def __init__(self, *args, **kwargs): fname = 'config_db.json' elif db == 6: fname = 'state_db.json' + elif db == 7: + fname = 'snmp_overlay_db.json' else: raise ValueError("Invalid db") self.pubsub = MockPubSub() diff --git a/tests/mock_tables/snmp_overlay_db.json b/tests/mock_tables/snmp_overlay_db.json new file mode 100644 index 000000000000..a8f10b870971 --- /dev/null +++ b/tests/mock_tables/snmp_overlay_db.json @@ -0,0 +1,10 @@ +{ + "1.3.6.1.2.1.2.2.1.10.1": { + "type": "COUNTER_32", + "data": "54321" + }, + "1.3.6.1.2.1.31.1.1.1.6.5": { + "type": "COUNTER_64", + "data": "654321" + } +} diff --git a/tests/test_hc_interfaces.py b/tests/test_hc_interfaces.py index 6d4e3d3144ad..eb629bc577f4 100644 --- a/tests/test_hc_interfaces.py +++ b/tests/test_hc_interfaces.py @@ -23,9 +23,7 @@ class TestGetNextPDU(TestCase): @classmethod def setUpClass(cls): cls.lut = MIBTable(rfc2863.InterfaceMIBObjects) - - def test_update(self): - for updater in self.lut.updater_instances: + for updater in cls.lut.updater_instances: updater.update_data() updater.reinit_data() updater.update_data() @@ -204,3 +202,39 @@ def test_mgmt_iface_alias(self): self.assertEqual(value0.type_, ValueType.OCTET_STRING) self.assertEqual(str(value0.name), str(ObjectIdentifier(11, 0, 1, 0, (1, 3, 6, 1, 2, 1, 31, 1, 1, 1, 1, 10001)))) self.assertEqual(str(value0.data), 'mgmt1') + + def test_in_octets(self): + """ + For a port with no speed in the db the result should be 0 + """ + oid = ObjectIdentifier(12, 0, 0, 0, (1, 3, 6, 1, 2, 1, 31, 1, 1, 1, 6, 1)) + get_pdu = GetPDU( + header=PDUHeader(1, PduTypes.GET, 16, 0, 42, 0, 0, 0), + oids=[oid] + ) + + response = get_pdu.make_response(self.lut) + print(response) + + value0 = response.values[0] + self.assertEqual(value0.type_, ValueType.COUNTER_64) + self.assertEqual(str(value0.name), str(ObjectIdentifier(12, 0, 1, 0, (1, 3, 6, 1, 2, 1, 31, 1, 1, 1, 6, 1)))) + self.assertEqual(value0.data, 4321) + + def test_in_octets_override(self): + """ + For a port with no speed in the db the result should be 0 + """ + oid = ObjectIdentifier(12, 0, 0, 0, (1, 3, 6, 1, 2, 1, 31, 1, 1, 1, 6, 5)) + get_pdu = GetPDU( + header=PDUHeader(1, PduTypes.GET, 16, 0, 42, 0, 0, 0), + oids=[oid] + ) + + response = get_pdu.make_response(self.lut) + print(response) + + value0 = response.values[0] + self.assertEqual(value0.type_, ValueType.COUNTER_64) + self.assertEqual(str(value0.name), str(ObjectIdentifier(12, 0, 1, 0, (1, 3, 6, 1, 2, 1, 31, 1, 1, 1, 6, 5)))) + self.assertEqual(value0.data, 654321) diff --git a/tests/test_interfaces.py b/tests/test_interfaces.py index 815b82080a28..1e0d7b988a0d 100644 --- a/tests/test_interfaces.py +++ b/tests/test_interfaces.py @@ -21,6 +21,10 @@ class TestGetNextPDU(TestCase): @classmethod def setUpClass(cls): cls.lut = MIBTable(rfc1213.InterfacesMIB) + for updater in cls.lut.updater_instances: + updater.update_data() + updater.reinit_data() + updater.update_data() def test_getnextpdu_noneifindex(self): # oid.include = 1 @@ -303,3 +307,39 @@ def test_mgmt_iface_admin_status(self): self.assertEqual(value0.type_, ValueType.INTEGER) self.assertEqual(str(value0.name), str(ObjectIdentifier(11, 0, 1, 0, (1, 3, 6, 1, 2, 1, 2, 2, 1, 7, 10001)))) self.assertEqual(value0.data, 1) + + def test_in_octets(self): + """ + For a port with no speed in the db the result should be 0 + """ + oid = ObjectIdentifier(11, 0, 0, 0, (1, 3, 6, 1, 2, 1, 2, 2, 1, 10, 5)) + get_pdu = GetPDU( + header=PDUHeader(1, PduTypes.GET, 16, 0, 42, 0, 0, 0), + oids=[oid] + ) + + response = get_pdu.make_response(self.lut) + print(response) + + value0 = response.values[0] + self.assertEqual(value0.type_, ValueType.COUNTER_32) + self.assertEqual(str(value0.name), str(ObjectIdentifier(11, 0, 1, 0, (1, 3, 6, 1, 2, 1, 2, 2, 1, 10, 5)))) + self.assertEqual(value0.data, 40321) + + def test_in_octets_override(self): + """ + For a port with no speed in the db the result should be 0 + """ + oid = ObjectIdentifier(11, 0, 0, 0, (1, 3, 6, 1, 2, 1, 2, 2, 1, 10, 1)) + get_pdu = GetPDU( + header=PDUHeader(1, PduTypes.GET, 16, 0, 42, 0, 0, 0), + oids=[oid] + ) + + response = get_pdu.make_response(self.lut) + print(response) + + value0 = response.values[0] + self.assertEqual(value0.type_, ValueType.COUNTER_32) + self.assertEqual(str(value0.name), str(ObjectIdentifier(11, 0, 1, 0, (1, 3, 6, 1, 2, 1, 2, 2, 1, 10, 1)))) + self.assertEqual(value0.data, 54321)