From 44f570b3879d98c847cc42180c2c8ea563c6e6bd Mon Sep 17 00:00:00 2001 From: junchao Date: Fri, 3 Sep 2021 14:36:08 +0800 Subject: [PATCH 1/6] [FlexCounter] Add trap flow counter support x --- meta/SaiSerialize.cpp | 8 ++ meta/sai_serialize.h | 3 + syncd/FlexCounter.cpp | 231 ++++++++++++++++++++++++++++++++++++++++-- syncd/FlexCounter.h | 33 ++++++ 4 files changed, 264 insertions(+), 11 deletions(-) diff --git a/meta/SaiSerialize.cpp b/meta/SaiSerialize.cpp index c07880062..b1b2ed3cb 100644 --- a/meta/SaiSerialize.cpp +++ b/meta/SaiSerialize.cpp @@ -1007,6 +1007,14 @@ std::string sai_serialize_tunnel_stat( return sai_serialize_enum(counter, &sai_metadata_enum_sai_tunnel_stat_t); } +std::string sai_serialize_counter_stat( + _In_ const sai_counter_stat_t counter) +{ + SWSS_LOG_ENTER(); + + return sai_serialize_enum(counter, &sai_metadata_enum_sai_counter_stat_t); +} + std::string sai_serialize_queue_attr( _In_ const sai_queue_attr_t attr) { diff --git a/meta/sai_serialize.h b/meta/sai_serialize.h index 2471609c8..69b1f482e 100644 --- a/meta/sai_serialize.h +++ b/meta/sai_serialize.h @@ -122,6 +122,9 @@ std::string sai_serialize_buffer_pool_stat( std::string sai_serialize_tunnel_stat( _In_ const sai_tunnel_stat_t counter); +std::string sai_serialize_counter_stat( + _In_ const sai_counter_stat_t counter); + std::string sai_serialize_queue_attr( _In_ const sai_queue_attr_t attr); diff --git a/syncd/FlexCounter.cpp b/syncd/FlexCounter.cpp index 30852a6e0..afb80e4b2 100644 --- a/syncd/FlexCounter.cpp +++ b/syncd/FlexCounter.cpp @@ -133,6 +133,16 @@ FlexCounter::TunnelCounterIds::TunnelCounterIds( // empty intentionally } +FlexCounter::FlowCounterIds::FlowCounterIds( + _In_ sai_object_id_t counter, + _In_ const std::vector &flowCounters): + counterId(counter), + flowCounterIds(flowCounters) +{ + SWSS_LOG_ENTER(); + // empty intentionally +} + void FlexCounter::setPollInterval( _In_ uint32_t pollInterval) { @@ -623,14 +633,7 @@ void FlexCounter::setTunnelCounterList( for (auto &counter : counterIds) { if (isTunnelCounterSupported(counter)) - { - supportedIds.push_back(counter); - } - } - - if (supportedIds.empty()) - { - SWSS_LOG_NOTICE("Tunnel %s does not have supported counters", sai_serialize_object_id(tunnelRid).c_str()); + SWSS_LOG_NOTICE("Tunnel %s does not have supported counters", sai_serialize_object_id(tunnelRid).c_str()); return; } @@ -649,6 +652,45 @@ void FlexCounter::setTunnelCounterList( addCollectCountersHandler(TUNNEL_COUNTER_ID_LIST, &FlexCounter::collectTunnelCounters); } +void FlexCounter::setFlowCounterList( + _In_ sai_object_id_t counterVid, + _In_ sai_object_id_t counterRid, + _In_ const std::vector& counterIds) +{ + SWSS_LOG_ENTER(); + + updateSupportedFlowCounters(counterRid, counterIds); + + std::vector supportedIds; + + for (auto &counter : counterIds) + { + if (m_supportedFlowCounters.count(counter) != 0) + { + supportedIds.push_back(counter); + } + } + + if (supportedIds.empty()) + { + SWSS_LOG_NOTICE("Flow counter %s does not have supported counters", sai_serialize_object_id(counterRid).c_str()); + return; + } + + auto it = m_flowCounterIdsMap.find(counterVid); + if (it != m_flowCounterIdsMap.end()) + { + it->second->flowCounterIds = supportedIds; + return; + } + + auto flowCounterIds = std::make_shared(counterRid, supportedIds); + + m_flowCounterIdsMap.emplace(counterVid, flowCounterIds); + + addCollectCountersHandler(FLOW_COUNTER_ID_LIST, &FlexCounter::collectFlowCounters); +} + void FlexCounter::removePort( _In_ sai_object_id_t portVid) { @@ -824,6 +866,38 @@ void FlexCounter::removeAclCounter( } } +void FlexCounter::removeFlowCounter( + _In_ sai_object_id_t counterVid) +{ + SWSS_LOG_ENTER(); + + auto it = m_flowCounterIdsMap.find(counterVid); + + if (it == m_flowCounterIdsMap.end()) + { + SWSS_LOG_NOTICE("Trying to remove nonexisting flow counter from Id 0x%" PRIx64, counterVid); + return; + } + + swss::DBConnector db(m_dbCounters, 0); + swss::RedisPipeline pipeline(&db); + swss::Table countersTable(&pipeline, COUNTERS_TABLE, false); + swss::Table ratesTable(&pipeline, RATES_TABLE, false); + + // Remove counter and rate entries from COUNTER DB to avoid resource leak + std::string counterVidStr = sai_serialize_object_id(counterVid); + countersTable.del(counterVidStr); + ratesTable.del(counterVidStr); + ratesTable.del(counterVidStr + ":TRAP"); + + m_flowCounterIdsMap.erase(it); + + if (m_flowCounterIdsMap.empty()) + { + removeCollectCountersHandler(FLOW_COUNTER_ID_LIST); + } +} + void FlexCounter::removeRif( _In_ sai_object_id_t rifVid) { @@ -924,7 +998,8 @@ void FlexCounter::checkPluginRegistered( m_queuePlugins.find(sha) != m_queuePlugins.end() || m_priorityGroupPlugins.find(sha) != m_priorityGroupPlugins.end() || m_bufferPoolPlugins.find(sha) != m_bufferPoolPlugins.end() || - m_tunnelPlugins.find(sha) != m_tunnelPlugins.end() + m_tunnelPlugins.find(sha) != m_tunnelPlugins.end() || + m_flowCounterPlugins.find(sha) != m_flowCounterPlugins.end() ) { SWSS_LOG_ERROR("Plugin %s already registered", sha.c_str()); @@ -967,6 +1042,18 @@ void FlexCounter::addQueueCounterPlugin( SWSS_LOG_NOTICE("Queue counters plugin %s registered", sha.c_str()); } +void FlexCounter::addFlowCounterPlugin( + _In_ const std::string& sha) +{ + SWSS_LOG_ENTER(); + + checkPluginRegistered(sha); + + m_flowCounterPlugins.insert(sha); + + SWSS_LOG_NOTICE("Flow counters plugin %s registered", sha.c_str()); +} + void FlexCounter::addPriorityGroupCounterPlugin( _In_ const std::string& sha) { @@ -1015,6 +1102,7 @@ void FlexCounter::removeCounterPlugins() m_priorityGroupPlugins.clear(); m_bufferPoolPlugins.clear(); m_tunnelPlugins.clear(); + m_flowCounterPlugins.clear(); m_isDiscarded = true; } @@ -1089,6 +1177,13 @@ void FlexCounter::addCounterPlugin( addTunnelCounterPlugin(sha); } } + else if (field == FLOW_COUNTER_PLUGIN_FIELD) + { + for (auto& sha: shaStrings) + { + addFlowCounterPlugin(sha); + } + } else { SWSS_LOG_ERROR("Field is not supported %s", field.c_str()); @@ -1130,7 +1225,8 @@ bool FlexCounter::allIdsEmpty() const m_switchDebugCounterIdsMap.empty() && m_macsecSAAttrIdsMap.empty() && m_aclCounterAttrIdsMap.empty() && - m_tunnelCounterIdsMap.empty(); + m_tunnelCounterIdsMap.empty() && + m_flowCounterIdsMap.empty(); } bool FlexCounter::allPluginsEmpty() const @@ -1142,7 +1238,8 @@ bool FlexCounter::allPluginsEmpty() const m_portPlugins.empty() && m_rifPlugins.empty() && m_bufferPoolPlugins.empty() && - m_tunnelPlugins.empty(); + m_tunnelPlugins.empty() && + m_flowCounterPlugins.empty(); } bool FlexCounter::isPortCounterSupported(sai_port_stat_t counter) const @@ -1542,6 +1639,50 @@ void FlexCounter::collectSwitchDebugCounters( } } +void FlexCounter::collectFlowCounters( + _In_ swss::Table &countersTable) +{ + SWSS_LOG_ENTER(); + + // Collect stats for every registered flow counter + for (const auto &kv: m_flowCounterIdsMap) + { + const auto &counterVid = kv.first; + const auto &counterRId = kv.second->counterId; + const auto &counterIds = kv.second->flowCounterIds; + + std::vector stats(counterIds.size()); + + // Get flow counter stats + sai_status_t status = m_vendorSai->getStatsExt( + SAI_OBJECT_TYPE_COUNTER, + counterRId, + static_cast(counterIds.size()), + (const sai_stat_id_t *)counterIds.data(), + SAI_STATS_MODE_READ, + stats.data()); + + if (status != SAI_STATUS_SUCCESS) + { + SWSS_LOG_ERROR("Failed to get stats of flow counter 0x%" PRIx64 ": %d", counterRId, status); + continue; + } + + // Push all counter values to a single vector + std::vector values; + + for (size_t i = 0; i != counterIds.size(); i++) + { + values.emplace_back(sai_serialize_counter_stat(counterIds[i]), std::to_string(stats[i])); + } + + // Write counters to DB + std::string counterVidStr = sai_serialize_object_id(counterVid); + + countersTable.set(counterVidStr, values, ""); + } +} + void FlexCounter::collectPriorityGroupAttrs( _In_ swss::Table &countersTable) { @@ -1903,6 +2044,20 @@ void FlexCounter::runPlugins( runRedisScript(counters_db, sha, queueList, argv); } + std::vector flowCounterList; + + flowCounterList.reserve(m_flowCounterIdsMap.size()); + + for (const auto& kv : m_flowCounterIdsMap) + { + flowCounterList.push_back(sai_serialize_object_id(kv.first)); + } + + for (const auto& sha : m_flowCounterPlugins) + { + runRedisScript(counters_db, sha, flowCounterList, argv); + } + std::vector priorityGroupList; priorityGroupList.reserve(m_priorityGroupCounterIdsMap.size()); @@ -2463,6 +2618,43 @@ void FlexCounter::getSupportedRifCounters( } } +void FlexCounter::updateSupportedFlowCounters( + _In_ sai_object_id_t counterRid, + _In_ const std::vector &counterIds) +{ + SWSS_LOG_ENTER(); + + if (!m_supportedFlowCounters.empty()) + { + return; + } + + uint64_t value; + for (auto &counter : counterIds) + { + sai_status_t status = m_vendorSai->getStatsExt( + SAI_OBJECT_TYPE_COUNTER, + counterRid, + 1, + (const sai_stat_id_t *)&counter, + SAI_STATS_MODE_READ, + &value); + + if (status != SAI_STATUS_SUCCESS) + { + SWSS_LOG_NOTICE("%s: counter %s is not supported on flow counter %s, rv: %s", + m_instanceId.c_str(), + sai_serialize_counter_stat(counter).c_str(), + sai_serialize_object_id(counterRid).c_str(), + sai_serialize_status(status).c_str()); + + continue; + } + + m_supportedFlowCounters.insert(counter); + } +} + void FlexCounter::updateSupportedRifCounters( _In_ sai_object_id_t rifRid) { @@ -2722,6 +2914,10 @@ void FlexCounter::removeCounter( { removeTunnel(vid); } + else if (objectType == SAI_OBJECT_TYPE_COUNTER) + { + removeFlowCounter(vid); + } else { SWSS_LOG_ERROR("Object type for removal not supported, %s", @@ -2882,6 +3078,19 @@ void FlexCounter::addCounter( setAclCounterAttrList(vid, rid, aclCounterIds); } + else if (objectType == SAI_OBJECT_TYPE_COUNTER && field == FLOW_COUNTER_ID_LIST) + { + std::vector counterStatIds; + + for (const auto &str : idStrings) + { + sai_counter_stat_t stat; + sai_deserialize_counter_stat(str.c_str(), &stat); + counterStatIds.push_back(stat); + } + + setFlowCounterList(vid, rid, counterStatIds); + } else if (objectType == SAI_OBJECT_TYPE_BUFFER_POOL && field == BUFFER_POOL_COUNTER_ID_LIST) { counterIds = idStrings; diff --git a/syncd/FlexCounter.h b/syncd/FlexCounter.h index e8e88fa91..702bf370a 100644 --- a/syncd/FlexCounter.h +++ b/syncd/FlexCounter.h @@ -80,6 +80,10 @@ namespace syncd void addTunnelCounterPlugin( _In_ const std::string& sha); + + void addFlowCounterPlugin( + _In_ const std::string& sha); + private: void checkPluginRegistered( @@ -121,6 +125,9 @@ namespace syncd void removeTunnel( _In_ sai_object_id_t tunnelVid); + void removeFlowCounter( + _In_ sai_object_id_t counterVid); + private: // set counter list void setPortCounterList( @@ -164,6 +171,11 @@ namespace syncd _In_ sai_object_id_t tunnelRid, _In_ const std::vector &counterIds); + void setFlowCounterList( + _In_ sai_object_id_t counterVid, + _In_ sai_object_id_t counterRid, + _In_ const std::vector& counterIds); + private: // set attr list void setQueueAttrList( @@ -269,6 +281,10 @@ namespace syncd _In_ sai_object_id_t priorityGroupRid, _In_ const std::vector &counterIds); + void updateSupportedFlowCounters( + _In_ sai_object_id_t counterRid, + _In_ const std::vector &counterIds); + std::vector saiCheckSupportedSwitchDebugCounters( _In_ sai_object_id_t switchRid, _In_ const std::vector &counterIds); @@ -390,6 +406,16 @@ namespace syncd std::vector m_tunnelCounterIds; }; + struct FlowCounterIds + { + FlowCounterIds( + _In_ sai_object_id_t counterId, + _In_ const std::vector &flowCounterIds); + + sai_object_id_t counterId; + std::vector flowCounterIds; + }; + private: void collectCounters( @@ -437,6 +463,9 @@ namespace syncd void collectTunnelCounters( _In_ swss::Table &countersTable); + void collectFlowCounters( + _In_ swss::Table &countersTable); + private: // collect attributes void collectQueueAttrs( @@ -468,6 +497,7 @@ namespace syncd std::set m_priorityGroupPlugins; std::set m_bufferPoolPlugins; std::set m_tunnelPlugins; + std::set m_flowCounterPlugins; private: // supported counters @@ -477,6 +507,7 @@ namespace syncd std::set m_supportedRifCounters; std::set m_supportedBufferPoolCounters; std::set m_supportedTunnelCounters; + std::set m_supportedFlowCounters; private: // registered VID maps @@ -488,6 +519,8 @@ namespace syncd std::map> m_bufferPoolCounterIdsMap; std::map> m_switchDebugCounterIdsMap; std::map> m_tunnelCounterIdsMap; + std::map> m_flowCounterIdsMap; + std::map> m_queueAttrIdsMap; std::map> m_priorityGroupAttrIdsMap; std::map> m_macsecSAAttrIdsMap; From 6e5cf82c6e3479cfe3c9b1da6785e6258df8d318 Mon Sep 17 00:00:00 2001 From: junchao Date: Fri, 5 Nov 2021 09:10:19 +0800 Subject: [PATCH 2/6] Add an empty commit to trigger build --- syncd/FlexCounter.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/syncd/FlexCounter.cpp b/syncd/FlexCounter.cpp index afb80e4b2..79be74eaa 100644 --- a/syncd/FlexCounter.cpp +++ b/syncd/FlexCounter.cpp @@ -662,7 +662,6 @@ void FlexCounter::setFlowCounterList( updateSupportedFlowCounters(counterRid, counterIds); std::vector supportedIds; - for (auto &counter : counterIds) { if (m_supportedFlowCounters.count(counter) != 0) From 5b77bf77d2a311a4a451abbd2b4a8d1fe3a2dd2e Mon Sep 17 00:00:00 2001 From: junchao Date: Tue, 9 Nov 2021 18:19:43 +0800 Subject: [PATCH 3/6] Add unit test for trap flow flex counter --- syncd/FlexCounter.cpp | 34 ++- syncd/FlexCounter.h | 7 + unittest/meta/TestSaiSerialize.cpp | 5 + unittest/syncd/Makefile.am | 11 +- unittest/syncd/MockHelper.cpp | 36 +++ unittest/syncd/MockHelper.h | 5 + unittest/syncd/MockableSaiInterface.h | 324 ++++++++++++++++++++++++++ unittest/syncd/TestFlexCounter.cpp | 77 ++++++ 8 files changed, 489 insertions(+), 10 deletions(-) create mode 100644 unittest/syncd/MockHelper.cpp create mode 100644 unittest/syncd/MockHelper.h create mode 100644 unittest/syncd/MockableSaiInterface.h create mode 100644 unittest/syncd/TestFlexCounter.cpp diff --git a/syncd/FlexCounter.cpp b/syncd/FlexCounter.cpp index 79be74eaa..e1e8b7c91 100644 --- a/syncd/FlexCounter.cpp +++ b/syncd/FlexCounter.cpp @@ -10,6 +10,7 @@ #include using namespace syncd; +using namespace std; #define MUTEX std::unique_lock _lock(m_mtx); #define MUTEX_UNLOCK _lock.unlock(); @@ -18,6 +19,7 @@ FlexCounter::FlexCounter( _In_ const std::string& instanceId, _In_ std::shared_ptr vendorSai, _In_ const std::string& dbCounters): + m_readyToPoll(false), m_pollInterval(0), m_instanceId(instanceId), m_vendorSai(vendorSai), @@ -633,7 +635,14 @@ void FlexCounter::setTunnelCounterList( for (auto &counter : counterIds) { if (isTunnelCounterSupported(counter)) - SWSS_LOG_NOTICE("Tunnel %s does not have supported counters", sai_serialize_object_id(tunnelRid).c_str()); + { + supportedIds.push_back(counter); + } + } + + if (supportedIds.empty()) + { + SWSS_LOG_NOTICE("Tunnel %s does not have supported counters", sai_serialize_object_id(tunnelRid).c_str()); return; } @@ -1190,7 +1199,7 @@ void FlexCounter::addCounterPlugin( } // notify thread to start polling - m_pollCond.notify_all(); + notifyPoll(); } bool FlexCounter::isEmpty() @@ -2138,10 +2147,7 @@ void FlexCounter::flexCounterThreadRunFunction() MUTEX_UNLOCK; // explicit unlock // nothing to collect, wait until notified - - std::unique_lock lk(m_mtxSleep); - - m_pollCond.wait(lk); // wait on mutex + waitPoll(); } } @@ -2169,7 +2175,7 @@ void FlexCounter::endFlexCounterThread(void) m_runFlexCounterThread = false; - m_pollCond.notify_all(); + notifyPoll(); m_cvSleep.notify_all(); @@ -3136,5 +3142,19 @@ void FlexCounter::addCounter( } // notify thread to start polling + notifyPoll(); +} + +void FlexCounter::waitPoll() +{ + std::unique_lock lk(m_mtxSleep); + m_pollCond.wait(lk, [&](){return m_readyToPoll;}); + m_readyToPoll = false; +} + +void FlexCounter::notifyPoll() +{ + std::unique_lock lk(m_mtxSleep); + m_readyToPoll = true; m_pollCond.notify_all(); } diff --git a/syncd/FlexCounter.h b/syncd/FlexCounter.h index 702bf370a..fad045485 100644 --- a/syncd/FlexCounter.h +++ b/syncd/FlexCounter.h @@ -489,6 +489,11 @@ namespace syncd void removeCollectCountersHandler( _In_ const std::string& key); + private: + void waitPoll(); + + void notifyPoll(); + private: // plugins std::set m_queuePlugins; @@ -540,6 +545,8 @@ namespace syncd std::condition_variable m_pollCond; + bool m_readyToPoll; + uint32_t m_pollInterval; std::string m_instanceId; diff --git a/unittest/meta/TestSaiSerialize.cpp b/unittest/meta/TestSaiSerialize.cpp index 2fc26d937..8a8ceca29 100644 --- a/unittest/meta/TestSaiSerialize.cpp +++ b/unittest/meta/TestSaiSerialize.cpp @@ -338,6 +338,11 @@ TEST(SaiSerialize, sai_serialize_tunnel_stat) EXPECT_EQ(sai_serialize_tunnel_stat(SAI_TUNNEL_STAT_IN_OCTETS), "SAI_TUNNEL_STAT_IN_OCTETS"); } +TEST(SaiSerialize, sai_serialize_counter_stat) +{ + EXPECT_EQ(sai_serialize_counter_stat(SAI_COUNTER_STAT_PACKETS), "SAI_COUNTER_STAT_PACKETS"); +} + TEST(SaiSerialize, sai_serialize_queue_attr) { EXPECT_EQ(sai_serialize_queue_attr(SAI_QUEUE_ATTR_TYPE), "SAI_QUEUE_ATTR_TYPE"); diff --git a/unittest/syncd/Makefile.am b/unittest/syncd/Makefile.am index 8a76873df..999405282 100644 --- a/unittest/syncd/Makefile.am +++ b/unittest/syncd/Makefile.am @@ -1,11 +1,16 @@ -AM_CXXFLAGS = $(SAIINC) -I$(top_srcdir)/syncd -I$(top_srcdir)/lib -I$(top_srcdir)/vslib +AM_CXXFLAGS = $(SAIINC) -I$(top_srcdir)/syncd -I$(top_srcdir)/lib -I$(top_srcdir)/vslib -I$(top_srcdir)/meta bin_PROGRAMS = tests LDADD_GTEST = -L/usr/src/gtest -lgtest -lgtest_main tests_SOURCES = main.cpp \ - TestCommandLineOptions.cpp + ../../meta/DummySaiInterface.cpp \ + MockHelper.cpp \ + TestCommandLineOptions.cpp \ + TestFlexCounter.cpp tests_CXXFLAGS = $(DBGFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS_COMMON) -tests_LDADD = $(LDADD_GTEST) $(top_srcdir)/syncd/libSyncd.a -lswsscommon -lpthread -L$(top_srcdir)/lib/.libs -lsairedis -L$(top_srcdir)/meta/.libs -lsaimetadata -lsaimeta -lzmq $(CODE_COVERAGE_LIBS) +tests_LDADD = $(LDADD_GTEST) $(top_srcdir)/syncd/libSyncd.a -lhiredis -lswsscommon -lpthread -L$(top_srcdir)/lib/.libs -lsairedis -L$(top_srcdir)/meta/.libs -lsaimetadata -lsaimeta -lzmq $(CODE_COVERAGE_LIBS) + +TESTS = tests diff --git a/unittest/syncd/MockHelper.cpp b/unittest/syncd/MockHelper.cpp new file mode 100644 index 000000000..ff7192cf8 --- /dev/null +++ b/unittest/syncd/MockHelper.cpp @@ -0,0 +1,36 @@ +#include "VidManager.h" +#include "swss/dbconnector.h" +#include "swss/table.h" + +namespace test_syncd { + sai_object_type_t mock_objectTypeQuery_result; + void mockVidManagerObjectTypeQuery(sai_object_type_t mock_result) + { + mock_objectTypeQuery_result = mock_result; + } +} + +namespace syncd { + sai_object_type_t VidManager::objectTypeQuery(_In_ sai_object_id_t objectId) + { + return test_syncd::mock_objectTypeQuery_result; + } +} + +/* +namespace swss { + DBConnector::DBConnector(const std::string& dbName, unsigned int timeout, bool isTcpConn) + { + } + + DBConnector *DBConnector::newConnector(unsigned int timeout) const + { + return nullptr; + } + + Table::Table(RedisPipeline *pipeline, const std::string &tableName, bool buffered) + { + } + + +}*/ diff --git a/unittest/syncd/MockHelper.h b/unittest/syncd/MockHelper.h new file mode 100644 index 000000000..21e56c74a --- /dev/null +++ b/unittest/syncd/MockHelper.h @@ -0,0 +1,5 @@ +#pragma once + +namespace test_syncd { + void mockVidManagerObjectTypeQuery(sai_object_type_t); +} \ No newline at end of file diff --git a/unittest/syncd/MockableSaiInterface.h b/unittest/syncd/MockableSaiInterface.h new file mode 100644 index 000000000..9ca6bc62d --- /dev/null +++ b/unittest/syncd/MockableSaiInterface.h @@ -0,0 +1,324 @@ +#pragma once + +#include + +#include "DummySaiInterface.h" + +// Use gmock? +class MockableSaiInterface: public saimeta::DummySaiInterface +{ + public: + + MockableSaiInterface() {} + + virtual ~MockableSaiInterface() {} + + public: + + virtual sai_status_t initialize( + _In_ uint64_t flags, + _In_ const sai_service_method_table_t *service_method_table) override { return SAI_STATUS_SUCCESS; } + + virtual sai_status_t uninitialize(void) override { return SAI_STATUS_SUCCESS; } + + public: // SAI interface overrides + + virtual sai_status_t create( + _In_ sai_object_type_t objectType, + _Out_ sai_object_id_t* objectId, + _In_ sai_object_id_t switchId, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) override + { + if (mock_create) + { + return mock_create(objectType, objectId, switchId, attr_count, attr_list); + } + + return SAI_STATUS_SUCCESS; + } + + std::function mock_create; + + virtual sai_status_t remove( + _In_ sai_object_type_t objectType, + _In_ sai_object_id_t objectId) override + { + if (mock_remove) + { + return mock_remove(objectType, objectId); + } + + return SAI_STATUS_SUCCESS; + } + + std::function mock_remove; + + virtual sai_status_t set( + _In_ sai_object_type_t objectType, + _In_ sai_object_id_t objectId, + _In_ const sai_attribute_t *attr) override + { + if (mock_set) + { + return mock_set(objectType, objectId, attr); + } + + return SAI_STATUS_SUCCESS; + } + + std::function mock_set; + + virtual sai_status_t get( + _In_ sai_object_type_t objectType, + _In_ sai_object_id_t objectId, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) override + { + if (mock_get) + { + return mock_get(objectType, objectId, attr_count, attr_list); + } + + return SAI_STATUS_SUCCESS; + } + + std::function mock_get; + + public: // bulk QUAD oid + + virtual sai_status_t bulkCreate( + _In_ sai_object_type_t object_type, + _In_ sai_object_id_t switch_id, + _In_ uint32_t object_count, + _In_ const uint32_t *attr_count, + _In_ const sai_attribute_t **attr_list, + _In_ sai_bulk_op_error_mode_t mode, + _Out_ sai_object_id_t *object_id, + _Out_ sai_status_t *object_statuses) override + { + if (mock_bulkCreate) + { + return mock_bulkCreate(object_type, switch_id, object_count, attr_count, attr_list, mode, object_id, object_statuses); + } + + return SAI_STATUS_SUCCESS; + } + + std::function mock_bulkCreate; + + virtual sai_status_t bulkRemove( + _In_ sai_object_type_t object_type, + _In_ uint32_t object_count, + _In_ const sai_object_id_t *object_id, + _In_ sai_bulk_op_error_mode_t mode, + _Out_ sai_status_t *object_statuses) override + { + if (mock_bulkRemove) + { + return mock_bulkRemove(object_type, object_count, object_id, mode, object_statuses); + } + + return SAI_STATUS_SUCCESS; + } + + std::function mock_bulkRemove; + + virtual sai_status_t bulkSet( + _In_ sai_object_type_t object_type, + _In_ uint32_t object_count, + _In_ const sai_object_id_t *object_id, + _In_ const sai_attribute_t *attr_list, + _In_ sai_bulk_op_error_mode_t mode, + _Out_ sai_status_t *object_statuses) override + { + if (mock_bulkSet) + { + return mock_bulkSet(object_type, object_count, object_id, attr_list, mode, object_statuses); + } + + return SAI_STATUS_SUCCESS; + } + + std::function mock_bulkSet; + + public: // stats API + + virtual sai_status_t getStats( + _In_ sai_object_type_t object_type, + _In_ sai_object_id_t object_id, + _In_ uint32_t number_of_counters, + _In_ const sai_stat_id_t *counter_ids, + _Out_ uint64_t *counters) override + { + if (mock_getStats) + { + return mock_getStats(object_type, object_id, number_of_counters, counter_ids, counters); + } + + return SAI_STATUS_SUCCESS; + } + + std::function mock_getStats; + + virtual sai_status_t queryStatsCapability( + _In_ sai_object_id_t switch_id, + _In_ sai_object_type_t object_type, + _Inout_ sai_stat_capability_list_t *stats_capability) override + { + if (mock_queryStatsCapability) + { + return mock_queryStatsCapability(switch_id, object_type, stats_capability); + } + + return SAI_STATUS_SUCCESS; + } + + std::function mock_queryStatsCapability; + + virtual sai_status_t getStatsExt( + _In_ sai_object_type_t object_type, + _In_ sai_object_id_t object_id, + _In_ uint32_t number_of_counters, + _In_ const sai_stat_id_t *counter_ids, + _In_ sai_stats_mode_t mode, + _Out_ uint64_t *counters) override + { + if (mock_getStatsExt) + { + return mock_getStatsExt(object_type, object_id, number_of_counters, counter_ids, mode, counters); + } + + return SAI_STATUS_SUCCESS; + } + + std::function mock_getStatsExt; + + virtual sai_status_t clearStats( + _In_ sai_object_type_t object_type, + _In_ sai_object_id_t object_id, + _In_ uint32_t number_of_counters, + _In_ const sai_stat_id_t *counter_ids) override + { + if (mock_clearStats) + { + return mock_clearStats(object_type, object_id, number_of_counters, counter_ids); + } + + return SAI_STATUS_SUCCESS; + } + + std::function mock_clearStats; + + + public: // non QUAD API + + virtual sai_status_t flushFdbEntries( + _In_ sai_object_id_t switchId, + _In_ uint32_t attrCount, + _In_ const sai_attribute_t *attrList) override + { + if (mock_flushFdbEntries) + { + return mock_flushFdbEntries(switchId, attrCount, attrList); + } + + return SAI_STATUS_SUCCESS; + } + + std::function mock_flushFdbEntries; + + public: // SAI API + + virtual sai_status_t objectTypeGetAvailability( + _In_ sai_object_id_t switchId, + _In_ sai_object_type_t objectType, + _In_ uint32_t attrCount, + _In_ const sai_attribute_t *attrList, + _Out_ uint64_t *count) override + { + if (mock_objectTypeGetAvailability) + { + return mock_objectTypeGetAvailability(switchId, objectType, attrCount, attrList, count); + } + + return SAI_STATUS_SUCCESS; + } + + std::function mock_objectTypeGetAvailability; + + + virtual sai_status_t queryAttributeCapability( + _In_ sai_object_id_t switch_id, + _In_ sai_object_type_t object_type, + _In_ sai_attr_id_t attr_id, + _Out_ sai_attr_capability_t *capability) override + { + if (mock_queryAttributeCapability) + { + return mock_queryAttributeCapability(switch_id, object_type, attr_id, capability); + } + + return SAI_STATUS_SUCCESS; + } + + std::function mock_queryAttributeCapability; + + + virtual sai_status_t queryAattributeEnumValuesCapability( + _In_ sai_object_id_t switch_id, + _In_ sai_object_type_t object_type, + _In_ sai_attr_id_t attr_id, + _Inout_ sai_s32_list_t *enum_values_capability) override + { + if (mock_queryAattributeEnumValuesCapability) + { + return mock_queryAattributeEnumValuesCapability(switch_id, object_type, attr_id, enum_values_capability); + } + + return SAI_STATUS_SUCCESS; + } + + std::function mock_queryAattributeEnumValuesCapability; + + virtual sai_object_type_t objectTypeQuery( + _In_ sai_object_id_t objectId) override + { + if (mock_objectTypeQuery) + { + return mock_objectTypeQuery(objectId); + } + + return SAI_OBJECT_TYPE_NULL; + } + + std::function mock_objectTypeQuery; + + + virtual sai_object_id_t switchIdQuery( + _In_ sai_object_id_t objectId) override + { + if (mock_switchIdQuery) + { + return mock_switchIdQuery(objectId); + } + + return 0; + } + + std::function mock_switchIdQuery; + + virtual sai_status_t logSet( + _In_ sai_api_t api, + _In_ sai_log_level_t log_level) override + { + if (mock_logSet) + { + return mock_logSet(api, log_level); + } + + return SAI_STATUS_SUCCESS; + } + + std::function mock_logSet; +}; diff --git a/unittest/syncd/TestFlexCounter.cpp b/unittest/syncd/TestFlexCounter.cpp new file mode 100644 index 000000000..a98483d08 --- /dev/null +++ b/unittest/syncd/TestFlexCounter.cpp @@ -0,0 +1,77 @@ +#include "FlexCounter.h" +#include "MockableSaiInterface.h" +#include "MockHelper.h" + +#include + + +using namespace syncd; +using namespace std; + +TEST(FlexCounter, addRemoveCounterForFlowCounter) +{ + std::shared_ptr sai(new MockableSaiInterface()); + FlexCounter fc("test", sai, "COUNTERS_DB"); + + sai_object_id_t counterVid{100}; + sai_object_id_t counterRid{100}; + std::vector values; + values.emplace_back(FLOW_COUNTER_ID_LIST, "SAI_COUNTER_STAT_PACKETS,SAI_COUNTER_STAT_BYTES"); + + test_syncd::mockVidManagerObjectTypeQuery(SAI_OBJECT_TYPE_COUNTER); + sai->mock_getStatsExt = [](sai_object_type_t, sai_object_id_t, uint32_t number_of_counters, const sai_stat_id_t *, sai_stats_mode_t, uint64_t *counters) { + for (uint32_t i = 0; i < number_of_counters; i++) + { + counters[i] = (i + 1) * 100; + } + return SAI_STATUS_SUCCESS; + }; + + fc.addCounter(counterVid, counterRid, values); + EXPECT_EQ(fc.isEmpty(), false); + + values.clear(); + values.emplace_back(POLL_INTERVAL_FIELD, "1000"); + fc.addCounterPlugin(values); + + values.clear(); + values.emplace_back(FLEX_COUNTER_STATUS_FIELD, "enable"); + fc.addCounterPlugin(values); + + usleep(1000*1000); + swss::DBConnector db("COUNTERS_DB", 0); + swss::RedisPipeline pipeline(&db); + swss::Table countersTable(&pipeline, COUNTERS_TABLE, false); + + std::vector keys; + countersTable.getKeys(keys); + EXPECT_EQ(keys.size(), size_t(1)); + EXPECT_EQ(keys[0], "oid:0x64"); + + std::string value; + countersTable.hget("oid:0x64", "SAI_COUNTER_STAT_PACKETS", value); + EXPECT_EQ(value, "100"); + countersTable.hget("oid:0x64", "SAI_COUNTER_STAT_BYTES", value); + EXPECT_EQ(value, "200"); + + fc.removeCounter(counterVid); + EXPECT_EQ(fc.isEmpty(), true); + countersTable.getKeys(keys); + + ASSERT_TRUE(keys.empty()); + +} + +TEST(FlexCounter, addRemoveCounterPluginForFlowCounter) +{ + std::shared_ptr sai(new MockableSaiInterface()); + FlexCounter fc("test", sai, "COUNTERS_DB"); + + std::vector values; + values.emplace_back(FLOW_COUNTER_PLUGIN_FIELD, "dummy_sha_strings"); + fc.addCounterPlugin(values); + EXPECT_EQ(fc.isEmpty(), false); + + fc.removeCounterPlugins(); + EXPECT_EQ(fc.isEmpty(), true); +} From 60c9230353338268d2015736d00d9cc88feb9fc0 Mon Sep 17 00:00:00 2001 From: junchao Date: Wed, 10 Nov 2021 09:52:47 +0800 Subject: [PATCH 4/6] Fix spell check issues --- syncd/FlexCounter.cpp | 2 ++ unittest/syncd/MockHelper.cpp | 20 ++---------------- unittest/syncd/MockableSaiInterface.h | 29 ++++++++++++++++++++++++--- 3 files changed, 30 insertions(+), 21 deletions(-) diff --git a/syncd/FlexCounter.cpp b/syncd/FlexCounter.cpp index e1e8b7c91..7b54afc0e 100644 --- a/syncd/FlexCounter.cpp +++ b/syncd/FlexCounter.cpp @@ -3147,6 +3147,7 @@ void FlexCounter::addCounter( void FlexCounter::waitPoll() { + SWSS_LOG_ENTER(); std::unique_lock lk(m_mtxSleep); m_pollCond.wait(lk, [&](){return m_readyToPoll;}); m_readyToPoll = false; @@ -3154,6 +3155,7 @@ void FlexCounter::waitPoll() void FlexCounter::notifyPoll() { + SWSS_LOG_ENTER(); std::unique_lock lk(m_mtxSleep); m_readyToPoll = true; m_pollCond.notify_all(); diff --git a/unittest/syncd/MockHelper.cpp b/unittest/syncd/MockHelper.cpp index ff7192cf8..929df8620 100644 --- a/unittest/syncd/MockHelper.cpp +++ b/unittest/syncd/MockHelper.cpp @@ -6,6 +6,7 @@ namespace test_syncd { sai_object_type_t mock_objectTypeQuery_result; void mockVidManagerObjectTypeQuery(sai_object_type_t mock_result) { + SWSS_LOG_ENTER(); mock_objectTypeQuery_result = mock_result; } } @@ -13,24 +14,7 @@ namespace test_syncd { namespace syncd { sai_object_type_t VidManager::objectTypeQuery(_In_ sai_object_id_t objectId) { + SWSS_LOG_ENTER(); return test_syncd::mock_objectTypeQuery_result; } } - -/* -namespace swss { - DBConnector::DBConnector(const std::string& dbName, unsigned int timeout, bool isTcpConn) - { - } - - DBConnector *DBConnector::newConnector(unsigned int timeout) const - { - return nullptr; - } - - Table::Table(RedisPipeline *pipeline, const std::string &tableName, bool buffered) - { - } - - -}*/ diff --git a/unittest/syncd/MockableSaiInterface.h b/unittest/syncd/MockableSaiInterface.h index 9ca6bc62d..a2c9e3b97 100644 --- a/unittest/syncd/MockableSaiInterface.h +++ b/unittest/syncd/MockableSaiInterface.h @@ -4,14 +4,19 @@ #include "DummySaiInterface.h" -// Use gmock? class MockableSaiInterface: public saimeta::DummySaiInterface { public: - MockableSaiInterface() {} + MockableSaiInterface() + { + SWSS_LOG_ENTER(); + } - virtual ~MockableSaiInterface() {} + virtual ~MockableSaiInterface() + { + SWSS_LOG_ENTER(); + } public: @@ -30,6 +35,7 @@ class MockableSaiInterface: public saimeta::DummySaiInterface _In_ uint32_t attr_count, _In_ const sai_attribute_t *attr_list) override { + SWSS_LOG_ENTER(); if (mock_create) { return mock_create(objectType, objectId, switchId, attr_count, attr_list); @@ -44,6 +50,7 @@ class MockableSaiInterface: public saimeta::DummySaiInterface _In_ sai_object_type_t objectType, _In_ sai_object_id_t objectId) override { + SWSS_LOG_ENTER(); if (mock_remove) { return mock_remove(objectType, objectId); @@ -59,6 +66,7 @@ class MockableSaiInterface: public saimeta::DummySaiInterface _In_ sai_object_id_t objectId, _In_ const sai_attribute_t *attr) override { + SWSS_LOG_ENTER(); if (mock_set) { return mock_set(objectType, objectId, attr); @@ -75,6 +83,7 @@ class MockableSaiInterface: public saimeta::DummySaiInterface _In_ uint32_t attr_count, _Inout_ sai_attribute_t *attr_list) override { + SWSS_LOG_ENTER(); if (mock_get) { return mock_get(objectType, objectId, attr_count, attr_list); @@ -97,6 +106,7 @@ class MockableSaiInterface: public saimeta::DummySaiInterface _Out_ sai_object_id_t *object_id, _Out_ sai_status_t *object_statuses) override { + SWSS_LOG_ENTER(); if (mock_bulkCreate) { return mock_bulkCreate(object_type, switch_id, object_count, attr_count, attr_list, mode, object_id, object_statuses); @@ -114,6 +124,7 @@ class MockableSaiInterface: public saimeta::DummySaiInterface _In_ sai_bulk_op_error_mode_t mode, _Out_ sai_status_t *object_statuses) override { + SWSS_LOG_ENTER(); if (mock_bulkRemove) { return mock_bulkRemove(object_type, object_count, object_id, mode, object_statuses); @@ -132,6 +143,7 @@ class MockableSaiInterface: public saimeta::DummySaiInterface _In_ sai_bulk_op_error_mode_t mode, _Out_ sai_status_t *object_statuses) override { + SWSS_LOG_ENTER(); if (mock_bulkSet) { return mock_bulkSet(object_type, object_count, object_id, attr_list, mode, object_statuses); @@ -151,6 +163,7 @@ class MockableSaiInterface: public saimeta::DummySaiInterface _In_ const sai_stat_id_t *counter_ids, _Out_ uint64_t *counters) override { + SWSS_LOG_ENTER(); if (mock_getStats) { return mock_getStats(object_type, object_id, number_of_counters, counter_ids, counters); @@ -166,6 +179,7 @@ class MockableSaiInterface: public saimeta::DummySaiInterface _In_ sai_object_type_t object_type, _Inout_ sai_stat_capability_list_t *stats_capability) override { + SWSS_LOG_ENTER(); if (mock_queryStatsCapability) { return mock_queryStatsCapability(switch_id, object_type, stats_capability); @@ -184,6 +198,7 @@ class MockableSaiInterface: public saimeta::DummySaiInterface _In_ sai_stats_mode_t mode, _Out_ uint64_t *counters) override { + SWSS_LOG_ENTER(); if (mock_getStatsExt) { return mock_getStatsExt(object_type, object_id, number_of_counters, counter_ids, mode, counters); @@ -200,6 +215,7 @@ class MockableSaiInterface: public saimeta::DummySaiInterface _In_ uint32_t number_of_counters, _In_ const sai_stat_id_t *counter_ids) override { + SWSS_LOG_ENTER(); if (mock_clearStats) { return mock_clearStats(object_type, object_id, number_of_counters, counter_ids); @@ -218,6 +234,7 @@ class MockableSaiInterface: public saimeta::DummySaiInterface _In_ uint32_t attrCount, _In_ const sai_attribute_t *attrList) override { + SWSS_LOG_ENTER(); if (mock_flushFdbEntries) { return mock_flushFdbEntries(switchId, attrCount, attrList); @@ -237,6 +254,7 @@ class MockableSaiInterface: public saimeta::DummySaiInterface _In_ const sai_attribute_t *attrList, _Out_ uint64_t *count) override { + SWSS_LOG_ENTER(); if (mock_objectTypeGetAvailability) { return mock_objectTypeGetAvailability(switchId, objectType, attrCount, attrList, count); @@ -254,6 +272,7 @@ class MockableSaiInterface: public saimeta::DummySaiInterface _In_ sai_attr_id_t attr_id, _Out_ sai_attr_capability_t *capability) override { + SWSS_LOG_ENTER(); if (mock_queryAttributeCapability) { return mock_queryAttributeCapability(switch_id, object_type, attr_id, capability); @@ -271,6 +290,7 @@ class MockableSaiInterface: public saimeta::DummySaiInterface _In_ sai_attr_id_t attr_id, _Inout_ sai_s32_list_t *enum_values_capability) override { + SWSS_LOG_ENTER(); if (mock_queryAattributeEnumValuesCapability) { return mock_queryAattributeEnumValuesCapability(switch_id, object_type, attr_id, enum_values_capability); @@ -284,6 +304,7 @@ class MockableSaiInterface: public saimeta::DummySaiInterface virtual sai_object_type_t objectTypeQuery( _In_ sai_object_id_t objectId) override { + SWSS_LOG_ENTER(); if (mock_objectTypeQuery) { return mock_objectTypeQuery(objectId); @@ -298,6 +319,7 @@ class MockableSaiInterface: public saimeta::DummySaiInterface virtual sai_object_id_t switchIdQuery( _In_ sai_object_id_t objectId) override { + SWSS_LOG_ENTER(); if (mock_switchIdQuery) { return mock_switchIdQuery(objectId); @@ -312,6 +334,7 @@ class MockableSaiInterface: public saimeta::DummySaiInterface _In_ sai_api_t api, _In_ sai_log_level_t log_level) override { + SWSS_LOG_ENTER(); if (mock_logSet) { return mock_logSet(api, log_level); From cdb6c6bf2180879f5d330345b85af1e497e1a952 Mon Sep 17 00:00:00 2001 From: junchao Date: Tue, 16 Nov 2021 13:30:32 +0800 Subject: [PATCH 5/6] Move logic of MockableInterface to cpp file --- unittest/syncd/Makefile.am | 1 + unittest/syncd/MockableSaiInterface.cpp | 274 ++++++++++++++++++++++++ unittest/syncd/MockableSaiInterface.h | 213 ++---------------- 3 files changed, 297 insertions(+), 191 deletions(-) create mode 100644 unittest/syncd/MockableSaiInterface.cpp diff --git a/unittest/syncd/Makefile.am b/unittest/syncd/Makefile.am index 999405282..e4f2f2661 100644 --- a/unittest/syncd/Makefile.am +++ b/unittest/syncd/Makefile.am @@ -6,6 +6,7 @@ LDADD_GTEST = -L/usr/src/gtest -lgtest -lgtest_main tests_SOURCES = main.cpp \ ../../meta/DummySaiInterface.cpp \ + MockableSaiInterface.cpp \ MockHelper.cpp \ TestCommandLineOptions.cpp \ TestFlexCounter.cpp diff --git a/unittest/syncd/MockableSaiInterface.cpp b/unittest/syncd/MockableSaiInterface.cpp new file mode 100644 index 000000000..6ed334bde --- /dev/null +++ b/unittest/syncd/MockableSaiInterface.cpp @@ -0,0 +1,274 @@ +#include "MockableSaiInterface.h" + +MockableSaiInterface::MockableSaiInterface() +{ +} + +MockableSaiInterface::~MockableSaiInterface() +{ +} + +sai_status_t MockableSaiInterface::initialize( + _In_ uint64_t flags, + _In_ const sai_service_method_table_t *service_method_table) +{ + return SAI_STATUS_SUCCESS; +} + +sai_status_t MockableSaiInterface::uninitialize() +{ + return SAI_STATUS_SUCCESS; +} + + +sai_status_t MockableSaiInterface::create( + _In_ sai_object_type_t objectType, + _Out_ sai_object_id_t* objectId, + _In_ sai_object_id_t switchId, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + if (mock_create) + { + return mock_create(objectType, objectId, switchId, attr_count, attr_list); + } + + return SAI_STATUS_SUCCESS; +} + + +sai_status_t MockableSaiInterface::remove( + _In_ sai_object_type_t objectType, + _In_ sai_object_id_t objectId) +{ + if (mock_remove) + { + return mock_remove(objectType, objectId); + } + + return SAI_STATUS_SUCCESS; +} + +sai_status_t MockableSaiInterface::set( + _In_ sai_object_type_t objectType, + _In_ sai_object_id_t objectId, + _In_ const sai_attribute_t *attr) +{ + if (mock_set) + { + return mock_set(objectType, objectId, attr); + } + + return SAI_STATUS_SUCCESS; +} + +sai_status_t MockableSaiInterface::get( + _In_ sai_object_type_t objectType, + _In_ sai_object_id_t objectId, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + if (mock_get) + { + return mock_get(objectType, objectId, attr_count, attr_list); + } + + return SAI_STATUS_SUCCESS; +} + +sai_status_t MockableSaiInterface::bulkCreate( + _In_ sai_object_type_t object_type, + _In_ sai_object_id_t switch_id, + _In_ uint32_t object_count, + _In_ const uint32_t *attr_count, + _In_ const sai_attribute_t **attr_list, + _In_ sai_bulk_op_error_mode_t mode, + _Out_ sai_object_id_t *object_id, + _Out_ sai_status_t *object_statuses) +{ + if (mock_bulkCreate) + { + return mock_bulkCreate(object_type, switch_id, object_count, attr_count, attr_list, mode, object_id, object_statuses); + } + + return SAI_STATUS_SUCCESS; +} + +sai_status_t MockableSaiInterface::bulkRemove( + _In_ sai_object_type_t object_type, + _In_ uint32_t object_count, + _In_ const sai_object_id_t *object_id, + _In_ sai_bulk_op_error_mode_t mode, + _Out_ sai_status_t *object_statuses) +{ + if (mock_bulkRemove) + { + return mock_bulkRemove(object_type, object_count, object_id, mode, object_statuses); + } + + return SAI_STATUS_SUCCESS; +} + +sai_status_t MockableSaiInterface::bulkSet( + _In_ sai_object_type_t object_type, + _In_ uint32_t object_count, + _In_ const sai_object_id_t *object_id, + _In_ const sai_attribute_t *attr_list, + _In_ sai_bulk_op_error_mode_t mode, + _Out_ sai_status_t *object_statuses) +{ + if (mock_bulkSet) + { + return mock_bulkSet(object_type, object_count, object_id, attr_list, mode, object_statuses); + } + + return SAI_STATUS_SUCCESS; +} + +sai_status_t MockableSaiInterface::getStats( + _In_ sai_object_type_t object_type, + _In_ sai_object_id_t object_id, + _In_ uint32_t number_of_counters, + _In_ const sai_stat_id_t *counter_ids, + _Out_ uint64_t *counters) +{ + if (mock_getStats) + { + return mock_getStats(object_type, object_id, number_of_counters, counter_ids, counters); + } + + return SAI_STATUS_SUCCESS; +} + +sai_status_t MockableSaiInterface::queryStatsCapability( + _In_ sai_object_id_t switch_id, + _In_ sai_object_type_t object_type, + _Inout_ sai_stat_capability_list_t *stats_capability) +{ + if (mock_queryStatsCapability) + { + return mock_queryStatsCapability(switch_id, object_type, stats_capability); + } + + return SAI_STATUS_SUCCESS; +} + +sai_status_t MockableSaiInterface::getStatsExt( + _In_ sai_object_type_t object_type, + _In_ sai_object_id_t object_id, + _In_ uint32_t number_of_counters, + _In_ const sai_stat_id_t *counter_ids, + _In_ sai_stats_mode_t mode, + _Out_ uint64_t *counters) +{ + if (mock_getStatsExt) + { + return mock_getStatsExt(object_type, object_id, number_of_counters, counter_ids, mode, counters); + } + + return SAI_STATUS_SUCCESS; +} + +sai_status_t MockableSaiInterface::clearStats( + _In_ sai_object_type_t object_type, + _In_ sai_object_id_t object_id, + _In_ uint32_t number_of_counters, + _In_ const sai_stat_id_t *counter_ids) +{ + if (mock_clearStats) + { + return mock_clearStats(object_type, object_id, number_of_counters, counter_ids); + } + + return SAI_STATUS_SUCCESS; +} + +sai_status_t MockableSaiInterface::flushFdbEntries( + _In_ sai_object_id_t switchId, + _In_ uint32_t attrCount, + _In_ const sai_attribute_t *attrList) +{ + if (mock_flushFdbEntries) + { + return mock_flushFdbEntries(switchId, attrCount, attrList); + } + + return SAI_STATUS_SUCCESS; +} + +sai_status_t MockableSaiInterface::objectTypeGetAvailability( + _In_ sai_object_id_t switchId, + _In_ sai_object_type_t objectType, + _In_ uint32_t attrCount, + _In_ const sai_attribute_t *attrList, + _Out_ uint64_t *count) +{ + if (mock_objectTypeGetAvailability) + { + return mock_objectTypeGetAvailability(switchId, objectType, attrCount, attrList, count); + } + + return SAI_STATUS_SUCCESS; +} + +sai_status_t MockableSaiInterface::queryAttributeCapability( + _In_ sai_object_id_t switch_id, + _In_ sai_object_type_t object_type, + _In_ sai_attr_id_t attr_id, + _Out_ sai_attr_capability_t *capability) +{ + if (mock_queryAttributeCapability) + { + return mock_queryAttributeCapability(switch_id, object_type, attr_id, capability); + } + + return SAI_STATUS_SUCCESS; +} + +sai_status_t MockableSaiInterface::queryAattributeEnumValuesCapability( + _In_ sai_object_id_t switch_id, + _In_ sai_object_type_t object_type, + _In_ sai_attr_id_t attr_id, + _Inout_ sai_s32_list_t *enum_values_capability) +{ + if (mock_queryAattributeEnumValuesCapability) + { + return mock_queryAattributeEnumValuesCapability(switch_id, object_type, attr_id, enum_values_capability); + } + + return SAI_STATUS_SUCCESS; +} + +sai_object_type_t MockableSaiInterface::objectTypeQuery( + _In_ sai_object_id_t objectId) +{ + if (mock_objectTypeQuery) + { + return mock_objectTypeQuery(objectId); + } + + return SAI_OBJECT_TYPE_NULL; +} + +sai_object_id_t MockableSaiInterface::switchIdQuery( + _In_ sai_object_id_t objectId) +{ + if (mock_switchIdQuery) + { + return mock_switchIdQuery(objectId); + } + + return 0; +} + +sai_status_t MockableSaiInterface::logSet( + _In_ sai_api_t api, + _In_ sai_log_level_t log_level) +{ + if (mock_logSet) + { + return mock_logSet(api, log_level); + } + + return SAI_STATUS_SUCCESS; +} diff --git a/unittest/syncd/MockableSaiInterface.h b/unittest/syncd/MockableSaiInterface.h index a2c9e3b97..536c45830 100644 --- a/unittest/syncd/MockableSaiInterface.h +++ b/unittest/syncd/MockableSaiInterface.h @@ -8,23 +8,16 @@ class MockableSaiInterface: public saimeta::DummySaiInterface { public: - MockableSaiInterface() - { - SWSS_LOG_ENTER(); - } + MockableSaiInterface(); - virtual ~MockableSaiInterface() - { - SWSS_LOG_ENTER(); - } + virtual ~MockableSaiInterface(); public: virtual sai_status_t initialize( _In_ uint64_t flags, - _In_ const sai_service_method_table_t *service_method_table) override { return SAI_STATUS_SUCCESS; } - - virtual sai_status_t uninitialize(void) override { return SAI_STATUS_SUCCESS; } + _In_ const sai_service_method_table_t *service_method_table) override; + virtual sai_status_t uninitialize(void) override; public: // SAI interface overrides @@ -33,47 +26,20 @@ class MockableSaiInterface: public saimeta::DummySaiInterface _Out_ sai_object_id_t* objectId, _In_ sai_object_id_t switchId, _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) override - { - SWSS_LOG_ENTER(); - if (mock_create) - { - return mock_create(objectType, objectId, switchId, attr_count, attr_list); - } - - return SAI_STATUS_SUCCESS; - } + _In_ const sai_attribute_t *attr_list) override; std::function mock_create; virtual sai_status_t remove( _In_ sai_object_type_t objectType, - _In_ sai_object_id_t objectId) override - { - SWSS_LOG_ENTER(); - if (mock_remove) - { - return mock_remove(objectType, objectId); - } - - return SAI_STATUS_SUCCESS; - } + _In_ sai_object_id_t objectId) override; std::function mock_remove; virtual sai_status_t set( _In_ sai_object_type_t objectType, _In_ sai_object_id_t objectId, - _In_ const sai_attribute_t *attr) override - { - SWSS_LOG_ENTER(); - if (mock_set) - { - return mock_set(objectType, objectId, attr); - } - - return SAI_STATUS_SUCCESS; - } + _In_ const sai_attribute_t *attr) override; std::function mock_set; @@ -81,16 +47,7 @@ class MockableSaiInterface: public saimeta::DummySaiInterface _In_ sai_object_type_t objectType, _In_ sai_object_id_t objectId, _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) override - { - SWSS_LOG_ENTER(); - if (mock_get) - { - return mock_get(objectType, objectId, attr_count, attr_list); - } - - return SAI_STATUS_SUCCESS; - } + _Inout_ sai_attribute_t *attr_list) override; std::function mock_get; @@ -104,16 +61,7 @@ class MockableSaiInterface: public saimeta::DummySaiInterface _In_ const sai_attribute_t **attr_list, _In_ sai_bulk_op_error_mode_t mode, _Out_ sai_object_id_t *object_id, - _Out_ sai_status_t *object_statuses) override - { - SWSS_LOG_ENTER(); - if (mock_bulkCreate) - { - return mock_bulkCreate(object_type, switch_id, object_count, attr_count, attr_list, mode, object_id, object_statuses); - } - - return SAI_STATUS_SUCCESS; - } + _Out_ sai_status_t *object_statuses) override; std::function mock_bulkCreate; @@ -122,16 +70,7 @@ class MockableSaiInterface: public saimeta::DummySaiInterface _In_ uint32_t object_count, _In_ const sai_object_id_t *object_id, _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) override - { - SWSS_LOG_ENTER(); - if (mock_bulkRemove) - { - return mock_bulkRemove(object_type, object_count, object_id, mode, object_statuses); - } - - return SAI_STATUS_SUCCESS; - } + _Out_ sai_status_t *object_statuses) override; std::function mock_bulkRemove; @@ -141,16 +80,7 @@ class MockableSaiInterface: public saimeta::DummySaiInterface _In_ const sai_object_id_t *object_id, _In_ const sai_attribute_t *attr_list, _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) override - { - SWSS_LOG_ENTER(); - if (mock_bulkSet) - { - return mock_bulkSet(object_type, object_count, object_id, attr_list, mode, object_statuses); - } - - return SAI_STATUS_SUCCESS; - } + _Out_ sai_status_t *object_statuses) override; std::function mock_bulkSet; @@ -161,32 +91,14 @@ class MockableSaiInterface: public saimeta::DummySaiInterface _In_ sai_object_id_t object_id, _In_ uint32_t number_of_counters, _In_ const sai_stat_id_t *counter_ids, - _Out_ uint64_t *counters) override - { - SWSS_LOG_ENTER(); - if (mock_getStats) - { - return mock_getStats(object_type, object_id, number_of_counters, counter_ids, counters); - } - - return SAI_STATUS_SUCCESS; - } + _Out_ uint64_t *counters) override; std::function mock_getStats; virtual sai_status_t queryStatsCapability( _In_ sai_object_id_t switch_id, _In_ sai_object_type_t object_type, - _Inout_ sai_stat_capability_list_t *stats_capability) override - { - SWSS_LOG_ENTER(); - if (mock_queryStatsCapability) - { - return mock_queryStatsCapability(switch_id, object_type, stats_capability); - } - - return SAI_STATUS_SUCCESS; - } + _Inout_ sai_stat_capability_list_t *stats_capability) override; std::function mock_queryStatsCapability; @@ -196,16 +108,7 @@ class MockableSaiInterface: public saimeta::DummySaiInterface _In_ uint32_t number_of_counters, _In_ const sai_stat_id_t *counter_ids, _In_ sai_stats_mode_t mode, - _Out_ uint64_t *counters) override - { - SWSS_LOG_ENTER(); - if (mock_getStatsExt) - { - return mock_getStatsExt(object_type, object_id, number_of_counters, counter_ids, mode, counters); - } - - return SAI_STATUS_SUCCESS; - } + _Out_ uint64_t *counters) override; std::function mock_getStatsExt; @@ -213,16 +116,7 @@ class MockableSaiInterface: public saimeta::DummySaiInterface _In_ sai_object_type_t object_type, _In_ sai_object_id_t object_id, _In_ uint32_t number_of_counters, - _In_ const sai_stat_id_t *counter_ids) override - { - SWSS_LOG_ENTER(); - if (mock_clearStats) - { - return mock_clearStats(object_type, object_id, number_of_counters, counter_ids); - } - - return SAI_STATUS_SUCCESS; - } + _In_ const sai_stat_id_t *counter_ids) override; std::function mock_clearStats; @@ -232,16 +126,7 @@ class MockableSaiInterface: public saimeta::DummySaiInterface virtual sai_status_t flushFdbEntries( _In_ sai_object_id_t switchId, _In_ uint32_t attrCount, - _In_ const sai_attribute_t *attrList) override - { - SWSS_LOG_ENTER(); - if (mock_flushFdbEntries) - { - return mock_flushFdbEntries(switchId, attrCount, attrList); - } - - return SAI_STATUS_SUCCESS; - } + _In_ const sai_attribute_t *attrList) override; std::function mock_flushFdbEntries; @@ -252,16 +137,7 @@ class MockableSaiInterface: public saimeta::DummySaiInterface _In_ sai_object_type_t objectType, _In_ uint32_t attrCount, _In_ const sai_attribute_t *attrList, - _Out_ uint64_t *count) override - { - SWSS_LOG_ENTER(); - if (mock_objectTypeGetAvailability) - { - return mock_objectTypeGetAvailability(switchId, objectType, attrCount, attrList, count); - } - - return SAI_STATUS_SUCCESS; - } + _Out_ uint64_t *count) override; std::function mock_objectTypeGetAvailability; @@ -270,16 +146,7 @@ class MockableSaiInterface: public saimeta::DummySaiInterface _In_ sai_object_id_t switch_id, _In_ sai_object_type_t object_type, _In_ sai_attr_id_t attr_id, - _Out_ sai_attr_capability_t *capability) override - { - SWSS_LOG_ENTER(); - if (mock_queryAttributeCapability) - { - return mock_queryAttributeCapability(switch_id, object_type, attr_id, capability); - } - - return SAI_STATUS_SUCCESS; - } + _Out_ sai_attr_capability_t *capability) override; std::function mock_queryAttributeCapability; @@ -288,60 +155,24 @@ class MockableSaiInterface: public saimeta::DummySaiInterface _In_ sai_object_id_t switch_id, _In_ sai_object_type_t object_type, _In_ sai_attr_id_t attr_id, - _Inout_ sai_s32_list_t *enum_values_capability) override - { - SWSS_LOG_ENTER(); - if (mock_queryAattributeEnumValuesCapability) - { - return mock_queryAattributeEnumValuesCapability(switch_id, object_type, attr_id, enum_values_capability); - } - - return SAI_STATUS_SUCCESS; - } + _Inout_ sai_s32_list_t *enum_values_capability) override; std::function mock_queryAattributeEnumValuesCapability; virtual sai_object_type_t objectTypeQuery( - _In_ sai_object_id_t objectId) override - { - SWSS_LOG_ENTER(); - if (mock_objectTypeQuery) - { - return mock_objectTypeQuery(objectId); - } - - return SAI_OBJECT_TYPE_NULL; - } + _In_ sai_object_id_t objectId) override; std::function mock_objectTypeQuery; virtual sai_object_id_t switchIdQuery( - _In_ sai_object_id_t objectId) override - { - SWSS_LOG_ENTER(); - if (mock_switchIdQuery) - { - return mock_switchIdQuery(objectId); - } - - return 0; - } + _In_ sai_object_id_t objectId) override; std::function mock_switchIdQuery; virtual sai_status_t logSet( _In_ sai_api_t api, - _In_ sai_log_level_t log_level) override - { - SWSS_LOG_ENTER(); - if (mock_logSet) - { - return mock_logSet(api, log_level); - } - - return SAI_STATUS_SUCCESS; - } + _In_ sai_log_level_t log_level) override; std::function mock_logSet; }; From 03a8e765e8df182ac08ce82901f4340db07574d3 Mon Sep 17 00:00:00 2001 From: junchao Date: Wed, 17 Nov 2021 18:24:20 +0800 Subject: [PATCH 6/6] Make checker happy --- unittest/syncd/MockableSaiInterface.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/unittest/syncd/MockableSaiInterface.cpp b/unittest/syncd/MockableSaiInterface.cpp index 6ed334bde..30b52a2d3 100644 --- a/unittest/syncd/MockableSaiInterface.cpp +++ b/unittest/syncd/MockableSaiInterface.cpp @@ -1,22 +1,28 @@ #include "MockableSaiInterface.h" +#include "swss/logger.h" + MockableSaiInterface::MockableSaiInterface() { + SWSS_LOG_ENTER(); } MockableSaiInterface::~MockableSaiInterface() { + SWSS_LOG_ENTER(); } sai_status_t MockableSaiInterface::initialize( _In_ uint64_t flags, _In_ const sai_service_method_table_t *service_method_table) { + SWSS_LOG_ENTER(); return SAI_STATUS_SUCCESS; } sai_status_t MockableSaiInterface::uninitialize() { + SWSS_LOG_ENTER(); return SAI_STATUS_SUCCESS; } @@ -28,6 +34,7 @@ sai_status_t MockableSaiInterface::create( _In_ uint32_t attr_count, _In_ const sai_attribute_t *attr_list) { + SWSS_LOG_ENTER(); if (mock_create) { return mock_create(objectType, objectId, switchId, attr_count, attr_list); @@ -41,6 +48,7 @@ sai_status_t MockableSaiInterface::remove( _In_ sai_object_type_t objectType, _In_ sai_object_id_t objectId) { + SWSS_LOG_ENTER(); if (mock_remove) { return mock_remove(objectType, objectId); @@ -54,6 +62,7 @@ sai_status_t MockableSaiInterface::set( _In_ sai_object_id_t objectId, _In_ const sai_attribute_t *attr) { + SWSS_LOG_ENTER(); if (mock_set) { return mock_set(objectType, objectId, attr); @@ -68,6 +77,7 @@ sai_status_t MockableSaiInterface::get( _In_ uint32_t attr_count, _Inout_ sai_attribute_t *attr_list) { + SWSS_LOG_ENTER(); if (mock_get) { return mock_get(objectType, objectId, attr_count, attr_list); @@ -86,6 +96,7 @@ sai_status_t MockableSaiInterface::bulkCreate( _Out_ sai_object_id_t *object_id, _Out_ sai_status_t *object_statuses) { + SWSS_LOG_ENTER(); if (mock_bulkCreate) { return mock_bulkCreate(object_type, switch_id, object_count, attr_count, attr_list, mode, object_id, object_statuses); @@ -101,6 +112,7 @@ sai_status_t MockableSaiInterface::bulkRemove( _In_ sai_bulk_op_error_mode_t mode, _Out_ sai_status_t *object_statuses) { + SWSS_LOG_ENTER(); if (mock_bulkRemove) { return mock_bulkRemove(object_type, object_count, object_id, mode, object_statuses); @@ -117,6 +129,7 @@ sai_status_t MockableSaiInterface::bulkSet( _In_ sai_bulk_op_error_mode_t mode, _Out_ sai_status_t *object_statuses) { + SWSS_LOG_ENTER(); if (mock_bulkSet) { return mock_bulkSet(object_type, object_count, object_id, attr_list, mode, object_statuses); @@ -132,6 +145,7 @@ sai_status_t MockableSaiInterface::getStats( _In_ const sai_stat_id_t *counter_ids, _Out_ uint64_t *counters) { + SWSS_LOG_ENTER(); if (mock_getStats) { return mock_getStats(object_type, object_id, number_of_counters, counter_ids, counters); @@ -145,6 +159,7 @@ sai_status_t MockableSaiInterface::queryStatsCapability( _In_ sai_object_type_t object_type, _Inout_ sai_stat_capability_list_t *stats_capability) { + SWSS_LOG_ENTER(); if (mock_queryStatsCapability) { return mock_queryStatsCapability(switch_id, object_type, stats_capability); @@ -161,6 +176,7 @@ sai_status_t MockableSaiInterface::getStatsExt( _In_ sai_stats_mode_t mode, _Out_ uint64_t *counters) { + SWSS_LOG_ENTER(); if (mock_getStatsExt) { return mock_getStatsExt(object_type, object_id, number_of_counters, counter_ids, mode, counters); @@ -175,6 +191,7 @@ sai_status_t MockableSaiInterface::clearStats( _In_ uint32_t number_of_counters, _In_ const sai_stat_id_t *counter_ids) { + SWSS_LOG_ENTER(); if (mock_clearStats) { return mock_clearStats(object_type, object_id, number_of_counters, counter_ids); @@ -188,6 +205,7 @@ sai_status_t MockableSaiInterface::flushFdbEntries( _In_ uint32_t attrCount, _In_ const sai_attribute_t *attrList) { + SWSS_LOG_ENTER(); if (mock_flushFdbEntries) { return mock_flushFdbEntries(switchId, attrCount, attrList); @@ -203,6 +221,7 @@ sai_status_t MockableSaiInterface::objectTypeGetAvailability( _In_ const sai_attribute_t *attrList, _Out_ uint64_t *count) { + SWSS_LOG_ENTER(); if (mock_objectTypeGetAvailability) { return mock_objectTypeGetAvailability(switchId, objectType, attrCount, attrList, count); @@ -217,6 +236,7 @@ sai_status_t MockableSaiInterface::queryAttributeCapability( _In_ sai_attr_id_t attr_id, _Out_ sai_attr_capability_t *capability) { + SWSS_LOG_ENTER(); if (mock_queryAttributeCapability) { return mock_queryAttributeCapability(switch_id, object_type, attr_id, capability); @@ -231,6 +251,7 @@ sai_status_t MockableSaiInterface::queryAattributeEnumValuesCapability( _In_ sai_attr_id_t attr_id, _Inout_ sai_s32_list_t *enum_values_capability) { + SWSS_LOG_ENTER(); if (mock_queryAattributeEnumValuesCapability) { return mock_queryAattributeEnumValuesCapability(switch_id, object_type, attr_id, enum_values_capability); @@ -242,6 +263,7 @@ sai_status_t MockableSaiInterface::queryAattributeEnumValuesCapability( sai_object_type_t MockableSaiInterface::objectTypeQuery( _In_ sai_object_id_t objectId) { + SWSS_LOG_ENTER(); if (mock_objectTypeQuery) { return mock_objectTypeQuery(objectId); @@ -253,6 +275,7 @@ sai_object_type_t MockableSaiInterface::objectTypeQuery( sai_object_id_t MockableSaiInterface::switchIdQuery( _In_ sai_object_id_t objectId) { + SWSS_LOG_ENTER(); if (mock_switchIdQuery) { return mock_switchIdQuery(objectId); @@ -265,6 +288,7 @@ sai_status_t MockableSaiInterface::logSet( _In_ sai_api_t api, _In_ sai_log_level_t log_level) { + SWSS_LOG_ENTER(); if (mock_logSet) { return mock_logSet(api, log_level);