From 9999dae0186d4371d37272f270dec7983910354c Mon Sep 17 00:00:00 2001 From: Junhua Zhai Date: Sat, 28 May 2022 11:43:57 +0800 Subject: [PATCH] [counter] Support gearbox counters (#2218) 1/ Enable gearbox port counter collection in GB_COUNTERS_DB 2/ Enable gearbox macsec counter collection in GB_COUNTERS_DB --- .../flex_counter/flex_counter_manager.cpp | 20 ++- orchagent/flex_counter/flex_counter_manager.h | 8 ++ orchagent/flexcounterorch.cpp | 6 + orchagent/macsecorch.cpp | 60 +++++++-- orchagent/macsecorch.h | 11 ++ orchagent/port.h | 1 + orchagent/portsorch.cpp | 122 +++++++++++++++++- orchagent/portsorch.h | 10 ++ tests/mock_tests/database_config.json | 15 +++ tests/test_gearbox.py | 63 +++++++-- 10 files changed, 287 insertions(+), 29 deletions(-) diff --git a/orchagent/flex_counter/flex_counter_manager.cpp b/orchagent/flex_counter/flex_counter_manager.cpp index 3e61289acdda..ecccf415b2f7 100644 --- a/orchagent/flex_counter/flex_counter_manager.cpp +++ b/orchagent/flex_counter/flex_counter_manager.cpp @@ -89,14 +89,28 @@ FlexCounterManager::FlexCounterManager( const uint polling_interval, const bool enabled, FieldValueTuple fv_plugin) : + FlexCounterManager("FLEX_COUNTER_DB", group_name, stats_mode, + polling_interval, enabled, fv_plugin) +{ +} + +FlexCounterManager::FlexCounterManager( + const string& db_name, + const string& group_name, + const StatsMode stats_mode, + const uint polling_interval, + const bool enabled, + FieldValueTuple fv_plugin) : group_name(group_name), stats_mode(stats_mode), polling_interval(polling_interval), enabled(enabled), fv_plugin(fv_plugin), - flex_counter_db(new DBConnector("FLEX_COUNTER_DB", 0)), - flex_counter_group_table(new ProducerTable(flex_counter_db.get(), FLEX_COUNTER_GROUP_TABLE)), - flex_counter_table(new ProducerTable(flex_counter_db.get(), FLEX_COUNTER_TABLE)) + flex_counter_db(new DBConnector(db_name, 0)), + flex_counter_group_table(new ProducerTable(flex_counter_db.get(), + FLEX_COUNTER_GROUP_TABLE)), + flex_counter_table(new ProducerTable(flex_counter_db.get(), + FLEX_COUNTER_TABLE)) { SWSS_LOG_ENTER(); diff --git a/orchagent/flex_counter/flex_counter_manager.h b/orchagent/flex_counter/flex_counter_manager.h index 6a997f28f7df..38bf82905851 100644 --- a/orchagent/flex_counter/flex_counter_manager.h +++ b/orchagent/flex_counter/flex_counter_manager.h @@ -52,6 +52,14 @@ class FlexCounterManager FlexCounterManager() {} + FlexCounterManager( + const std::string& db_name, + const std::string& group_name, + const StatsMode stats_mode, + const uint polling_interval, + const bool enabled, + swss::FieldValueTuple fv_plugin = std::make_pair("","")); + FlexCounterManager(const FlexCounterManager&) = delete; FlexCounterManager& operator=(const FlexCounterManager&) = delete; virtual ~FlexCounterManager(); diff --git a/orchagent/flexcounterorch.cpp b/orchagent/flexcounterorch.cpp index a3770b76cb8a..29563d90a57c 100644 --- a/orchagent/flexcounterorch.cpp +++ b/orchagent/flexcounterorch.cpp @@ -196,6 +196,12 @@ void FlexCounterOrch::doTask(Consumer &consumer) vector fieldValues; fieldValues.emplace_back(FLEX_COUNTER_STATUS_FIELD, value); m_flexCounterGroupTable->set(flexCounterGroupMap[key], fieldValues); + + // Update FLEX_COUNTER_STATUS for gearbox port + if (key == PORT_KEY && gPortsOrch && gPortsOrch->isGearboxEnabled()) + { + gPortsOrch->setGearboxFlexCounterStatus(value == "enable"); + } } else if(field == FLEX_COUNTER_DELAY_STATUS_FIELD) { diff --git a/orchagent/macsecorch.cpp b/orchagent/macsecorch.cpp index 20b60577330a..70721979d277 100644 --- a/orchagent/macsecorch.cpp +++ b/orchagent/macsecorch.cpp @@ -621,6 +621,21 @@ MACsecOrch::MACsecOrch( StatsMode::READ, MACSEC_STAT_FLEX_COUNTER_POLLING_INTERVAL_MS, true), m_macsec_flow_stat_manager( + COUNTERS_MACSEC_FLOW_GROUP, + StatsMode::READ, + MACSEC_STAT_FLEX_COUNTER_POLLING_INTERVAL_MS, true), + m_gb_macsec_sa_attr_manager( + "GB_FLEX_COUNTER_DB", + COUNTERS_MACSEC_SA_ATTR_GROUP, + StatsMode::READ, + MACSEC_STAT_FLEX_COUNTER_POLLING_INTERVAL_MS, true), + m_gb_macsec_sa_stat_manager( + "GB_FLEX_COUNTER_DB", + COUNTERS_MACSEC_SA_GROUP, + StatsMode::READ, + MACSEC_STAT_FLEX_COUNTER_POLLING_INTERVAL_MS, true), + m_gb_macsec_flow_stat_manager( + "GB_FLEX_COUNTER_DB", COUNTERS_MACSEC_FLOW_GROUP, StatsMode::READ, MACSEC_STAT_FLEX_COUNTER_POLLING_INTERVAL_MS, true) @@ -2122,17 +2137,17 @@ task_process_status MACsecOrch::createMACsecSA( sc->m_sa_ids.erase(an); }); - installCounter(CounterType::MACSEC_SA_ATTR, direction, port_sci_an, sc->m_sa_ids[an], macsec_sa_attrs); + installCounter(ctx, CounterType::MACSEC_SA_ATTR, direction, port_sci_an, sc->m_sa_ids[an], macsec_sa_attrs); std::vector fvVector; fvVector.emplace_back("state", "ok"); if (direction == SAI_MACSEC_DIRECTION_EGRESS) { - installCounter(CounterType::MACSEC_SA, direction, port_sci_an, sc->m_sa_ids[an], macsec_sa_egress_stats); + installCounter(ctx, CounterType::MACSEC_SA, direction, port_sci_an, sc->m_sa_ids[an], macsec_sa_egress_stats); m_state_macsec_egress_sa.set(swss::join('|', port_name, sci, an), fvVector); } else { - installCounter(CounterType::MACSEC_SA, direction, port_sci_an, sc->m_sa_ids[an], macsec_sa_ingress_stats); + installCounter(ctx, CounterType::MACSEC_SA, direction, port_sci_an, sc->m_sa_ids[an], macsec_sa_ingress_stats); m_state_macsec_ingress_sa.set(swss::join('|', port_name, sci, an), fvVector); } @@ -2167,8 +2182,8 @@ task_process_status MACsecOrch::deleteMACsecSA( auto result = task_success; - uninstallCounter(CounterType::MACSEC_SA_ATTR, direction, port_sci_an, ctx.get_macsec_sc()->m_sa_ids[an]); - uninstallCounter(CounterType::MACSEC_SA, direction, port_sci_an, ctx.get_macsec_sc()->m_sa_ids[an]); + uninstallCounter(ctx, CounterType::MACSEC_SA_ATTR, direction, port_sci_an, ctx.get_macsec_sc()->m_sa_ids[an]); + uninstallCounter(ctx, CounterType::MACSEC_SA, direction, port_sci_an, ctx.get_macsec_sc()->m_sa_ids[an]); if (!deleteMACsecSA(ctx.get_macsec_sc()->m_sa_ids[an])) { SWSS_LOG_WARN("Cannot delete the MACsec SA %s.", port_sci_an.c_str()); @@ -2293,7 +2308,29 @@ bool MACsecOrch::deleteMACsecSA(sai_object_id_t sa_id) return true; } +FlexCounterManager& MACsecOrch::MACsecSaStatManager(MACsecOrchContext &ctx) +{ + if (ctx.get_gearbox_phy() != nullptr) + return m_gb_macsec_sa_stat_manager; + return m_macsec_sa_stat_manager; +} + +FlexCounterManager& MACsecOrch::MACsecSaAttrStatManager(MACsecOrchContext &ctx) +{ + if (ctx.get_gearbox_phy() != nullptr) + return m_gb_macsec_sa_attr_manager; + return m_macsec_sa_attr_manager; +} + +FlexCounterManager& MACsecOrch::MACsecFlowStatManager(MACsecOrchContext &ctx) +{ + if (ctx.get_gearbox_phy() != nullptr) + return m_gb_macsec_flow_stat_manager; + return m_macsec_flow_stat_manager; +} + void MACsecOrch::installCounter( + MACsecOrchContext &ctx, CounterType counter_type, sai_macsec_direction_t direction, const std::string &obj_name, @@ -2312,12 +2349,12 @@ void MACsecOrch::installCounter( switch(counter_type) { case CounterType::MACSEC_SA_ATTR: - m_macsec_sa_attr_manager.setCounterIdList(obj_id, counter_type, counter_stats); + MACsecSaAttrStatManager(ctx).setCounterIdList(obj_id, counter_type, counter_stats); m_macsec_counters_map.set("", fields); break; case CounterType::MACSEC_SA: - m_macsec_sa_stat_manager.setCounterIdList(obj_id, counter_type, counter_stats); + MACsecSaStatManager(ctx).setCounterIdList(obj_id, counter_type, counter_stats); if (direction == SAI_MACSEC_DIRECTION_EGRESS) { m_macsec_sa_tx_counters_map.set("", fields); @@ -2329,7 +2366,7 @@ void MACsecOrch::installCounter( break; case CounterType::MACSEC_FLOW: - m_macsec_flow_stat_manager.setCounterIdList(obj_id, counter_type, counter_stats); + MACsecFlowStatManager(ctx).setCounterIdList(obj_id, counter_type, counter_stats); break; default: @@ -2340,6 +2377,7 @@ void MACsecOrch::installCounter( } void MACsecOrch::uninstallCounter( + MACsecOrchContext &ctx, CounterType counter_type, sai_macsec_direction_t direction, const std::string &obj_name, @@ -2348,12 +2386,12 @@ void MACsecOrch::uninstallCounter( switch(counter_type) { case CounterType::MACSEC_SA_ATTR: - m_macsec_sa_attr_manager.clearCounterIdList(obj_id); + MACsecSaAttrStatManager(ctx).clearCounterIdList(obj_id); m_counter_db.hdel(COUNTERS_MACSEC_NAME_MAP, obj_name); break; case CounterType::MACSEC_SA: - m_macsec_sa_stat_manager.clearCounterIdList(obj_id); + MACsecSaStatManager(ctx).clearCounterIdList(obj_id); if (direction == SAI_MACSEC_DIRECTION_EGRESS) { m_counter_db.hdel(COUNTERS_MACSEC_SA_TX_NAME_MAP, obj_name); @@ -2365,7 +2403,7 @@ void MACsecOrch::uninstallCounter( break; case CounterType::MACSEC_FLOW: - m_macsec_flow_stat_manager.clearCounterIdList(obj_id); + MACsecFlowStatManager(ctx).clearCounterIdList(obj_id); break; default: diff --git a/orchagent/macsecorch.h b/orchagent/macsecorch.h index b59984a3a613..2472d8c0efca 100644 --- a/orchagent/macsecorch.h +++ b/orchagent/macsecorch.h @@ -72,6 +72,10 @@ class MACsecOrch : public Orch FlexCounterManager m_macsec_sa_stat_manager; FlexCounterManager m_macsec_flow_stat_manager; + FlexCounterManager m_gb_macsec_sa_attr_manager; + FlexCounterManager m_gb_macsec_sa_stat_manager; + FlexCounterManager m_gb_macsec_flow_stat_manager; + struct MACsecACLTable { sai_object_id_t m_table_id; @@ -209,17 +213,24 @@ class MACsecOrch : public Orch /* Counter */ void installCounter( + MACsecOrchContext &ctx, CounterType counter_type, sai_macsec_direction_t direction, const std::string &obj_name, sai_object_id_t obj_id, const std::vector &stats); void uninstallCounter( + MACsecOrchContext &ctx, CounterType counter_type, sai_macsec_direction_t direction, const std::string &obj_name, sai_object_id_t obj_id); + /* Flex Counter Manager */ + FlexCounterManager& MACsecSaStatManager(MACsecOrchContext &ctx); + FlexCounterManager& MACsecSaAttrStatManager(MACsecOrchContext &ctx); + FlexCounterManager& MACsecFlowStatManager(MACsecOrchContext &ctx); + /* MACsec ACL */ bool initMACsecACLTable( MACsecACLTable &acl_table, diff --git a/orchagent/port.h b/orchagent/port.h index db9f2b7bffb6..fe366630ac55 100644 --- a/orchagent/port.h +++ b/orchagent/port.h @@ -171,6 +171,7 @@ class Port SystemLagInfo m_system_lag_info; sai_object_id_t m_switch_id = 0; + sai_object_id_t m_system_side_id = 0; sai_object_id_t m_line_side_id = 0; bool m_fec_cfg = false; diff --git a/orchagent/portsorch.cpp b/orchagent/portsorch.cpp index 5a6ba61e5cf7..8c3ad481a320 100755 --- a/orchagent/portsorch.cpp +++ b/orchagent/portsorch.cpp @@ -245,6 +245,24 @@ const vector port_stat_ids = SAI_PORT_STAT_IF_IN_FEC_SYMBOL_ERRORS }; +const vector gbport_stat_ids = +{ + SAI_PORT_STAT_IF_IN_OCTETS, + SAI_PORT_STAT_IF_OUT_OCTETS, + SAI_PORT_STAT_IF_IN_DISCARDS, + SAI_PORT_STAT_IF_OUT_DISCARDS, + SAI_PORT_STAT_IF_IN_ERRORS, + SAI_PORT_STAT_IF_OUT_ERRORS, + SAI_PORT_STAT_ETHER_RX_OVERSIZE_PKTS, + SAI_PORT_STAT_ETHER_TX_OVERSIZE_PKTS, + SAI_PORT_STAT_ETHER_STATS_UNDERSIZE_PKTS, + SAI_PORT_STAT_ETHER_STATS_JABBERS, + SAI_PORT_STAT_ETHER_STATS_FRAGMENTS, + SAI_PORT_STAT_IF_IN_FEC_CORRECTABLE_FRAMES, + SAI_PORT_STAT_IF_IN_FEC_NOT_CORRECTABLE_FRAMES, + SAI_PORT_STAT_IF_IN_FEC_SYMBOL_ERRORS +}; + const vector port_buffer_drop_stat_ids = { SAI_PORT_STAT_IN_DROPPED_PKTS, @@ -305,6 +323,9 @@ PortsOrch::PortsOrch(DBConnector *db, DBConnector *stateDb, vectorgetPortCountersState()) { auto port_counter_stats = generateCounterStats(PORT_STAT_COUNTER_FLEX_COUNTER_GROUP); - port_stat_manager.setCounterIdList(p.m_port_id, CounterType::PORT, port_counter_stats); + port_stat_manager.setCounterIdList(p.m_port_id, + CounterType::PORT, port_counter_stats); + auto gbport_counter_stats = generateCounterStats(GBPORT_STAT_COUNTER_FLEX_COUNTER_GROUP); + if (p.m_system_side_id) + gb_port_stat_manager.setCounterIdList(p.m_system_side_id, + CounterType::PORT, gbport_counter_stats); + if (p.m_line_side_id) + gb_port_stat_manager.setCounterIdList(p.m_line_side_id, + CounterType::PORT, gbport_counter_stats); } if (flex_counters_orch->getPortBufferDropCountersState()) { @@ -5690,6 +5724,7 @@ void PortsOrch::generatePortCounterMap() } auto port_counter_stats = generateCounterStats(PORT_STAT_COUNTER_FLEX_COUNTER_GROUP); + auto gbport_counter_stats = generateCounterStats(GBPORT_STAT_COUNTER_FLEX_COUNTER_GROUP); for (const auto& it: m_portList) { // Set counter stats only for PHY ports to ensure syncd will not try to query the counter statistics from the HW for non-PHY ports. @@ -5697,7 +5732,14 @@ void PortsOrch::generatePortCounterMap() { continue; } - port_stat_manager.setCounterIdList(it.second.m_port_id, CounterType::PORT, port_counter_stats); + port_stat_manager.setCounterIdList(it.second.m_port_id, + CounterType::PORT, port_counter_stats); + if (it.second.m_system_side_id) + gb_port_stat_manager.setCounterIdList(it.second.m_system_side_id, + CounterType::PORT, gbport_counter_stats); + if (it.second.m_line_side_id) + gb_port_stat_manager.setCounterIdList(it.second.m_line_side_id, + CounterType::PORT, gbport_counter_stats); } m_isPortCounterMapGenerated = true; @@ -5803,6 +5845,7 @@ void PortsOrch::updatePortOperStatus(Port &port, sai_port_oper_status_t status) if (port.m_type == Port::PHY) { updateDbPortOperStatus(port, status); + updateGearboxPortOperStatus(port); } port.m_oper_status = status; @@ -6285,6 +6328,9 @@ void PortsOrch::initGearbox() SWSS_LOG_NOTICE("BOX: m_gearboxInterfaceMap size = %d.", (int) m_gearboxInterfaceMap.size()); SWSS_LOG_NOTICE("BOX: m_gearboxLaneMap size = %d.", (int) m_gearboxLaneMap.size()); SWSS_LOG_NOTICE("BOX: m_gearboxPortMap size = %d.", (int) m_gearboxPortMap.size()); + + m_gb_counter_db = shared_ptr(new DBConnector("GB_COUNTERS_DB", 0)); + m_gbcounterTable = unique_ptr(new Table(m_gb_counter_db.get(), COUNTERS_PORT_NAME_MAP)); } } @@ -6383,6 +6429,7 @@ bool PortsOrch::initGearboxPort(Port &port) } SWSS_LOG_NOTICE("BOX: Created Gearbox system-side port 0x%" PRIx64 " for alias:%s index:%d", systemPort, port.m_alias.c_str(), port.m_index); + port.m_system_side_id = systemPort; /* Create LINE-SIDE port */ attrs.clear(); @@ -6495,6 +6542,15 @@ bool PortsOrch::initGearboxPort(Port &port) SWSS_LOG_NOTICE("BOX: Connected Gearbox ports; system-side:0x%" PRIx64 " to line-side:0x%" PRIx64, systemPort, linePort); m_gearboxPortListLaneMap[port.m_port_id] = make_tuple(systemPort, linePort); port.m_line_side_id = linePort; + + /* Add gearbox system/line port name map to counter table */ + FieldValueTuple tuple(port.m_alias + "_system", sai_serialize_object_id(systemPort)); + vector fields; + fields.push_back(tuple); + m_gbcounterTable->set("", fields); + + fields[0] = FieldValueTuple(port.m_alias + "_line", sai_serialize_object_id(linePort)); + m_gbcounterTable->set("", fields); } } @@ -6920,6 +6976,13 @@ std::unordered_set PortsOrch::generateCounterStats(const string& ty counter_stats.emplace(sai_serialize_port_stat(it)); } } + else if (type == GBPORT_STAT_COUNTER_FLEX_COUNTER_GROUP) + { + for (const auto& it: gbport_stat_ids) + { + counter_stats.emplace(sai_serialize_port_stat(it)); + } + } else if (type == PORT_BUFFER_DROP_STAT_FLEX_COUNTER_GROUP) { for (const auto& it: port_buffer_drop_stat_ids) @@ -6930,6 +6993,61 @@ std::unordered_set PortsOrch::generateCounterStats(const string& ty return counter_stats; } +void PortsOrch::setGearboxFlexCounterStatus(bool enabled) +{ + if (enabled) + { + gb_port_stat_manager.enableFlexCounterGroup(); + } + else + { + gb_port_stat_manager.disableFlexCounterGroup(); + } +} + +void PortsOrch::updateGearboxPortOperStatus(const Port& port) +{ + if (!isGearboxEnabled()) + return; + + SWSS_LOG_NOTICE("BOX: port %s, system_side_id:0x%" PRIx64 "line_side_id:0x%" PRIx64, + port.m_alias.c_str(), port.m_system_side_id, port.m_line_side_id); + + if (!port.m_system_side_id || !port.m_line_side_id) + return; + + sai_attribute_t attr; + attr.id = SAI_PORT_ATTR_OPER_STATUS; + sai_status_t ret = sai_port_api->get_port_attribute(port.m_system_side_id, 1, &attr); + if (ret != SAI_STATUS_SUCCESS) + { + SWSS_LOG_ERROR("BOX: Failed to get system_oper_status for %s", port.m_alias.c_str()); + } + else + { + sai_port_oper_status_t oper = static_cast(attr.value.u32); + vector tuples; + FieldValueTuple tuple("system_oper_status", oper_status_strings.at(oper)); + tuples.push_back(tuple); + m_portTable->set(port.m_alias, tuples); + } + + attr.id = SAI_PORT_ATTR_OPER_STATUS; + ret = sai_port_api->get_port_attribute(port.m_line_side_id, 1, &attr); + if (ret != SAI_STATUS_SUCCESS) + { + SWSS_LOG_ERROR("BOX: Failed to get line_oper_status for %s", port.m_alias.c_str()); + } + else + { + sai_port_oper_status_t oper = static_cast(attr.value.u32); + vector tuples; + FieldValueTuple tuple("line_oper_status", oper_status_strings.at(oper)); + tuples.push_back(tuple); + m_portTable->set(port.m_alias, tuples); + } +} + bool PortsOrch::decrFdbCount(const std::string& alias, int count) { auto itr = m_portList.find(alias); diff --git a/orchagent/portsorch.h b/orchagent/portsorch.h index 2848cdcb9177..ab35277d80c6 100755 --- a/orchagent/portsorch.h +++ b/orchagent/portsorch.h @@ -20,6 +20,7 @@ #define VLAN_TAG_LEN 4 #define PORT_STAT_COUNTER_FLEX_COUNTER_GROUP "PORT_STAT_COUNTER" #define PORT_RATE_COUNTER_FLEX_COUNTER_GROUP "PORT_RATE_COUNTER" +#define GBPORT_STAT_COUNTER_FLEX_COUNTER_GROUP "GBPORT_STAT_COUNTER" #define PORT_BUFFER_DROP_STAT_FLEX_COUNTER_GROUP "PORT_BUFFER_DROP_STAT" #define QUEUE_STAT_COUNTER_FLEX_COUNTER_GROUP "QUEUE_STAT_COUNTER" #define QUEUE_WATERMARK_STAT_COUNTER_FLEX_COUNTER_GROUP "QUEUE_WATERMARK_STAT_COUNTER" @@ -80,6 +81,7 @@ class PortsOrch : public Orch, public Subject bool allPortsReady(); bool isInitDone(); bool isConfigDone(); + bool isGearboxEnabled(); bool isPortAdminUp(const string &alias); map& getAllPorts(); @@ -168,7 +170,11 @@ class PortsOrch : public Orch, public Subject bool getPortOperStatus(const Port& port, sai_port_oper_status_t& status) const; + void setGearboxFlexCounterStatus(bool enabled); + void updateGearboxPortOperStatus(const Port& port); + bool decrFdbCount(const string& alias, int count); + private: unique_ptr
m_counterTable; unique_ptr
m_counterLagTable; @@ -199,6 +205,10 @@ class PortsOrch : public Orch, public Subject FlexCounterManager port_buffer_drop_stat_manager; FlexCounterManager queue_stat_manager; + FlexCounterManager gb_port_stat_manager; + shared_ptr m_gb_counter_db; + unique_ptr
m_gbcounterTable; + std::map m_portSupportedSpeeds; bool m_initDone = false; diff --git a/tests/mock_tests/database_config.json b/tests/mock_tests/database_config.json index 83018486836d..68f850481d76 100644 --- a/tests/mock_tests/database_config.json +++ b/tests/mock_tests/database_config.json @@ -57,6 +57,21 @@ "separator": "|", "instance" : "redis" }, + "GB_ASIC_DB" : { + "id" : 9, + "separator": ":", + "instance" : "redis" + }, + "GB_COUNTERS_DB" : { + "id" : 10, + "separator": ":", + "instance" : "redis" + }, + "GB_FLEX_COUNTER_DB" : { + "id" : 11, + "separator": ":", + "instance" : "redis" + }, "CHASSIS_APP_DB" : { "id" : 12, "separator": "|", diff --git a/tests/test_gearbox.py b/tests/test_gearbox.py index 00a87c2f96d3..7d5b568661b6 100644 --- a/tests/test_gearbox.py +++ b/tests/test_gearbox.py @@ -49,20 +49,20 @@ def __init__(self, dvs): for i in [x for x in intf_table.getKeys() if sr not in x]: (status, fvs) = intf_table.get(i) assert status == True - self.interfaces[i] = {"attrs" : dict(fvs)} + self.interfaces[i] = dict(fvs) - def SanityCheck(self, dvs, testlog): + def SanityCheck(self, testlog): """ Verify data integrity of Gearbox objects in APPL_DB """ for i in self.interfaces: - phy_id = self.interfaces[i]["attrs"]["phy_id"] + phy_id = self.interfaces[i]["phy_id"] assert phy_id in self.phys - assert self.interfaces[i]["attrs"]["index"] in self.phys[phy_id]["ports"] + assert self.interfaces[i]["index"] in self.phys[phy_id]["ports"] - for lane in self.interfaces[i]["attrs"]["system_lanes"].split(','): + for lane in self.interfaces[i]["system_lanes"].split(','): assert lane in self.phys[phy_id]["lanes"] - for lane in self.interfaces[i]["attrs"]["line_lanes"].split(','): + for lane in self.interfaces[i]["line_lanes"].split(','): assert lane in self.phys[phy_id]["lanes"] class GBAsic(DVSDatabase): @@ -85,9 +85,9 @@ def __init__(self, db_id: int, connector: str, gearbox: Gearbox): for i in self.gearbox.interfaces: intf = self.gearbox.interfaces[i] - if intf["attrs"]["system_lanes"] == system_lanes: - assert intf["attrs"]["line_lanes"] == line_lanes - self.ports[intf["attrs"]["index"]] = (system_port_oid, line_port_oid) + if intf["system_lanes"] == system_lanes: + assert intf["line_lanes"] == line_lanes + self.ports[intf["index"]] = (system_port_oid, line_port_oid) assert len(self.ports) == len(self.gearbox.interfaces) @@ -112,13 +112,50 @@ def _verify_db_contents(): init_polling_config = PollingConfig(2, 30, strict=True) wait_for_result(_verify_db_contents, init_polling_config) +@pytest.fixture(scope="module") +def gearbox(dvs): + return Gearbox(dvs) + +@pytest.fixture(scope="module") +def gbasic(dvs, gearbox): + return GBAsic(swsscommon.GB_ASIC_DB, dvs.redis_sock, gearbox) + +@pytest.fixture(scope="module") +def enable_port_counter(dvs): + flex_counter_table = swsscommon.Table(dvs.get_config_db().db_connection, + "FLEX_COUNTER_TABLE") + + # Enable port counter + flex_counter_table.hset("PORT", "FLEX_COUNTER_STATUS", "enable") + yield + # Disable port counter + flex_counter_table.hdel("PORT", "FLEX_COUNTER_STATUS") class TestGearbox(object): - def test_GearboxSanity(self, dvs, testlog): - Gearbox(dvs).SanityCheck(dvs, testlog) + def test_GearboxSanity(self, gearbox, testlog): + gearbox.SanityCheck(testlog) + + def test_GearboxCounter(self, dvs, gbasic, enable_port_counter, testlog): + counters_db = DVSDatabase(swsscommon.COUNTERS_DB, dvs.redis_sock) + gb_counters_db = DVSDatabase(swsscommon.GB_COUNTERS_DB, dvs.redis_sock) + + intf = gbasic.gearbox.interfaces["0"] + port_oid = counters_db.get_entry("COUNTERS_PORT_NAME_MAP", "")[intf["name"]] + system_port_oid, line_port_oid = gbasic.ports["0"] + + fvs = gb_counters_db.wait_for_entry("COUNTERS", system_port_oid) + assert fvs.get("SAI_PORT_STAT_IF_OUT_ERRORS") + + fvs = gb_counters_db.wait_for_entry("COUNTERS", line_port_oid) + assert fvs.get("SAI_PORT_STAT_IF_IN_ERRORS") + + fvs = counters_db.wait_for_entry("COUNTERS", port_oid) + assert fvs.get("SAI_PORT_STAT_IF_IN_ERRORS") + + fvs = counters_db.wait_for_entry("COUNTERS", port_oid) + assert fvs.get("SAI_PORT_STAT_IF_IN_ERRORS") - def test_GbAsicFEC(self, dvs, testlog): - gbasic = GBAsic(swsscommon.GB_ASIC_DB, dvs.redis_sock, Gearbox(dvs)) + def test_GbAsicFEC(self, gbasic, testlog): # set fec rs on port 0 of phy 1 fvs = swsscommon.FieldValuePairs([("system_fec","rs")])