From e6ec1424788b887bcb04947486e16a1d770dc2c3 Mon Sep 17 00:00:00 2001 From: Kamil Cudnik Date: Fri, 22 Nov 2024 14:34:58 +0100 Subject: [PATCH] [syncd] Add attribute version check feature (#1470) By default disabled. If enabled, it will use SAI metadata and libsai version returned by sai_api_version_query to verify if given attribute during SAI discovery process was introduced in the current libsai version or below that version. This feature is partial solution to this problem: https://github.com/sonic-net/sonic-buildimage/issues/20725, more here: https://github.com/opencomputeproject/SAI/issues/2099 --- syncd/AttrVersionChecker.cpp | 107 ++++++++++++++++++ syncd/AttrVersionChecker.h | 40 +++++++ syncd/CommandLineOptions.cpp | 4 + syncd/CommandLineOptions.h | 1 + syncd/CommandLineOptionsParser.cpp | 11 +- syncd/HardReiniter.cpp | 9 +- syncd/HardReiniter.h | 5 +- syncd/Makefile.am | 1 + syncd/SaiDiscovery.cpp | 30 ++++- syncd/SaiDiscovery.h | 7 +- syncd/SaiSwitch.cpp | 10 +- syncd/SaiSwitch.h | 5 +- syncd/SingleReiniter.cpp | 8 +- syncd/SingleReiniter.h | 5 +- syncd/Syncd.cpp | 8 +- tests/aspell.en.pws | 1 + tests/utils.pm | 10 +- unittest/syncd/Makefile.am | 1 + unittest/syncd/TestAttrVersionChecker.cpp | 132 ++++++++++++++++++++++ unittest/syncd/TestCommandLineOptions.cpp | 4 +- 20 files changed, 371 insertions(+), 28 deletions(-) create mode 100644 syncd/AttrVersionChecker.cpp create mode 100644 syncd/AttrVersionChecker.h create mode 100644 unittest/syncd/TestAttrVersionChecker.cpp diff --git a/syncd/AttrVersionChecker.cpp b/syncd/AttrVersionChecker.cpp new file mode 100644 index 000000000..320afcaf5 --- /dev/null +++ b/syncd/AttrVersionChecker.cpp @@ -0,0 +1,107 @@ +#include "AttrVersionChecker.h" + +#include "swss/logger.h" + +using namespace syncd; + +AttrVersionChecker::AttrVersionChecker(): + m_enabled(false), + m_saiApiVersion(SAI_VERSION(0,0,0)) +{ + SWSS_LOG_ENTER(); + + // empty +} + +void AttrVersionChecker::enable( + _In_ bool enable) +{ + SWSS_LOG_ENTER(); + + m_enabled = enable; +} + +void AttrVersionChecker::setSaiApiVersion( + _In_ sai_api_version_t version) +{ + SWSS_LOG_ENTER(); + + m_saiApiVersion = version; +} + +void AttrVersionChecker::reset() +{ + SWSS_LOG_ENTER(); + + m_visitedAttributes.clear(); +} + +bool AttrVersionChecker::isSufficientVersion( + _In_ const sai_attr_metadata_t *md) +{ + SWSS_LOG_ENTER(); + + if (md == nullptr) + { + SWSS_LOG_ERROR("md is NULL"); + + return false; + } + + if (!m_enabled) + { + return true; + } + + if (SAI_METADATA_HAVE_ATTR_VERSION == 0) + { + // metadata does not contain attr versions, no check will be preformed + return true; + } + + // check attr version if metadata have version defined + + if (m_saiApiVersion > md->apiversion) + { + // ok, SAI version is bigger than attribute release version + + return true; + } + + if (m_saiApiVersion < md->apiversion) + { + // skip, SAI version is not sufficient + + if (m_visitedAttributes.find(md->attridname) == m_visitedAttributes.end()) + { + m_visitedAttributes.insert(md->attridname); + + // log only once + + SWSS_LOG_WARN("SAI version %lu, not sufficient to discover %s", m_saiApiVersion, md->attridname); + } + + return false; + } + + // m_saiApiVersion == md->apiversion + + if (md->nextrelease == false) + { + // ok, SAI version is equal to attribute version + return true; + } + + // next release == true + + if (m_visitedAttributes.find(md->attridname) == m_visitedAttributes.end()) + { + m_visitedAttributes.insert(md->attridname); + + // warn only once + + SWSS_LOG_WARN("%s is ment for next release after %lu, will not discover", md->attridname, m_saiApiVersion); + } + + return false; +} diff --git a/syncd/AttrVersionChecker.h b/syncd/AttrVersionChecker.h new file mode 100644 index 000000000..f2b65cddd --- /dev/null +++ b/syncd/AttrVersionChecker.h @@ -0,0 +1,40 @@ +#pragma once + +extern "C" { +#include "sai.h" +#include "saimetadata.h" +} + +#include +#include + +namespace syncd +{ + class AttrVersionChecker + { + public: + + AttrVersionChecker(); + + public: + + void enable( + _In_ bool enable); + + void setSaiApiVersion( + _In_ sai_api_version_t version); + + void reset(); + + bool isSufficientVersion( + _In_ const sai_attr_metadata_t *md); + + private: + + bool m_enabled; + + sai_api_version_t m_saiApiVersion; + + std::set m_visitedAttributes; + }; +} diff --git a/syncd/CommandLineOptions.cpp b/syncd/CommandLineOptions.cpp index 0c25c8cad..59ef25106 100644 --- a/syncd/CommandLineOptions.cpp +++ b/syncd/CommandLineOptions.cpp @@ -44,6 +44,9 @@ CommandLineOptions::CommandLineOptions() #endif // SAITHRIFT + m_supportingBulkCounterGroups = ""; + + m_enableAttrVersionCheck = false; } std::string CommandLineOptions::getCommandLineString() const @@ -67,6 +70,7 @@ std::string CommandLineOptions::getCommandLineString() const ss << " BreakConfig=" << m_breakConfig; ss << " WatchdogWarnTimeSpan=" << m_watchdogWarnTimeSpan; ss << " SupportingBulkCounters=" << m_supportingBulkCounterGroups; + ss << " EnableAttrVersionCheck=" << (m_enableAttrVersionCheck ? "YES" : "NO"); #ifdef SAITHRIFT diff --git a/syncd/CommandLineOptions.h b/syncd/CommandLineOptions.h index 99d0827d6..72982ea5e 100644 --- a/syncd/CommandLineOptions.h +++ b/syncd/CommandLineOptions.h @@ -100,5 +100,6 @@ namespace syncd std::string m_supportingBulkCounterGroups; + bool m_enableAttrVersionCheck; }; } diff --git a/syncd/CommandLineOptionsParser.cpp b/syncd/CommandLineOptionsParser.cpp index d49624336..66c13e49c 100644 --- a/syncd/CommandLineOptionsParser.cpp +++ b/syncd/CommandLineOptionsParser.cpp @@ -19,9 +19,9 @@ std::shared_ptr CommandLineOptionsParser::parseCommandLine( auto options = std::make_shared(); #ifdef SAITHRIFT - const char* const optstring = "dp:t:g:x:b:B:w:uSUCsz:lrm:h"; + const char* const optstring = "dp:t:g:x:b:B:aw:uSUCsz:lrm:h"; #else - const char* const optstring = "dp:t:g:x:b:B:w:uSUCsz:lh"; + const char* const optstring = "dp:t:g:x:b:B:aw:uSUCsz:lh"; #endif // SAITHRIFT while (true) @@ -43,6 +43,7 @@ std::shared_ptr CommandLineOptionsParser::parseCommandLine( { "breakConfig", required_argument, 0, 'b' }, { "watchdogWarnTimeSpan", optional_argument, 0, 'w' }, { "supportingBulkCounters", required_argument, 0, 'B' }, + { "enableAttrVersionCheck", no_argument, 0, 'a' }, #ifdef SAITHRIFT { "rpcserver", no_argument, 0, 'r' }, { "portmap", required_argument, 0, 'm' }, @@ -138,6 +139,10 @@ std::shared_ptr CommandLineOptionsParser::parseCommandLine( options->m_supportingBulkCounterGroups = std::string(optarg); break; + case 'a': + options->m_enableAttrVersionCheck = true; + break; + case 'h': printUsage(); exit(EXIT_SUCCESS); @@ -196,6 +201,8 @@ void CommandLineOptionsParser::printUsage() std::cout << " Watchdog time span (in microseconds) to watch for execution" << std::endl; std::cout << " -B --supportingBulkCounters" << std::endl; std::cout << " Counter groups those support bulk polling" << std::endl; + std::cout << " -a --enableAttrVersionCheck" << std::endl; + std::cout << " Enable attribute SAI version check when performing SAI discovery" << std::endl; #ifdef SAITHRIFT diff --git a/syncd/HardReiniter.cpp b/syncd/HardReiniter.cpp index 8c714eb23..9b621f8b0 100644 --- a/syncd/HardReiniter.cpp +++ b/syncd/HardReiniter.cpp @@ -13,11 +13,13 @@ HardReiniter::HardReiniter( _In_ std::shared_ptr client, _In_ std::shared_ptr translator, _In_ std::shared_ptr sai, - _In_ std::shared_ptr handler): + _In_ std::shared_ptr handler, + _In_ bool checkAttrVersion): m_vendorSai(sai), m_translator(translator), m_client(client), - m_handler(handler) + m_handler(handler), + m_checkAttrVersion(checkAttrVersion) { SWSS_LOG_ENTER(); @@ -99,7 +101,8 @@ std::map> HardReiniter::hardR m_handler, m_switchVidToRid.at(kvp.first), m_switchRidToVid.at(kvp.first), - kvp.second); + kvp.second, + m_checkAttrVersion); sr->hardReinit(); diff --git a/syncd/HardReiniter.h b/syncd/HardReiniter.h index 9a032d16e..435f38f16 100644 --- a/syncd/HardReiniter.h +++ b/syncd/HardReiniter.h @@ -27,7 +27,8 @@ namespace syncd _In_ std::shared_ptr client, _In_ std::shared_ptr translator, _In_ std::shared_ptr sai, - _In_ std::shared_ptr handler); + _In_ std::shared_ptr handler, + _In_ bool checkAttrVersion); virtual ~HardReiniter(); @@ -59,5 +60,7 @@ namespace syncd std::shared_ptr m_client; std::shared_ptr m_handler; + + bool m_checkAttrVersion; }; } diff --git a/syncd/Makefile.am b/syncd/Makefile.am index 3c546fb74..8c8cddaf3 100644 --- a/syncd/Makefile.am +++ b/syncd/Makefile.am @@ -17,6 +17,7 @@ noinst_LIBRARIES = libSyncd.a libSyncdRequestShutdown.a libMdioIpcClient.a libSyncd_a_SOURCES = \ AsicOperation.cpp \ AsicView.cpp \ + AttrVersionChecker.cpp \ BestCandidateFinder.cpp \ BreakConfig.cpp \ BreakConfigParser.cpp \ diff --git a/syncd/SaiDiscovery.cpp b/syncd/SaiDiscovery.cpp index 8615526bb..43e01016a 100644 --- a/syncd/SaiDiscovery.cpp +++ b/syncd/SaiDiscovery.cpp @@ -19,12 +19,31 @@ using namespace syncd; #define SAI_DISCOVERY_LIST_MAX_ELEMENTS 1024 SaiDiscovery::SaiDiscovery( - _In_ std::shared_ptr sai): + _In_ std::shared_ptr sai, + _In_ bool checkAttrVersion): m_sai(sai) { SWSS_LOG_ENTER(); - // empty + sai_api_version_t version = SAI_VERSION(0,0,0); + + sai_status_t status = m_sai->queryApiVersion(&version); + + if (status == SAI_STATUS_SUCCESS) + { + m_attrVersionChecker.enable(checkAttrVersion); + m_attrVersionChecker.setSaiApiVersion(version); + + SWSS_LOG_NOTICE("check attr version ENABLED, libsai api version: %lu", version); + } + else + { + m_attrVersionChecker.enable(false); + m_attrVersionChecker.setSaiApiVersion(SAI_API_VERSION); + + SWSS_LOG_WARN("failed to obtain libsai api version: %s, will discover all attributes", + sai_serialize_status(status).c_str()); + } } SaiDiscovery::~SaiDiscovery() @@ -110,6 +129,11 @@ void SaiDiscovery::discover( attr.id = md->attrid; + if (!m_attrVersionChecker.isSufficientVersion(md)) + { + continue; + } + if (md->attrvaluetype == SAI_ATTR_VALUE_TYPE_OBJECT_ID) { if (md->defaultvaluetype == SAI_DEFAULT_VALUE_TYPE_CONST) @@ -259,6 +283,8 @@ std::set SaiDiscovery::discover( m_defaultOidMap.clear(); + m_attrVersionChecker.reset(); + std::set discovered_rids; { diff --git a/syncd/SaiDiscovery.h b/syncd/SaiDiscovery.h index c48372b08..c677a5b87 100644 --- a/syncd/SaiDiscovery.h +++ b/syncd/SaiDiscovery.h @@ -2,6 +2,8 @@ #include "meta/SaiInterface.h" +#include "AttrVersionChecker.h" + #include #include #include @@ -18,7 +20,8 @@ namespace syncd public: SaiDiscovery( - _In_ std::shared_ptr sai); + _In_ std::shared_ptr sai, + _In_ bool checkAttrVersion); virtual ~SaiDiscovery(); @@ -61,5 +64,7 @@ namespace syncd std::shared_ptr m_sai; DefaultOidMap m_defaultOidMap; + + AttrVersionChecker m_attrVersionChecker; }; } diff --git a/syncd/SaiSwitch.cpp b/syncd/SaiSwitch.cpp index fb711db4d..4f11dba4c 100644 --- a/syncd/SaiSwitch.cpp +++ b/syncd/SaiSwitch.cpp @@ -26,12 +26,14 @@ SaiSwitch::SaiSwitch( _In_ std::shared_ptr client, _In_ std::shared_ptr translator, _In_ std::shared_ptr vendorSai, - _In_ bool warmBoot): + _In_ bool warmBoot, + _In_ bool checkAttrVersion): SaiSwitchInterface(switch_vid, switch_rid), m_vendorSai(vendorSai), m_warmBoot(warmBoot), m_translator(translator), - m_client(client) + m_client(client), + m_checkAttrVersion(checkAttrVersion) { SWSS_LOG_ENTER(); @@ -661,7 +663,7 @@ void SaiSwitch::helperDiscover() { SWSS_LOG_ENTER(); - SaiDiscovery sd(m_vendorSai); + SaiDiscovery sd(m_vendorSai, m_checkAttrVersion); m_discovered_rids = sd.discover(m_switch_rid); @@ -952,7 +954,7 @@ void SaiSwitch::onPostPortCreate( { SWSS_LOG_ENTER(); - SaiDiscovery sd(m_vendorSai); + SaiDiscovery sd(m_vendorSai, m_checkAttrVersion); auto discovered = sd.discover(port_rid); diff --git a/syncd/SaiSwitch.h b/syncd/SaiSwitch.h index 523e1fe1d..4c317678a 100644 --- a/syncd/SaiSwitch.h +++ b/syncd/SaiSwitch.h @@ -34,7 +34,8 @@ namespace syncd _In_ std::shared_ptr client, _In_ std::shared_ptr translator, _In_ std::shared_ptr vendorSai, - _In_ bool warmBoot = false); + _In_ bool warmBoot, + _In_ bool checkAttrVersion); virtual ~SaiSwitch() = default; @@ -353,5 +354,7 @@ namespace syncd std::shared_ptr m_translator; std::shared_ptr m_client; + + bool m_checkAttrVersion; }; } diff --git a/syncd/SingleReiniter.cpp b/syncd/SingleReiniter.cpp index f757ba515..6844d3cf7 100644 --- a/syncd/SingleReiniter.cpp +++ b/syncd/SingleReiniter.cpp @@ -22,14 +22,16 @@ SingleReiniter::SingleReiniter( _In_ std::shared_ptr handler, _In_ const ObjectIdMap& vidToRidMap, _In_ const ObjectIdMap& ridToVidMap, - _In_ const std::vector& asicKeys): + _In_ const std::vector& asicKeys, + _In_ bool checkAttrVersion): m_vendorSai(sai), m_vidToRidMap(vidToRidMap), m_ridToVidMap(ridToVidMap), m_asicKeys(asicKeys), m_translator(translator), m_client(client), - m_handler(handler) + m_handler(handler), + m_checkAttrVersion(checkAttrVersion) { SWSS_LOG_ENTER(); @@ -317,7 +319,7 @@ void SingleReiniter::processSwitches() * object, so when doing discover we will get full default ASIC view. */ - m_sw = std::make_shared(m_switch_vid, m_switch_rid, m_client, m_translator, m_vendorSai); + m_sw = std::make_shared(m_switch_vid, m_switch_rid, m_client, m_translator, m_vendorSai, false, m_checkAttrVersion); /* * We processed switch. We have switch vid/rid so we can process all diff --git a/syncd/SingleReiniter.h b/syncd/SingleReiniter.h index e33b26af8..b6a27eaab 100644 --- a/syncd/SingleReiniter.h +++ b/syncd/SingleReiniter.h @@ -32,7 +32,8 @@ namespace syncd _In_ std::shared_ptr handler, _In_ const ObjectIdMap& vidToRidMap, _In_ const ObjectIdMap& ridToVidMap, - _In_ const std::vector& asicKeys); + _In_ const std::vector& asicKeys, + _In_ bool checkAttrVersion); virtual ~SingleReiniter(); @@ -136,5 +137,7 @@ namespace syncd std::shared_ptr m_client; std::shared_ptr m_handler; + + bool m_checkAttrVersion; }; } diff --git a/syncd/Syncd.cpp b/syncd/Syncd.cpp index 9c2533c3a..83f6b18ba 100644 --- a/syncd/Syncd.cpp +++ b/syncd/Syncd.cpp @@ -3136,7 +3136,7 @@ sai_status_t Syncd::processOidCreate( * constructor, like getting all queues, ports, etc. */ - m_switches[switchVid] = std::make_shared(switchVid, objectRid, m_client, m_translator, m_vendorSai); + m_switches[switchVid] = std::make_shared(switchVid, objectRid, m_client, m_translator, m_vendorSai, false, m_commandLineOptions->m_enableAttrVersionCheck); m_mdioIpcServer->setSwitchId(objectRid); @@ -4353,7 +4353,7 @@ void Syncd::onSyncdStart( SWSS_LOG_THROW("performing hard reinit, but there are %zu switches defined, bug!", m_switches.size()); } - HardReiniter hr(m_client, m_translator, m_vendorSai, m_handler); + HardReiniter hr(m_client, m_translator, m_vendorSai, m_handler, m_commandLineOptions->m_enableAttrVersionCheck); m_switches = hr.hardReinit(); @@ -4455,7 +4455,7 @@ void Syncd::onSwitchCreateInInitViewMode( // make switch initialization and get all default data - m_switches[switchVid] = std::make_shared(switchVid, switchRid, m_client, m_translator, m_vendorSai); + m_switches[switchVid] = std::make_shared(switchVid, switchRid, m_client, m_translator, m_vendorSai, false, m_commandLineOptions->m_enableAttrVersionCheck); m_mdioIpcServer->setSwitchId(switchRid); @@ -4639,7 +4639,7 @@ void Syncd::performWarmRestartSingleSwitch( // perform all get operations on existing switch - auto sw = m_switches[switchVid] = std::make_shared(switchVid, switchRid, m_client, m_translator, m_vendorSai, true); + auto sw = m_switches[switchVid] = std::make_shared(switchVid, switchRid, m_client, m_translator, m_vendorSai, true, m_commandLineOptions->m_enableAttrVersionCheck); startDiagShell(switchRid); } diff --git a/tests/aspell.en.pws b/tests/aspell.en.pws index 1908c5834..a51e8f4c6 100644 --- a/tests/aspell.en.pws +++ b/tests/aspell.en.pws @@ -478,3 +478,4 @@ saiproxy submodule Enqueue deque +apiversion diff --git a/tests/utils.pm b/tests/utils.pm index 489e5bb5a..34b120bf8 100644 --- a/tests/utils.pm +++ b/tests/utils.pm @@ -48,19 +48,19 @@ sub flush_redis sub start_syncd { print color('bright_blue') . "Starting syncd" . color('reset') . "\n"; - `./vssyncd -SUu -p "$DIR/vsprofile.ini" @_ >/dev/null 2>/dev/null &`; + `./vssyncd -aSUu -p "$DIR/vsprofile.ini" @_ >/dev/null 2>/dev/null &`; } sub start_syncd_bulk { print color('bright_blue') . "Starting syncd bulk" . color('reset') . "\n"; - `./vssyncd -SUul -p "$DIR/vsprofile.ini" @_ >/dev/null 2>/dev/null &`; + `./vssyncd -aSUul -p "$DIR/vsprofile.ini" @_ >/dev/null 2>/dev/null &`; } sub start_syncd_warm { print color('bright_blue') . "Starting syncd warm" . color('reset') . "\n"; - `./vssyncd -SUu -t warm -p "$DIR/vsprofile.ini" >/dev/null 2>/dev/null &`; + `./vssyncd -aSUu -t warm -p "$DIR/vsprofile.ini" >/dev/null 2>/dev/null &`; sleep 1; } @@ -68,13 +68,13 @@ sub start_syncd_warm sub sync_start_syncd { print color('bright_blue') . "Starting syncd" . color('reset') . "\n"; - `./vssyncd -s -SUu -p "$DIR/vsprofile.ini" >/dev/null 2>/dev/null &`; + `./vssyncd -s -aSUu -p "$DIR/vsprofile.ini" >/dev/null 2>/dev/null &`; } sub sync_start_syncd_warm { print color('bright_blue') . "Starting syncd warm" . color('reset') . "\n"; - `./vssyncd -s -SUu -t warm -p "$DIR/vsprofile.ini" >/dev/null 2>/dev/null &`; + `./vssyncd -s -aSUu -t warm -p "$DIR/vsprofile.ini" >/dev/null 2>/dev/null &`; sleep 1; } diff --git a/unittest/syncd/Makefile.am b/unittest/syncd/Makefile.am index b06a3ec08..13b0a43d2 100644 --- a/unittest/syncd/Makefile.am +++ b/unittest/syncd/Makefile.am @@ -7,6 +7,7 @@ LDADD_GTEST = -L/usr/src/gtest -lgtest -lgtest_main -lgmock tests_SOURCES = main.cpp \ MockableSaiInterface.cpp \ MockHelper.cpp \ + TestAttrVersionChecker.cpp \ TestCommandLineOptions.cpp \ TestConcurrentQueue.cpp \ TestFlexCounter.cpp \ diff --git a/unittest/syncd/TestAttrVersionChecker.cpp b/unittest/syncd/TestAttrVersionChecker.cpp new file mode 100644 index 000000000..f1bc91ab9 --- /dev/null +++ b/unittest/syncd/TestAttrVersionChecker.cpp @@ -0,0 +1,132 @@ +#include + +#include +#include +#include + +#include + +#include "AttrVersionChecker.h" +#include "swss/logger.h" + +using namespace syncd; + +TEST(AttrVersionChecker, ctr) +{ + AttrVersionChecker avc; +} + +TEST(AttrVersionChecker, enable) +{ + AttrVersionChecker avc; + + avc.enable(true); + + avc.enable(false); +} + +TEST(AttrVersionChecker, setSaiApiVersion) +{ + AttrVersionChecker avc; + + avc.setSaiApiVersion(SAI_VERSION(1,13,0)); +} + +TEST(AttrVersionChecker, reset) +{ + AttrVersionChecker avc; + + avc.reset(); +} + +#define MD(x,v,n) \ + const sai_attr_metadata_t x = {\ + .objecttype = (sai_object_type_t)SAI_OBJECT_TYPE_BRIDGE,\ + .attrid = SAI_BRIDGE_ATTR_PORT_LIST,\ + .attridname = "SAI_BRIDGE_ATTR_PORT_LIST",\ + .brief = "List of bridge ports associated to this bridge.",\ + .attrvaluetype = SAI_ATTR_VALUE_TYPE_OBJECT_LIST,\ + .flags = (sai_attr_flags_t)(SAI_ATTR_FLAGS_READ_ONLY),\ + .allowedobjecttypes = NULL,\ + .allowedobjecttypeslength = 0,\ + .allowrepetitiononlist = false,\ + .allowmixedobjecttypes = false,\ + .allowemptylist = false,\ + .allownullobjectid = false,\ + .isoidattribute = (1 > 0),\ + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE,\ + .defaultvalue = NULL,\ + .defaultvalueobjecttype = SAI_OBJECT_TYPE_NULL,\ + .defaultvalueattrid = SAI_INVALID_ATTRIBUTE_ID,\ + .storedefaultvalue = false,\ + .isenum = false,\ + .isenumlist = false,\ + .enummetadata = NULL,\ + .conditiontype = SAI_ATTR_CONDITION_TYPE_NONE,\ + .conditions = NULL,\ + .conditionslength = 0,\ + .isconditional = (0 != 0),\ + .validonlytype = SAI_ATTR_CONDITION_TYPE_NONE,\ + .validonly = NULL,\ + .validonlylength = 0,\ + .isvalidonly = (0 != 0),\ + .getsave = false,\ + .isvlan = false,\ + .isaclfield = false,\ + .isaclaction = false,\ + .isaclmask = false,\ + .ismandatoryoncreate = false,\ + .iscreateonly = false,\ + .iscreateandset = false,\ + .isreadonly = true,\ + .iskey = false,\ + .isprimitive = false,\ + .notificationtype = -1,\ + .iscallback = false,\ + .pointertype = -1,\ + .capability = NULL,\ + .capabilitylength = 0,\ + .isextensionattr = false,\ + .isresourcetype = false,\ + .isdeprecated = false,\ + .isconditionrelaxed = false,\ + .iscustom = false,\ + .apiversion = (v),\ + .nextrelease = (n),\ + };\ + + +TEST(AttrVersionChecker, isSufficientVersion) +{ + AttrVersionChecker avc; + + avc.enable(true); + EXPECT_EQ(avc.isSufficientVersion(nullptr), false); + + avc.enable(false); + avc.setSaiApiVersion(SAI_VERSION(1,10,0)); + avc.enable(true); + + MD(md,SAI_VERSION(1,9,0),false); + EXPECT_EQ(avc.isSufficientVersion(&md), true); + + MD(md1,SAI_VERSION(1,11,0),false); + EXPECT_EQ(avc.isSufficientVersion(&md1),false); + + avc.enable(false); + EXPECT_EQ(avc.isSufficientVersion(&md1),true); + + avc.enable(true); + avc.setSaiApiVersion(SAI_VERSION(1,10,0)); + EXPECT_EQ(avc.isSufficientVersion(&md1),false); + + avc.setSaiApiVersion(SAI_VERSION(1,12,0)); + EXPECT_EQ(avc.isSufficientVersion(&md1),true); + + avc.setSaiApiVersion(SAI_VERSION(1,11,0)); + EXPECT_EQ(avc.isSufficientVersion(&md1),true); + + MD(md2,SAI_VERSION(1,11,0),true); + avc.setSaiApiVersion(SAI_VERSION(1,11,0)); + EXPECT_EQ(avc.isSufficientVersion(&md2),false); +} diff --git a/unittest/syncd/TestCommandLineOptions.cpp b/unittest/syncd/TestCommandLineOptions.cpp index 7c9088bf0..0eb5aaef3 100644 --- a/unittest/syncd/TestCommandLineOptions.cpp +++ b/unittest/syncd/TestCommandLineOptions.cpp @@ -38,6 +38,8 @@ R"(Usage: syncd [-d] [-p profile] [-t type] [-u] [-S] [-U] [-C] [-s] [-z mode] [ Watchdog time span (in microseconds) to watch for execution -B --supportingBulkCounters Counter groups those support bulk polling + -a --enableAttrVersionCheck + Enable attribute SAI version check when performing SAI discovery -h --help Print out this message )"; @@ -51,7 +53,7 @@ TEST(CommandLineOptions, getCommandLineString) EXPECT_EQ(str, " EnableDiagShell=NO EnableTempView=NO DisableExitSleep=NO EnableUnittests=NO" " EnableConsistencyCheck=NO EnableSyncMode=NO RedisCommunicationMode=redis_async" " EnableSaiBulkSuport=NO StartType=cold ProfileMapFile= GlobalContext=0 ContextConfig= BreakConfig=" - " WatchdogWarnTimeSpan=30000000 SupportingBulkCounters="); + " WatchdogWarnTimeSpan=30000000 SupportingBulkCounters= EnableAttrVersionCheck=NO"); } TEST(CommandLineOptions, startTypeStringToStartType)