diff --git a/.azure-pipelines/build-swss-template.yml b/.azure-pipelines/build-swss-template.yml index 9a0098c43..6c1c3173d 100644 --- a/.azure-pipelines/build-swss-template.yml +++ b/.azure-pipelines/build-swss-template.yml @@ -50,10 +50,6 @@ jobs: sudo apt-get install -y libzmq5 libzmq3-dev sudo apt-get install -qq -y \ libhiredis-dev \ - libnl-3-dev \ - libnl-genl-3-dev \ - libnl-route-3-dev \ - libnl-nf-3-dev \ swig3.0 sudo apt-get install -y libdbus-1-3 sudo apt-get install -y libteam-dev \ @@ -73,7 +69,24 @@ jobs: inputs: artifact: ${{ parameters.sairedis_artifact_name }} displayName: "Download sonic sairedis deb packages" + - task: DownloadPipelineArtifact@2 + inputs: + source: specific + project: build + pipeline: 1 + artifact: sonic-buildimage.vs + runVersion: 'latestFromBranch' + runBranch: 'refs/heads/master' + displayName: "Download sonic buildimage" - script: | + sudo dpkg -i target/debs/buster/libnl-3-200_*.deb + sudo dpkg -i target/debs/buster/libnl-3-dev_*.deb + sudo dpkg -i target/debs/buster/libnl-genl-3-200_*.deb + sudo dpkg -i target/debs/buster/libnl-genl-3-dev_*.deb + sudo dpkg -i target/debs/buster/libnl-route-3-200_*.deb + sudo dpkg -i target/debs/buster/libnl-route-3-dev_*.deb + sudo dpkg -i target/debs/buster/libnl-nf-3-200_*.deb + sudo dpkg -i target/debs/buster/libnl-nf-3-dev_*.deb sudo dpkg -i libswsscommon_1.0.0_${{ parameters.arch }}.deb sudo dpkg -i libswsscommon-dev_1.0.0_${{ parameters.arch }}.deb sudo dpkg -i libsaivs_*.deb @@ -84,7 +97,7 @@ jobs: sudo dpkg -i libsaimetadata-dev_*.deb sudo dpkg -i syncd-vs_*.deb workingDirectory: $(Pipeline.Workspace) - displayName: "Install sonic swss common and sairedis" + displayName: "Install libnl3, sonic swss common, and sairedis" - checkout: sonic-swss path: s submodules: true diff --git a/.azure-pipelines/build-template.yml b/.azure-pipelines/build-template.yml index 2432d375e..8fc68c31c 100644 --- a/.azure-pipelines/build-template.yml +++ b/.azure-pipelines/build-template.yml @@ -33,6 +33,10 @@ parameters: type: boolean default: false +- name: archive_gcov + type: boolean + default: false + jobs: - job: displayName: ${{ parameters.arch }} @@ -97,20 +101,48 @@ jobs: - checkout: self submodules: true - script: | + set -ex ./autogen.sh - fakeroot dpkg-buildpackage -b -us -uc -Tbinary-syncd-vs -j$(nproc) && cp ../*.deb . - displayName: "Compile sonic sairedis" + fakeroot debian/rules DEB_CONFIGURE_EXTRA_FLAGS='--enable-code-coverage' CFLAGS="" CXXFLAGS="" binary-syncd-vs && cp ../*.deb . + displayName: "Compile sonic sairedis with coverage enabled" - script: | sudo cp azsyslog.conf /etc/rsyslog.conf sudo service rsyslog restart displayName: "Update rsyslog.conf" - ${{ if eq(parameters.run_unit_test, true) }}: - script: | + set -ex + git clone https://github.com/Spacetown/gcovr.git + cd gcovr/ + git checkout origin/recursive_search_file + sudo pip3 install setuptools + sudo python3 setup.py install + cd .. + sudo rm -rf gcovr + displayName: "Install gcovr 5.0 with recursive fix" + - script: | + set -ex make check + gcovr --version + gcovr -r ./ -e ".*/SAI/.*" -e ".+/json.hpp" -e "swss/.+" -e ".*/.libs/.*" -e ".*/debian/.*" --exclude-unreachable-branches --exclude-throw-branches -x -o coverage.xml displayName: "Run sonic sairedis unit tests" - publish: $(System.DefaultWorkingDirectory)/ artifact: ${{ parameters.artifact_name }} displayName: "Archive sonic sairedis debian packages" + - ${{ if eq(parameters.archive_gcov, true) }}: + - script: | + set -ex + # Install .NET CORE + curl -sSL https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add - + sudo apt-add-repository https://packages.microsoft.com/debian/10/prod + sudo apt-get update + sudo apt-get install -y dotnet-sdk-5.0 + displayName: "Install .NET CORE" + - task: PublishCodeCoverageResults@1 + inputs: + codeCoverageTool: Cobertura + summaryFileLocation: '$(System.DefaultWorkingDirectory)/coverage.xml' + displayName: 'Publish test coverage' - script: | pwd sudo chmod a+r /var/log/syslog* diff --git a/.gitignore b/.gitignore index 02d2723f9..b55d71be9 100644 --- a/.gitignore +++ b/.gitignore @@ -88,8 +88,8 @@ deps/ # Executables # ############### lib/tests -vslib/tests meta/tests +saiasiccmp/saiasiccmp saidiscovery/saidiscovery saidump/saidump saiplayer/saiplayer @@ -97,10 +97,16 @@ saisdkdump/saisdkdump syncd/syncd syncd/syncd_request_shutdown tests/syncd -tests/vssyncd -saiasiccmp/saiasiccmp -tests/tests tests/testclient +tests/tests +tests/vssyncd +unittest/lib/tests +unittest/lib/testslibsairedis +unittest/meta/tests +unittest/syncd/tests +unittest/vslib/tests +unittest/vslib/testslibsaivs +vslib/tests # Temporary files # ################### diff --git a/azure-pipelines.yml b/azure-pipelines.yml index a786b0997..49f85d5a5 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -27,6 +27,7 @@ stages: artifact_name: sonic-sairedis syslog_artifact_name: sonic-sairedis.syslog run_unit_test: true + archive_gcov: true - stage: BuildArm dependsOn: Build @@ -35,7 +36,7 @@ stages: - template: .azure-pipelines/build-template.yml parameters: arch: armhf - timeout: 180 + timeout: 240 pool: sonicbld sonic_slave: sonic-slave-buster-armhf swss_common_artifact_name: sonic-swss-common.armhf @@ -45,7 +46,7 @@ stages: - template: .azure-pipelines/build-template.yml parameters: arch: arm64 - timeout: 180 + timeout: 240 pool: sonicbld sonic_slave: sonic-slave-buster-arm64 swss_common_artifact_name: sonic-swss-common.arm64 diff --git a/debian/rules b/debian/rules index 674ba1f05..f83631959 100755 --- a/debian/rules +++ b/debian/rules @@ -69,7 +69,7 @@ binary-syncd-vs: override_dh_auto_configure: ./autogen.sh - dh_auto_configure -- $(shell cat /tmp/syncd-build) ${SWSS_COMMON_CONFIG} + dh_auto_configure -- $(DEB_CONFIGURE_EXTRA_FLAGS) $(shell cat /tmp/syncd-build) ${SWSS_COMMON_CONFIG} override_dh_install: dh_install diff --git a/lib/ClientConfig.cpp b/lib/ClientConfig.cpp index 7a165d5ad..c54b2858b 100644 --- a/lib/ClientConfig.cpp +++ b/lib/ClientConfig.cpp @@ -55,7 +55,7 @@ std::shared_ptr ClientConfig::loadFromFile( auto cc = std::make_shared(); cc->m_zmqEndpoint = j["zmq_endpoint"]; - cc->m_zmqNtfEndpoint = j["zmq_endpoint_ntf"]; + cc->m_zmqNtfEndpoint = j["zmq_ntf_endpoint"]; SWSS_LOG_NOTICE("client config: %s, %s", cc->m_zmqEndpoint.c_str(), diff --git a/lib/ServerConfig.cpp b/lib/ServerConfig.cpp index 09f8e7a0d..4c8adda57 100644 --- a/lib/ServerConfig.cpp +++ b/lib/ServerConfig.cpp @@ -55,7 +55,7 @@ std::shared_ptr ServerConfig::loadFromFile( auto cc = std::make_shared(); cc->m_zmqEndpoint = j["zmq_endpoint"]; - cc->m_zmqNtfEndpoint = j["zmq_endpoint_ntf"]; + cc->m_zmqNtfEndpoint = j["zmq_ntf_endpoint"]; SWSS_LOG_NOTICE("server config: %s, %s", cc->m_zmqEndpoint.c_str(), diff --git a/lib/Switch.cpp b/lib/Switch.cpp index 0f909f13e..8e513e145 100644 --- a/lib/Switch.cpp +++ b/lib/Switch.cpp @@ -109,7 +109,7 @@ void Switch::updateNotifications( break; case SAI_SWITCH_ATTR_BFD_SESSION_STATE_CHANGE_NOTIFY: - m_switchNotifications.on_bfd_session_state_change = + m_switchNotifications.on_bfd_session_state_change = (sai_bfd_session_state_change_notification_fn)attr.value.ptr; break; diff --git a/lib/src/client_config.json b/lib/client_config.json similarity index 100% rename from lib/src/client_config.json rename to lib/client_config.json diff --git a/lib/src/context_config.json b/lib/context_config.json similarity index 100% rename from lib/src/context_config.json rename to lib/context_config.json diff --git a/lib/sairediscommon.h b/lib/sairediscommon.h index d0de3dd26..7f3eeda96 100644 --- a/lib/sairediscommon.h +++ b/lib/sairediscommon.h @@ -8,9 +8,14 @@ #define SYNCD_INIT_VIEW "INIT_VIEW" #define SYNCD_APPLY_VIEW "APPLY_VIEW" #define SYNCD_INSPECT_ASIC "SYNCD_INSPECT_ASIC" + #define ASIC_STATE_TABLE "ASIC_STATE" #define TEMP_PREFIX "TEMP_" +#define REDIS_COMMUNICATION_MODE_REDIS_ASYNC_STRING "redis_async" +#define REDIS_COMMUNICATION_MODE_REDIS_SYNC_STRING "redis_sync" +#define REDIS_COMMUNICATION_MODE_ZMQ_SYNC_STRING "zmq_sync" + /* * Asic state table commands. Those names are special and they will be used * inside swsscommon library LUA scripts to perform operations on redis diff --git a/meta/Makefile.am b/meta/Makefile.am index fa3e2a86c..89cf12562 100644 --- a/meta/Makefile.am +++ b/meta/Makefile.am @@ -34,15 +34,16 @@ libsaimeta_la_SOURCES = \ NotificationSwitchShutdownRequest.cpp \ NotificationSwitchStateChange.cpp \ NotificationBfdSessionStateChange.cpp \ + NumberOidIndexGenerator.cpp \ OidRefCounter.cpp \ PerformanceIntervalTimer.cpp \ PortRelatedSet.cpp \ RedisSelectableChannel.cpp \ - SaiAttributeList.cpp \ SaiAttrWrapper.cpp \ + SaiAttributeList.cpp \ SaiInterface.cpp \ - SaiObjectCollection.cpp \ SaiObject.cpp \ + SaiObjectCollection.cpp \ SaiSerialize.cpp \ SelectableChannel.cpp \ ZeroMQSelectableChannel.cpp @@ -50,19 +51,3 @@ libsaimeta_la_SOURCES = \ libsaimeta_la_CPPFLAGS = $(CODE_COVERAGE_CPPFLAGS) libsaimeta_la_CXXFLAGS = $(DBGFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS_COMMON) $(CODE_COVERAGE_CXXFLAGS) libsaimeta_la_LIBADD = -lhiredis -lswsscommon libsaimetadata.la $(CODE_COVERAGE_LIBS) - -bin_PROGRAMS = tests - -tests_SOURCES = \ - tests.cpp \ - DummySaiInterface.cpp \ - MetaTestSaiInterface.cpp \ - NumberOidIndexGenerator.cpp \ - ../lib/VirtualObjectIdManager.cpp \ - ../lib/SwitchConfig.cpp \ - ../lib/SwitchConfigContainer.cpp - -tests_CXXFLAGS = $(DBGFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS_COMMON) -tests_LDADD = -lhiredis -lswsscommon -lpthread libsaimetadata.la libsaimeta.la -lzmq - -TESTS = tests diff --git a/meta/Meta.cpp b/meta/Meta.cpp index 5e9d3263c..5a4b8d4b6 100644 --- a/meta/Meta.cpp +++ b/meta/Meta.cpp @@ -33,6 +33,11 @@ } \ } +#define META_LOG_STATUS(status,msg) \ + if ((status) == SAI_STATUS_SUCCESS) \ + { SWSS_LOG_DEBUG(msg " status: %s", sai_serialize_status(status).c_str()); } \ + else { SWSS_LOG_ERROR(msg " status: %s", sai_serialize_status(status).c_str()); } + using namespace saimeta; Meta::Meta( @@ -101,7 +106,7 @@ void Meta::meta_init_db() SWSS_LOG_NOTICE("end"); } -bool Meta::isEmpty() +bool Meta::isEmpty() const { SWSS_LOG_ENTER(); @@ -111,6 +116,31 @@ bool Meta::isEmpty() && m_saiObjectCollection.getAllKeys().empty(); } +void Meta::dump() const +{ + SWSS_LOG_ENTER(); + + if (isEmpty() == false) + { + std::cout << "portRelatedSet: " << m_portRelatedSet.getAllPorts().size() << std::endl; + std::cout << "oids: " << m_oids.getAllOids().size() << std::endl; + std::cout << "attrKeys: " << m_attrKeys.getAllKeys().size() << std::endl; + std::cout << "saiObjectCollection: " << m_saiObjectCollection.getAllKeys().size() << std::endl; + + for (auto &oid: m_oids.getAllReferences()) + { + printf("oid: %s: count: %u\n", + sai_serialize_object_id(oid.first).c_str(), + oid.second); + } + + for (auto &mk: m_saiObjectCollection.getAllKeys()) + { + printf("objcollection: %s\n", sai_serialize_object_meta_key(mk).c_str()); + } + } +} + sai_status_t Meta::remove( _In_ sai_object_type_t object_type, _In_ sai_object_id_t object_id) @@ -135,14 +165,7 @@ sai_status_t Meta::remove( status = m_implementation->remove(object_type, object_id); - if (status == SAI_STATUS_SUCCESS) - { - SWSS_LOG_DEBUG("remove status: %s", sai_serialize_status(status).c_str()); - } - else - { - SWSS_LOG_ERROR("remove status: %s", sai_serialize_status(status).c_str()); - } + META_LOG_STATUS(status, "remove"); if (status == SAI_STATUS_SUCCESS) { @@ -175,14 +198,7 @@ sai_status_t Meta::remove( status = m_implementation->remove(fdb_entry); - if (status == SAI_STATUS_SUCCESS) - { - SWSS_LOG_DEBUG("remove status: %s", sai_serialize_status(status).c_str()); - } - else - { - SWSS_LOG_ERROR("remove status: %s", sai_serialize_status(status).c_str()); - } + META_LOG_STATUS(status, "remove"); if (status == SAI_STATUS_SUCCESS) { @@ -215,14 +231,7 @@ sai_status_t Meta::remove( status = m_implementation->remove(mcast_fdb_entry); - if (status == SAI_STATUS_SUCCESS) - { - SWSS_LOG_DEBUG("remove status: %s", sai_serialize_status(status).c_str()); - } - else - { - SWSS_LOG_ERROR("remove status: %s", sai_serialize_status(status).c_str()); - } + META_LOG_STATUS(status, "remove"); if (status == SAI_STATUS_SUCCESS) { @@ -255,14 +264,7 @@ sai_status_t Meta::remove( status = m_implementation->remove(neighbor_entry); - if (status == SAI_STATUS_SUCCESS) - { - SWSS_LOG_DEBUG("remove status: %s", sai_serialize_status(status).c_str()); - } - else - { - SWSS_LOG_ERROR("remove status: %s", sai_serialize_status(status).c_str()); - } + META_LOG_STATUS(status, "remove"); if (status == SAI_STATUS_SUCCESS) { @@ -295,14 +297,7 @@ sai_status_t Meta::remove( status = m_implementation->remove(route_entry); - if (status == SAI_STATUS_SUCCESS) - { - SWSS_LOG_DEBUG("remove status: %s", sai_serialize_status(status).c_str()); - } - else - { - SWSS_LOG_ERROR("remove status: %s", sai_serialize_status(status).c_str()); - } + META_LOG_STATUS(status, "remove"); if (status == SAI_STATUS_SUCCESS) { @@ -335,14 +330,7 @@ sai_status_t Meta::remove( status = m_implementation->remove(l2mc_entry); - if (status == SAI_STATUS_SUCCESS) - { - SWSS_LOG_DEBUG("remove status: %s", sai_serialize_status(status).c_str()); - } - else - { - SWSS_LOG_ERROR("remove status: %s", sai_serialize_status(status).c_str()); - } + META_LOG_STATUS(status, "remove"); if (status == SAI_STATUS_SUCCESS) { @@ -375,14 +363,7 @@ sai_status_t Meta::remove( status = m_implementation->remove(ipmc_entry); - if (status == SAI_STATUS_SUCCESS) - { - SWSS_LOG_DEBUG("remove status: %s", sai_serialize_status(status).c_str()); - } - else - { - SWSS_LOG_ERROR("remove status: %s", sai_serialize_status(status).c_str()); - } + META_LOG_STATUS(status, "remove"); if (status == SAI_STATUS_SUCCESS) { @@ -415,14 +396,7 @@ sai_status_t Meta::remove( status = m_implementation->remove(nat_entry); - if (status == SAI_STATUS_SUCCESS) - { - SWSS_LOG_DEBUG("remove status: %s", sai_serialize_status(status).c_str()); - } - else - { - SWSS_LOG_ERROR("remove status: %s", sai_serialize_status(status).c_str()); - } + META_LOG_STATUS(status, "remove"); if (status == SAI_STATUS_SUCCESS) { @@ -455,14 +429,7 @@ sai_status_t Meta::remove( status = m_implementation->remove(inseg_entry); - if (status == SAI_STATUS_SUCCESS) - { - SWSS_LOG_DEBUG("remove status: %s", sai_serialize_status(status).c_str()); - } - else - { - SWSS_LOG_ERROR("remove status: %s", sai_serialize_status(status).c_str()); - } + META_LOG_STATUS(status, "remove"); if (status == SAI_STATUS_SUCCESS) { @@ -497,14 +464,7 @@ sai_status_t Meta::create( status = m_implementation->create(fdb_entry, attr_count, attr_list); - if (status == SAI_STATUS_SUCCESS) - { - SWSS_LOG_DEBUG("create status: %s", sai_serialize_status(status).c_str()); - } - else - { - SWSS_LOG_ERROR("create status: %s", sai_serialize_status(status).c_str()); - } + META_LOG_STATUS(status, "create"); if (status == SAI_STATUS_SUCCESS) { @@ -539,14 +499,7 @@ sai_status_t Meta::create( status = m_implementation->create(mcast_fdb_entry, attr_count, attr_list); - if (status == SAI_STATUS_SUCCESS) - { - SWSS_LOG_DEBUG("create status: %s", sai_serialize_status(status).c_str()); - } - else - { - SWSS_LOG_ERROR("create status: %s", sai_serialize_status(status).c_str()); - } + META_LOG_STATUS(status, "create"); if (status == SAI_STATUS_SUCCESS) { @@ -581,14 +534,7 @@ sai_status_t Meta::create( status = m_implementation->create(neighbor_entry, attr_count, attr_list); - if (status == SAI_STATUS_SUCCESS) - { - SWSS_LOG_DEBUG("create status: %s", sai_serialize_status(status).c_str()); - } - else - { - SWSS_LOG_ERROR("create status: %s", sai_serialize_status(status).c_str()); - } + META_LOG_STATUS(status, "create"); if (status == SAI_STATUS_SUCCESS) { @@ -622,14 +568,7 @@ sai_status_t Meta::create( status = m_implementation->create(route_entry, attr_count, attr_list); - if (status == SAI_STATUS_SUCCESS) - { - SWSS_LOG_DEBUG("create status: %s", sai_serialize_status(status).c_str()); - } - else - { - SWSS_LOG_ERROR("create status: %s", sai_serialize_status(status).c_str()); - } + META_LOG_STATUS(status, "create"); if (status == SAI_STATUS_SUCCESS) { @@ -664,14 +603,7 @@ sai_status_t Meta::create( status = m_implementation->create(l2mc_entry, attr_count, attr_list); - if (status == SAI_STATUS_SUCCESS) - { - SWSS_LOG_DEBUG("create status: %s", sai_serialize_status(status).c_str()); - } - else - { - SWSS_LOG_ERROR("create status: %s", sai_serialize_status(status).c_str()); - } + META_LOG_STATUS(status, "create"); if (status == SAI_STATUS_SUCCESS) { @@ -706,14 +638,7 @@ sai_status_t Meta::create( status = m_implementation->create(ipmc_entry, attr_count, attr_list); - if (status == SAI_STATUS_SUCCESS) - { - SWSS_LOG_DEBUG("create status: %s", sai_serialize_status(status).c_str()); - } - else - { - SWSS_LOG_ERROR("create status: %s", sai_serialize_status(status).c_str()); - } + META_LOG_STATUS(status, "create"); if (status == SAI_STATUS_SUCCESS) { @@ -748,14 +673,7 @@ sai_status_t Meta::create( status = m_implementation->create(inseg_entry, attr_count, attr_list); - if (status == SAI_STATUS_SUCCESS) - { - SWSS_LOG_DEBUG("create status: %s", sai_serialize_status(status).c_str()); - } - else - { - SWSS_LOG_ERROR("create status: %s", sai_serialize_status(status).c_str()); - } + META_LOG_STATUS(status, "create"); if (status == SAI_STATUS_SUCCESS) { @@ -790,14 +708,7 @@ sai_status_t Meta::create( status = m_implementation->create(nat_entry, attr_count, attr_list); - if (status == SAI_STATUS_SUCCESS) - { - SWSS_LOG_DEBUG("create status: %s", sai_serialize_status(status).c_str()); - } - else - { - SWSS_LOG_ERROR("create status: %s", sai_serialize_status(status).c_str()); - } + META_LOG_STATUS(status, "create"); if (status == SAI_STATUS_SUCCESS) { @@ -831,14 +742,7 @@ sai_status_t Meta::set( status = m_implementation->set(fdb_entry, attr); - if (status == SAI_STATUS_SUCCESS) - { - SWSS_LOG_DEBUG("set status: %s", sai_serialize_status(status).c_str()); - } - else - { - SWSS_LOG_ERROR("set status: %s", sai_serialize_status(status).c_str()); - } + META_LOG_STATUS(status, "set"); if (status == SAI_STATUS_SUCCESS) { @@ -872,14 +776,7 @@ sai_status_t Meta::set( status = m_implementation->set(mcast_fdb_entry, attr); - if (status == SAI_STATUS_SUCCESS) - { - SWSS_LOG_DEBUG("set status: %s", sai_serialize_status(status).c_str()); - } - else - { - SWSS_LOG_ERROR("set status: %s", sai_serialize_status(status).c_str()); - } + META_LOG_STATUS(status, "set"); if (status == SAI_STATUS_SUCCESS) { @@ -913,14 +810,7 @@ sai_status_t Meta::set( status = m_implementation->set(neighbor_entry, attr); - if (status == SAI_STATUS_SUCCESS) - { - SWSS_LOG_DEBUG("set status: %s", sai_serialize_status(status).c_str()); - } - else - { - SWSS_LOG_ERROR("set status: %s", sai_serialize_status(status).c_str()); - } + META_LOG_STATUS(status, "set"); if (status == SAI_STATUS_SUCCESS) { @@ -954,14 +844,7 @@ sai_status_t Meta::set( status = m_implementation->set(route_entry, attr); - if (status == SAI_STATUS_SUCCESS) - { - SWSS_LOG_DEBUG("set status: %s", sai_serialize_status(status).c_str()); - } - else - { - SWSS_LOG_ERROR("set status: %s", sai_serialize_status(status).c_str()); - } + META_LOG_STATUS(status, "set"); if (status == SAI_STATUS_SUCCESS) { @@ -995,14 +878,7 @@ sai_status_t Meta::set( status = m_implementation->set(l2mc_entry, attr); - if (status == SAI_STATUS_SUCCESS) - { - SWSS_LOG_DEBUG("set status: %s", sai_serialize_status(status).c_str()); - } - else - { - SWSS_LOG_ERROR("set status: %s", sai_serialize_status(status).c_str()); - } + META_LOG_STATUS(status, "set"); if (status == SAI_STATUS_SUCCESS) { @@ -1036,14 +912,7 @@ sai_status_t Meta::set( status = m_implementation->set(ipmc_entry, attr); - if (status == SAI_STATUS_SUCCESS) - { - SWSS_LOG_DEBUG("set status: %s", sai_serialize_status(status).c_str()); - } - else - { - SWSS_LOG_ERROR("set status: %s", sai_serialize_status(status).c_str()); - } + META_LOG_STATUS(status, "set"); if (status == SAI_STATUS_SUCCESS) { @@ -1077,14 +946,7 @@ sai_status_t Meta::set( status = m_implementation->set(inseg_entry, attr); - if (status == SAI_STATUS_SUCCESS) - { - SWSS_LOG_DEBUG("set status: %s", sai_serialize_status(status).c_str()); - } - else - { - SWSS_LOG_ERROR("set status: %s", sai_serialize_status(status).c_str()); - } + META_LOG_STATUS(status, "set"); if (status == SAI_STATUS_SUCCESS) { @@ -1117,14 +979,7 @@ sai_status_t Meta::set( status = m_implementation->set(nat_entry, attr); - if (status == SAI_STATUS_SUCCESS) - { - SWSS_LOG_DEBUG("set status: %s", sai_serialize_status(status).c_str()); - } - else - { - SWSS_LOG_ERROR("set status: %s", sai_serialize_status(status).c_str()); - } + META_LOG_STATUS(status, "set"); if (status == SAI_STATUS_SUCCESS) { @@ -1429,14 +1284,7 @@ sai_status_t Meta::create( status = m_implementation->create(object_type, object_id, switch_id, attr_count, attr_list); - if (status == SAI_STATUS_SUCCESS) - { - SWSS_LOG_DEBUG("create status: %s", sai_serialize_status(status).c_str()); - } - else - { - SWSS_LOG_ERROR("create status: %s", sai_serialize_status(status).c_str()); - } + META_LOG_STATUS(status, "create"); if (status == SAI_STATUS_SUCCESS) { @@ -1484,14 +1332,7 @@ sai_status_t Meta::set( status = m_implementation->set(object_type, object_id, attr); - if (status == SAI_STATUS_SUCCESS) - { - SWSS_LOG_DEBUG("set status: %s", sai_serialize_status(status).c_str()); - } - else - { - SWSS_LOG_ERROR("set status: %s", sai_serialize_status(status).c_str()); - } + META_LOG_STATUS(status, "set"); if (status == SAI_STATUS_SUCCESS) { @@ -1636,17 +1477,6 @@ sai_status_t Meta::flushFdbEntries( switch (md.attrvaluetype) { - case SAI_ATTR_VALUE_TYPE_UINT16: - - if (md.isvlan && (value.u16 >= 0xFFF || value.u16 == 0)) - { - META_LOG_ERROR(md, "is vlan id but has invalid id %u", value.u16); - - return SAI_STATUS_INVALID_PARAMETER; - } - - break; - case SAI_ATTR_VALUE_TYPE_INT32: if (md.isenum && !sai_metadata_is_allowed_enum_value(&md, value.s32)) @@ -1710,10 +1540,9 @@ sai_status_t Meta::flushFdbEntries( } else { - // no type specified so we need to flush static and dynamic entries + // no type specified so we need to flush dynamic only types.push_back(SAI_FDB_ENTRY_TYPE_DYNAMIC); - types.push_back(SAI_FDB_ENTRY_TYPE_STATIC); } for (auto type: types) @@ -4435,7 +4264,9 @@ sai_status_t Meta::meta_generic_validation_create( if (mdp == NULL) { - SWSS_LOG_ERROR("unable to find attribute metadata %d:%d", meta_key.objecttype, attr->id); + SWSS_LOG_ERROR("unable to find attribute metadata %s:%d", + sai_serialize_object_type(meta_key.objecttype).c_str(), + attr->id); return SAI_STATUS_FAILURE; } @@ -5083,7 +4914,9 @@ sai_status_t Meta::meta_generic_validation_set( if (mdp == NULL) { - SWSS_LOG_ERROR("unable to find attribute metadata %d:%d", meta_key.objecttype, attr->id); + SWSS_LOG_ERROR("unable to find attribute metadata %s:%d", + sai_serialize_object_type(meta_key.objecttype).c_str(), + attr->id); return SAI_STATUS_FAILURE; } @@ -5578,7 +5411,9 @@ sai_status_t Meta::meta_generic_validation_get( if (mdp == NULL) { - SWSS_LOG_ERROR("unable to find attribute metadata %d:%d", meta_key.objecttype, attr->id); + SWSS_LOG_ERROR("unable to find attribute metadata %s:%d", + sai_serialize_object_type(meta_key.objecttype).c_str(), + attr->id); return SAI_STATUS_FAILURE; } @@ -7562,6 +7397,14 @@ void Meta::meta_sai_on_switch_state_change( { SWSS_LOG_ENTER(); + if (!sai_metadata_get_enum_value_name( + &sai_metadata_enum_sai_switch_oper_status_t, + switch_oper_status)) + { + SWSS_LOG_WARN("switch oper status value (%d) not found in sai_switch_oper_status_t", + switch_oper_status); + } + auto ot = objectTypeQuery(switch_id); if (ot != SAI_OBJECT_TYPE_SWITCH) @@ -7569,6 +7412,8 @@ void Meta::meta_sai_on_switch_state_change( SWSS_LOG_WARN("switch_id %s is of type %s, but expected SAI_OBJECT_TYPE_SWITCH", sai_serialize_object_id(switch_id).c_str(), sai_serialize_object_type(ot).c_str()); + + return; } sai_object_meta_key_t switch_meta_key = { .objecttype = ot , .objectkey = { .key = { .object_id = switch_id } } }; @@ -7580,14 +7425,6 @@ void Meta::meta_sai_on_switch_state_change( } // we should not snoop switch_id, since switch id should be created directly by user - - if (!sai_metadata_get_enum_value_name( - &sai_metadata_enum_sai_switch_oper_status_t, - switch_oper_status)) - { - SWSS_LOG_WARN("switch oper status value (%d) not found in sai_switch_oper_status_t", - switch_oper_status); - } } void Meta::meta_sai_on_switch_shutdown_request( @@ -7602,6 +7439,8 @@ void Meta::meta_sai_on_switch_shutdown_request( SWSS_LOG_WARN("switch_id %s is of type %s, but expected SAI_OBJECT_TYPE_SWITCH", sai_serialize_object_id(switch_id).c_str(), sai_serialize_object_type(ot).c_str()); + + return; } sai_object_meta_key_t switch_meta_key = { .objecttype = ot , .objectkey = { .key = { .object_id = switch_id } } }; diff --git a/meta/Meta.h b/meta/Meta.h index e498d2a5d..28fec1c86 100644 --- a/meta/Meta.h +++ b/meta/Meta.h @@ -161,7 +161,9 @@ namespace saimeta void meta_init_db(); - bool isEmpty(); + bool isEmpty() const; + + void dump() const; public: // notifications @@ -186,7 +188,7 @@ namespace saimeta void meta_sai_on_bfd_session_state_change( _In_ uint32_t count, - _In_ const sai_bfd_session_state_notification_t *data); + _In_ const sai_bfd_session_state_notification_t *data); private: // notifications helpers diff --git a/meta/MetaKeyHasher.cpp b/meta/MetaKeyHasher.cpp index 1da4d8585..d7a6ee847 100644 --- a/meta/MetaKeyHasher.cpp +++ b/meta/MetaKeyHasher.cpp @@ -18,6 +18,17 @@ static bool operator==( memcmp(a.mac_address, b.mac_address, sizeof(a.mac_address)) == 0; } +static bool operator==( + _In_ const sai_mcast_fdb_entry_t& a, + _In_ const sai_mcast_fdb_entry_t& b) +{ + SWSS_LOG_ENTER(); + + return a.switch_id == b.switch_id && + a.bv_id == b.bv_id && + memcmp(a.mac_address, b.mac_address, sizeof(a.mac_address)) == 0; +} + static bool operator==( _In_ const sai_route_entry_t& a, _In_ const sai_route_entry_t& b) @@ -42,6 +53,88 @@ static bool operator==( memcmp(a.destination.mask.ip6, b.destination.mask.ip6, sizeof(b.destination.mask.ip6)) == 0; } + SWSS_LOG_THROW("unknown route entry IP addr family: %d", a.destination.addr_family); +} + +static bool operator==( + _In_ const sai_l2mc_entry_t& a, + _In_ const sai_l2mc_entry_t& b) +{ + // SWSS_LOG_ENTER(); // disabled for performance reasons + + bool part = a.switch_id == b.switch_id && + a.bv_id == b.bv_id && + a.type == b.type && + a.destination.addr_family == b.destination.addr_family && + a.source.addr_family == b.source.addr_family; + + if (a.destination.addr_family == SAI_IP_ADDR_FAMILY_IPV4) + { + part &= a.destination.addr.ip4 == b.destination.addr.ip4; + } + else if (a.destination.addr_family == SAI_IP_ADDR_FAMILY_IPV6) + { + part &= memcmp(a.destination.addr.ip6, b.destination.addr.ip6, sizeof(b.destination.addr.ip6)) == 0; + } + else + { + SWSS_LOG_THROW("unknown l2mc entry destination IP addr family: %d", a.destination.addr_family); + } + + if (a.source.addr_family == SAI_IP_ADDR_FAMILY_IPV4) + { + part &= a.source.addr.ip4 == b.source.addr.ip4; + } + else if (a.source.addr_family == SAI_IP_ADDR_FAMILY_IPV6) + { + part &= memcmp(a.source.addr.ip6, b.source.addr.ip6, sizeof(b.source.addr.ip6)) == 0; + } + else + { + SWSS_LOG_THROW("unknown l2mc entry source IP addr family: %d", a.source.addr_family); + } + + return part; +} + +static bool operator==( + _In_ const sai_ipmc_entry_t& a, + _In_ const sai_ipmc_entry_t& b) +{ + // SWSS_LOG_ENTER(); // disabled for performance reasons + + bool part = a.switch_id == b.switch_id && + a.vr_id == b.vr_id && + a.type == b.type && + a.destination.addr_family == b.destination.addr_family && + a.source.addr_family == b.source.addr_family; + + if (a.destination.addr_family == SAI_IP_ADDR_FAMILY_IPV4) + { + part &= a.destination.addr.ip4 == b.destination.addr.ip4; + } + else if (a.destination.addr_family == SAI_IP_ADDR_FAMILY_IPV6) + { + part &= memcmp(a.destination.addr.ip6, b.destination.addr.ip6, sizeof(b.destination.addr.ip6)) == 0; + } + else + { + SWSS_LOG_THROW("unknown l2mc entry destination IP addr family: %d", a.destination.addr_family); + } + + if (a.source.addr_family == SAI_IP_ADDR_FAMILY_IPV4) + { + part &= a.source.addr.ip4 == b.source.addr.ip4; + } + else if (a.source.addr_family == SAI_IP_ADDR_FAMILY_IPV6) + { + part &= memcmp(a.source.addr.ip6, b.source.addr.ip6, sizeof(b.source.addr.ip6)) == 0; + } + else + { + SWSS_LOG_THROW("unknown l2mc entry source IP addr family: %d", a.source.addr_family); + } + return part; } @@ -61,7 +154,7 @@ static bool operator==( if (a.ip_address.addr_family == SAI_IP_ADDR_FAMILY_IPV6) return part && memcmp(a.ip_address.addr.ip6, b.ip_address.addr.ip6, sizeof(b.ip_address.addr.ip6)) == 0; - return part; + SWSS_LOG_THROW("unknown neighbor entry IP addr family= %d", a.ip_address.addr_family); } static bool operator==( @@ -127,6 +220,15 @@ bool MetaKeyHasher::operator()( if (a.objecttype == SAI_OBJECT_TYPE_INSEG_ENTRY) return a.objectkey.key.inseg_entry == b.objectkey.key.inseg_entry; + if (a.objecttype == SAI_OBJECT_TYPE_MCAST_FDB_ENTRY) + return a.objectkey.key.mcast_fdb_entry == b.objectkey.key.mcast_fdb_entry; + + if (a.objecttype == SAI_OBJECT_TYPE_L2MC_ENTRY) + return a.objectkey.key.l2mc_entry == b.objectkey.key.l2mc_entry; + + if (a.objecttype == SAI_OBJECT_TYPE_IPMC_ENTRY) + return a.objectkey.key.ipmc_entry == b.objectkey.key.ipmc_entry; + SWSS_LOG_THROW("not implemented: %s", sai_serialize_object_meta_key(a).c_str()); } @@ -152,7 +254,7 @@ static inline std::size_t sai_get_hash( return ip6[0] ^ ip6[1] ^ ip6[2] ^ ip6[3]; } - return re.destination.addr_family; + SWSS_LOG_THROW("unknown route entry IP addr family: %d", re.destination.addr_family); } static inline std::size_t sai_get_hash( @@ -174,7 +276,7 @@ static inline std::size_t sai_get_hash( return ip6[0] ^ ip6[1] ^ ip6[2] ^ ip6[3]; } - return ne.ip_address.addr_family; + SWSS_LOG_THROW("unknown neighbor entry IP addr family= %d", ne.ip_address.addr_family); } static_assert(sizeof(uint32_t) == 4, "uint32_t expected to be 4 bytes"); @@ -211,6 +313,64 @@ static inline std::size_t sai_get_hash( return ie.label; } +static inline std::size_t sai_get_hash( + _In_ const sai_mcast_fdb_entry_t& mfe) +{ + // SWSS_LOG_ENTER(); // disabled for performance reasons + + uint32_t data; + + // use low 4 bytes of mac address as hash value + // use memcpy instead of cast because of strict-aliasing rules + memcpy(&data, mfe.mac_address + 2, sizeof(uint32_t)); + + return data; +} + +static inline std::size_t sai_get_hash( + _In_ const sai_l2mc_entry_t& le) +{ + // SWSS_LOG_ENTER(); // disabled for performance reasons + + if (le.destination.addr_family == SAI_IP_ADDR_FAMILY_IPV4) + { + return le.destination.addr.ip4; + } + + if (le.destination.addr_family == SAI_IP_ADDR_FAMILY_IPV6) + { + // cast is not good enough for arm (cast align) + uint32_t ip6[4]; + memcpy(ip6, le.destination.addr.ip6, sizeof(ip6)); + + return ip6[0] ^ ip6[1] ^ ip6[2] ^ ip6[3]; + } + + SWSS_LOG_THROW("unknown l2mc entry IP addr family: %d", le.destination.addr_family); +} + +static inline std::size_t sai_get_hash( + _In_ const sai_ipmc_entry_t& ie) +{ + // SWSS_LOG_ENTER(); // disabled for performance reasons + + if (ie.destination.addr_family == SAI_IP_ADDR_FAMILY_IPV4) + { + return ie.destination.addr.ip4; + } + + if (ie.destination.addr_family == SAI_IP_ADDR_FAMILY_IPV6) + { + // cast is not good enough for arm (cast align) + uint32_t ip6[4]; + memcpy(ip6, ie.destination.addr.ip6, sizeof(ip6)); + + return ip6[0] ^ ip6[1] ^ ip6[2] ^ ip6[3]; + } + + SWSS_LOG_THROW("unknown ipmc entry IP addr family: %d", ie.destination.addr_family); +} + std::size_t MetaKeyHasher::operator()( _In_ const sai_object_meta_key_t& k) const { @@ -241,6 +401,15 @@ std::size_t MetaKeyHasher::operator()( case SAI_OBJECT_TYPE_INSEG_ENTRY: return sai_get_hash(k.objectkey.key.inseg_entry); + case SAI_OBJECT_TYPE_MCAST_FDB_ENTRY: + return sai_get_hash(k.objectkey.key.mcast_fdb_entry); + + case SAI_OBJECT_TYPE_L2MC_ENTRY: + return sai_get_hash(k.objectkey.key.l2mc_entry); + + case SAI_OBJECT_TYPE_IPMC_ENTRY: + return sai_get_hash(k.objectkey.key.ipmc_entry); + default: SWSS_LOG_THROW("not handled: %s", sai_serialize_object_type(k.objecttype).c_str()); } diff --git a/meta/NotificationFactory.cpp b/meta/NotificationFactory.cpp index d5a0b81ab..c9adf4863 100644 --- a/meta/NotificationFactory.cpp +++ b/meta/NotificationFactory.cpp @@ -35,7 +35,5 @@ std::shared_ptr NotificationFactory::deserialize( if (name == SAI_SWITCH_NOTIFICATION_NAME_BFD_SESSION_STATE_CHANGE) return std::make_shared(serializedNotification); - SWSS_LOG_ERROR("unknown notification: '%s', FIXME", name.c_str()); - - return nullptr; + SWSS_LOG_THROW("unknown notification: '%s', FIXME", name.c_str()); } diff --git a/meta/SaiAttributeList.cpp b/meta/SaiAttributeList.cpp index c89ce30e8..7338d5906 100644 --- a/meta/SaiAttributeList.cpp +++ b/meta/SaiAttributeList.cpp @@ -28,6 +28,7 @@ SaiAttributeList::SaiAttributeList( sai_deserialize_attr_id(str_attr_id, attr.id); + // TODO object type is not necessary, we can use get attr metadata from attr id name auto meta = sai_metadata_get_attr_metadata(objectType, attr.id); if (meta == NULL) @@ -64,6 +65,7 @@ SaiAttributeList::SaiAttributeList( sai_deserialize_attr_id(str_attr_id, attr.id); + // TODO object type is not necessary, we can use get attr metadata from attr id name auto meta = sai_metadata_get_attr_metadata(objectType, attr.id); if (meta == NULL) diff --git a/meta/SaiObject.cpp b/meta/SaiObject.cpp index 14ea98dde..92e9fd686 100644 --- a/meta/SaiObject.cpp +++ b/meta/SaiObject.cpp @@ -12,7 +12,10 @@ SaiObject::SaiObject( { SWSS_LOG_ENTER(); - // empty + if (!sai_metadata_is_object_type_valid(metaKey.objecttype)) + { + SWSS_LOG_THROW("invalid object type: %d", metaKey.objecttype); + } } sai_object_type_t SaiObject::getObjectType() const diff --git a/meta/SaiSerialize.cpp b/meta/SaiSerialize.cpp index aab641c78..e5e8931e1 100644 --- a/meta/SaiSerialize.cpp +++ b/meta/SaiSerialize.cpp @@ -1,4 +1,6 @@ #include "sai_serialize.h" +#include "sairediscommon.h" + #include "swss/tokenize.h" #pragma GCC diagnostic push @@ -155,9 +157,9 @@ sai_status_t transfer_attribute( transfer_primitive(src_attr.value.u16, dst_attr.value.u16); break; - case SAI_ATTR_VALUE_TYPE_INT16: - transfer_primitive(src_attr.value.s16, dst_attr.value.s16); - break; +// case SAI_ATTR_VALUE_TYPE_INT16: +// transfer_primitive(src_attr.value.s16, dst_attr.value.s16); +// break; case SAI_ATTR_VALUE_TYPE_UINT32: transfer_primitive(src_attr.value.u32, dst_attr.value.u32); @@ -171,9 +173,9 @@ sai_status_t transfer_attribute( transfer_primitive(src_attr.value.u64, dst_attr.value.u64); break; - case SAI_ATTR_VALUE_TYPE_INT64: - transfer_primitive(src_attr.value.s64, dst_attr.value.s64); - break; +// case SAI_ATTR_VALUE_TYPE_INT64: +// transfer_primitive(src_attr.value.s64, dst_attr.value.s64); +// break; case SAI_ATTR_VALUE_TYPE_MAC: transfer_primitive(src_attr.value.mac, dst_attr.value.mac); @@ -215,13 +217,13 @@ sai_status_t transfer_attribute( RETURN_ON_ERROR(transfer_list(src_attr.value.s8list, dst_attr.value.s8list, countOnly)); break; - case SAI_ATTR_VALUE_TYPE_UINT16_LIST: - RETURN_ON_ERROR(transfer_list(src_attr.value.u16list, dst_attr.value.u16list, countOnly)); - break; - - case SAI_ATTR_VALUE_TYPE_INT16_LIST: - RETURN_ON_ERROR(transfer_list(src_attr.value.s16list, dst_attr.value.s16list, countOnly)); - break; +// case SAI_ATTR_VALUE_TYPE_UINT16_LIST: +// RETURN_ON_ERROR(transfer_list(src_attr.value.u16list, dst_attr.value.u16list, countOnly)); +// break; +// +// case SAI_ATTR_VALUE_TYPE_INT16_LIST: +// RETURN_ON_ERROR(transfer_list(src_attr.value.s16list, dst_attr.value.s16list, countOnly)); +// break; case SAI_ATTR_VALUE_TYPE_UINT32_LIST: RETURN_ON_ERROR(transfer_list(src_attr.value.u32list, dst_attr.value.u32list, countOnly)); @@ -235,8 +237,12 @@ sai_status_t transfer_attribute( transfer_primitive(src_attr.value.u32range, dst_attr.value.u32range); break; - case SAI_ATTR_VALUE_TYPE_INT32_RANGE: - transfer_primitive(src_attr.value.s32range, dst_attr.value.s32range); +// case SAI_ATTR_VALUE_TYPE_INT32_RANGE: +// transfer_primitive(src_attr.value.s32range, dst_attr.value.s32range); +// break; + + case SAI_ATTR_VALUE_TYPE_TIMESPEC: + transfer_primitive(src_attr.value.timespec, dst_attr.value.timespec); break; case SAI_ATTR_VALUE_TYPE_VLAN_LIST: @@ -268,11 +274,11 @@ sai_status_t transfer_attribute( transfer_primitive(src_attr.value.aclfield.data.u8, dst_attr.value.aclfield.data.u8); break; - case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_INT8: - transfer_primitive(src_attr.value.aclfield.enable, dst_attr.value.aclfield.enable); - transfer_primitive(src_attr.value.aclfield.mask.s8, dst_attr.value.aclfield.mask.s8); - transfer_primitive(src_attr.value.aclfield.data.s8, dst_attr.value.aclfield.data.s8); - break; +// case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_INT8: +// transfer_primitive(src_attr.value.aclfield.enable, dst_attr.value.aclfield.enable); +// transfer_primitive(src_attr.value.aclfield.mask.s8, dst_attr.value.aclfield.mask.s8); +// transfer_primitive(src_attr.value.aclfield.data.s8, dst_attr.value.aclfield.data.s8); +// break; case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT16: transfer_primitive(src_attr.value.aclfield.enable, dst_attr.value.aclfield.enable); @@ -280,11 +286,11 @@ sai_status_t transfer_attribute( transfer_primitive(src_attr.value.aclfield.data.u16, dst_attr.value.aclfield.data.u16); break; - case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_INT16: - transfer_primitive(src_attr.value.aclfield.enable, dst_attr.value.aclfield.enable); - transfer_primitive(src_attr.value.aclfield.mask.s16, dst_attr.value.aclfield.mask.s16); - transfer_primitive(src_attr.value.aclfield.data.s16, dst_attr.value.aclfield.data.s16); - break; +// case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_INT16: +// transfer_primitive(src_attr.value.aclfield.enable, dst_attr.value.aclfield.enable); +// transfer_primitive(src_attr.value.aclfield.mask.s16, dst_attr.value.aclfield.mask.s16); +// transfer_primitive(src_attr.value.aclfield.data.s16, dst_attr.value.aclfield.data.s16); +// break; case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT32: transfer_primitive(src_attr.value.aclfield.enable, dst_attr.value.aclfield.enable); @@ -350,21 +356,20 @@ sai_status_t transfer_attribute( transfer_primitive(src_attr.value.aclaction.parameter.u8, dst_attr.value.aclaction.parameter.u8); break; - case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_INT8: - transfer_primitive(src_attr.value.aclaction.enable, dst_attr.value.aclaction.enable); - transfer_primitive(src_attr.value.aclaction.parameter.s8, dst_attr.value.aclaction.parameter.s8); - break; +// case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_INT8: +// transfer_primitive(src_attr.value.aclaction.enable, dst_attr.value.aclaction.enable); +// transfer_primitive(src_attr.value.aclaction.parameter.s8, dst_attr.value.aclaction.parameter.s8); +// break; case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_UINT16: transfer_primitive(src_attr.value.aclaction.enable, dst_attr.value.aclaction.enable); transfer_primitive(src_attr.value.aclaction.parameter.u16, dst_attr.value.aclaction.parameter.u16); break; - case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_INT16: - transfer_primitive(src_attr.value.aclaction.enable, dst_attr.value.aclaction.enable); - transfer_primitive(src_attr.value.aclaction.parameter.s16, dst_attr.value.aclaction.parameter.s16); - break; - +// case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_INT16: +// transfer_primitive(src_attr.value.aclaction.enable, dst_attr.value.aclaction.enable); +// transfer_primitive(src_attr.value.aclaction.parameter.s16, dst_attr.value.aclaction.parameter.s16); +// break; case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_UINT32: transfer_primitive(src_attr.value.aclaction.enable, dst_attr.value.aclaction.enable); @@ -391,6 +396,11 @@ sai_status_t transfer_attribute( transfer_primitive(src_attr.value.aclaction.parameter.ip6, dst_attr.value.aclaction.parameter.ip6); break; + case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_IP_ADDRESS: + transfer_primitive(src_attr.value.aclaction.enable, dst_attr.value.aclaction.enable); + transfer_primitive(src_attr.value.aclaction.parameter.ipaddr, dst_attr.value.aclaction.parameter.ipaddr); + break; + case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_OBJECT_ID: transfer_primitive(src_attr.value.aclaction.enable, dst_attr.value.aclaction.enable); transfer_primitive(src_attr.value.aclaction.parameter.oid, dst_attr.value.aclaction.parameter.oid); @@ -410,12 +420,52 @@ sai_status_t transfer_attribute( transfer_primitive(src_attr.value.sysportconfig, dst_attr.value.sysportconfig); break; + case SAI_ATTR_VALUE_TYPE_MACSEC_AUTH_KEY: + transfer_primitive(src_attr.value.macsecauthkey, dst_attr.value.macsecauthkey); + break; + + case SAI_ATTR_VALUE_TYPE_MACSEC_SALT: + transfer_primitive(src_attr.value.macsecsalt, dst_attr.value.macsecsalt); + break; + + case SAI_ATTR_VALUE_TYPE_MACSEC_SAK: + transfer_primitive(src_attr.value.macsecsak, dst_attr.value.macsecsak); + break; + + case SAI_ATTR_VALUE_TYPE_PORT_ERR_STATUS_LIST: + RETURN_ON_ERROR(transfer_list(src_attr.value.porterror, dst_attr.value.porterror, countOnly)); + break; + + case SAI_ATTR_VALUE_TYPE_PORT_EYE_VALUES_LIST: + RETURN_ON_ERROR(transfer_list(src_attr.value.porteyevalues, dst_attr.value.porteyevalues, countOnly)); + break; + + case SAI_ATTR_VALUE_TYPE_FABRIC_PORT_REACHABILITY: + transfer_primitive(src_attr.value.reachability, dst_attr.value.reachability); + break; + + case SAI_ATTR_VALUE_TYPE_PRBS_RX_STATE: + transfer_primitive(src_attr.value.rx_state, dst_attr.value.rx_state); + break; + + case SAI_ATTR_VALUE_TYPE_SEGMENT_LIST: + RETURN_ON_ERROR(transfer_list(src_attr.value.segmentlist, dst_attr.value.segmentlist, countOnly)); + break; + + case SAI_ATTR_VALUE_TYPE_MAP_LIST: + RETURN_ON_ERROR(transfer_list(src_attr.value.maplist, dst_attr.value.maplist, countOnly)); + break; + + case SAI_ATTR_VALUE_TYPE_TLV_LIST: + RETURN_ON_ERROR(transfer_list(src_attr.value.tlvlist, dst_attr.value.tlvlist, countOnly)); + break; + case SAI_ATTR_VALUE_TYPE_SYSTEM_PORT_CONFIG_LIST: RETURN_ON_ERROR(transfer_list(src_attr.value.sysportconfiglist, dst_attr.value.sysportconfiglist, countOnly)); break; default: - return SAI_STATUS_NOT_IMPLEMENTED; + SWSS_LOG_THROW("sai attr value %s is not implemented, FIXME", sai_serialize_attr_value_type(serialization_type).c_str()); } return SAI_STATUS_SUCCESS; @@ -1312,14 +1362,14 @@ std::string sai_serialize_acl_action( case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_UINT8: return sai_serialize_number(action.parameter.u8); - case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_INT8: - return sai_serialize_number(action.parameter.s8); +// case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_INT8: +// return sai_serialize_number(action.parameter.s8); case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_UINT16: return sai_serialize_number(action.parameter.u16); - case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_INT16: - return sai_serialize_number(action.parameter.s16); +// case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_INT16: +// return sai_serialize_number(action.parameter.s16); case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_UINT32: return sai_serialize_number(action.parameter.u32); @@ -1336,6 +1386,9 @@ std::string sai_serialize_acl_action( case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_IPV6: return sai_serialize_ipv6(action.parameter.ip6); + case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_IP_ADDRESS: + return sai_serialize_ip_address(action.parameter.ipaddr); + case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_OBJECT_ID: return sai_serialize_object_id(action.parameter.oid); @@ -1343,7 +1396,7 @@ std::string sai_serialize_acl_action( return sai_serialize_oid_list(action.parameter.objlist, countOnly); default: - SWSS_LOG_THROW("FATAIL: invalid serialization type %d", meta.attrvaluetype); + SWSS_LOG_THROW("sai attr value %s is not implemented, FIXME", sai_serialize_attr_value_type(meta.attrvaluetype).c_str()); } } @@ -1368,14 +1421,14 @@ std::string sai_serialize_acl_field( case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT8: return sai_serialize_number(field.data.u8) + "&mask:" + sai_serialize_number(field.mask.u8, true); - case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_INT8: - return sai_serialize_number(field.data.s8) + "&mask:" + sai_serialize_number(field.mask.s8, true); +// case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_INT8: +// return sai_serialize_number(field.data.s8) + "&mask:" + sai_serialize_number(field.mask.s8, true); case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT16: return sai_serialize_number(field.data.u16) + "&mask:" + sai_serialize_number(field.mask.u16, true); - case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_INT16: - return sai_serialize_number(field.data.s16) + "&mask:" + sai_serialize_number(field.mask.s16, true); +// case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_INT16: +// return sai_serialize_number(field.data.s16) + "&mask:" + sai_serialize_number(field.mask.s16, true); case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT32: return sai_serialize_number(field.data.u32) + "&mask:" + sai_serialize_number(field.mask.u32, true); @@ -1405,7 +1458,7 @@ std::string sai_serialize_acl_field( return sai_serialize_number_list(field.data.u8list, countOnly) + "&mask:" + sai_serialize_number_list(field.mask.u8list, countOnly, true); default: - SWSS_LOG_THROW("FATAIL: invalid serialization type %d", meta.attrvaluetype); + SWSS_LOG_THROW("sai attr value %s is not implemented, FIXME", sai_serialize_attr_value_type(meta.attrvaluetype).c_str()); } } @@ -1540,8 +1593,8 @@ std::string sai_serialize_attr_value( case SAI_ATTR_VALUE_TYPE_UINT16: return sai_serialize_number(attr.value.u16); - case SAI_ATTR_VALUE_TYPE_INT16: - return sai_serialize_number(attr.value.s16); +// case SAI_ATTR_VALUE_TYPE_INT16: +// return sai_serialize_number(attr.value.s16); case SAI_ATTR_VALUE_TYPE_UINT32: return sai_serialize_number(attr.value.u32); @@ -1552,8 +1605,8 @@ std::string sai_serialize_attr_value( case SAI_ATTR_VALUE_TYPE_UINT64: return sai_serialize_number(attr.value.u64); - case SAI_ATTR_VALUE_TYPE_INT64: - return sai_serialize_number(attr.value.s64); +// case SAI_ATTR_VALUE_TYPE_INT64: +// return sai_serialize_number(attr.value.s64); case SAI_ATTR_VALUE_TYPE_MAC: return sai_serialize_mac(attr.value.mac); @@ -1585,11 +1638,11 @@ std::string sai_serialize_attr_value( case SAI_ATTR_VALUE_TYPE_INT8_LIST: return sai_serialize_number_list(attr.value.s8list, countOnly); - case SAI_ATTR_VALUE_TYPE_UINT16_LIST: - return sai_serialize_number_list(attr.value.u16list, countOnly); - - case SAI_ATTR_VALUE_TYPE_INT16_LIST: - return sai_serialize_number_list(attr.value.s16list, countOnly); +// case SAI_ATTR_VALUE_TYPE_UINT16_LIST: +// return sai_serialize_number_list(attr.value.u16list, countOnly); +// +// case SAI_ATTR_VALUE_TYPE_INT16_LIST: +// return sai_serialize_number_list(attr.value.s16list, countOnly); case SAI_ATTR_VALUE_TYPE_UINT32_LIST: return sai_serialize_number_list(attr.value.u32list, countOnly); @@ -1600,8 +1653,8 @@ std::string sai_serialize_attr_value( case SAI_ATTR_VALUE_TYPE_UINT32_RANGE: return sai_serialize_range(attr.value.u32range); - case SAI_ATTR_VALUE_TYPE_INT32_RANGE: - return sai_serialize_range(attr.value.s32range); +// case SAI_ATTR_VALUE_TYPE_INT32_RANGE: +// return sai_serialize_range(attr.value.s32range); case SAI_ATTR_VALUE_TYPE_VLAN_LIST: return sai_serialize_number_list(attr.value.vlanlist, countOnly); @@ -1647,6 +1700,7 @@ std::string sai_serialize_attr_value( case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_IPV6: case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_OBJECT_ID: case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_OBJECT_LIST: + case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_IP_ADDRESS: return sai_serialize_acl_action(meta, attr.value.aclaction, countOnly); case SAI_ATTR_VALUE_TYPE_ACL_CAPABILITY: @@ -1670,7 +1724,7 @@ std::string sai_serialize_attr_value( return sai_serialize_system_port_config_list(meta, attr.value.sysportconfiglist, countOnly); default: - SWSS_LOG_THROW("FATAL: invalid serialization type %d", meta.attrvaluetype); + SWSS_LOG_THROW("sai attr value type %s is not implemented, FIXME", sai_serialize_attr_value_type(meta.attrvaluetype).c_str()); } } @@ -1944,7 +1998,7 @@ std::string sai_serialize_object_meta_key( std::string key; - if (meta_key.objecttype == SAI_OBJECT_TYPE_NULL || meta_key.objecttype >= SAI_OBJECT_TYPE_EXTENSIONS_MAX) + if (!sai_metadata_is_object_type_valid(meta_key.objecttype)) { SWSS_LOG_THROW("invalid object type value %s", sai_serialize_object_type(meta_key.objecttype).c_str()); } @@ -1973,6 +2027,18 @@ std::string sai_serialize_object_meta_key( key = sai_serialize_inseg_entry(meta_key.objectkey.key.inseg_entry); break; + case SAI_OBJECT_TYPE_L2MC_ENTRY: + key = sai_serialize_l2mc_entry(meta_key.objectkey.key.l2mc_entry); + break; + + case SAI_OBJECT_TYPE_IPMC_ENTRY: + key = sai_serialize_ipmc_entry(meta_key.objectkey.key.ipmc_entry); + break; + + case SAI_OBJECT_TYPE_MCAST_FDB_ENTRY: + key = sai_serialize_mcast_fdb_entry(meta_key.objectkey.key.mcast_fdb_entry); + break; + default: if (meta->isnonobjectid) @@ -1992,10 +2058,6 @@ std::string sai_serialize_object_meta_key( return key; } -#define SYNCD_INIT_VIEW "INIT_VIEW" -#define SYNCD_APPLY_VIEW "APPLY_VIEW" -#define SYNCD_INSPECT_ASIC "SYNCD_INSPECT_ASIC" - std::string sai_serialize( _In_ const sai_redis_notify_syncd_t& value) { @@ -2014,16 +2076,10 @@ std::string sai_serialize( default: - SWSS_LOG_WARN("unknown value on sai_redis_notify_syncd_t: %d", value); - - return std::to_string(value); + SWSS_LOG_THROW("unknown value on sai_redis_notify_syncd_t: %d", value); } } -#define REDIS_COMMUNICATION_MODE_REDIS_ASYNC_STRING "redis_async" -#define REDIS_COMMUNICATION_MODE_REDIS_SYNC_STRING "redis_sync" -#define REDIS_COMMUNICATION_MODE_ZMQ_SYNC_STRING "zmq_sync" - std::string sai_serialize_redis_communication_mode( _In_ sai_redis_communication_mode_t value) { @@ -2042,9 +2098,7 @@ std::string sai_serialize_redis_communication_mode( default: - SWSS_LOG_WARN("unknown value on sai_redis_communication_mode_t: %d", value); - - return std::to_string(value); + SWSS_LOG_THROW("unknown value on sai_redis_communication_mode_t: %d", value); } } @@ -2473,8 +2527,7 @@ void sai_deserialize_acl_resource_list( if (arr.size() != (size_t)aclresource.count) { - SWSS_LOG_ERROR("acl resource count mismatch %lu vs %u", arr.size(), aclresource.count); - throw std::runtime_error("acl resource count mismatch"); + SWSS_LOG_THROW("acl resource count mismatch %lu vs %u", arr.size(), aclresource.count); } aclresource.list = sai_alloc_n_of_ptr_type(aclresource.count, aclresource.list); @@ -2646,20 +2699,20 @@ void sai_deserialize_acl_field( sai_deserialize_number(smask, field.mask.u8, true); return; - case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_INT8: - sai_deserialize_number(sfield, field.data.s8); - sai_deserialize_number(smask, field.mask.s8, true); - return; +// case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_INT8: +// sai_deserialize_number(sfield, field.data.s8); +// sai_deserialize_number(smask, field.mask.s8, true); +// return; case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT16: sai_deserialize_number(sfield, field.data.u16); sai_deserialize_number(smask, field.mask.u16, true); return; - case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_INT16: - sai_deserialize_number(sfield, field.data.s16); - sai_deserialize_number(smask, field.mask.s16, true); - return; +// case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_INT16: +// sai_deserialize_number(sfield, field.data.s16); +// sai_deserialize_number(smask, field.mask.s16, true); +// return; case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT32: sai_deserialize_number(sfield, field.data.u32); @@ -2696,12 +2749,14 @@ void sai_deserialize_acl_field( case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_OBJECT_LIST: return sai_deserialize_oid_list(sfield, field.data.objlist, countOnly); - /* - case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT8_LIST: - return sai_deserialize_number_list(field.data.u8list, countOnly) + "&mask:" + sai_deserialize_uint8_hex_list(field.mask.u8list, countOnly); - */ + + case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT8_LIST: + sai_deserialize_number_list(sfield, field.data.u8list, countOnly); + sai_deserialize_number_list(smask, field.mask.u8list, countOnly, true); + return; + default: - SWSS_LOG_THROW("FATAIL: invalid serialization type %d", meta.attrvaluetype); + SWSS_LOG_THROW("sai attr value %s is not implemented, FIXME", sai_serialize_attr_value_type(meta.attrvaluetype).c_str()); } } @@ -2729,14 +2784,14 @@ void sai_deserialize_acl_action( case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_UINT8: return sai_deserialize_number(s, action.parameter.u8); - case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_INT8: - return sai_deserialize_number(s, action.parameter.s8); +// case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_INT8: +// return sai_deserialize_number(s, action.parameter.s8); case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_UINT16: return sai_deserialize_number(s, action.parameter.u16); - case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_INT16: - return sai_deserialize_number(s, action.parameter.s16); +// case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_INT16: +// return sai_deserialize_number(s, action.parameter.s16); case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_UINT32: return sai_deserialize_number(s, action.parameter.u32); @@ -2759,8 +2814,12 @@ void sai_deserialize_acl_action( case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_OBJECT_LIST: return sai_deserialize_oid_list(s, action.parameter.objlist, countOnly); + case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_IP_ADDRESS: + sai_deserialize_ip_address(s, action.parameter.ipaddr); + return; + default: - SWSS_LOG_THROW("FATAIL: invalid serialization type %d", meta.attrvaluetype); + SWSS_LOG_THROW("sai attr value %s is not implemented, FIXME", sai_serialize_attr_value_type(meta.attrvaluetype).c_str()); } } @@ -2888,8 +2947,7 @@ void sai_deserialize_system_port_config_list( if (arr.size() != (size_t)sysportconfiglist.count) { - SWSS_LOG_ERROR("system port config list count mismatch %lu vs %u", arr.size(), sysportconfiglist.count); - throw std::runtime_error("system port config list count mismatch"); + SWSS_LOG_THROW("system port config list count mismatch %lu vs %u", arr.size(), sysportconfiglist.count); } sysportconfiglist.list = sai_alloc_n_of_ptr_type(sysportconfiglist.count, sysportconfiglist.list); @@ -2929,8 +2987,8 @@ void sai_deserialize_attr_value( case SAI_ATTR_VALUE_TYPE_UINT16: return sai_deserialize_number(s, attr.value.u16); - case SAI_ATTR_VALUE_TYPE_INT16: - return sai_deserialize_number(s, attr.value.s16); +// case SAI_ATTR_VALUE_TYPE_INT16: +// return sai_deserialize_number(s, attr.value.s16); case SAI_ATTR_VALUE_TYPE_UINT32: return sai_deserialize_number(s, attr.value.u32); @@ -2941,8 +2999,8 @@ void sai_deserialize_attr_value( case SAI_ATTR_VALUE_TYPE_UINT64: return sai_deserialize_number(s, attr.value.u64); - case SAI_ATTR_VALUE_TYPE_INT64: - return sai_deserialize_number(s, attr.value.s64); +// case SAI_ATTR_VALUE_TYPE_INT64: +// return sai_deserialize_number(s, attr.value.s64); case SAI_ATTR_VALUE_TYPE_MAC: return sai_deserialize_mac(s, attr.value.mac); @@ -2974,11 +3032,11 @@ void sai_deserialize_attr_value( case SAI_ATTR_VALUE_TYPE_INT8_LIST: return sai_deserialize_number_list(s, attr.value.s8list, countOnly); - case SAI_ATTR_VALUE_TYPE_UINT16_LIST: - return sai_deserialize_number_list(s, attr.value.u16list, countOnly); - - case SAI_ATTR_VALUE_TYPE_INT16_LIST: - return sai_deserialize_number_list(s, attr.value.s16list, countOnly); +// case SAI_ATTR_VALUE_TYPE_UINT16_LIST: +// return sai_deserialize_number_list(s, attr.value.u16list, countOnly); +// +// case SAI_ATTR_VALUE_TYPE_INT16_LIST: +// return sai_deserialize_number_list(s, attr.value.s16list, countOnly); case SAI_ATTR_VALUE_TYPE_UINT32_LIST: return sai_deserialize_number_list(s, attr.value.u32list, countOnly); @@ -2989,8 +3047,8 @@ void sai_deserialize_attr_value( case SAI_ATTR_VALUE_TYPE_UINT32_RANGE: return sai_deserialize_range(s, attr.value.u32range); - case SAI_ATTR_VALUE_TYPE_INT32_RANGE: - return sai_deserialize_range(s, attr.value.s32range); +// case SAI_ATTR_VALUE_TYPE_INT32_RANGE: +// return sai_deserialize_range(s, attr.value.s32range); case SAI_ATTR_VALUE_TYPE_VLAN_LIST: return sai_deserialize_number_list(s, attr.value.vlanlist, countOnly); @@ -3036,6 +3094,7 @@ void sai_deserialize_attr_value( case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_IPV6: case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_OBJECT_ID: case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_OBJECT_LIST: + case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_IP_ADDRESS: return sai_deserialize_acl_action(s, meta, attr.value.aclaction, countOnly); case SAI_ATTR_VALUE_TYPE_ACL_CAPABILITY: @@ -3088,6 +3147,24 @@ void sai_deserialize_queue_deadlock( sai_deserialize_enum(s, &sai_metadata_enum_sai_queue_pfc_deadlock_event_type_t, (int32_t&)event); } +void sai_deserialize_ipmc_entry_type( + _In_ const std::string& s, + _Out_ sai_ipmc_entry_type_t& type) +{ + SWSS_LOG_ENTER(); + + return sai_deserialize_enum(s, &sai_metadata_enum_sai_ipmc_entry_type_t, (int32_t&)type); +} + +void sai_deserialize_l2mc_entry_type( + _In_ const std::string& s, + _Out_ sai_l2mc_entry_type_t& type) +{ + SWSS_LOG_ENTER(); + + return sai_deserialize_enum(s, &sai_metadata_enum_sai_l2mc_entry_type_t, (int32_t&)type); +} + void sai_deserialize_fdb_event( _In_ const std::string& s, _Out_ sai_fdb_event_t& event) @@ -3336,6 +3413,49 @@ void sai_deserialize_nat_entry( sai_deserialize_nat_entry_data(j["nat_data"], nat_entry.data); } +void sai_deserialize_ipmc_entry( + _In_ const std::string &s, + _Out_ sai_ipmc_entry_t& ipmc_entry) +{ + SWSS_LOG_ENTER(); + + json j = json::parse(s); + + sai_deserialize_object_id(j["switch_id"], ipmc_entry.switch_id); + sai_deserialize_object_id(j["vr_id"], ipmc_entry.vr_id); + sai_deserialize_ipmc_entry_type(j["type"], ipmc_entry.type); + sai_deserialize_ip_address(j["destination"], ipmc_entry.destination); + sai_deserialize_ip_address(j["source"], ipmc_entry.source); +} + +void sai_deserialize_l2mc_entry( + _In_ const std::string &s, + _Out_ sai_l2mc_entry_t& l2mc_entry) +{ + SWSS_LOG_ENTER(); + + json j = json::parse(s); + + sai_deserialize_object_id(j["switch_id"], l2mc_entry.switch_id); + sai_deserialize_object_id(j["bv_id"], l2mc_entry.bv_id); + sai_deserialize_l2mc_entry_type(j["type"], l2mc_entry.type); + sai_deserialize_ip_address(j["destination"], l2mc_entry.destination); + sai_deserialize_ip_address(j["source"], l2mc_entry.source); +} + +void sai_deserialize_mcast_fdb_entry( + _In_ const std::string &s, + _Out_ sai_mcast_fdb_entry_t& mcast_fdb_entry) +{ + SWSS_LOG_ENTER(); + + json j = json::parse(s); + + sai_deserialize_object_id(j["switch_id"], mcast_fdb_entry.switch_id); + sai_deserialize_object_id(j["bv_id"], mcast_fdb_entry.bv_id); + sai_deserialize_mac(j["mac_address"], mcast_fdb_entry.mac_address); +} + void sai_deserialize_attr_id( _In_ const std::string& s, _Out_ const sai_attr_metadata_t** meta) @@ -3389,7 +3509,7 @@ void sai_deserialize_object_meta_key( sai_deserialize_object_type(str_object_type, meta_key.objecttype); - if (meta_key.objecttype == SAI_OBJECT_TYPE_NULL || meta_key.objecttype >= SAI_OBJECT_TYPE_EXTENSIONS_MAX) + if (!sai_metadata_is_object_type_valid(meta_key.objecttype)) { SWSS_LOG_THROW("invalid object type value %s", sai_serialize_object_type(meta_key.objecttype).c_str()); } @@ -3418,6 +3538,18 @@ void sai_deserialize_object_meta_key( sai_deserialize_inseg_entry(str_object_id, meta_key.objectkey.key.inseg_entry); break; + case SAI_OBJECT_TYPE_L2MC_ENTRY: + sai_deserialize_l2mc_entry(str_object_id, meta_key.objectkey.key.l2mc_entry); + break; + + case SAI_OBJECT_TYPE_IPMC_ENTRY: + sai_deserialize_ipmc_entry(str_object_id, meta_key.objectkey.key.ipmc_entry); + break; + + case SAI_OBJECT_TYPE_MCAST_FDB_ENTRY: + sai_deserialize_mcast_fdb_entry(str_object_id, meta_key.objectkey.key.mcast_fdb_entry); + break; + default: if (meta->isnonobjectid) @@ -3592,13 +3724,13 @@ void sai_deserialize_free_attribute_value( sai_free_list(attr.value.s8list); break; - case SAI_ATTR_VALUE_TYPE_UINT16_LIST: - sai_free_list(attr.value.u16list); - break; - - case SAI_ATTR_VALUE_TYPE_INT16_LIST: - sai_free_list(attr.value.s16list); - break; +// case SAI_ATTR_VALUE_TYPE_UINT16_LIST: +// sai_free_list(attr.value.u16list); +// break; +// +// case SAI_ATTR_VALUE_TYPE_INT16_LIST: +// sai_free_list(attr.value.s16list); +// break; case SAI_ATTR_VALUE_TYPE_UINT32_LIST: sai_free_list(attr.value.u32list); @@ -3665,6 +3797,7 @@ void sai_deserialize_free_attribute_value( case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_IPV4: case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_IPV6: case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_OBJECT_ID: + case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_IP_ADDRESS: break; case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_OBJECT_LIST: @@ -3690,7 +3823,7 @@ void sai_deserialize_free_attribute_value( break; default: - SWSS_LOG_THROW("unsupported type %d on deserialize free, FIXME", type); + SWSS_LOG_THROW("sai attr value %s is not implemented, FIXME", sai_serialize_attr_value_type(type).c_str()); } } @@ -3808,9 +3941,7 @@ void sai_deserialize( } else { - SWSS_LOG_WARN("enum %s not found in sai_redis_notify_syncd_t", s.c_str()); - - sai_deserialize_number(s, value); + SWSS_LOG_THROW("enum %s not found in sai_redis_notify_syncd_t", s.c_str()); } } diff --git a/meta/sai_serialize.h b/meta/sai_serialize.h index 969b85843..d752f4a7a 100644 --- a/meta/sai_serialize.h +++ b/meta/sai_serialize.h @@ -129,6 +129,26 @@ std::string sai_serialize_hex_binary( _In_ const void *buffer, _In_ size_t length); +void sai_deserialize_system_port_config_list( + _In_ const std::string& s, + _Out_ sai_system_port_config_list_t& sysportconfiglist, + _In_ bool countOnly); + +std::string sai_serialize_chardata( + _In_ const char data[32]); + +std::string sai_serialize_oid_list( + _In_ const sai_object_list_t &list, + _In_ bool countOnly); + +std::string sai_serialize_system_port_config_list( + _In_ const sai_attr_metadata_t &meta, + _In_ const sai_system_port_config_list_t& sysportconfiglist, + _In_ bool countOnly); + +std::string sai_serialize_queue_deadlock_event( + _In_ sai_queue_pfc_deadlock_event_type_t event); + template std::string sai_serialize_hex_binary( _In_ const T &value) @@ -258,6 +278,14 @@ void sai_deserialize_api( _In_ const std::string& s, _Out_ sai_api_t& api); +void sai_deserialize_ipmc_entry_type( + _In_ const std::string& s, + _Out_ sai_ipmc_entry_type_t& type); + +void sai_deserialize_l2mc_entry_type( + _In_ const std::string& s, + _Out_ sai_l2mc_entry_type_t& type); + void sai_deserialize_fdb_entry( _In_ const std::string& s, _In_ sai_fdb_entry_t &fdb_entry); @@ -328,6 +356,18 @@ void sai_deserialize_mac( _In_ const std::string& s, _Out_ sai_mac_t& mac); +void sai_deserialize_ipv4( + _In_ const std::string& s, + _Out_ sai_ip4_t& ipaddr); + +void sai_deserialize_ipv6( + _In_ const std::string& s, + _Out_ sai_ip6_t& ipaddr); + +void sai_deserialize_chardata( + _In_ const std::string& s, + _Out_ char chardata[32]); + // deserialize notifications void sai_deserialize_fdb_event_ntf( @@ -372,7 +412,7 @@ void sai_deserialize_free_queue_deadlock_ntf( void sai_deserialize_free_bfd_session_state_ntf( _In_ uint32_t count, - _In_ sai_bfd_session_state_notification_t* bfdsessionstate); + _In_ sai_bfd_session_state_notification_t* bfdsessionstate); void sai_deserialize_ingress_priority_group_attr( _In_ const std::string& s, diff --git a/meta/tests.cpp b/meta/tests.cpp deleted file mode 100644 index 4990fa04a..000000000 --- a/meta/tests.cpp +++ /dev/null @@ -1,4045 +0,0 @@ -#include "sai_serialize.h" - -#include "OidRefCounter.h" -#include "SaiAttrWrapper.h" -#include "AttrKeyMap.h" -#include "SaiObjectCollection.h" -#include "MetaTestSaiInterface.h" -#include "Meta.h" - -#include -#include -#include - -#include -#include -#include -#include -#include - -using namespace saimeta; - -static std::shared_ptr g_sai = std::make_shared(); -static std::shared_ptr g_meta = std::make_shared(g_sai); - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wmissing-noreturn" - -sai_object_type_t sai_object_type_query( - _In_ sai_object_id_t oid) -{ - SWSS_LOG_ENTER(); - - SWSS_LOG_THROW("should not be used"); -} - -void clear_local() -{ - SWSS_LOG_ENTER(); - - g_sai = std::make_shared(); - g_meta = std::make_shared(g_sai); -} - -sai_object_id_t create_dummy_object_id( - _In_ sai_object_type_t object_type, - _In_ sai_object_id_t switch_id) -{ - SWSS_LOG_ENTER(); - - sai_object_id_t oid; - - auto status = g_sai->create(object_type, &oid, switch_id, 0, NULL); - - if (status != SAI_STATUS_SUCCESS) - { - SWSS_LOG_THROW("failed to create oid"); - } - - SWSS_LOG_DEBUG("created oid %s", sai_serialize_object_id(oid).c_str()); - - return oid; -} - -sai_object_id_t sai_switch_id_query( - _In_ sai_object_id_t oid) -{ - SWSS_LOG_ENTER(); - - SWSS_LOG_THROW("should not be used"); -} - -#pragma GCC diagnostic pop - -// META ASSERTS - -#define META_ASSERT_SUCCESS(x) \ - if (x != SAI_STATUS_SUCCESS) \ -{\ - SWSS_LOG_ERROR("expected success, line: %d", __LINE__);\ - throw;\ -} - -#define META_ASSERT_FAIL(x) \ - if (x == SAI_STATUS_SUCCESS) \ -{\ - SWSS_LOG_ERROR("expected failure, line: %d", __LINE__);\ - throw;\ -} - -#define META_ASSERT_TRUE(x) \ - if (!(x)) \ -{\ - SWSS_LOG_ERROR("assert true failed '%s', line: %d", # x, __LINE__);\ - throw;\ -} - -// SWITCH TESTS - -sai_object_id_t create_switch() -{ - SWSS_LOG_ENTER(); - - sai_attribute_t attr; - - sai_object_id_t switch_id; - - attr.id = SAI_SWITCH_ATTR_INIT_SWITCH; - attr.value.booldata = true; - - auto status = g_meta->create(SAI_OBJECT_TYPE_SWITCH, &switch_id, SAI_NULL_OBJECT_ID, 1, &attr); - META_ASSERT_SUCCESS(status); - - return switch_id; -} - -void remove_switch( - _In_ sai_object_id_t switchId) -{ - SWSS_LOG_ENTER(); - - META_ASSERT_TRUE(g_meta->isEmpty() == false); - - SWSS_LOG_NOTICE("removing: %lX", switchId); - - auto status = g_meta->remove(SAI_OBJECT_TYPE_SWITCH, switchId); - - META_ASSERT_SUCCESS(status); - - META_ASSERT_TRUE(g_meta->isEmpty()); -} - -void test_switch_set() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - sai_status_t status; - sai_attribute_t attr; - - sai_object_id_t switch_id = create_switch(); - - status = g_meta->set(SAI_OBJECT_TYPE_SWITCH, switch_id, NULL); - META_ASSERT_FAIL(status); - - status = g_meta->set(SAI_OBJECT_TYPE_SWITCH, switch_id, &attr); - META_ASSERT_FAIL(status); - - // id outside range - attr.id = -1; - status = g_meta->set(SAI_OBJECT_TYPE_SWITCH, switch_id, &attr); - META_ASSERT_FAIL(status); - - g_sai->setStatus(SAI_STATUS_FAILURE); - attr.id = SAI_SWITCH_ATTR_PORT_NUMBER; - status = g_meta->set(SAI_OBJECT_TYPE_SWITCH, switch_id, &attr); - META_ASSERT_FAIL(status); - g_sai->setStatus(SAI_STATUS_SUCCESS); - - attr.id = SAI_SWITCH_ATTR_PORT_NUMBER; - status = g_meta->set(SAI_OBJECT_TYPE_SWITCH, switch_id, &attr); - META_ASSERT_FAIL(status); - - attr.id = SAI_SWITCH_ATTR_SWITCHING_MODE; - attr.value.s32 = 0x1000; - status = g_meta->set(SAI_OBJECT_TYPE_SWITCH, switch_id, &attr); - META_ASSERT_FAIL(status); - - // enum - attr.id = SAI_SWITCH_ATTR_SWITCHING_MODE; - attr.value.s32 = SAI_SWITCH_SWITCHING_MODE_STORE_AND_FORWARD; - status = g_meta->set(SAI_OBJECT_TYPE_SWITCH, switch_id, &attr); - META_ASSERT_SUCCESS(status); - - // bool - attr.id = SAI_SWITCH_ATTR_BCAST_CPU_FLOOD_ENABLE; - attr.value.booldata = SAI_SWITCH_SWITCHING_MODE_STORE_AND_FORWARD; - status = g_meta->set(SAI_OBJECT_TYPE_SWITCH, switch_id, &attr); - META_ASSERT_SUCCESS(status); - - // mac - sai_mac_t mac = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; - - attr.id = SAI_SWITCH_ATTR_SRC_MAC_ADDRESS; - memcpy(attr.value.mac, mac, sizeof(mac)); - status = g_meta->set(SAI_OBJECT_TYPE_SWITCH, switch_id, &attr); - META_ASSERT_SUCCESS(status); - - // uint8 - attr.id = SAI_SWITCH_ATTR_QOS_DEFAULT_TC; - attr.value.u8 = 0x11; - status = g_meta->set(SAI_OBJECT_TYPE_SWITCH, switch_id, &attr); - META_ASSERT_SUCCESS(status); - - // object id with not allowed null - -// currently hash is read only -// -// // null oid -// attr.id = SAI_SWITCH_ATTR_LAG_HASH_IPV6; -// attr.value.oid = SAI_NULL_OBJECT_ID; -// status = g_meta->set(SAI_OBJECT_TYPE_SWITCH, switch_id, &attr); -// META_ASSERT_FAIL(status); -// -// // wrong object type -// attr.id = SAI_SWITCH_ATTR_LAG_HASH_IPV6; -// attr.value.oid = create_dummy_object_id(SAI_OBJECT_TYPE_LAG); -// status = g_meta->set(SAI_OBJECT_TYPE_SWITCH, switch_id, &attr); -// META_ASSERT_FAIL(status); -// -// // valid object (object must exist) -// attr.id = SAI_SWITCH_ATTR_LAG_HASH_IPV6; -// attr.value.oid = create_hash(switch_id); -// -// status = g_meta->set(SAI_OBJECT_TYPE_SWITCH, switch_id, &attr); -// META_ASSERT_SUCCESS(status); -// -// META_ASSERT_TRUE(g_meta->getObjectReferenceCount(attr.value.oid) == 1); - - // object id with allowed null - - // null oid - attr.id = SAI_SWITCH_ATTR_QOS_DOT1P_TO_TC_MAP; - attr.value.oid = SAI_NULL_OBJECT_ID; - status = g_meta->set(SAI_OBJECT_TYPE_SWITCH, switch_id, &attr); - META_ASSERT_SUCCESS(status); - - // wrong object - attr.id = SAI_SWITCH_ATTR_QOS_DOT1P_TO_TC_MAP; - status = g_meta->create(SAI_OBJECT_TYPE_LAG, &attr.value.oid, switch_id, 0, NULL); - META_ASSERT_SUCCESS(status); - - status = g_meta->set(SAI_OBJECT_TYPE_SWITCH, switch_id, &attr); - META_ASSERT_FAIL(status); - - // good object - attr.id = SAI_SWITCH_ATTR_QOS_DOT1P_TO_TC_MAP; - - sai_attribute_t a[2] = { }; - a[0].id = SAI_QOS_MAP_ATTR_TYPE; - a[0].value.s32 = 1; - a[1].id = SAI_QOS_MAP_ATTR_MAP_TO_VALUE_LIST; - status = g_meta->create(SAI_OBJECT_TYPE_QOS_MAP, &attr.value.oid, switch_id, 2, a); - META_ASSERT_SUCCESS(status); - - sai_object_id_t oid = attr.value.oid; - - status = g_meta->set(SAI_OBJECT_TYPE_SWITCH, switch_id, &attr); - META_ASSERT_SUCCESS(status); - - META_ASSERT_TRUE(g_meta->getObjectReferenceCount(attr.value.oid) == 1); - - attr.id = SAI_SWITCH_ATTR_QOS_DOT1P_TO_TC_MAP; - attr.value.oid = SAI_NULL_OBJECT_ID; - status = g_meta->set(SAI_OBJECT_TYPE_SWITCH, switch_id, &attr); - META_ASSERT_SUCCESS(status); - - // check if it was decreased - META_ASSERT_TRUE(g_meta->getObjectReferenceCount(oid) == 0); - - remove_switch(switch_id); -} - -void test_switch_get() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - sai_status_t status; - sai_attribute_t attr; - - sai_object_id_t switch_id = create_switch(); - - attr.id = SAI_SWITCH_ATTR_PORT_NUMBER; - status = g_meta->get(SAI_OBJECT_TYPE_SWITCH, switch_id, 0, &attr); - META_ASSERT_FAIL(status); - - status = g_meta->get(SAI_OBJECT_TYPE_SWITCH, switch_id, 1000, &attr); - META_ASSERT_FAIL(status); - - status = g_meta->get(SAI_OBJECT_TYPE_SWITCH, switch_id, 1, NULL); - META_ASSERT_FAIL(status); - - status = g_meta->get(SAI_OBJECT_TYPE_SWITCH, switch_id, 1, NULL); - META_ASSERT_FAIL(status); - - status = g_meta->get(SAI_OBJECT_TYPE_SWITCH, switch_id, 1, &attr); - META_ASSERT_SUCCESS(status); - - attr.id = -1; - status = g_meta->get(SAI_OBJECT_TYPE_SWITCH, switch_id, 1, &attr); - META_ASSERT_FAIL(status); - - attr.id = SAI_SWITCH_ATTR_PORT_NUMBER; - attr.value.u32 = 0; - status = g_meta->get(SAI_OBJECT_TYPE_SWITCH, switch_id, 1, &attr); - META_ASSERT_SUCCESS(status); - - sai_attribute_t attr1; - attr1.id = SAI_SWITCH_ATTR_PORT_NUMBER; - - sai_attribute_t attr2; - attr2.id = SAI_SWITCH_ATTR_DEFAULT_VIRTUAL_ROUTER_ID; - sai_attribute_t list[2] = { attr1, attr2 }; - - status = g_meta->get(SAI_OBJECT_TYPE_SWITCH, switch_id, 2, list); - META_ASSERT_SUCCESS(status); - - remove_switch(switch_id); -} - -// FDB TESTS - -static sai_object_id_t create_bridge( - _In_ sai_object_id_t switch_id) -{ - SWSS_LOG_ENTER(); - - sai_object_id_t bridge_id; - - sai_attribute_t attrs[9] = {}; - - attrs[0].id = SAI_BRIDGE_ATTR_TYPE; - attrs[0].value.s32 = SAI_BRIDGE_TYPE_1Q; - - sai_status_t status = g_meta->create(SAI_OBJECT_TYPE_BRIDGE, &bridge_id, switch_id, 1, attrs); - META_ASSERT_SUCCESS(status); - - return bridge_id; -} - -static sai_object_id_t create_port( - _In_ sai_object_id_t switch_id) -{ - SWSS_LOG_ENTER(); - - sai_object_id_t port; - - static uint32_t id = 1; - id++; - sai_attribute_t attrs[9] = { }; - - uint32_t list[1] = { id }; - - attrs[0].id = SAI_PORT_ATTR_HW_LANE_LIST; - attrs[0].value.u32list.count = 1; - attrs[0].value.u32list.list = list; - - attrs[1].id = SAI_PORT_ATTR_SPEED; - attrs[1].value.u32 = 10000; - - auto status = g_meta->create(SAI_OBJECT_TYPE_PORT, &port, switch_id, 2, attrs); - META_ASSERT_SUCCESS(status); - - return port; -} - -static sai_object_id_t create_bridge_port( - _In_ sai_object_id_t switch_id, - _In_ sai_object_id_t bridge_id) -{ - SWSS_LOG_ENTER(); - - sai_object_id_t bridge_port; - - sai_attribute_t attrs[9] = { }; - - auto port = create_port(switch_id); - - attrs[0].id = SAI_BRIDGE_PORT_ATTR_TYPE; - attrs[0].value.s32 = SAI_BRIDGE_PORT_TYPE_PORT; - - attrs[1].id = SAI_BRIDGE_PORT_ATTR_PORT_ID; - attrs[1].value.oid = port; - - auto status = g_meta->create(SAI_OBJECT_TYPE_BRIDGE_PORT, &bridge_port, switch_id, 2, attrs); - META_ASSERT_SUCCESS(status); - - return bridge_port; -} - -void test_fdb_entry_create() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - sai_status_t status; - sai_attribute_t attr; - - sai_object_id_t switch_id = create_switch(); - - sai_fdb_entry_t fdb_entry; - - sai_mac_t mac = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; - - memcpy(fdb_entry.mac_address, mac, sizeof(mac)); - - fdb_entry.switch_id = switch_id; - sai_object_id_t bridge_id = create_bridge(switch_id); - fdb_entry.bv_id = bridge_id; - - sai_object_id_t port = create_bridge_port(switch_id, bridge_id); - - SWSS_LOG_NOTICE("create tests"); - - SWSS_LOG_NOTICE("zero attribute count (but there are mandatory attributes)"); - attr.id = SAI_FDB_ENTRY_ATTR_TYPE; - status = g_meta->create(&fdb_entry, 0, &attr); - META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("attr is null"); - status = g_meta->create(&fdb_entry, 1, NULL); - META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("fdb entry is null"); - status = g_meta->create((const sai_fdb_entry_t*)NULL, 1, &attr); - META_ASSERT_FAIL(status); - - sai_attribute_t list1[4] = { }; - - sai_attribute_t &attr1 = list1[0]; - sai_attribute_t &attr2 = list1[1]; - sai_attribute_t &attr3 = list1[2]; - sai_attribute_t &attr4 = list1[3]; - - attr1.id = SAI_FDB_ENTRY_ATTR_TYPE; - attr1.value.s32 = SAI_FDB_ENTRY_TYPE_STATIC; - - attr2.id = SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID; - attr2.value.oid = port; - - attr3.id = SAI_FDB_ENTRY_ATTR_PACKET_ACTION; - attr3.value.s32 = SAI_PACKET_ACTION_FORWARD; - - attr4.id = -1; - - SWSS_LOG_NOTICE("invalid attribute id"); - status = g_meta->create(&fdb_entry, 4, list1); - META_ASSERT_FAIL(status); - -// // packet action is now optional -// SWSS_LOG_NOTICE("passing optional attribute"); -// status = g_meta->create(&fdb_entry, 1, list1); -// META_ASSERT_SUCCESS(status); - - attr2.value.oid = create_dummy_object_id(SAI_OBJECT_TYPE_HASH, switch_id); - - SWSS_LOG_NOTICE("invalid attribute value on oid"); - status = g_meta->create(&fdb_entry, 3, list1); - META_ASSERT_FAIL(status); - - attr2.value.oid = create_dummy_object_id(SAI_OBJECT_TYPE_PORT, switch_id); - - SWSS_LOG_NOTICE("non existing object on oid"); - status = g_meta->create(&fdb_entry, 3, list1); - META_ASSERT_FAIL(status); - - attr2.value.oid = port; - attr3.value.s32 = 0x100; - - SWSS_LOG_NOTICE("invalid attribute value on enum"); - status = g_meta->create(&fdb_entry, 3, list1); - META_ASSERT_FAIL(status); - - attr3.value.s32 = SAI_PACKET_ACTION_FORWARD; - - sai_attribute_t list2[4] = { attr1, attr2, attr3, attr3 }; - - SWSS_LOG_NOTICE("repeated attribute id"); - status = g_meta->create(&fdb_entry, 4, list2); - META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("correct"); - status = g_meta->create(&fdb_entry, 3, list2); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("already exists"); - status = g_meta->create(&fdb_entry, 3, list2); - META_ASSERT_FAIL(status); - - remove_switch(switch_id); -} - -void test_fdb_entry_remove() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - sai_status_t status; - - sai_object_id_t switch_id = create_switch(); - - sai_fdb_entry_t fdb_entry; - - sai_mac_t mac = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; - - memcpy(fdb_entry.mac_address, mac, sizeof(mac)); - fdb_entry.switch_id = switch_id; - sai_object_id_t bridge_id = create_bridge(switch_id); - fdb_entry.bv_id= bridge_id; - - sai_object_id_t port = create_bridge_port(switch_id, bridge_id); - - sai_attribute_t list1[3] = { }; - - sai_attribute_t &attr1 = list1[0]; - sai_attribute_t &attr2 = list1[1]; - sai_attribute_t &attr3 = list1[2]; - - attr1.id = SAI_FDB_ENTRY_ATTR_TYPE; - attr1.value.s32 = SAI_FDB_ENTRY_TYPE_STATIC; - - attr2.id = SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID; - attr2.value.oid = port; - - attr3.id = SAI_FDB_ENTRY_ATTR_PACKET_ACTION; - attr3.value.s32 = SAI_PACKET_ACTION_FORWARD; - - SWSS_LOG_NOTICE("creating fdb entry"); - status = g_meta->create(&fdb_entry, 3, list1); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("remove tests"); - - SWSS_LOG_NOTICE("fdb_entry is null"); - status = g_meta->remove((const sai_fdb_entry_t*)NULL); - META_ASSERT_FAIL(status); - - //SWSS_LOG_NOTICE("invalid vlan"); - //status = g_meta->remove(&fdb_entry); - //META_ASSERT_FAIL(status); - - fdb_entry.mac_address[0] = 1; - - SWSS_LOG_NOTICE("invalid mac"); - status = g_meta->remove(&fdb_entry); - META_ASSERT_FAIL(status); - - fdb_entry.mac_address[0] = 0x11; - - sai_object_meta_key_t key = { .objecttype = SAI_OBJECT_TYPE_FDB_ENTRY, .objectkey = { .key = { .fdb_entry = fdb_entry } } }; - - META_ASSERT_TRUE(g_meta->objectExists(key)); - - SWSS_LOG_NOTICE("success"); - status = g_meta->remove(&fdb_entry); - META_ASSERT_SUCCESS(status); - - META_ASSERT_TRUE(!g_meta->objectExists(key)); - - remove_switch(switch_id); -} - -static sai_fdb_entry_t create_fdb_entry() -{ - SWSS_LOG_ENTER(); - - sai_fdb_entry_t fdb_entry; - - sai_mac_t mac = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; - - memcpy(fdb_entry.mac_address, mac, sizeof(mac)); - - auto switch_id = create_switch(); - - fdb_entry.switch_id = switch_id; - sai_object_id_t bridge_id = create_bridge(switch_id); - fdb_entry.bv_id = bridge_id; - - sai_object_id_t port = create_bridge_port(switch_id, bridge_id); - - sai_attribute_t list1[4] = { }; - - sai_attribute_t &attr1 = list1[0]; - sai_attribute_t &attr2 = list1[1]; - sai_attribute_t &attr3 = list1[2]; - sai_attribute_t &attr4 = list1[3]; - - attr1.id = SAI_FDB_ENTRY_ATTR_TYPE; - attr1.value.s32 = SAI_FDB_ENTRY_TYPE_STATIC; - - attr2.id = SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID; - attr2.value.oid = port; - - attr3.id = SAI_FDB_ENTRY_ATTR_PACKET_ACTION; - attr3.value.s32 = SAI_PACKET_ACTION_FORWARD; - - attr4.id = -1; - - sai_attribute_t list2[4] = { attr1, attr2, attr3, attr3 }; - - auto status = g_meta->create(&fdb_entry, 3, list2); - META_ASSERT_SUCCESS(status); - - return fdb_entry; -} - -void test_fdb_entry_set() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - sai_status_t status; - sai_attribute_t attr; - - sai_fdb_entry_t fdb_entry = create_fdb_entry(); - - //status = g_meta->create(&fdb_entry, 0, 0); - //META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("attr is null"); - status = g_meta->set(&fdb_entry, NULL); - META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("fdb entry is null"); - status = g_meta->set((const sai_fdb_entry_t*)NULL, &attr); - META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("setting read only object"); - attr.id = SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID; - attr.value.oid = create_dummy_object_id(SAI_OBJECT_TYPE_BRIDGE_PORT, fdb_entry.switch_id); - - status = g_meta->set(&fdb_entry, &attr); - META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("setting invalid attrib id"); - attr.id = -1; - status = g_meta->set(&fdb_entry, &attr); - META_ASSERT_FAIL(status); - - //SWSS_LOG_NOTICE("invalid vlan"); - //attr.id = SAI_FDB_ENTRY_ATTR_TYPE; - //attr.value.s32 = SAI_FDB_ENTRY_TYPE_STATIC; - //status = g_meta->set(&fdb_entry, &attr); - //META_ASSERT_FAIL(status); - - //SWSS_LOG_NOTICE("vlan outside range"); - //attr.id = SAI_FDB_ENTRY_ATTR_TYPE; - //attr.value.s32 = SAI_FDB_ENTRY_TYPE_STATIC; - //status = g_meta->set(&fdb_entry, &attr); - //META_ASSERT_FAIL(status); - - // correct - attr.id = SAI_FDB_ENTRY_ATTR_TYPE; - attr.value.s32 = SAI_FDB_ENTRY_TYPE_STATIC; - status = g_meta->set(&fdb_entry, &attr); - META_ASSERT_SUCCESS(status); - - // TODO check references ? - - remove_switch(fdb_entry.switch_id); -} - -void test_fdb_entry_get() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - sai_status_t status; - sai_attribute_t attr; - - sai_fdb_entry_t fdb_entry = create_fdb_entry(); - - attr.id = SAI_FDB_ENTRY_ATTR_TYPE; - attr.value.s32 = SAI_FDB_ENTRY_TYPE_STATIC; - status = g_meta->set(&fdb_entry, &attr); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("get test"); - - // zero attribute count - attr.id = SAI_FDB_ENTRY_ATTR_TYPE; - status = g_meta->get(&fdb_entry, 0, &attr); - META_ASSERT_FAIL(status); - - // attr is null - status = g_meta->get(&fdb_entry, 1, NULL); - META_ASSERT_FAIL(status); - - // fdb entry is null - status = g_meta->get((sai_fdb_entry_t*)NULL, 1, &attr); - META_ASSERT_FAIL(status); - - // attr id out of range - attr.id = -1; - status = g_meta->get(&fdb_entry, 1, &attr); - META_ASSERT_FAIL(status); - - // correct single valid attribute - attr.id = SAI_FDB_ENTRY_ATTR_TYPE; - status = g_meta->get(&fdb_entry, 1, &attr); - META_ASSERT_SUCCESS(status); - - // correct 2 attributes - sai_attribute_t attr1; - attr1.id = SAI_FDB_ENTRY_ATTR_TYPE; - - sai_attribute_t attr2; - attr2.id = SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID; - sai_attribute_t list[2] = { attr1, attr2 }; - - status = g_meta->get(&fdb_entry, 2, list); - META_ASSERT_SUCCESS(status); - - remove_switch(fdb_entry.switch_id); -} - -void test_fdb_entry_flow() -{ - SWSS_LOG_ENTER(); - - SWSS_LOG_TIMER("fdb flow"); - - clear_local(); - - sai_object_id_t switch_id = create_switch(); - sai_status_t status; - sai_attribute_t attr; - - sai_fdb_entry_t fdb_entry; - - sai_mac_t mac = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; - - memcpy(fdb_entry.mac_address, mac, sizeof(mac)); - fdb_entry.switch_id = switch_id; - - sai_object_id_t bridge_id = create_bridge(switch_id); - fdb_entry.bv_id= bridge_id; - - sai_object_id_t lag = create_bridge_port(switch_id, bridge_id); - - sai_attribute_t list[4] = { }; - - sai_attribute_t &attr1 = list[0]; - sai_attribute_t &attr2 = list[1]; - sai_attribute_t &attr3 = list[2]; - sai_attribute_t &attr4 = list[3]; - - attr1.id = SAI_FDB_ENTRY_ATTR_TYPE; - attr1.value.s32 = SAI_FDB_ENTRY_TYPE_STATIC; - - attr2.id = SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID; - attr2.value.oid = lag; - - attr3.id = SAI_FDB_ENTRY_ATTR_PACKET_ACTION; - attr3.value.s32 = SAI_PACKET_ACTION_FORWARD; - - attr4.id = SAI_FDB_ENTRY_ATTR_META_DATA; - attr4.value.u32 = 0x12345678; - - SWSS_LOG_NOTICE("create"); - status = g_meta->create(&fdb_entry, 4, list); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("create existing"); - status = g_meta->create(&fdb_entry, 4, list); - META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("set"); - attr.id = SAI_FDB_ENTRY_ATTR_TYPE; - attr.value.s32 = SAI_FDB_ENTRY_TYPE_DYNAMIC; - status = g_meta->set(&fdb_entry, &attr); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("set"); - attr.id = SAI_FDB_ENTRY_ATTR_META_DATA; - attr.value.u32 = SAI_FDB_ENTRY_TYPE_DYNAMIC; - status = g_meta->set(&fdb_entry, &attr); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("get"); - status = g_meta->get(&fdb_entry, 4, list); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("remove"); - status = g_meta->remove(&fdb_entry); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("remove non existing"); - status = g_meta->remove(&fdb_entry); - META_ASSERT_FAIL(status); - - remove_switch(switch_id); -} - -// NEIGHBOR TESTS - -static sai_object_id_t create_virtual_router( - _In_ sai_object_id_t switch_id) -{ - SWSS_LOG_ENTER(); - - sai_object_id_t vr; - - auto status = g_meta->create(SAI_OBJECT_TYPE_VIRTUAL_ROUTER, &vr, switch_id, 0, NULL); - META_ASSERT_SUCCESS(status); - - return vr; -} - -static sai_object_id_t create_rif( - _In_ sai_object_id_t switch_id) -{ - SWSS_LOG_ENTER(); - - sai_object_id_t rif; - - sai_attribute_t attrs[9] = { }; - - auto port = create_port(switch_id); - - auto vr = create_virtual_router(switch_id); - - attrs[0].id = SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID; - attrs[0].value.oid = vr; - - attrs[1].id = SAI_ROUTER_INTERFACE_ATTR_TYPE; - attrs[1].value.s32 = SAI_ROUTER_INTERFACE_TYPE_PORT; - - attrs[2].id = SAI_ROUTER_INTERFACE_ATTR_PORT_ID; - attrs[2].value.oid = port; - - auto status = g_meta->create(SAI_OBJECT_TYPE_ROUTER_INTERFACE, &rif, switch_id, 3, attrs); - META_ASSERT_SUCCESS(status); - - return rif; -} - -void test_neighbor_entry_create() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - sai_object_id_t switch_id = create_switch(); - sai_status_t status; - sai_attribute_t attr; - - sai_mac_t mac = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; - - sai_neighbor_entry_t neighbor_entry; - - sai_object_id_t rif = create_rif(switch_id); - - neighbor_entry.ip_address.addr_family = SAI_IP_ADDR_FAMILY_IPV4; - neighbor_entry.ip_address.addr.ip4 = htonl(0x0a00000f); - neighbor_entry.rif_id = rif; - neighbor_entry.switch_id = switch_id; - - SWSS_LOG_NOTICE("create tests"); - - SWSS_LOG_NOTICE("zero attribute count (but there are mandatory attributes)"); - status = g_meta->create(&neighbor_entry, 0, &attr); - META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("attr is null"); - status = g_meta->create(&neighbor_entry, 1, NULL); - META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("neighbor entry is null"); - status = g_meta->create((sai_neighbor_entry_t*)NULL, 1, &attr); - META_ASSERT_FAIL(status); - - sai_attribute_t list[3] = { }; - - sai_attribute_t &attr1 = list[0]; - sai_attribute_t &attr2 = list[1]; - sai_attribute_t &attr3 = list[2]; - - attr1.id = SAI_NEIGHBOR_ENTRY_ATTR_DST_MAC_ADDRESS; - memcpy(attr1.value.mac, mac, 6); - - attr2.id = SAI_NEIGHBOR_ENTRY_ATTR_PACKET_ACTION; - attr2.value.s32 = SAI_PACKET_ACTION_FORWARD; - - attr3.id = -1; - - SWSS_LOG_NOTICE("invalid attribute id"); - status = g_meta->create(&neighbor_entry, 3, list); - META_ASSERT_FAIL(status); - - attr2.value.s32 = SAI_PACKET_ACTION_FORWARD + 0x100; - SWSS_LOG_NOTICE("invalid attribute value on enum"); - status = g_meta->create(&neighbor_entry, 2, list); - META_ASSERT_FAIL(status); - - attr2.value.s32 = SAI_PACKET_ACTION_FORWARD; - - sai_attribute_t list2[4] = { attr1, attr2, attr2 }; - - SWSS_LOG_NOTICE("repeated attribute id"); - status = g_meta->create(&neighbor_entry, 3, list2); - META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("correct ipv4"); - status = g_meta->create(&neighbor_entry, 2, list2); - META_ASSERT_SUCCESS(status); - - neighbor_entry.ip_address.addr_family = SAI_IP_ADDR_FAMILY_IPV6; - sai_ip6_t ip6 = {0x00, 0x11, 0x22, 0x33,0x44, 0x55, 0x66,0x77, 0x88, 0x99, 0xaa, 0xbb,0xcc,0xdd,0xee,0xff}; - memcpy(neighbor_entry.ip_address.addr.ip6, ip6, 16); - - SWSS_LOG_NOTICE("correct ipv6"); - status = g_meta->create(&neighbor_entry, 2, list2); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("already exists"); - status = g_meta->create(&neighbor_entry, 2, list2); - META_ASSERT_FAIL(status); - - remove_switch(switch_id); -} - -sai_neighbor_entry_t create_neighbor_entry() -{ - SWSS_LOG_ENTER(); - - sai_object_id_t switch_id = create_switch(); - sai_status_t status; - - sai_mac_t mac = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; - - sai_neighbor_entry_t neighbor_entry; - - sai_object_id_t rif = create_rif(switch_id); - - neighbor_entry.ip_address.addr_family = SAI_IP_ADDR_FAMILY_IPV4; - neighbor_entry.ip_address.addr.ip4 = htonl(0x0a00000f); - neighbor_entry.rif_id = rif; - neighbor_entry.switch_id = switch_id; - - sai_attribute_t list[3] = { }; - - sai_attribute_t &attr1 = list[0]; - sai_attribute_t &attr2 = list[1]; - sai_attribute_t &attr3 = list[2]; - - attr1.id = SAI_NEIGHBOR_ENTRY_ATTR_DST_MAC_ADDRESS; - memcpy(attr1.value.mac, mac, 6); - - attr2.id = SAI_NEIGHBOR_ENTRY_ATTR_PACKET_ACTION; - attr2.value.s32 = SAI_PACKET_ACTION_FORWARD; - - attr3.id = -1; - - attr2.value.s32 = SAI_PACKET_ACTION_FORWARD; - - sai_attribute_t list2[4] = { attr1, attr2, attr2 }; - - status = g_meta->create(&neighbor_entry, 2, list2); - META_ASSERT_SUCCESS(status); - - return neighbor_entry; -} - -static sai_object_id_t create_hash( - _In_ sai_object_id_t switch_id) -{ - SWSS_LOG_ENTER(); - - sai_object_id_t hash; - - auto status = g_meta->create(SAI_OBJECT_TYPE_HASH, &hash, switch_id, 0, NULL); - META_ASSERT_SUCCESS(status); - - return hash; -} - -void test_neighbor_entry_remove() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - sai_status_t status; - - sai_object_id_t switch_id = create_switch(); - sai_neighbor_entry_t neighbor_entry; - - sai_mac_t mac = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; - - sai_attribute_t list[2] = { }; - - sai_attribute_t &attr1 = list[0]; - sai_attribute_t &attr2 = list[1]; - - attr1.id = SAI_NEIGHBOR_ENTRY_ATTR_DST_MAC_ADDRESS; - memcpy(attr1.value.mac, mac, 6); - - attr2.id = SAI_NEIGHBOR_ENTRY_ATTR_PACKET_ACTION; - attr2.value.s32 = SAI_PACKET_ACTION_FORWARD; - - sai_object_id_t rif = create_rif(switch_id); - - neighbor_entry.ip_address.addr_family = SAI_IP_ADDR_FAMILY_IPV4; - neighbor_entry.ip_address.addr.ip4 = htonl(0x0a00000f); - neighbor_entry.rif_id = rif; - neighbor_entry.switch_id = switch_id; - - SWSS_LOG_NOTICE("create"); - - SWSS_LOG_NOTICE("correct ipv4"); - status = g_meta->create(&neighbor_entry, 2, list); - META_ASSERT_SUCCESS(status); - - neighbor_entry.ip_address.addr_family = SAI_IP_ADDR_FAMILY_IPV6; - sai_ip6_t ip6 = {0x00, 0x11, 0x22, 0x33,0x44, 0x55, 0x66,0x77, 0x88, 0x99, 0xaa, 0xbb,0xcc,0xdd,0xee,0xff}; - memcpy(neighbor_entry.ip_address.addr.ip6, ip6, 16); - - SWSS_LOG_NOTICE("correct ipv6"); - status = g_meta->create(&neighbor_entry, 2, list); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("remove tests"); - - SWSS_LOG_NOTICE("neighbor_entry is null"); - status = g_meta->remove((sai_neighbor_entry_t*)NULL); - META_ASSERT_FAIL(status); - - neighbor_entry.rif_id = SAI_NULL_OBJECT_ID; - - SWSS_LOG_NOTICE("invalid object id null"); - status = g_meta->remove(&neighbor_entry); - META_ASSERT_FAIL(status); - - neighbor_entry.rif_id = create_hash(switch_id); - - SWSS_LOG_NOTICE("invalid object id hash"); - status = g_meta->remove(&neighbor_entry); - META_ASSERT_FAIL(status); - - neighbor_entry.rif_id = create_rif(switch_id); - - SWSS_LOG_NOTICE("invalid object id router"); - status = g_meta->remove(&neighbor_entry); - META_ASSERT_FAIL(status); - - neighbor_entry.rif_id = rif; - - sai_object_meta_key_t key = { .objecttype = SAI_OBJECT_TYPE_NEIGHBOR_ENTRY, .objectkey = { .key = { .neighbor_entry = neighbor_entry } } }; - - META_ASSERT_TRUE(g_meta->objectExists(key)); - - SWSS_LOG_NOTICE("success"); - status = g_meta->remove(&neighbor_entry); - META_ASSERT_SUCCESS(status); - - META_ASSERT_TRUE(!g_meta->objectExists(key)); - - remove_switch(switch_id); -} - -void test_neighbor_entry_set() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - sai_status_t status; - - sai_attribute_t attr; - - sai_object_id_t switch_id = create_switch(); - sai_neighbor_entry_t neighbor_entry; - - sai_mac_t mac = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; - - sai_attribute_t list[2] = { }; - - sai_attribute_t &attr1 = list[0]; - sai_attribute_t &attr2 = list[1]; - - attr1.id = SAI_NEIGHBOR_ENTRY_ATTR_DST_MAC_ADDRESS; - memcpy(attr1.value.mac, mac, 6); - - attr2.id = SAI_NEIGHBOR_ENTRY_ATTR_PACKET_ACTION; - attr2.value.s32 = SAI_PACKET_ACTION_FORWARD; - - sai_object_id_t rif = create_rif(switch_id); - - neighbor_entry.ip_address.addr_family = SAI_IP_ADDR_FAMILY_IPV4; - neighbor_entry.ip_address.addr.ip4 = htonl(0x0a00000f); - neighbor_entry.rif_id = rif; - neighbor_entry.switch_id = switch_id; - - SWSS_LOG_NOTICE("create"); - - SWSS_LOG_NOTICE("correct ipv4"); - status = g_meta->create(&neighbor_entry, 2, list); - META_ASSERT_SUCCESS(status); - - neighbor_entry.ip_address.addr_family = SAI_IP_ADDR_FAMILY_IPV6; - sai_ip6_t ip6 = {0x00, 0x11, 0x22, 0x33,0x44, 0x55, 0x66,0x77, 0x88, 0x99, 0xaa, 0xbb,0xcc,0xdd,0xee,0xff}; - memcpy(neighbor_entry.ip_address.addr.ip6, ip6, 16); - - SWSS_LOG_NOTICE("correct ipv6"); - status = g_meta->create(&neighbor_entry, 2, list); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("set tests"); - - SWSS_LOG_NOTICE("attr is null"); - status = g_meta->set(&neighbor_entry, NULL); - META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("neighbor entry is null"); - status = g_meta->set((sai_neighbor_entry_t*)NULL, &attr); - META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("setting invalid attrib id"); - attr.id = -1; - status = g_meta->set(&neighbor_entry, &attr); - META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("value outside range"); - attr.id = SAI_NEIGHBOR_ENTRY_ATTR_PACKET_ACTION; - attr.value.s32 = 0x100; - status = g_meta->set(&neighbor_entry, &attr); - META_ASSERT_FAIL(status); - - // correct - attr.id = SAI_NEIGHBOR_ENTRY_ATTR_PACKET_ACTION; - attr.value.s32 = SAI_PACKET_ACTION_DROP; - status = g_meta->set(&neighbor_entry, &attr); - META_ASSERT_SUCCESS(status); - - remove_switch(switch_id); -} - -void test_neighbor_entry_get() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - sai_status_t status; - - sai_attribute_t attr; - - sai_object_id_t switch_id = create_switch(); - sai_neighbor_entry_t neighbor_entry; - - sai_mac_t mac = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; - - sai_attribute_t list[2] = { }; - - sai_attribute_t &attr1 = list[0]; - sai_attribute_t &attr2 = list[1]; - - attr1.id = SAI_NEIGHBOR_ENTRY_ATTR_DST_MAC_ADDRESS; - memcpy(attr1.value.mac, mac, 6); - - attr2.id = SAI_NEIGHBOR_ENTRY_ATTR_PACKET_ACTION; - attr2.value.s32 = SAI_PACKET_ACTION_FORWARD; - - sai_object_id_t rif = create_rif(switch_id); - - neighbor_entry.ip_address.addr_family = SAI_IP_ADDR_FAMILY_IPV4; - neighbor_entry.ip_address.addr.ip4 = htonl(0x0a00000f); - neighbor_entry.rif_id = rif; - neighbor_entry.switch_id = switch_id; - - SWSS_LOG_NOTICE("create"); - - SWSS_LOG_NOTICE("correct ipv4"); - status = g_meta->create(&neighbor_entry, 2, list); - META_ASSERT_SUCCESS(status); - - neighbor_entry.ip_address.addr_family = SAI_IP_ADDR_FAMILY_IPV6; - sai_ip6_t ip6 = {0x00, 0x11, 0x22, 0x33,0x44, 0x55, 0x66,0x77, 0x88, 0x99, 0xaa, 0xbb,0xcc,0xdd,0xee,0xff}; - memcpy(neighbor_entry.ip_address.addr.ip6, ip6, 16); - - SWSS_LOG_NOTICE("correct ipv6"); - status = g_meta->create(&neighbor_entry, 2, list); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("get test"); - - SWSS_LOG_NOTICE("zero attribute count"); - attr.id = SAI_NEIGHBOR_ENTRY_ATTR_PACKET_ACTION; - status = g_meta->get(&neighbor_entry, 0, &attr); - META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("attr is null"); - status = g_meta->get(&neighbor_entry, 1, NULL); - META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("neighbor entry is null"); - status = g_meta->get((sai_neighbor_entry_t*)NULL, 1, &attr); - META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("attr id out of range"); - attr.id = -1; - status = g_meta->get(&neighbor_entry, 1, &attr); - META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("correct single valid attribute"); - attr.id = SAI_NEIGHBOR_ENTRY_ATTR_PACKET_ACTION; - status = g_meta->get(&neighbor_entry, 1, &attr); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("correct 2 attributes"); - - sai_attribute_t attr3; - sai_attribute_t attr4; - attr3.id = SAI_NEIGHBOR_ENTRY_ATTR_PACKET_ACTION; - attr3.value.s32 = 1; - attr4.id = SAI_NEIGHBOR_ENTRY_ATTR_NO_HOST_ROUTE; - - sai_attribute_t list2[2] = { attr3, attr4 }; - status = g_meta->get(&neighbor_entry, 2, list2); - META_ASSERT_SUCCESS(status); - - remove_switch(switch_id); -} - -void test_neighbor_entry_flow() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - sai_status_t status; - - sai_object_id_t switch_id = create_switch(); - sai_neighbor_entry_t neighbor_entry; - - sai_mac_t mac = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; - - sai_attribute_t list[4] = { }; - - sai_attribute_t &attr1 = list[0]; - sai_attribute_t &attr2 = list[1]; - sai_attribute_t &attr3 = list[1]; - sai_attribute_t &attr4 = list[1]; - - attr1.id = SAI_NEIGHBOR_ENTRY_ATTR_DST_MAC_ADDRESS; - memcpy(attr1.value.mac, mac, 6); - - attr2.id = SAI_NEIGHBOR_ENTRY_ATTR_PACKET_ACTION; - attr2.value.s32 = SAI_PACKET_ACTION_FORWARD; - - attr3.id = SAI_NEIGHBOR_ENTRY_ATTR_NO_HOST_ROUTE; - attr3.value.booldata = true; - - attr4.id = SAI_NEIGHBOR_ENTRY_ATTR_META_DATA; - attr4.value.u32 = 1; - - sai_object_id_t rif = create_rif(switch_id); - - neighbor_entry.ip_address.addr_family = SAI_IP_ADDR_FAMILY_IPV4; - neighbor_entry.ip_address.addr.ip4 = htonl(0x0a00000f); - neighbor_entry.rif_id = rif; - neighbor_entry.switch_id = switch_id; - - SWSS_LOG_NOTICE("create"); - - SWSS_LOG_NOTICE("correct ipv4"); - status = g_meta->create(&neighbor_entry, 2, list); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("correct ipv4 existing"); - status = g_meta->create(&neighbor_entry, 2, list); - META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("set"); - status = g_meta->set(&neighbor_entry, &attr1); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("set"); - status = g_meta->set(&neighbor_entry, &attr2); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("set"); - status = g_meta->set(&neighbor_entry, &attr3); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("set"); - status = g_meta->set(&neighbor_entry, &attr4); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("remove"); - status = g_meta->remove(&neighbor_entry); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("remove existing"); - status = g_meta->remove(&neighbor_entry); - META_ASSERT_FAIL(status); - - remove_switch(switch_id); -} - -// VLAN TESTS - -sai_object_id_t create_vlan( - _In_ sai_object_id_t switch_id) -{ - SWSS_LOG_ENTER(); - - sai_object_id_t vlan; - - sai_attribute_t attrs[9] = { }; - - attrs[0].id = SAI_VLAN_ATTR_VLAN_ID; - attrs[0].value.u16 = 1; - - auto status = g_meta->create(SAI_OBJECT_TYPE_VLAN, &vlan, switch_id, 1, attrs); - META_ASSERT_SUCCESS(status); - - return vlan; -} - -static sai_object_id_t create_stp( - _In_ sai_object_id_t switch_id) -{ - SWSS_LOG_ENTER(); - - sai_object_id_t stp; - - auto status = g_meta->create(SAI_OBJECT_TYPE_STP, &stp, switch_id, 0, NULL); - META_ASSERT_SUCCESS(status); - - return stp; -} - -void test_vlan_create() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - sai_status_t status; - - sai_attribute_t vlan1_att; - vlan1_att.id = SAI_VLAN_ATTR_VLAN_ID; - vlan1_att.value.u16 = 1; - - sai_object_id_t vlan1_id; - - sai_object_id_t switch_id = create_switch(); - - status = g_meta->create(SAI_OBJECT_TYPE_VLAN, &vlan1_id, switch_id, 1, &vlan1_att); - META_ASSERT_SUCCESS(status); - - sai_attribute_t vlan; - vlan.id = SAI_VLAN_ATTR_VLAN_ID; - vlan.value.u16 = 2; - - sai_object_id_t vlan_id; - - SWSS_LOG_NOTICE("create tests"); - -// SWSS_LOG_NOTICE("existing vlan"); -// status = g_meta->create(SAI_OBJECT_TYPE_VLAN, &vlan_id, switch_id, 1, &vlan); -// META_ASSERT_FAIL(status); - - vlan.value.u16 = MAXIMUM_VLAN_NUMBER + 1; - -// SWSS_LOG_NOTICE("vlan outside range"); -// status = g_meta->create(SAI_OBJECT_TYPE_VLAN, &vlan_id, switch_id, 1, &vlan); -// META_ASSERT_FAIL(status); - - vlan.value.u16 = 2; - - SWSS_LOG_NOTICE("correct"); - status = g_meta->create(SAI_OBJECT_TYPE_VLAN, &vlan_id, switch_id, 1, &vlan); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("existing"); - status = g_meta->create(SAI_OBJECT_TYPE_VLAN, &vlan_id, switch_id, 1, &vlan); - META_ASSERT_FAIL(status); - - remove_switch(switch_id); -} - -void test_vlan_remove() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - sai_status_t status; - - sai_attribute_t vlan1_att; - vlan1_att.id = SAI_VLAN_ATTR_VLAN_ID; - vlan1_att.value.u16 = 1; - - sai_object_id_t vlan1_id; - sai_object_id_t switch_id = create_switch(); - - SWSS_LOG_NOTICE("create"); - - status = g_meta->create(SAI_OBJECT_TYPE_VLAN, &vlan1_id, switch_id, 1, &vlan1_att); - META_ASSERT_SUCCESS(status); - - sai_attribute_t vlan; - vlan.id = SAI_VLAN_ATTR_VLAN_ID; - vlan.value.u16 = 2; - - sai_object_id_t vlan_id; - - SWSS_LOG_NOTICE("correct"); - status = g_meta->create(SAI_OBJECT_TYPE_VLAN, &vlan_id, switch_id, 1, &vlan); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("remove tests"); - - SWSS_LOG_NOTICE("invalid vlan"); - status = g_meta->remove(SAI_OBJECT_TYPE_VLAN, SAI_NULL_OBJECT_ID); - META_ASSERT_FAIL(status); - -// SWSS_LOG_NOTICE("default vlan"); -// status = g_meta->remove(SAI_OBJECT_TYPE_VLAN, vlan1_id); -// META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("success"); - status = g_meta->remove(SAI_OBJECT_TYPE_VLAN, vlan_id); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("non existing"); - status = g_meta->remove(SAI_OBJECT_TYPE_VLAN, vlan_id); - META_ASSERT_FAIL(status); - - remove_switch(switch_id); -} - -void test_vlan_set() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - sai_status_t status; - - sai_attribute_t attr; - - sai_attribute_t vlan1_att; - vlan1_att.id = SAI_VLAN_ATTR_VLAN_ID; - vlan1_att.value.u16 = 1; - - sai_object_id_t vlan1_id; - sai_object_id_t switch_id = create_switch(); - - sai_object_id_t stp = create_stp(switch_id); - - SWSS_LOG_NOTICE("create"); - - status = g_meta->create(SAI_OBJECT_TYPE_VLAN, &vlan1_id, switch_id, 1, &vlan1_att); - META_ASSERT_SUCCESS(status); - - sai_attribute_t vlan; - vlan.id = SAI_VLAN_ATTR_VLAN_ID; - vlan.value.u16 = 2; - - sai_object_id_t vlan_id; - - SWSS_LOG_NOTICE("correct"); - status = g_meta->create(SAI_OBJECT_TYPE_VLAN, &vlan_id, switch_id, 1, &vlan); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("set tests"); - - SWSS_LOG_NOTICE("invalid vlan"); - status = g_meta->set(SAI_OBJECT_TYPE_VLAN, SAI_NULL_OBJECT_ID, &vlan); - META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("set is null"); - status = g_meta->set(SAI_OBJECT_TYPE_VLAN, vlan_id, &vlan); - META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("attr is null"); - status = g_meta->set(SAI_OBJECT_TYPE_VLAN, vlan_id, NULL); - META_ASSERT_FAIL(status); - - attr.id = -1; - - SWSS_LOG_NOTICE("invalid attribute"); - status = g_meta->set(SAI_OBJECT_TYPE_VLAN, vlan_id, &attr); - META_ASSERT_FAIL(status); - - attr.id = SAI_VLAN_ATTR_MEMBER_LIST; - - SWSS_LOG_NOTICE("read only"); - status = g_meta->set(SAI_OBJECT_TYPE_VLAN, vlan_id, &attr); - META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("max learned addresses"); - attr.id = SAI_VLAN_ATTR_MAX_LEARNED_ADDRESSES; - attr.value.u32 = 1; - status = g_meta->set(SAI_OBJECT_TYPE_VLAN, vlan_id, &attr); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("null stp instance"); - attr.id = SAI_VLAN_ATTR_STP_INSTANCE; - attr.value.oid = SAI_NULL_OBJECT_ID; - status = g_meta->set(SAI_OBJECT_TYPE_VLAN, vlan_id, &attr); - META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("wrong type on stp instance"); - attr.id = SAI_VLAN_ATTR_STP_INSTANCE; - attr.value.oid = create_dummy_object_id(SAI_OBJECT_TYPE_HASH,switch_id); - status = g_meta->set(SAI_OBJECT_TYPE_VLAN, vlan_id, &attr); - META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("wrong type on stp instance"); - attr.id = SAI_VLAN_ATTR_STP_INSTANCE; - attr.value.oid = create_dummy_object_id(SAI_OBJECT_TYPE_STP,switch_id); - status = g_meta->set(SAI_OBJECT_TYPE_VLAN, vlan_id, &attr); - META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("good stp oid"); - attr.id = SAI_VLAN_ATTR_STP_INSTANCE; - attr.value.oid = stp; - status = g_meta->set(SAI_OBJECT_TYPE_VLAN, vlan_id, &attr); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("learn disable"); - attr.id = SAI_VLAN_ATTR_LEARN_DISABLE; - attr.value.booldata = false; - status = g_meta->set(SAI_OBJECT_TYPE_VLAN, vlan_id, &attr); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("metadat"); - attr.id = SAI_VLAN_ATTR_META_DATA; - attr.value.u32 = 1; - status = g_meta->set(SAI_OBJECT_TYPE_VLAN, vlan_id, &attr); - META_ASSERT_SUCCESS(status); - - remove_switch(switch_id); -} - -void test_vlan_get() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - sai_object_id_t switch_id = create_switch(); - sai_status_t status; - - sai_attribute_t attr; - - sai_attribute_t vlan1_att; - vlan1_att.id = SAI_VLAN_ATTR_VLAN_ID; - vlan1_att.value.u16 = 1; - - sai_object_id_t vlan1_id; - - sai_object_id_t stp = create_stp(switch_id); - - SWSS_LOG_NOTICE("create"); - - status = g_meta->create(SAI_OBJECT_TYPE_VLAN, &vlan1_id, switch_id, 1, &vlan1_att); - META_ASSERT_SUCCESS(status); - - sai_attribute_t vlan; - vlan.id = SAI_VLAN_ATTR_VLAN_ID; - vlan.value.u16 = 2; - - sai_object_id_t vlan_id; - - SWSS_LOG_NOTICE("correct"); - status = g_meta->create(SAI_OBJECT_TYPE_VLAN, &vlan_id, switch_id, 1, &vlan); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("get tests"); - - attr.id = SAI_VLAN_ATTR_MAX_LEARNED_ADDRESSES; - - SWSS_LOG_NOTICE("invalid vlan"); - status = g_meta->get(SAI_OBJECT_TYPE_VLAN, 0, 1, &attr); - META_ASSERT_FAIL(status); - -// SWSS_LOG_NOTICE("invalid vlan"); -// status = g_meta->get(SAI_OBJECT_TYPE_VLAN, 3, 1, &attr); -// META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("attr is null"); - status = g_meta->get(SAI_OBJECT_TYPE_VLAN, vlan_id, 1, NULL); - META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("zero attributes"); - status = g_meta->get(SAI_OBJECT_TYPE_VLAN, vlan_id, 0, &attr); - META_ASSERT_FAIL(status); - - attr.id = -1; - - SWSS_LOG_NOTICE("invalid attribute"); - status = g_meta->get(SAI_OBJECT_TYPE_VLAN, vlan_id, 1, &attr); - META_ASSERT_FAIL(status); - - attr.id = SAI_VLAN_ATTR_MEMBER_LIST; - attr.value.objlist.count = 1; - attr.value.objlist.list = NULL; - - SWSS_LOG_NOTICE("read only null list"); - status = g_meta->get(SAI_OBJECT_TYPE_VLAN, vlan_id, 1, &attr); - META_ASSERT_FAIL(status); - - sai_object_id_t list[5] = { }; - - list[0] = SAI_NULL_OBJECT_ID; - list[1] = create_dummy_object_id(SAI_OBJECT_TYPE_HASH,switch_id); - list[2] = create_dummy_object_id(SAI_OBJECT_TYPE_VLAN_MEMBER,switch_id); - list[3] = stp; - - attr.value.objlist.count = 0; - attr.value.objlist.list = list; - - SWSS_LOG_NOTICE("readonly 0 count and not null"); - status = g_meta->get(SAI_OBJECT_TYPE_VLAN, vlan_id, 1, &attr); -// META_ASSERT_SUCCESS(status); - - attr.value.objlist.count = 5; - - SWSS_LOG_NOTICE("readonly count and not null"); - status = g_meta->get(SAI_OBJECT_TYPE_VLAN, vlan_id, 1, &attr); - META_ASSERT_SUCCESS(status); - - attr.value.objlist.count = 0; - attr.value.objlist.list = NULL; - - SWSS_LOG_NOTICE("readonly count 0 and null"); - status = g_meta->get(SAI_OBJECT_TYPE_VLAN, vlan_id, 1, &attr); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("max learned addresses"); - attr.id = SAI_VLAN_ATTR_MAX_LEARNED_ADDRESSES; - status = g_meta->get(SAI_OBJECT_TYPE_VLAN, vlan_id, 1, &attr); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("stp instance"); - attr.id = SAI_VLAN_ATTR_STP_INSTANCE; - status = g_meta->get(SAI_OBJECT_TYPE_VLAN, vlan_id, 1, &attr); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("learn disable"); - attr.id = SAI_VLAN_ATTR_LEARN_DISABLE; - status = g_meta->get(SAI_OBJECT_TYPE_VLAN, vlan_id, 1, &attr); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("metadata"); - attr.id = SAI_VLAN_ATTR_META_DATA; - status = g_meta->get(SAI_OBJECT_TYPE_VLAN, vlan_id, 1, &attr); - META_ASSERT_SUCCESS(status); - - remove_switch(switch_id); -} - -void test_vlan_flow() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - sai_attribute_t attr; - - sai_status_t status; - - sai_object_id_t vlan_id; - - sai_attribute_t at; - at.id = SAI_VLAN_ATTR_VLAN_ID; - at.value.u16 = 2; - sai_object_id_t switch_id = create_switch(); - - status = g_meta->create(SAI_OBJECT_TYPE_VLAN, &vlan_id, switch_id, 1, &at); - META_ASSERT_SUCCESS(status); - - sai_object_id_t stp = create_stp(switch_id); - - SWSS_LOG_NOTICE("create"); - - attr.id = SAI_VLAN_ATTR_VLAN_ID; - at.value.u16 = 2; - - SWSS_LOG_NOTICE("correct"); - status = g_meta->create(SAI_OBJECT_TYPE_VLAN, &vlan_id, switch_id, 1, &attr); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("existing"); - status = g_meta->create(SAI_OBJECT_TYPE_VLAN, &vlan_id, switch_id, 1, &attr); - META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("set"); - - SWSS_LOG_NOTICE("max learned addresses"); - attr.id = SAI_VLAN_ATTR_MAX_LEARNED_ADDRESSES; - attr.value.u32 = 1; - status = g_meta->set(SAI_OBJECT_TYPE_VLAN, vlan_id, &attr); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("good stp oid"); - attr.id = SAI_VLAN_ATTR_STP_INSTANCE; - attr.value.oid = stp; - status = g_meta->set(SAI_OBJECT_TYPE_VLAN, vlan_id, &attr); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("learn disable"); - attr.id = SAI_VLAN_ATTR_LEARN_DISABLE; - attr.value.booldata = false; - status = g_meta->set(SAI_OBJECT_TYPE_VLAN, vlan_id, &attr); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("metadata"); - attr.id = SAI_VLAN_ATTR_META_DATA; - attr.value.u32 = 1; - status = g_meta->set(SAI_OBJECT_TYPE_VLAN, vlan_id, &attr); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("get"); - - sai_object_id_t list[5] = { }; - - list[0] = SAI_NULL_OBJECT_ID; - list[1] = create_dummy_object_id(SAI_OBJECT_TYPE_HASH,switch_id); - list[2] = create_dummy_object_id(SAI_OBJECT_TYPE_VLAN_MEMBER,switch_id); - list[3] = stp; - - attr.value.objlist.count = 0; - attr.value.objlist.list = list; - - SWSS_LOG_NOTICE("readonly 0 count and not null"); - status = g_meta->get(SAI_OBJECT_TYPE_VLAN, vlan_id, 1, &attr); - META_ASSERT_SUCCESS(status); - - attr.value.objlist.count = 5; - - SWSS_LOG_NOTICE("readonly count and not null"); - status = g_meta->get(SAI_OBJECT_TYPE_VLAN, vlan_id, 1, &attr); - META_ASSERT_SUCCESS(status); - - attr.value.objlist.count = 0; - attr.value.objlist.list = NULL; - - SWSS_LOG_NOTICE("readonly count 0 and null"); - status = g_meta->get(SAI_OBJECT_TYPE_VLAN, vlan_id, 1, &attr); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("max learned addresses"); - attr.id = SAI_VLAN_ATTR_MAX_LEARNED_ADDRESSES; - status = g_meta->get(SAI_OBJECT_TYPE_VLAN, vlan_id, 1, &attr); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("stp instance"); - attr.id = SAI_VLAN_ATTR_STP_INSTANCE; - status = g_meta->get(SAI_OBJECT_TYPE_VLAN, vlan_id, 1, &attr); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("learn disable"); - attr.id = SAI_VLAN_ATTR_LEARN_DISABLE; - status = g_meta->get(SAI_OBJECT_TYPE_VLAN, vlan_id, 1, &attr); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("metadata"); - attr.id = SAI_VLAN_ATTR_META_DATA; - status = g_meta->get(SAI_OBJECT_TYPE_VLAN, vlan_id, 1, &attr); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("remove"); - - SWSS_LOG_NOTICE("success"); - status = g_meta->remove(SAI_OBJECT_TYPE_VLAN, vlan_id); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("non existing"); - status = g_meta->remove(SAI_OBJECT_TYPE_VLAN, vlan_id); - META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("learn disable"); - attr.id = SAI_VLAN_ATTR_LEARN_DISABLE; - status = g_meta->get(SAI_OBJECT_TYPE_VLAN, vlan_id, 1, &attr); - META_ASSERT_FAIL(status); - - remove_switch(switch_id); -} - -// ROUTE TESTS - -static sai_object_id_t create_next_hop( - _In_ sai_object_id_t switch_id) -{ - SWSS_LOG_ENTER(); - - sai_object_id_t nh; - - sai_attribute_t attrs[9] = { }; - - attrs[0].id = SAI_NEXT_HOP_ATTR_TYPE; - attrs[0].value.s32 = SAI_NEXT_HOP_TYPE_IP; - - attrs[1].id = SAI_NEXT_HOP_ATTR_IP; - - auto rif = create_rif(switch_id); - - attrs[2].id = SAI_NEXT_HOP_ATTR_ROUTER_INTERFACE_ID; - attrs[2].value.oid = rif; - - auto status = g_meta->create(SAI_OBJECT_TYPE_NEXT_HOP, &nh, switch_id, 3, attrs); - META_ASSERT_SUCCESS(status); - - return nh; -} - -void test_route_entry_create() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - sai_status_t status; - sai_attribute_t attr; - - sai_object_id_t switch_id = create_switch(); - sai_route_entry_t route_entry; - - sai_object_id_t vr = create_virtual_router(switch_id); - - sai_object_id_t hop = create_next_hop(switch_id); - - route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; - route_entry.destination.addr.ip4 = htonl(0x0a00000f); - route_entry.destination.mask.ip4 = htonl(0xffffff00); - route_entry.vr_id = vr; - route_entry.switch_id = switch_id; - - SWSS_LOG_NOTICE("create tests"); - - // commented out as there is no mandatory attribute - // SWSS_LOG_NOTICE("zero attribute count (but there are mandatory attributes)"); - // attr.id = SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID; - // status = g_meta->create(&route_entry, 0, &attr); - // META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("attr is null"); - status = g_meta->create(&route_entry, 1, NULL); - META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("route entry is null"); - status = g_meta->create((sai_route_entry_t*)NULL, 1, &attr); - META_ASSERT_FAIL(status); - - sai_attribute_t list[3] = { }; - - sai_attribute_t &attr1 = list[0]; - sai_attribute_t &attr2 = list[1]; - sai_attribute_t &attr3 = list[2]; - - attr1.id = SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID; - attr1.value.oid = hop; - - attr2.id = SAI_ROUTE_ENTRY_ATTR_PACKET_ACTION; - attr2.value.s32 = SAI_PACKET_ACTION_FORWARD; - - attr3.id = -1; - - SWSS_LOG_NOTICE("invalid attribute id"); - status = g_meta->create(&route_entry, 3, list); - META_ASSERT_FAIL(status); - - attr2.value.s32 = SAI_PACKET_ACTION_FORWARD + 0x100; - SWSS_LOG_NOTICE("invalid attribute value on enum"); - status = g_meta->create(&route_entry, 2, list); - META_ASSERT_FAIL(status); - - attr2.value.s32 = SAI_PACKET_ACTION_FORWARD; - - sai_attribute_t list2[4] = { attr1, attr2, attr2 }; - - SWSS_LOG_NOTICE("repeated attribute id"); - status = g_meta->create(&route_entry, 3, list2); - META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("wrong object type"); - attr1.value.oid = create_dummy_object_id(SAI_OBJECT_TYPE_HASH,switch_id); - status = g_meta->create(&route_entry, 2, list); - META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("non existing object"); - attr1.value.oid = create_dummy_object_id(SAI_OBJECT_TYPE_NEXT_HOP,switch_id); - status = g_meta->create(&route_entry, 2, list); - META_ASSERT_FAIL(status); - - int fam = 10; - attr1.value.oid = hop; - route_entry.destination.addr_family = (sai_ip_addr_family_t)fam; - - SWSS_LOG_NOTICE("wrong address family"); - status = g_meta->create(&route_entry, 2, list); - META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("correct ipv4"); - route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; - status = g_meta->create(&route_entry, 2, list); - META_ASSERT_SUCCESS(status); - - route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV6; - sai_ip6_t ip62 = {0x00, 0x11, 0x22, 0x33,0x44, 0x55, 0x66,0x77, 0x88, 0x99, 0xaa, 0xbb,0xcc,0xdd,0xee,0x99}; - memcpy(route_entry.destination.addr.ip6, ip62, 16); - - sai_ip6_t ip6mask2 = {0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff, 0xff,0xff,0xff,0xf7,0x00}; - memcpy(route_entry.destination.mask.ip6, ip6mask2, 16); - - SWSS_LOG_NOTICE("invalid mask"); - status = g_meta->create(&route_entry, 2, list); - META_ASSERT_FAIL(status); - - route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV6; - sai_ip6_t ip6 = {0x00, 0x11, 0x22, 0x33,0x44, 0x55, 0x66,0x77, 0x88, 0x99, 0xaa, 0xbb,0xcc,0xdd,0xee,0xff}; - memcpy(route_entry.destination.addr.ip6, ip6, 16); - - sai_ip6_t ip6mask = {0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff, 0xff,0xff,0xff,0xff,0x00}; - memcpy(route_entry.destination.mask.ip6, ip6mask, 16); - - SWSS_LOG_NOTICE("correct ipv6"); - status = g_meta->create(&route_entry, 2, list); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("already exists"); - status = g_meta->create(&route_entry, 2, list); - META_ASSERT_FAIL(status); - - remove_switch(switch_id); -} - -void test_route_entry_remove() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - sai_status_t status; - sai_object_id_t switch_id = create_switch(); - - sai_route_entry_t route_entry; - - sai_object_id_t vr = create_virtual_router(switch_id); - sai_object_id_t hop = create_next_hop(switch_id); - - route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; - route_entry.destination.addr.ip4 = htonl(0x0a00000f); - route_entry.destination.mask.ip4 = htonl(0xffffff00); - route_entry.vr_id = vr; - route_entry.switch_id = switch_id; - - SWSS_LOG_NOTICE("create tests"); - - sai_attribute_t list[3] = { }; - - sai_attribute_t &attr1 = list[0]; - sai_attribute_t &attr2 = list[1]; - - attr1.id = SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID; - attr1.value.oid = hop; - - attr2.id = SAI_ROUTE_ENTRY_ATTR_PACKET_ACTION; - attr2.value.s32 = SAI_PACKET_ACTION_FORWARD; - - SWSS_LOG_NOTICE("correct ipv4"); - route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; - status = g_meta->create(&route_entry, 2, list); - META_ASSERT_SUCCESS(status); - - route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV6; - sai_ip6_t ip6 = {0x00, 0x11, 0x22, 0x33,0x44, 0x55, 0x66,0x77, 0x88, 0x99, 0xaa, 0xbb,0xcc,0xdd,0xee,0xff}; - memcpy(route_entry.destination.addr.ip6, ip6, 16); - - sai_ip6_t ip6mask = {0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff, 0xff,0xff,0xff,0xff,0x00}; - memcpy(route_entry.destination.mask.ip6, ip6mask, 16); - - SWSS_LOG_NOTICE("correct ipv6"); - status = g_meta->create(&route_entry, 2, list); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("remove tests"); - - SWSS_LOG_NOTICE("route_entry is null"); - status = g_meta->remove((sai_route_entry_t*)NULL); - META_ASSERT_FAIL(status); - - route_entry.vr_id = SAI_NULL_OBJECT_ID; - - SWSS_LOG_NOTICE("invalid object id null"); - status = g_meta->remove(&route_entry); - META_ASSERT_FAIL(status); - - route_entry.vr_id = create_dummy_object_id(SAI_OBJECT_TYPE_HASH,switch_id); - - SWSS_LOG_NOTICE("invalid object id hash"); - status = g_meta->remove(&route_entry); - META_ASSERT_FAIL(status); - - route_entry.vr_id = create_dummy_object_id(SAI_OBJECT_TYPE_VIRTUAL_ROUTER,switch_id); - - SWSS_LOG_NOTICE("invalid object id router"); - status = g_meta->remove(&route_entry); - META_ASSERT_FAIL(status); - - route_entry.vr_id = vr; - - sai_object_meta_key_t key = { .objecttype = SAI_OBJECT_TYPE_ROUTE_ENTRY, .objectkey = { .key = { .route_entry = route_entry } } }; - - META_ASSERT_TRUE(g_meta->objectExists(key)); - - SWSS_LOG_NOTICE("success"); - status = g_meta->remove(&route_entry); - META_ASSERT_SUCCESS(status); - - META_ASSERT_TRUE(!g_meta->objectExists(key)); - - route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; - route_entry.destination.addr.ip4 = htonl(0x0a00000f); - route_entry.destination.mask.ip4 = htonl(0xffffff00); - - SWSS_LOG_NOTICE("success"); - status = g_meta->remove(&route_entry); - META_ASSERT_SUCCESS(status); - - remove_switch(switch_id); -} - -void test_route_entry_set() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - sai_status_t status; - sai_attribute_t attr; - sai_object_id_t switch_id = create_switch(); - - sai_route_entry_t route_entry; - - sai_object_id_t vr = create_virtual_router(switch_id); - sai_object_id_t hop = create_next_hop(switch_id); - - route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; - route_entry.destination.addr.ip4 = htonl(0x0a00000f); - route_entry.destination.mask.ip4 = htonl(0xffffff00); - route_entry.vr_id = vr; - route_entry.switch_id = switch_id; - - SWSS_LOG_NOTICE("create tests"); - - sai_attribute_t list[3] = { }; - - sai_attribute_t &attr1 = list[0]; - sai_attribute_t &attr2 = list[1]; - - attr1.id = SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID; - attr1.value.oid = hop; - - attr2.id = SAI_ROUTE_ENTRY_ATTR_PACKET_ACTION; - attr2.value.s32 = SAI_PACKET_ACTION_FORWARD; - - SWSS_LOG_NOTICE("correct ipv4"); - route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; - status = g_meta->create(&route_entry, 2, list); - META_ASSERT_SUCCESS(status); - - route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV6; - sai_ip6_t ip6 = {0x00, 0x11, 0x22, 0x33,0x44, 0x55, 0x66,0x77, 0x88, 0x99, 0xaa, 0xbb,0xcc,0xdd,0xee,0xff}; - memcpy(route_entry.destination.addr.ip6, ip6, 16); - - sai_ip6_t ip6mask = {0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff, 0xff,0xff,0xff,0xff,0x00}; - memcpy(route_entry.destination.mask.ip6, ip6mask, 16); - - SWSS_LOG_NOTICE("correct ipv6"); - status = g_meta->create(&route_entry, 2, list); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("set tests"); - - SWSS_LOG_NOTICE("attr is null"); - status = g_meta->set(&route_entry, NULL); - META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("route entry is null"); - status = g_meta->set((sai_route_entry_t*)NULL, &attr); - META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("setting invalid attrib id"); - attr.id = -1; - status = g_meta->set(&route_entry, &attr); - META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("value outside range"); - attr.id = SAI_ROUTE_ENTRY_ATTR_PACKET_ACTION; - attr.value.s32 = 0x100; - status = g_meta->set(&route_entry, &attr); - META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("correct packet action"); - attr.id = SAI_ROUTE_ENTRY_ATTR_PACKET_ACTION; - attr.value.s32 = SAI_PACKET_ACTION_DROP; - status = g_meta->set(&route_entry, &attr); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("correct next hop"); - attr.id = SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID; - attr.value.oid = hop; - status = g_meta->set(&route_entry, &attr); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("correct metadata"); - attr.id = SAI_ROUTE_ENTRY_ATTR_META_DATA; - attr.value.u32 = 0x12345678; - status = g_meta->set(&route_entry, &attr); - META_ASSERT_SUCCESS(status); - - remove_switch(switch_id); -} - -void test_route_entry_get() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - sai_status_t status; - sai_attribute_t attr; - sai_object_id_t switch_id = create_switch(); - - sai_route_entry_t route_entry; - - sai_object_id_t vr = create_virtual_router(switch_id); - sai_object_id_t hop = create_next_hop(switch_id); - - route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; - route_entry.destination.addr.ip4 = htonl(0x0a00000f); - route_entry.destination.mask.ip4 = htonl(0xffffff00); - route_entry.vr_id = vr; - route_entry.switch_id = switch_id; - - SWSS_LOG_NOTICE("create tests"); - - sai_attribute_t list[3] = { }; - - sai_attribute_t &attr1 = list[0]; - sai_attribute_t &attr2 = list[1]; - - attr1.id = SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID; - attr1.value.oid = hop; - - attr2.id = SAI_ROUTE_ENTRY_ATTR_PACKET_ACTION; - attr2.value.s32 = SAI_PACKET_ACTION_FORWARD; - - SWSS_LOG_NOTICE("correct ipv4"); - route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; - status = g_meta->create(&route_entry, 2, list); - META_ASSERT_SUCCESS(status); - - route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV6; - sai_ip6_t ip6 = {0x00, 0x11, 0x22, 0x33,0x44, 0x55, 0x66,0x77, 0x88, 0x99, 0xaa, 0xbb,0xcc,0xdd,0xee,0xff}; - memcpy(route_entry.destination.addr.ip6, ip6, 16); - - sai_ip6_t ip6mask = {0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff, 0xff,0xff,0xff,0xff,0x00}; - memcpy(route_entry.destination.mask.ip6, ip6mask, 16); - - SWSS_LOG_NOTICE("correct ipv6"); - status = g_meta->create(&route_entry, 2, list); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("zero attribute count"); - attr.id = SAI_ROUTE_ENTRY_ATTR_PACKET_ACTION; - status = g_meta->get(&route_entry, 0, &attr); - META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("attr is null"); - status = g_meta->get(&route_entry, 1, NULL); - META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("route entry is null"); - status = g_meta->get((sai_route_entry_t*)NULL, 1, &attr); - META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("attr id out of range"); - attr.id = -1; - status = g_meta->get(&route_entry, 1, &attr); - META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("correct packet action"); - attr.id = SAI_ROUTE_ENTRY_ATTR_PACKET_ACTION; - status = g_meta->get(&route_entry, 1, &attr); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("correct next hop"); - attr.id = SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID; - status = g_meta->get(&route_entry, 1, &attr); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("correct meta"); - attr.id = SAI_ROUTE_ENTRY_ATTR_META_DATA; - status = g_meta->get(&route_entry, 1, &attr); - META_ASSERT_SUCCESS(status); - - remove_switch(switch_id); -} - -void test_route_entry_flow() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - sai_status_t status; - sai_attribute_t attr; - - sai_route_entry_t route_entry; - sai_object_id_t switch_id = create_switch(); - - sai_object_id_t vr = create_virtual_router(switch_id); - sai_object_id_t hop = create_next_hop(switch_id); - - route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; - route_entry.destination.addr.ip4 = htonl(0x0a00000f); - route_entry.destination.mask.ip4 = htonl(0xffffff00); - route_entry.vr_id = vr; - route_entry.switch_id = switch_id; - - SWSS_LOG_NOTICE("create tests"); - - sai_attribute_t list[3] = { }; - - sai_attribute_t &attr1 = list[0]; - sai_attribute_t &attr2 = list[1]; - - attr1.id = SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID; - attr1.value.oid = hop; - - attr2.id = SAI_ROUTE_ENTRY_ATTR_PACKET_ACTION; - attr2.value.s32 = SAI_PACKET_ACTION_FORWARD; - - SWSS_LOG_NOTICE("correct ipv4"); - route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; - status = g_meta->create(&route_entry, 2, list); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("already exists ipv4"); - route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; - status = g_meta->create(&route_entry, 2, list); - META_ASSERT_FAIL(status); - - route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV6; - sai_ip6_t ip62 = {0x00, 0x11, 0x22, 0x33,0x44, 0x55, 0x66,0x77, 0x88, 0x99, 0xaa, 0xbb,0xcc,0xdd,0xee,0x99}; - memcpy(route_entry.destination.addr.ip6, ip62, 16); - - sai_ip6_t ip6mask2 = {0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff, 0xff,0xff,0xff,0xf7,0x00}; - memcpy(route_entry.destination.mask.ip6, ip6mask2, 16); - - SWSS_LOG_NOTICE("invalid mask"); - status = g_meta->create(&route_entry, 2, list); - META_ASSERT_FAIL(status); - - route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV6; - sai_ip6_t ip6 = {0x00, 0x11, 0x22, 0x33,0x44, 0x55, 0x66,0x77, 0x88, 0x99, 0xaa, 0xbb,0xcc,0xdd,0xee,0xff}; - memcpy(route_entry.destination.addr.ip6, ip6, 16); - - sai_ip6_t ip6mask = {0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff, 0xff,0xff,0xff,0xff,0x00}; - memcpy(route_entry.destination.mask.ip6, ip6mask, 16); - - SWSS_LOG_NOTICE("correct ipv6"); - status = g_meta->create(&route_entry, 2, list); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("already exists"); - status = g_meta->create(&route_entry, 2, list); - META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("set tests"); - - SWSS_LOG_NOTICE("correct packet action"); - attr.id = SAI_ROUTE_ENTRY_ATTR_PACKET_ACTION; - attr.value.s32 = SAI_PACKET_ACTION_DROP; - status = g_meta->set(&route_entry, &attr); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("correct next hop"); - attr.id = SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID; - attr.value.oid = hop; - status = g_meta->set(&route_entry, &attr); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("correct metadata"); - attr.id = SAI_ROUTE_ENTRY_ATTR_META_DATA; - attr.value.u32 = 0x12345678; - status = g_meta->set(&route_entry, &attr); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("get tests"); - - SWSS_LOG_NOTICE("correct packet action"); - attr.id = SAI_ROUTE_ENTRY_ATTR_PACKET_ACTION; - status = g_meta->get(&route_entry, 1, &attr); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("correct next hop"); - attr.id = SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID; - status = g_meta->get(&route_entry, 1, &attr); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("correct meta"); - attr.id = SAI_ROUTE_ENTRY_ATTR_META_DATA; - status = g_meta->get(&route_entry, 1, &attr); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("remove tests"); - - SWSS_LOG_NOTICE("success"); - status = g_meta->remove(&route_entry); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("non existing"); - status = g_meta->remove(&route_entry); - META_ASSERT_FAIL(status); - - route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; - route_entry.destination.addr.ip4 = htonl(0x0a00000f); - route_entry.destination.mask.ip4 = htonl(0xffffff00); - - SWSS_LOG_NOTICE("success"); - status = g_meta->remove(&route_entry); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("non existing"); - status = g_meta->remove(&route_entry); - META_ASSERT_FAIL(status); - - remove_switch(switch_id); -} - -// SERIALIZATION TYPES TESTS - -void test_serialization_type_vlan_list() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - sai_status_t status; - - SWSS_LOG_NOTICE("create stp"); - sai_object_id_t switch_id = create_switch(); - - sai_object_id_t stp = create_stp(switch_id); - - sai_vlan_id_t list[2] = { 1, 2 }; - - sai_attribute_t attr; - - attr.id = SAI_STP_ATTR_VLAN_LIST; - attr.value.vlanlist.count = 2; - attr.value.vlanlist.list = list; - - SWSS_LOG_NOTICE("set vlan list"); - - status = g_meta->set(SAI_OBJECT_TYPE_STP, stp, &attr); - META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("get vlan list"); - - status = g_meta->get(SAI_OBJECT_TYPE_STP, stp, 1, &attr); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("remove stp"); - - status = g_meta->remove(SAI_OBJECT_TYPE_STP, stp); - META_ASSERT_SUCCESS(status); - - remove_switch(switch_id); -} - -void test_serialization_type_bool() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - sai_status_t status; - - sai_object_id_t vr; - - SWSS_LOG_NOTICE("create stp"); - sai_object_id_t switch_id = create_switch(); - - sai_attribute_t attr; - - attr.id = SAI_VIRTUAL_ROUTER_ATTR_ADMIN_V4_STATE; - attr.value.booldata = true; - - status = g_meta->create(SAI_OBJECT_TYPE_VIRTUAL_ROUTER, &vr, switch_id, 1, &attr); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("set bool"); - - status = g_meta->set(SAI_OBJECT_TYPE_VIRTUAL_ROUTER, vr, &attr); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("get bool"); - - status = g_meta->get(SAI_OBJECT_TYPE_VIRTUAL_ROUTER, vr, 1, &attr); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("remove vr"); - - status = g_meta->remove(SAI_OBJECT_TYPE_VIRTUAL_ROUTER, vr); - META_ASSERT_SUCCESS(status); - - remove_switch(switch_id); -} - -void test_serialization_type_char() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - sai_status_t status; - - sai_object_id_t hostif; - - SWSS_LOG_NOTICE("create port"); - sai_object_id_t switch_id = create_switch(); - - sai_object_id_t port = create_port(switch_id); - - sai_attribute_t attr, attr2, attr3; - - attr.id = SAI_HOSTIF_ATTR_TYPE; - attr.value.s32 = SAI_HOSTIF_TYPE_NETDEV; - - attr2.id = SAI_HOSTIF_ATTR_OBJ_ID; - attr2.value.oid = port; - - attr3.id = SAI_HOSTIF_ATTR_NAME; - - memcpy(attr3.value.chardata, "foo", sizeof("foo")); - - sai_attribute_t list[3] = { attr, attr2, attr3 }; - - // TODO we need to support conditions here - - SWSS_LOG_NOTICE("create hostif"); - - status = g_meta->create(SAI_OBJECT_TYPE_HOSTIF, &hostif, switch_id, 3, list); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("set char"); - - status = g_meta->set(SAI_OBJECT_TYPE_HOSTIF, hostif, &attr3); - META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("get char"); - - status = g_meta->get(SAI_OBJECT_TYPE_HOSTIF, hostif, 1, &attr3); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("remove hostif"); - - status = g_meta->remove(SAI_OBJECT_TYPE_HOSTIF, hostif); - META_ASSERT_SUCCESS(status); - - attr.id = SAI_HOSTIF_ATTR_TYPE; - attr.value.s32 = SAI_HOSTIF_TYPE_FD; - - sai_attribute_t list2[1] = { attr }; - - SWSS_LOG_NOTICE("create hostif with non mandatory"); - status = g_meta->create(SAI_OBJECT_TYPE_HOSTIF, &hostif, switch_id, 1, list2); - META_ASSERT_SUCCESS(status); - -// TODO this test should pass, we are doing query here for conditional -// attribute, where condition is not met so this attribute will not be used, so -// metadata should figure out that we can't query this attribute, but there is -// a problem with internal existing objects, since we don't have their values -// then we we can't tell whether attribute was passed or not, we need to get -// switch discovered objects and attributes and populate local db then we need -// to update metadata condition in meta_generic_validation_get method where we -// check if attribute is conditional -// -// SWSS_LOG_NOTICE("get char"); -// -// status = g_meta->get(SAI_OBJECT_TYPE_HOSTIF, hostif, 1, &attr2); -// META_ASSERT_FAIL(status); - - attr.id = SAI_HOSTIF_ATTR_TYPE; - attr.value.s32 = SAI_HOSTIF_TYPE_NETDEV; - - sai_attribute_t list3[1] = { attr }; - - SWSS_LOG_NOTICE("create hostif with mandatory missing"); - status = g_meta->create(SAI_OBJECT_TYPE_HOSTIF, &hostif, switch_id, 1, list3); - META_ASSERT_FAIL(status); - - remove_switch(switch_id); -} - -void test_serialization_type_int32_list() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - sai_status_t status; - - sai_object_id_t hash; - - sai_attribute_t attr; - - SWSS_LOG_NOTICE("create hash"); - sai_object_id_t switch_id = create_switch(); - - int32_t list[2] = { SAI_NATIVE_HASH_FIELD_SRC_IP, SAI_NATIVE_HASH_FIELD_VLAN_ID }; - - attr.id = SAI_HASH_ATTR_NATIVE_HASH_FIELD_LIST; - attr.value.s32list.count = 2; - attr.value.s32list.list = list; - - status = g_meta->create(SAI_OBJECT_TYPE_HASH, &hash, switch_id, 1, &attr); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("set hash"); - - status = g_meta->set(SAI_OBJECT_TYPE_HASH, hash, &attr); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("get hash"); - - status = g_meta->get(SAI_OBJECT_TYPE_HASH, hash, 1, &attr); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("remove hash"); - - status = g_meta->remove(SAI_OBJECT_TYPE_HASH, hash); - META_ASSERT_SUCCESS(status); - - remove_switch(switch_id); -} - -void test_serialization_type_uint32_list() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - sai_status_t status; - - sai_object_id_t hash; - - sai_attribute_t attr; - - SWSS_LOG_NOTICE("create hash"); - sai_object_id_t switch_id = create_switch(); - - int32_t list[2] = { SAI_NATIVE_HASH_FIELD_SRC_IP, SAI_NATIVE_HASH_FIELD_VLAN_ID }; - - attr.id = SAI_HASH_ATTR_NATIVE_HASH_FIELD_LIST; - attr.value.s32list.count = 2; - attr.value.s32list.list = list; - - status = g_meta->create(SAI_OBJECT_TYPE_HASH, &hash, switch_id, 1, &attr); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("set hash"); - - status = g_meta->set(SAI_OBJECT_TYPE_HASH, hash, &attr); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("get hash"); - - status = g_meta->get(SAI_OBJECT_TYPE_HASH, hash, 1, &attr); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("remove hash"); - - status = g_meta->remove(SAI_OBJECT_TYPE_HASH, hash); - META_ASSERT_SUCCESS(status); - - remove_switch(switch_id); -} - -// OTHER - -void test_mask() -{ - SWSS_LOG_ENTER(); - - sai_ip6_t ip6mask1 = {0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff, 0xff,0xff,0xff,0xff,0x00}; - sai_ip6_t ip6mask2 = {0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff, 0xff,0xff,0xff,0xff,0xff}; - sai_ip6_t ip6mask3 = {0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00}; - sai_ip6_t ip6mask4 = {0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff, 0xff,0xff,0xff,0xff,0xfe}; - sai_ip6_t ip6mask5 = {0x80, 0x00, 0x00, 0x00,0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00}; - - sai_ip6_t ip6mask6 = {0x01, 0x00, 0x00, 0x00,0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00}; - sai_ip6_t ip6mask7 = {0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff, 0xff,0xff,0xff,0xff,0x8f}; - sai_ip6_t ip6mask8 = {0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff, 0xff,0xff,0xff,0xff,0x8f}; - sai_ip6_t ip6mask9 = {0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff,0xf1, 0xff, 0xff, 0xff, 0xff,0xff,0xff,0xff,0xff}; - - META_ASSERT_TRUE(Meta::is_ipv6_mask_valid(ip6mask1)); - META_ASSERT_TRUE(Meta::is_ipv6_mask_valid(ip6mask2)); - META_ASSERT_TRUE(Meta::is_ipv6_mask_valid(ip6mask3)); - META_ASSERT_TRUE(Meta::is_ipv6_mask_valid(ip6mask4)); - META_ASSERT_TRUE(Meta::is_ipv6_mask_valid(ip6mask5)); - - META_ASSERT_TRUE(!Meta::is_ipv6_mask_valid(ip6mask6)); - META_ASSERT_TRUE(!Meta::is_ipv6_mask_valid(ip6mask7)); - META_ASSERT_TRUE(!Meta::is_ipv6_mask_valid(ip6mask8)); - META_ASSERT_TRUE(!Meta::is_ipv6_mask_valid(ip6mask9)); -} - -static sai_object_id_t create_acl_table( - _In_ sai_object_id_t switch_id) -{ - SWSS_LOG_ENTER(); - - sai_object_id_t at; - - sai_attribute_t attrs[9] = { }; - - attrs[0].id = SAI_ACL_TABLE_ATTR_ACL_STAGE; - attrs[0].value.s32 = SAI_ACL_STAGE_INGRESS; - - auto status = g_meta->create(SAI_OBJECT_TYPE_ACL_TABLE, &at, switch_id, 1, attrs); - META_ASSERT_SUCCESS(status); - - return at; -} - -static sai_object_id_t create_acl_counter( - _In_ sai_object_id_t switch_id) -{ - SWSS_LOG_ENTER(); - - sai_object_id_t ac; - - sai_attribute_t attrs[9] = { }; - - attrs[0].id = SAI_ACL_COUNTER_ATTR_TABLE_ID; - attrs[0].value.oid = create_acl_table(switch_id); - - auto status = g_meta->create(SAI_OBJECT_TYPE_ACL_COUNTER, &ac, switch_id, 1, attrs); - META_ASSERT_SUCCESS(status); - - return ac; -} - -static sai_object_id_t create_policer( - _In_ sai_object_id_t switch_id) -{ - SWSS_LOG_ENTER(); - - sai_object_id_t policer; - - sai_attribute_t attrs[9] = { }; - - attrs[0].id = SAI_POLICER_ATTR_METER_TYPE; - attrs[0].value.s32 = SAI_METER_TYPE_PACKETS; - attrs[1].id = SAI_POLICER_ATTR_MODE; - attrs[1].value.s32 = SAI_POLICER_MODE_SR_TCM; - - auto status = g_meta->create(SAI_OBJECT_TYPE_POLICER, &policer, switch_id, 2, attrs); - META_ASSERT_SUCCESS(status); - - return policer; -} - -static sai_object_id_t create_samplepacket( - _In_ sai_object_id_t switch_id) -{ - SWSS_LOG_ENTER(); - - sai_object_id_t sp; - - sai_attribute_t attrs[9] = { }; - - attrs[0].id = SAI_SAMPLEPACKET_ATTR_SAMPLE_RATE; - attrs[0].value.u32 = 1; - - auto status = g_meta->create(SAI_OBJECT_TYPE_SAMPLEPACKET, &sp, switch_id, 1, attrs); - META_ASSERT_SUCCESS(status); - - return sp; -} - -static sai_object_id_t create_hostif_udt( - _In_ sai_object_id_t switch_id) -{ - SWSS_LOG_ENTER(); - - sai_object_id_t udt; - - sai_attribute_t attrs[9] = { }; - - attrs[0].id = SAI_HOSTIF_USER_DEFINED_TRAP_ATTR_TYPE; - attrs[0].value.s32 = SAI_HOSTIF_USER_DEFINED_TRAP_TYPE_ROUTER; - - auto status = g_meta->create(SAI_OBJECT_TYPE_HOSTIF_USER_DEFINED_TRAP, &udt, switch_id, 1, attrs); - META_ASSERT_SUCCESS(status); - - return udt; -} - -static sai_object_id_t create_ipg( - _In_ sai_object_id_t switch_id) -{ - SWSS_LOG_ENTER(); - - sai_object_id_t ipg; - - sai_attribute_t attrs[9] = { }; - - attrs[0].id = SAI_INGRESS_PRIORITY_GROUP_ATTR_PORT; - attrs[0].value.oid = create_port(switch_id); - attrs[1].id = SAI_INGRESS_PRIORITY_GROUP_ATTR_INDEX; - attrs[1].value.u8 = 0; - - auto status = g_meta->create(SAI_OBJECT_TYPE_INGRESS_PRIORITY_GROUP, &ipg, switch_id, 2, attrs); - META_ASSERT_SUCCESS(status); - - return ipg; -} - -sai_object_id_t insert_dummy_object( - _In_ sai_object_type_t ot, - _In_ sai_object_id_t switch_id) -{ - SWSS_LOG_ENTER(); - - switch (ot) - { - case SAI_OBJECT_TYPE_PORT: - return create_port(switch_id); - - case SAI_OBJECT_TYPE_ACL_TABLE: - return create_acl_table(switch_id); - - case SAI_OBJECT_TYPE_ACL_COUNTER: - return create_acl_counter(switch_id); - - case SAI_OBJECT_TYPE_POLICER: - return create_policer(switch_id); - - case SAI_OBJECT_TYPE_SAMPLEPACKET: - return create_samplepacket(switch_id); - - case SAI_OBJECT_TYPE_HOSTIF_USER_DEFINED_TRAP: - return create_hostif_udt(switch_id); - - case SAI_OBJECT_TYPE_INGRESS_PRIORITY_GROUP: - return create_ipg(switch_id); - - default: - - SWSS_LOG_THROW("not implemented: %s, FIXME", sai_serialize_object_type(ot).c_str()); - } -} - -void test_acl_entry_field_and_action() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - sai_object_id_t switch_id = create_switch(); - sai_status_t status; - - sai_object_id_t aclentry; - - int32_t ids[] = { - SAI_ACL_ENTRY_ATTR_TABLE_ID, - SAI_ACL_ENTRY_ATTR_PRIORITY, - SAI_ACL_ENTRY_ATTR_FIELD_SRC_IPV6, - SAI_ACL_ENTRY_ATTR_FIELD_DST_IPV6, - SAI_ACL_ENTRY_ATTR_FIELD_SRC_MAC, - SAI_ACL_ENTRY_ATTR_FIELD_DST_MAC, - SAI_ACL_ENTRY_ATTR_FIELD_SRC_IP, - SAI_ACL_ENTRY_ATTR_FIELD_DST_IP, - SAI_ACL_ENTRY_ATTR_FIELD_IN_PORTS, - SAI_ACL_ENTRY_ATTR_FIELD_OUT_PORTS, - SAI_ACL_ENTRY_ATTR_FIELD_IN_PORT, - SAI_ACL_ENTRY_ATTR_FIELD_OUT_PORT, - SAI_ACL_ENTRY_ATTR_FIELD_SRC_PORT, - SAI_ACL_ENTRY_ATTR_FIELD_OUTER_VLAN_ID, - SAI_ACL_ENTRY_ATTR_FIELD_OUTER_VLAN_PRI, - SAI_ACL_ENTRY_ATTR_FIELD_OUTER_VLAN_CFI, - SAI_ACL_ENTRY_ATTR_FIELD_INNER_VLAN_ID, - SAI_ACL_ENTRY_ATTR_FIELD_INNER_VLAN_PRI, - SAI_ACL_ENTRY_ATTR_FIELD_INNER_VLAN_CFI, - SAI_ACL_ENTRY_ATTR_FIELD_L4_SRC_PORT, - SAI_ACL_ENTRY_ATTR_FIELD_L4_DST_PORT, - SAI_ACL_ENTRY_ATTR_FIELD_ETHER_TYPE, - SAI_ACL_ENTRY_ATTR_FIELD_IP_PROTOCOL, - SAI_ACL_ENTRY_ATTR_FIELD_DSCP, - SAI_ACL_ENTRY_ATTR_FIELD_ECN, - SAI_ACL_ENTRY_ATTR_FIELD_TTL, - SAI_ACL_ENTRY_ATTR_FIELD_TOS, - SAI_ACL_ENTRY_ATTR_FIELD_IP_FLAGS, - SAI_ACL_ENTRY_ATTR_FIELD_TCP_FLAGS, - SAI_ACL_ENTRY_ATTR_FIELD_ACL_IP_FRAG, - SAI_ACL_ENTRY_ATTR_FIELD_IPV6_FLOW_LABEL, - SAI_ACL_ENTRY_ATTR_FIELD_TC, - SAI_ACL_ENTRY_ATTR_FIELD_ICMP_TYPE, - SAI_ACL_ENTRY_ATTR_FIELD_ICMP_CODE, - SAI_ACL_ENTRY_ATTR_FIELD_FDB_DST_USER_META, - SAI_ACL_ENTRY_ATTR_FIELD_ROUTE_DST_USER_META, - SAI_ACL_ENTRY_ATTR_FIELD_NEIGHBOR_DST_USER_META, - SAI_ACL_ENTRY_ATTR_FIELD_PORT_USER_META, - SAI_ACL_ENTRY_ATTR_FIELD_VLAN_USER_META, - SAI_ACL_ENTRY_ATTR_FIELD_ACL_USER_META, - SAI_ACL_ENTRY_ATTR_FIELD_FDB_NPU_META_DST_HIT, - SAI_ACL_ENTRY_ATTR_FIELD_NEIGHBOR_NPU_META_DST_HIT, - SAI_ACL_ENTRY_ATTR_FIELD_ROUTE_NPU_META_DST_HIT, - SAI_ACL_ENTRY_ATTR_ACTION_REDIRECT, - //SAI_ACL_ENTRY_ATTR_ACTION_REDIRECT_LIST, - SAI_ACL_ENTRY_ATTR_ACTION_PACKET_ACTION, - SAI_ACL_ENTRY_ATTR_ACTION_FLOOD, - SAI_ACL_ENTRY_ATTR_ACTION_COUNTER, - SAI_ACL_ENTRY_ATTR_ACTION_MIRROR_INGRESS, - SAI_ACL_ENTRY_ATTR_ACTION_MIRROR_EGRESS, - SAI_ACL_ENTRY_ATTR_ACTION_SET_POLICER, - SAI_ACL_ENTRY_ATTR_ACTION_DECREMENT_TTL, - SAI_ACL_ENTRY_ATTR_ACTION_SET_TC, - SAI_ACL_ENTRY_ATTR_ACTION_SET_PACKET_COLOR, - SAI_ACL_ENTRY_ATTR_ACTION_SET_INNER_VLAN_ID, - SAI_ACL_ENTRY_ATTR_ACTION_SET_INNER_VLAN_PRI, - SAI_ACL_ENTRY_ATTR_ACTION_SET_OUTER_VLAN_ID, - SAI_ACL_ENTRY_ATTR_ACTION_SET_OUTER_VLAN_PRI, - SAI_ACL_ENTRY_ATTR_ACTION_SET_SRC_MAC, - SAI_ACL_ENTRY_ATTR_ACTION_SET_DST_MAC, - SAI_ACL_ENTRY_ATTR_ACTION_SET_SRC_IP, - SAI_ACL_ENTRY_ATTR_ACTION_SET_DST_IP, - SAI_ACL_ENTRY_ATTR_ACTION_SET_SRC_IPV6, - SAI_ACL_ENTRY_ATTR_ACTION_SET_DST_IPV6, - SAI_ACL_ENTRY_ATTR_ACTION_SET_DSCP, - SAI_ACL_ENTRY_ATTR_ACTION_SET_ECN, - SAI_ACL_ENTRY_ATTR_ACTION_SET_L4_SRC_PORT, - SAI_ACL_ENTRY_ATTR_ACTION_SET_L4_DST_PORT, - SAI_ACL_ENTRY_ATTR_ACTION_INGRESS_SAMPLEPACKET_ENABLE, - SAI_ACL_ENTRY_ATTR_ACTION_EGRESS_SAMPLEPACKET_ENABLE, - SAI_ACL_ENTRY_ATTR_ACTION_SET_ACL_META_DATA, - SAI_ACL_ENTRY_ATTR_ACTION_EGRESS_BLOCK_PORT_LIST, - SAI_ACL_ENTRY_ATTR_ACTION_SET_USER_TRAP_ID, - }; - - std::vector vattrs; - - // all lists are empty we need info if that is possible - - for (uint32_t i = 0; i < sizeof(ids)/sizeof(int32_t); ++i) - { - sai_attribute_t attr; - - memset(&attr,0,sizeof(attr)); - - attr.value.aclfield.enable = true; - attr.value.aclaction.enable = true; - - attr.id = ids[i]; - - if (attr.id == SAI_ACL_ENTRY_ATTR_TABLE_ID) - attr.value.oid = insert_dummy_object(SAI_OBJECT_TYPE_ACL_TABLE,switch_id); - - if (attr.id == SAI_ACL_ENTRY_ATTR_FIELD_IN_PORT) - attr.value.aclfield.data.oid = insert_dummy_object(SAI_OBJECT_TYPE_PORT,switch_id); - - if (attr.id == SAI_ACL_ENTRY_ATTR_FIELD_OUT_PORT) - attr.value.aclfield.data.oid = insert_dummy_object(SAI_OBJECT_TYPE_PORT,switch_id); - - if (attr.id == SAI_ACL_ENTRY_ATTR_FIELD_SRC_PORT) - attr.value.aclfield.data.oid = insert_dummy_object(SAI_OBJECT_TYPE_PORT,switch_id); - - if (attr.id == SAI_ACL_ENTRY_ATTR_ACTION_REDIRECT) - attr.value.aclaction.parameter.oid = insert_dummy_object(SAI_OBJECT_TYPE_PORT,switch_id); - - if (attr.id == SAI_ACL_ENTRY_ATTR_ACTION_COUNTER) - attr.value.aclaction.parameter.oid = insert_dummy_object(SAI_OBJECT_TYPE_ACL_COUNTER,switch_id); - - if (attr.id == SAI_ACL_ENTRY_ATTR_ACTION_SET_POLICER) - attr.value.aclaction.parameter.oid = insert_dummy_object(SAI_OBJECT_TYPE_POLICER,switch_id); - - if (attr.id == SAI_ACL_ENTRY_ATTR_ACTION_INGRESS_SAMPLEPACKET_ENABLE) - attr.value.aclaction.parameter.oid = insert_dummy_object(SAI_OBJECT_TYPE_SAMPLEPACKET,switch_id); - - if (attr.id == SAI_ACL_ENTRY_ATTR_ACTION_EGRESS_SAMPLEPACKET_ENABLE) - attr.value.aclaction.parameter.oid = insert_dummy_object(SAI_OBJECT_TYPE_SAMPLEPACKET,switch_id); - - if (attr.id == SAI_ACL_ENTRY_ATTR_ACTION_SET_USER_TRAP_ID) - attr.value.aclaction.parameter.oid = insert_dummy_object(SAI_OBJECT_TYPE_HOSTIF_USER_DEFINED_TRAP,switch_id); - - if (attr.id == SAI_ACL_ENTRY_ATTR_ACTION_REDIRECT_LIST) - { - sai_object_id_t list[1]; - - list[0] = insert_dummy_object(SAI_OBJECT_TYPE_QUEUE,switch_id); - - SWSS_LOG_NOTICE("0x%" PRIx64, list[0]); - - attr.value.aclaction.parameter.objlist.count = 1; - attr.value.aclaction.parameter.objlist.list = list; - } - - vattrs.push_back(attr); - } - - SWSS_LOG_NOTICE("create acl entry"); - - status = g_meta->create(SAI_OBJECT_TYPE_ACL_ENTRY, &aclentry, switch_id, (uint32_t)vattrs.size(), vattrs.data()); - META_ASSERT_SUCCESS(status); - - for (uint32_t i = 0; i < sizeof(ids)/sizeof(int32_t); ++i) - { - if (vattrs[i].id == SAI_ACL_ENTRY_ATTR_TABLE_ID) - continue; - - auto m = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_ACL_ENTRY, vattrs[i].id); - - SWSS_LOG_NOTICE("set aclentry %u %s", i, m->attridname); - - status = g_meta->set(SAI_OBJECT_TYPE_ACL_ENTRY, aclentry, &vattrs[i]); - META_ASSERT_SUCCESS(status); - } - - SWSS_LOG_NOTICE("get aclentry"); - - status = g_meta->get(SAI_OBJECT_TYPE_ACL_ENTRY, aclentry, (uint32_t)vattrs.size(), vattrs.data()); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("remove aclentry"); - - status = g_meta->remove(SAI_OBJECT_TYPE_ACL_ENTRY, aclentry); - META_ASSERT_SUCCESS(status); - - remove_switch(switch_id); -} - -void test_construct_key() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - sai_attribute_t attr; - - uint32_t list[4] = {1,2,3,4}; - - attr.id = SAI_PORT_ATTR_HW_LANE_LIST; - attr.value.u32list.count = 4; - attr.value.u32list.list = list; - - sai_object_meta_key_t meta_key; - - meta_key.objecttype = SAI_OBJECT_TYPE_PORT; - - sai_object_id_t switchId = 0x21000000000000; - - std::string key = AttrKeyMap::constructKey(switchId, meta_key, 1, &attr); - - SWSS_LOG_NOTICE("constructed key: %s", key.c_str()); - - META_ASSERT_TRUE(key == "oid:0x21000000000000;SAI_PORT_ATTR_HW_LANE_LIST:1,2,3,4;"); -} - -static sai_object_id_t create_scheduler_group( - _In_ sai_object_id_t switch_id) -{ - SWSS_LOG_ENTER(); - - sai_object_id_t sg; - - sai_attribute_t attrs[9] = { }; - - attrs[0].id = SAI_SCHEDULER_GROUP_ATTR_PORT_ID; - attrs[0].value.oid = create_port(switch_id); - attrs[1].id = SAI_SCHEDULER_GROUP_ATTR_LEVEL; - attrs[1].value.u8 = 0; - attrs[2].id = SAI_SCHEDULER_GROUP_ATTR_MAX_CHILDS; - attrs[2].value.u8 = 1; - attrs[3].id = SAI_SCHEDULER_GROUP_ATTR_PARENT_NODE; - attrs[3].value.oid = attrs[0].value.oid; - - auto status = g_meta->create(SAI_OBJECT_TYPE_SCHEDULER_GROUP, &sg, switch_id, 4, attrs); - META_ASSERT_SUCCESS(status); - - return sg; -} - -void test_queue_create() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - sai_object_id_t switch_id = create_switch(); - - sai_status_t status; - sai_object_id_t queue; - - sai_attribute_t attr1; - sai_attribute_t attr2; - sai_attribute_t attr3; - sai_attribute_t attr4; - - attr1.id = SAI_QUEUE_ATTR_TYPE; - attr1.value.s32 = SAI_QUEUE_TYPE_UNICAST; - - attr2.id = SAI_QUEUE_ATTR_INDEX; - attr2.value.u8 = 7; - - attr3.id = SAI_QUEUE_ATTR_PORT; - attr3.value.oid = create_port(switch_id); - - attr4.id = SAI_QUEUE_ATTR_PARENT_SCHEDULER_NODE; - attr4.value.oid = create_scheduler_group(switch_id); - - sai_attribute_t list[4] = { attr1, attr2, attr3, attr4 }; - - SWSS_LOG_NOTICE("create tests"); - - SWSS_LOG_NOTICE("create queue"); - status = g_meta->create(SAI_OBJECT_TYPE_QUEUE, &queue, switch_id, 4, list); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("create queue but key exists"); - status = g_meta->create(SAI_OBJECT_TYPE_QUEUE, &queue, switch_id, 4, list); - META_ASSERT_FAIL(status); - - SWSS_LOG_NOTICE("remove queue"); - status = g_meta->remove(SAI_OBJECT_TYPE_QUEUE, queue); - META_ASSERT_SUCCESS(status); - - SWSS_LOG_NOTICE("create queue"); - status = g_meta->create(SAI_OBJECT_TYPE_QUEUE, &queue, switch_id, 4, list); - META_ASSERT_SUCCESS(status); - - remove_switch(switch_id); -} - -void test_null_list() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - sai_status_t status; - - sai_object_id_t hash; - - sai_attribute_t attr; - - int32_t list[2] = { SAI_NATIVE_HASH_FIELD_SRC_IP, SAI_NATIVE_HASH_FIELD_VLAN_ID }; - - attr.id = SAI_HASH_ATTR_NATIVE_HASH_FIELD_LIST; - attr.value.s32list.count = 0; - attr.value.s32list.list = list; - sai_object_id_t switch_id = create_switch(); - - SWSS_LOG_NOTICE("0 count, not null list"); - status = g_meta->create(SAI_OBJECT_TYPE_HASH, &hash, switch_id, 1, &attr); - META_ASSERT_FAIL(status); - - attr.value.s32list.list = NULL; - - SWSS_LOG_NOTICE("0 count, null list"); - status = g_meta->create(SAI_OBJECT_TYPE_HASH, &hash, switch_id, 1, &attr); - META_ASSERT_SUCCESS(status); - - remove_switch(switch_id); -} - -void test_priority_group() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - sai_object_id_t switch_id = create_switch(); - - sai_status_t status; - - sai_attribute_t attr; - - sai_object_id_t pg = insert_dummy_object(SAI_OBJECT_TYPE_INGRESS_PRIORITY_GROUP, switch_id); - - SWSS_LOG_NOTICE("set SAI_INGRESS_PRIORITY_GROUP_ATTR_BUFFER_PROFILE attr"); - - attr.id = SAI_INGRESS_PRIORITY_GROUP_ATTR_BUFFER_PROFILE; - attr.value.oid = SAI_NULL_OBJECT_ID; - status = g_meta->set(SAI_OBJECT_TYPE_INGRESS_PRIORITY_GROUP, pg, &attr); - META_ASSERT_SUCCESS(status); - - remove_switch(switch_id); -} - -#define ASSERT_TRUE(x,y)\ - if ((x) != y) { std::cout << "assert true failed: '" << x << "' != '" << y << "'" << std::endl; throw; } - -#define ASSERT_FAIL(msg) \ - { std::cout << "assert failed: " << msg << std::endl; throw; } - -void test_serialize_bool() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - sai_attribute_t attr; - const sai_attr_metadata_t* meta; - std::string s; - - // test bool - - attr.id = SAI_SWITCH_ATTR_ON_LINK_ROUTE_SUPPORTED; - attr.value.booldata = true; - - meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_SWITCH, attr.id); - - s = sai_serialize_attr_value(*meta, attr); - - ASSERT_TRUE(s, "true"); - - attr.id = SAI_SWITCH_ATTR_ON_LINK_ROUTE_SUPPORTED; - attr.value.booldata = false; - - s = sai_serialize_attr_value(*meta, attr); - - ASSERT_TRUE(s, "false"); - - // deserialize - - attr.id = SAI_SWITCH_ATTR_ON_LINK_ROUTE_SUPPORTED; - - sai_deserialize_attr_value("true", *meta, attr); - ASSERT_TRUE(true, attr.value.booldata); - - sai_deserialize_attr_value("false", *meta, attr); - ASSERT_TRUE(false, attr.value.booldata); - - try - { - sai_deserialize_attr_value("xx", *meta, attr); - ASSERT_FAIL("invalid bool deserialize failed to throw exception"); - } - catch (const std::runtime_error& e) - { - // ok - } -} - -void test_serialize_chardata() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - sai_attribute_t attr; - const sai_attr_metadata_t* meta; - std::string s; - - memset(attr.value.chardata, 0, 32); - - attr.id = SAI_HOSTIF_ATTR_NAME; - memcpy(attr.value.chardata, "foo", sizeof("foo")); - - meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_HOSTIF, attr.id); - - s = sai_serialize_attr_value(*meta, attr); - - ASSERT_TRUE(s, "foo"); - - attr.id = SAI_HOSTIF_ATTR_NAME; - memcpy(attr.value.chardata, "f\\oo\x12", sizeof("f\\oo\x12")); - - meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_HOSTIF, attr.id); - - s = sai_serialize_attr_value(*meta, attr); - - ASSERT_TRUE(s, "f\\\\oo\\x12"); - - attr.id = SAI_HOSTIF_ATTR_NAME; - memcpy(attr.value.chardata, "\x80\xff", sizeof("\x80\xff")); - - meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_HOSTIF, attr.id); - - s = sai_serialize_attr_value(*meta, attr); - - ASSERT_TRUE(s, "\\x80\\xFF"); - - // deserialize - - sai_deserialize_attr_value("f\\\\oo\\x12", *meta, attr); - - SWSS_LOG_NOTICE("des: %s", attr.value.chardata); - - ASSERT_TRUE(0, strcmp(attr.value.chardata, "f\\oo\x12")); - - sai_deserialize_attr_value("foo", *meta, attr); - - ASSERT_TRUE(0, strcmp(attr.value.chardata, "foo")); - - try - { - sai_deserialize_attr_value("\\x2g", *meta, attr); - ASSERT_FAIL("invalid chardata deserialize failed to throw exception"); - } - catch (const std::runtime_error& e) - { - // ok - } - - try - { - sai_deserialize_attr_value("\\x2", *meta, attr); - ASSERT_FAIL("invalid chardata deserialize failed to throw exception"); - } - catch (const std::runtime_error& e) - { - // ok - } - - try - { - sai_deserialize_attr_value("\\s45", *meta, attr); - ASSERT_FAIL("invalid chardata deserialize failed to throw exception"); - } - catch (const std::runtime_error& e) - { - // ok - } - - try - { - sai_deserialize_attr_value("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", *meta, attr); - ASSERT_FAIL("invalid chardata deserialize failed to throw exception"); - } - catch (const std::runtime_error& e) - { - // ok - } -} - -void test_serialize_uint64() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - sai_attribute_t attr; - const sai_attr_metadata_t* meta; - std::string s; - - attr.id = SAI_SWITCH_ATTR_NV_STORAGE_SIZE; - attr.value.u64 = 42; - - meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_SWITCH, attr.id); - - s = sai_serialize_attr_value(*meta, attr); - - ASSERT_TRUE(s, "42"); - attr.value.u64 = 0x87654321aabbccdd; - - attr.id = SAI_SWITCH_ATTR_NV_STORAGE_SIZE; - - meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_SWITCH, attr.id); - - s = sai_serialize_attr_value(*meta, attr); - - char buf[32]; - sprintf(buf, "%" PRIu64, attr.value.u64); - - ASSERT_TRUE(s, std::string(buf)); - - // deserialize - - sai_deserialize_attr_value("12345", *meta, attr); - - ASSERT_TRUE(12345, attr.value.u64); - - try - { - sai_deserialize_attr_value("22345235345345345435", *meta, attr); - ASSERT_FAIL("invalid u64 deserialize failed to throw exception"); - } - catch (const std::runtime_error& e) - { - // ok - } - - try - { - sai_deserialize_attr_value("2a", *meta, attr); - ASSERT_FAIL("invalid u64 deserialize failed to throw exception"); - } - catch (const std::runtime_error& e) - { - // ok - } -} - -void test_serialize_enum() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - sai_attribute_t attr; - const sai_attr_metadata_t* meta; - std::string s; - - attr.id = SAI_SWITCH_ATTR_SWITCHING_MODE; - attr.value.s32 = SAI_SWITCH_SWITCHING_MODE_STORE_AND_FORWARD; - - meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_SWITCH, attr.id); - - s = sai_serialize_attr_value(*meta, attr); - - ASSERT_TRUE(s, "SAI_SWITCH_SWITCHING_MODE_STORE_AND_FORWARD"); - - attr.value.s32 = -1; - - attr.id = SAI_SWITCH_ATTR_SWITCHING_MODE; - - meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_SWITCH, attr.id); - - s = sai_serialize_attr_value(*meta, attr); - - ASSERT_TRUE(s, "-1"); - - attr.value.s32 = 100; - - attr.id = SAI_SWITCH_ATTR_SWITCHING_MODE; - - meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_SWITCH, attr.id); - - s = sai_serialize_attr_value(*meta, attr); - - ASSERT_TRUE(s, "100"); - - // deserialize - - sai_deserialize_attr_value("12345", *meta, attr); - - ASSERT_TRUE(12345, attr.value.s32); - - sai_deserialize_attr_value("-1", *meta, attr); - - ASSERT_TRUE(-1, attr.value.s32); - - sai_deserialize_attr_value("SAI_SWITCH_SWITCHING_MODE_STORE_AND_FORWARD", *meta, attr); - - ASSERT_TRUE(SAI_SWITCH_SWITCHING_MODE_STORE_AND_FORWARD, attr.value.s32); - - try - { - sai_deserialize_attr_value("foo", *meta, attr); - ASSERT_FAIL("invalid s32 deserialize failed to throw exception"); - } - catch (const std::runtime_error& e) - { - // ok - } -} - -void test_serialize_mac() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - sai_attribute_t attr; - const sai_attr_metadata_t* meta; - std::string s; - - attr.id = SAI_SWITCH_ATTR_SRC_MAC_ADDRESS; - memcpy(attr.value.mac, "\x01\x22\x33\xaa\xbb\xcc", 6); - - meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_SWITCH, attr.id); - - s = sai_serialize_attr_value(*meta, attr); - - ASSERT_TRUE(s, "01:22:33:AA:BB:CC"); - - // deserialize - - sai_deserialize_attr_value("ff:ee:dd:33:44:55", *meta, attr); - - ASSERT_TRUE(0, memcmp("\xff\xee\xdd\x33\x44\x55", attr.value.mac, 6)); - - try - { - sai_deserialize_attr_value("foo", *meta, attr); - ASSERT_FAIL("invalid s32 deserialize failed to throw exception"); - } - catch (const std::runtime_error& e) - { - // ok - } -} - -void test_serialize_ip_address() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - sai_attribute_t attr; - const sai_attr_metadata_t* meta; - std::string s; - - attr.id = SAI_TUNNEL_ATTR_ENCAP_SRC_IP; - attr.value.ipaddr.addr_family = SAI_IP_ADDR_FAMILY_IPV4; - attr.value.ipaddr.addr.ip4 = htonl(0x0a000015); - - meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_TUNNEL, attr.id); - - s = sai_serialize_attr_value(*meta, attr); - - ASSERT_TRUE(s, "10.0.0.21"); - - attr.id = SAI_TUNNEL_ATTR_ENCAP_SRC_IP; - attr.value.ipaddr.addr_family = SAI_IP_ADDR_FAMILY_IPV6; - - uint16_t ip6[] = { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0xaaaa, 0xbbbb }; - - memcpy(attr.value.ipaddr.addr.ip6, ip6, 16); - - meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_TUNNEL, attr.id); - - s = sai_serialize_attr_value(*meta, attr); - - ASSERT_TRUE(s, "1111:2222:3333:4444:5555:6666:aaaa:bbbb"); - - uint16_t ip6a[] = { 0x0100, 0 ,0 ,0 ,0 ,0 ,0 ,0xff00 }; - - memcpy(attr.value.ipaddr.addr.ip6, ip6a, 16); - - meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_TUNNEL, attr.id); - - s = sai_serialize_attr_value(*meta, attr); - - ASSERT_TRUE(s, "1::ff"); - - uint16_t ip6b[] = { 0, 0 ,0 ,0 ,0 ,0 ,0 ,0x100 }; - - memcpy(attr.value.ipaddr.addr.ip6, ip6b, 16); - - meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_TUNNEL, attr.id); - - s = sai_serialize_attr_value(*meta, attr); - - ASSERT_TRUE(s, "::1"); - - try - { - // invalid address family - int k = 100; - attr.value.ipaddr.addr_family = (sai_ip_addr_family_t)k; - - s = sai_serialize_attr_value(*meta, attr); - - ASSERT_FAIL("invalid family not throw exception"); - } - catch (const std::runtime_error &e) - { - // ok - } - - // deserialize - - sai_deserialize_attr_value("10.0.0.23", *meta, attr); - - ASSERT_TRUE(attr.value.ipaddr.addr.ip4, htonl(0x0a000017)); - ASSERT_TRUE(attr.value.ipaddr.addr_family, SAI_IP_ADDR_FAMILY_IPV4); - - sai_deserialize_attr_value("1::ff", *meta, attr); - - ASSERT_TRUE(0, memcmp(attr.value.ipaddr.addr.ip6, ip6a, 16)); - ASSERT_TRUE(attr.value.ipaddr.addr_family, SAI_IP_ADDR_FAMILY_IPV6); - - try - { - sai_deserialize_attr_value("foo", *meta, attr); - ASSERT_FAIL("invalid s32 deserialize failed to throw exception"); - } - catch (const std::runtime_error& e) - { - // ok - } -} - -void test_serialize_uint32_list() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - sai_attribute_t attr; - const sai_attr_metadata_t* meta; - std::string s; - - attr.id = SAI_PORT_ATTR_SUPPORTED_SPEED; //SAI_PORT_ATTR_SUPPORTED_HALF_DUPLEX_SPEED; - - uint32_t list[] = {1,2,3,4,5,6,7}; - - attr.value.u32list.count = 7; - attr.value.u32list.list = NULL; - - meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_PORT, attr.id); - - s = sai_serialize_attr_value(*meta, attr); - - ASSERT_TRUE(s, "7:null"); - - attr.value.u32list.list = list; - - meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_PORT, attr.id); - - s = sai_serialize_attr_value(*meta, attr); - - ASSERT_TRUE(s, "7:1,2,3,4,5,6,7"); - - attr.value.u32list.count = 0; - attr.value.u32list.list = list; - - meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_PORT, attr.id); - - s = sai_serialize_attr_value(*meta, attr); - - ASSERT_TRUE(s, "0:null"); - - attr.value.u32list.count = 0; - attr.value.u32list.list = NULL; - - meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_PORT, attr.id); - - s = sai_serialize_attr_value(*meta, attr); - - ASSERT_TRUE(s, "0:null"); - - memset(&attr, 0, sizeof(attr)); - - sai_deserialize_attr_value("7:1,2,3,4,5,6,7", *meta, attr, false); - - ASSERT_TRUE(attr.value.u32list.count, 7); - ASSERT_TRUE(attr.value.u32list.list[0], 1); - ASSERT_TRUE(attr.value.u32list.list[1], 2); - ASSERT_TRUE(attr.value.u32list.list[2], 3); - ASSERT_TRUE(attr.value.u32list.list[3], 4); -} - -void test_serialize_enum_list() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - sai_attribute_t attr; - const sai_attr_metadata_t* meta; - std::string s; - - attr.id = SAI_HASH_ATTR_NATIVE_HASH_FIELD_LIST; - - int32_t list[] = { - SAI_NATIVE_HASH_FIELD_SRC_IP, - SAI_NATIVE_HASH_FIELD_DST_IP, - SAI_NATIVE_HASH_FIELD_VLAN_ID, - 77 - }; - - attr.value.s32list.count = 4; - attr.value.s32list.list = NULL; - - meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_HASH, attr.id); - - s = sai_serialize_attr_value(*meta, attr); - - ASSERT_TRUE(s, "4:null"); - - attr.value.s32list.list = list; - - meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_HASH, attr.id); - - s = sai_serialize_attr_value(*meta, attr); - - // or for enum: 4:SAI_NATIVE_HASH_FIELD[SRC_IP,DST_IP,VLAN_ID,77] - - ASSERT_TRUE(s, "4:SAI_NATIVE_HASH_FIELD_SRC_IP,SAI_NATIVE_HASH_FIELD_DST_IP,SAI_NATIVE_HASH_FIELD_VLAN_ID,77"); - - attr.value.s32list.count = 0; - attr.value.s32list.list = list; - - meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_HASH, attr.id); - - s = sai_serialize_attr_value(*meta, attr); - - ASSERT_TRUE(s, "0:null"); - - attr.value.s32list.count = 0; - attr.value.s32list.list = NULL; - - meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_HASH, attr.id); - - s = sai_serialize_attr_value(*meta, attr); - - ASSERT_TRUE(s, "0:null"); -} - -void test_serialize_oid() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - sai_attribute_t attr; - const sai_attr_metadata_t* meta; - std::string s; - - attr.id = SAI_SWITCH_ATTR_DEFAULT_VIRTUAL_ROUTER_ID; - - attr.value.oid = 0x1234567890abcdef; - - meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_SWITCH, attr.id); - - s = sai_serialize_attr_value(*meta, attr); - - ASSERT_TRUE(s, "oid:0x1234567890abcdef"); - - // deserialize - - sai_deserialize_attr_value("oid:0x1234567890abcdef", *meta, attr); - - ASSERT_TRUE(0x1234567890abcdef, attr.value.oid); - - try - { - sai_deserialize_attr_value("foo", *meta, attr); - ASSERT_FAIL("invalid oid deserialize failed to throw exception"); - } - catch (const std::runtime_error& e) - { - // ok - } -} - -void test_serialize_oid_list() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - sai_attribute_t attr; - const sai_attr_metadata_t* meta; - std::string s; - - attr.id = SAI_SWITCH_ATTR_PORT_LIST; - - sai_object_id_t list[] = { - 1,0x42, 0x77 - }; - - attr.value.objlist.count = 3; - attr.value.objlist.list = NULL; - - meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_SWITCH, attr.id); - - s = sai_serialize_attr_value(*meta, attr); - - ASSERT_TRUE(s, "3:null"); - - attr.value.objlist.list = list; - - meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_SWITCH, attr.id); - - s = sai_serialize_attr_value(*meta, attr); - - // or: 4:[ROUTE:0x1,PORT:0x3,oid:0x77] if we have query function - - ASSERT_TRUE(s, "3:oid:0x1,oid:0x42,oid:0x77"); - - attr.value.objlist.count = 0; - attr.value.objlist.list = list; - - meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_SWITCH, attr.id); - - s = sai_serialize_attr_value(*meta, attr); - - ASSERT_TRUE(s, "0:null"); - - attr.value.objlist.count = 0; - attr.value.objlist.list = NULL; - - meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_SWITCH, attr.id); - - s = sai_serialize_attr_value(*meta, attr); - - ASSERT_TRUE(s, "0:null"); - - memset(&attr, 0, sizeof(attr)); - - // deserialize - - sai_deserialize_attr_value("3:oid:0x1,oid:0x42,oid:0x77", *meta, attr, false); - - ASSERT_TRUE(attr.value.objlist.count, 3); - ASSERT_TRUE(attr.value.objlist.list[0], 0x1); - ASSERT_TRUE(attr.value.objlist.list[1], 0x42); - ASSERT_TRUE(attr.value.objlist.list[2], 0x77); -} - -void test_serialize_acl_action() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - sai_attribute_t attr; - const sai_attr_metadata_t* meta; - std::string s; - - attr.id = SAI_ACL_ENTRY_ATTR_ACTION_REDIRECT; - - attr.value.aclaction.enable = true; - attr.value.aclaction.parameter.oid = (sai_object_id_t)2; - - meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_ACL_ENTRY, attr.id); - - s = sai_serialize_attr_value(*meta, attr); - - ASSERT_TRUE(s, "oid:0x2"); - - attr.value.aclaction.enable = false; - attr.value.aclaction.parameter.oid = (sai_object_id_t)2; - - meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_ACL_ENTRY, attr.id); - - s = sai_serialize_attr_value(*meta, attr); - - ASSERT_TRUE(s, "disabled"); - - attr.id = SAI_ACL_ENTRY_ATTR_ACTION_PACKET_ACTION; - - attr.value.aclaction.enable = true; - attr.value.aclaction.parameter.s32 = SAI_PACKET_ACTION_TRAP; - - meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_ACL_ENTRY, attr.id); - - s = sai_serialize_attr_value(*meta, attr); - - ASSERT_TRUE(s, "SAI_PACKET_ACTION_TRAP"); - - attr.value.aclaction.enable = true; - attr.value.aclaction.parameter.s32 = 77; - - meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_ACL_ENTRY, attr.id); - - s = sai_serialize_attr_value(*meta, attr); - - ASSERT_TRUE(s, "77"); -} - -void test_serialize_qos_map() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - sai_attribute_t attr; - const sai_attr_metadata_t* meta; - std::string s; - - attr.id = SAI_QOS_MAP_ATTR_MAP_TO_VALUE_LIST; - - sai_qos_map_t qm = { - .key = { .tc = 1, .dscp = 2, .dot1p = 3, .prio = 4, .pg = 5, .queue_index = 6, .color = SAI_PACKET_COLOR_RED, .mpls_exp = 0 }, - .value = { .tc = 11, .dscp = 22, .dot1p = 33, .prio = 44, .pg = 55, .queue_index = 66, .color = SAI_PACKET_COLOR_GREEN, .mpls_exp = 0 } }; - - attr.value.qosmap.count = 1; - attr.value.qosmap.list = &qm; - - meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_QOS_MAP, attr.id); - - s = sai_serialize_attr_value(*meta, attr); - - std::string ret = "{\"count\":1,\"list\":[{\"key\":{\"color\":\"SAI_PACKET_COLOR_RED\",\"dot1p\":3,\"dscp\":2,\"mpls_exp\":0,\"pg\":5,\"prio\":4,\"qidx\":6,\"tc\":1},\"value\":{\"color\":\"SAI_PACKET_COLOR_GREEN\",\"dot1p\":33,\"dscp\":22,\"mpls_exp\":0,\"pg\":55,\"prio\":44,\"qidx\":66,\"tc\":11}}]}"; - - ASSERT_TRUE(s, ret); - - s = sai_serialize_attr_value(*meta, attr, true); - - std::string ret2 = "{\"count\":1,\"list\":null}"; - ASSERT_TRUE(s, ret2); - - // deserialize - - memset(&attr, 0, sizeof(attr)); - - sai_deserialize_attr_value(ret, *meta, attr); - - ASSERT_TRUE(attr.value.qosmap.count, 1); - - auto &l = attr.value.qosmap.list[0]; - ASSERT_TRUE(l.key.tc, 1); - ASSERT_TRUE(l.key.dscp, 2); - ASSERT_TRUE(l.key.dot1p, 3); - ASSERT_TRUE(l.key.prio, 4); - ASSERT_TRUE(l.key.pg, 5); - ASSERT_TRUE(l.key.queue_index, 6); - ASSERT_TRUE(l.key.color, SAI_PACKET_COLOR_RED); - ASSERT_TRUE(l.key.mpls_exp, 0); - - ASSERT_TRUE(l.value.tc, 11); - ASSERT_TRUE(l.value.dscp, 22); - ASSERT_TRUE(l.value.dot1p, 33); - ASSERT_TRUE(l.value.prio, 44); - ASSERT_TRUE(l.value.pg, 55); - ASSERT_TRUE(l.value.queue_index, 66); - ASSERT_TRUE(l.value.color, SAI_PACKET_COLOR_GREEN); - ASSERT_TRUE(l.value.mpls_exp, 0); -} - -template -void deserialize_number( - _In_ const std::string& s, - _Out_ T& number, - _In_ bool hex = false) -{ - SWSS_LOG_ENTER(); - - errno = 0; - - char *endptr = NULL; - - number = (T)strtoull(s.c_str(), &endptr, hex ? 16 : 10); - - if (errno != 0 || endptr != s.c_str() + s.length()) - { - SWSS_LOG_THROW("invalid number %s", s.c_str()); - } -} - -template -std::string serialize_number( - _In_ const T& number, - _In_ bool hex = false) -{ - SWSS_LOG_ENTER(); - - if (hex) - { - char buf[32]; - - snprintf(buf, sizeof(buf), "0x%" PRIx64, (uint64_t)number); - - return buf; - } - - return std::to_string(number); -} - -void test_numbers() -{ - SWSS_LOG_ENTER(); - - int64_t sp = 0x12345678; - int64_t sn = -0x12345678; - int64_t u = 0x12345678; - - auto ssp = serialize_number(sp); - auto ssn = serialize_number(sn); - auto su = serialize_number(u); - - ASSERT_TRUE(ssp, std::to_string(sp)); - ASSERT_TRUE(ssn, std::to_string(sn)); - ASSERT_TRUE(su, std::to_string(u)); - - auto shsp = serialize_number(sp, true); - auto shsn = serialize_number(sn, true); - auto shu = serialize_number(u, true); - - ASSERT_TRUE(shsp, "0x12345678"); - ASSERT_TRUE(shsn, "0xffffffffedcba988"); - ASSERT_TRUE(shu, "0x12345678"); - - sp = 0; - sn = 0; - u = 0; - - deserialize_number(ssp, sp); - deserialize_number(ssn, sn); - deserialize_number(su, u); - - ASSERT_TRUE(sp, 0x12345678); - ASSERT_TRUE(sn, -0x12345678); - ASSERT_TRUE(u, 0x12345678); - - deserialize_number(shsp, sp, true); - deserialize_number(shsn, sn, true); - deserialize_number(shu, u, true); - - ASSERT_TRUE(sp, 0x12345678); - ASSERT_TRUE(sn, -0x12345678); - ASSERT_TRUE(u, 0x12345678); -} - -void test_bulk_route_entry_create() -{ - SWSS_LOG_ENTER(); - - clear_local(); - - int object_count = 1000; - - std::vector routes; - std::vector attr_counts; - std::vector attr_lists; - std::vector statuses(object_count); - - sai_object_id_t switch_id = create_switch(); - - sai_object_id_t vr = create_virtual_router(switch_id); - sai_object_id_t hop = create_next_hop(switch_id); - - sai_attribute_t attr; - - attr.id = SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID; - attr.value.oid = hop; - - int n = 100; - - for (int i = 0; i < object_count * n; i++) - { - sai_route_entry_t re; - - memset(re.destination.mask.ip6, 0xff, sizeof(re.destination.mask.ip6)); - re.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; - re.destination.addr.ip4 = htonl(0x0a00000f + i); - re.destination.mask.ip4 = htonl(0xffffff00); - re.vr_id = vr; - re.switch_id = switch_id; - - routes.push_back(re); - - attr_counts.push_back(1); - - // since we use the same attribute every where we can get away with this - - attr_lists.push_back(&attr); - } - - auto start = std::chrono::high_resolution_clock::now(); - - for (int i = 0; i < n; i++) - { - auto status = g_meta->bulkCreate( - object_count, - routes.data() + i * object_count, - attr_counts.data(), - attr_lists.data(), - SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR, - statuses.data()); - - ASSERT_TRUE(status, SAI_STATUS_SUCCESS); - } - - auto end = std::chrono::high_resolution_clock::now(); - auto time = end - start; - auto us = std::chrono::duration_cast(time); - - std::cout << "ms: " << (double)us.count()/1000 << " / " << n << "/" << object_count << std::endl; -} - -int main() -{ - swss::Logger::getInstance().setMinPrio(swss::Logger::SWSS_INFO); - - SWSS_LOG_ENTER(); - - test_bulk_route_entry_create(); - - // serialize tests - - test_serialize_bool(); - test_serialize_chardata(); - test_serialize_uint64(); - test_serialize_enum(); - test_serialize_mac(); - test_serialize_ip_address(); - test_serialize_uint32_list(); - test_serialize_enum_list(); - test_serialize_oid(); - test_serialize_oid_list(); - test_serialize_acl_action(); - test_serialize_qos_map(); - - // attributes tests - - test_switch_set(); - test_switch_get(); - - test_fdb_entry_create(); - test_fdb_entry_remove(); - test_fdb_entry_set(); - test_fdb_entry_get(); - test_fdb_entry_flow(); - - test_neighbor_entry_create(); - test_neighbor_entry_remove(); - test_neighbor_entry_set(); - test_neighbor_entry_get(); - test_neighbor_entry_flow(); - - test_vlan_create(); - test_vlan_remove(); - test_vlan_set(); - test_vlan_get(); - test_vlan_flow(); - - test_route_entry_create(); - test_route_entry_remove(); - test_route_entry_set(); - test_route_entry_get(); - test_route_entry_flow(); - - test_serialization_type_vlan_list(); - test_serialization_type_bool(); - test_serialization_type_char(); - test_serialization_type_int32_list(); - test_serialization_type_uint32_list(); - - test_mask(); - test_acl_entry_field_and_action(); - test_construct_key(); - test_queue_create(); - test_null_list(); - - test_numbers(); - - test_priority_group(); - - std::cout << "SUCCESS" << std::endl; -} diff --git a/syncd/AsicView.cpp b/syncd/AsicView.cpp index c5c35cc41..a5a954f54 100644 --- a/syncd/AsicView.cpp +++ b/syncd/AsicView.cpp @@ -506,7 +506,7 @@ std::vector> AsicView::getAllNotProcessedObjects() const * @param[in] rid Real ID * @param[in] vid Virtual ID */ -void AsicView::createDummyExistingObject( +std::shared_ptr AsicView::createDummyExistingObject( _In_ sai_object_id_t rid, _In_ sai_object_id_t vid) { @@ -540,6 +540,8 @@ void AsicView::createDummyExistingObject( m_ridToVid[rid] = vid; m_vidToRid[vid] = rid; + + return o; } /** @@ -1289,10 +1291,10 @@ void AsicView::checkObjectsStatus() const { const auto &o = *p.second; - SWSS_LOG_ERROR("object was not processed: %s %s, status: %d (ref: %d)", + SWSS_LOG_ERROR("object was not processed: %s %s, status: %s (ref: %d)", o.m_str_object_type.c_str(), o.m_str_object_id.c_str(), - o.getObjectStatus(), + ObjectStatus::sai_serialize_object_status(o.getObjectStatus()).c_str(), o.isOidObject() ? getVidReferenceCount(o.getVid()): -1); count++; diff --git a/syncd/AsicView.h b/syncd/AsicView.h index 89102b954..2aeb4d28e 100644 --- a/syncd/AsicView.h +++ b/syncd/AsicView.h @@ -188,7 +188,7 @@ namespace syncd * @param[in] rid Real ID * @param[in] vid Virtual ID */ - void createDummyExistingObject( + std::shared_ptr createDummyExistingObject( _In_ sai_object_id_t rid, _In_ sai_object_id_t vid); diff --git a/syncd/ComparisonLogic.cpp b/syncd/ComparisonLogic.cpp index af69bd596..99f45c239 100644 --- a/syncd/ComparisonLogic.cpp +++ b/syncd/ComparisonLogic.cpp @@ -122,6 +122,13 @@ void ComparisonLogic::compareViews() applyViewTransition(current, temp); + transferNotProcessed(current, temp); + + // TODO have a method to check for not processed objects + // and maybe add them to list on processing attributes + // and move note processed objects to temporary view as well + // we need to check oid attributes as well + SWSS_LOG_NOTICE("ASIC operations to execute: %zu", current.asicGetOperationsCount()); temp.checkObjectsStatus(); @@ -183,6 +190,8 @@ void ComparisonLogic::matchOids( { SWSS_LOG_ENTER(); + auto coldBootDiscoveredVids = m_switch->getColdBootDiscoveredVids(); + for (const auto &temporaryIt: temporaryView.m_oOids) { sai_object_id_t temporaryVid = temporaryIt.first; @@ -211,6 +220,37 @@ void ComparisonLogic::matchOids( currentIt->second->m_str_object_type.c_str(), sai_serialize_object_id(rid).c_str(), sai_serialize_object_id(vid).c_str()); + + if (coldBootDiscoveredVids.find(vid) == coldBootDiscoveredVids.end()) + { + auto ot = currentIt->second->getObjectType(); + + switch (ot) + { + case SAI_OBJECT_TYPE_INGRESS_PRIORITY_GROUP: + case SAI_OBJECT_TYPE_SCHEDULER_GROUP: + case SAI_OBJECT_TYPE_QUEUE: + case SAI_OBJECT_TYPE_PORT: + break; + + default: + + // Should we also add check if also not in removed? + // This is for case of only GET: + // 1. cold boot: + // - OA assigns buffer profile to Queue + // 2. warm boot: + // - OA do GET on Queue and got previous buffer profile + // - OA assigns new buffer profile on Queue + // + // Question: what should happen to old buffer profile? should it be removed? + // No, since OA still hold's the reference to that VID and may use it later. + SWSS_LOG_INFO("matched %s VID %s was not in cold boot, possible only GET?", + sai_serialize_object_id(vid).c_str(), + currentIt->second->m_str_object_type.c_str()); + break; + } + } } SWSS_LOG_NOTICE("matched oids"); @@ -1125,8 +1165,8 @@ void ComparisonLogic::updateObjectStatus( bool ComparisonLogic::performObjectSetTransition( _In_ AsicView ¤tView, _In_ AsicView &temporaryView, - _In_ const std::shared_ptr ¤tBestMatch, - _In_ const std::shared_ptr &temporaryObj, + _In_ const std::shared_ptr currentBestMatch, + _In_ std::shared_ptr temporaryObj, _In_ bool performTransition) { SWSS_LOG_ENTER(); @@ -1386,6 +1426,8 @@ bool ComparisonLogic::performObjectSetTransition( return false; } + const bool beginTempSizeZero = temporaryObj->getAllAttributes().size() == 0; + /* * Current best match can have more attributes than temporary object. * let see if we can bring them to default value if possible. @@ -1530,14 +1572,38 @@ bool ComparisonLogic::performObjectSetTransition( continue; } - // SAI_QUEUE_ATTR_PARENT_SCHEDULER_NODE - // SAI_SCHEDULER_GROUP_ATTR_SCHEDULER_PROFILE_ID* - // SAI_SCHEDULER_GROUP_ATTR_PARENT_NODE - // SAI_BRIDGE_PORT_ATTR_BRIDGE_ID - // - // TODO matched by ID (MATCHED state) should always be updatable - // except those 4 above (at least for those above since they can have - // default value present after switch creation + // current best match is MATCHED + + //auto vid = currentBestMatch->getVid(); + + // TODO don't transfer oid attributes, we don't know how to handle this yet + // If OA did GET on any attributes, snoop in syncd should catch that and write + // to database so we would have some attributes here. + + if (beginTempSizeZero && !meta->isoidattribute) + { + SWSS_LOG_WARN("current attr is MoC|CaS and object is MATCHED: %s transferring %s:%s to temp object (was empty)", + currentBestMatch->m_str_object_id.c_str(), + meta->attridname, + currentAttr->getStrAttrValue().c_str()); + + std::shared_ptr transferedAttr = std::make_shared( + currentAttr->getStrAttrId(), + currentAttr->getStrAttrValue()); + + temporaryObj->setAttr(transferedAttr); + + continue; + } + + // SAI_QUEUE_ATTR_PARENT_SCHEDULER_NODE + // SAI_SCHEDULER_GROUP_ATTR_SCHEDULER_PROFILE_ID* + // SAI_SCHEDULER_GROUP_ATTR_PARENT_NODE + // SAI_BRIDGE_PORT_ATTR_BRIDGE_ID + // + // TODO matched by ID (MATCHED state) should always be updatable + // except those 4 above (at least for those above since they can have + // default value present after switch creation // TODO SAI_SCHEDULER_GROUP_ATTR_SCHEDULER_PROFILE_ID is mandatory on create but also SET // if attribute is set we and object is in MATCHED state then that means we are able to @@ -1571,6 +1637,21 @@ bool ComparisonLogic::performObjectSetTransition( meta->attridname, currentAttr->getStrAttrValue().c_str()); + // don't produce too much noise for queues + if (currentAttr->getStrAttrId() != "SAI_QUEUE_ATTR_TYPE") + { + SWSS_LOG_WARN("current attr is CREATE_ONLY and object is MATCHED: %s transferring %s:%s to temp object", + currentBestMatch->m_str_object_id.c_str(), + meta->attridname, + currentAttr->getStrAttrValue().c_str()); + } + + std::shared_ptr transferedAttr = std::make_shared( + currentAttr->getStrAttrId(), + currentAttr->getStrAttrValue()); + + temporaryObj->setAttr(transferedAttr); + continue; } } @@ -1709,7 +1790,7 @@ bool ComparisonLogic::performObjectSetTransition( void ComparisonLogic::processObjectForViewTransition( _In_ AsicView ¤tView, _In_ AsicView &temporaryView, - _In_ const std::shared_ptr &temporaryObj) + _Inout_ std::shared_ptr temporaryObj) { SWSS_LOG_ENTER(); @@ -2273,6 +2354,10 @@ void ComparisonLogic::populateExistingObjects( if (temporaryView.hasRid(rid)) { + SWSS_LOG_INFO("temporary view has existing %s RID %s", + sai_serialize_object_type(m_vendorSai->objectTypeQuery(rid)).c_str(), + sai_serialize_object_id(rid).c_str()); + continue; } @@ -2295,6 +2380,11 @@ void ComparisonLogic::populateExistingObjects( * from current view as well. */ + SWSS_LOG_INFO("object was removed in init view: %s RID %s VID %s", + sai_serialize_object_type(m_vendorSai->objectTypeQuery(rid)).c_str(), + sai_serialize_object_id(rid).c_str(), + sai_serialize_object_id(vid).c_str()); + continue; } @@ -2730,6 +2820,79 @@ void ComparisonLogic::createPreMatchMap( count); } +void ComparisonLogic::transferNotProcessed( + _In_ AsicView& current, + _In_ AsicView& temp) +{ + SWSS_LOG_ENTER(); + + SWSS_LOG_NOTICE("calling transferNotProcessed"); + + /* + * It may happen that after performing view transition, some objects will + * not be processed. This may happen is scenario where buffer pool is + * assigned to buffer profile, and then buffer profile is assigned to + * queue. If OA will query only for oid for that buffer profile, then + * buffer pool will not be processed. Normally if it would be removed by + * comparison logic. More on this issue can be found on github: + * https://github.com/Azure/sonic-sairedis/issues/899 + * + * So what we will do, we will transfer all not processed objects to + * temporary view with the same RID and VID. If nothing will happen to them, + * they will stay there until next warm boot where they will be removed. + */ + + /* + * We need a loop (or recursion) since not processed objects may have oid + * attributes as well. + */ + + while (current.getAllNotProcessedObjects().size()) + { + SWSS_LOG_WARN("we have %zu not processed objects on current view, moving to temp view", current.getAllNotProcessedObjects().size()); + + for (const auto& obj: current.getAllNotProcessedObjects()) + { + auto vid = obj->getVid(); + + auto rid = current.m_vidToRid.at(vid); + + /* + * We should have only oid objects here, since all non oid objects + * are leafs in graph and has been removed. + */ + + auto tmp = temp.createDummyExistingObject(rid, vid); + + /* + * Move both objects to matched state since match oids was already + * called, and here we created some new objects that should be matched. + */ + + current.m_oOids.at(vid)->setObjectStatus(SAI_OBJECT_STATUS_FINAL); + temp.m_oOids.at(vid)->setObjectStatus(SAI_OBJECT_STATUS_FINAL); + + SWSS_LOG_WARN("moved %s VID %s RID %s to temporary view, and marked FINAL", + obj->m_str_object_type.c_str(), + obj->m_str_object_id.c_str(), + sai_serialize_object_id(rid).c_str()); + + for (auto& kvp: obj->getAllAttributes()) + { + auto& sh = kvp.second; + + auto attr = std::make_shared(sh->getStrAttrId(), sh->getStrAttrValue()); + + tmp->setAttr(attr); + + SWSS_LOG_WARN(" * with attr: %s: %s", + sh->getStrAttrId().c_str(), + sh->getStrAttrValue().c_str()); + } + + } + } +} void ComparisonLogic::applyViewTransition( _In_ AsicView ¤t, diff --git a/syncd/ComparisonLogic.h b/syncd/ComparisonLogic.h index 2255f0062..8b8b5b5e0 100644 --- a/syncd/ComparisonLogic.h +++ b/syncd/ComparisonLogic.h @@ -58,6 +58,10 @@ namespace syncd _In_ AsicView& current, _In_ AsicView& temp); + void transferNotProcessed( + _In_ AsicView& current, + _In_ AsicView& temp); + void checkInternalObjects( _In_ const AsicView& cv, _In_ const AsicView& tv); @@ -136,8 +140,8 @@ namespace syncd bool performObjectSetTransition( _In_ AsicView& currentView, _In_ AsicView& temporaryView, - _In_ const std::shared_ptr& currentBestMatch, - _In_ const std::shared_ptr& temporaryObj, + _In_ const std::shared_ptr currentBestMatch, + _In_ const std::shared_ptr temporaryObj, _In_ bool performTransition); void breakBeforeMake( @@ -154,7 +158,7 @@ namespace syncd void processObjectForViewTransition( _In_ AsicView& currentView, _In_ AsicView& temporaryView, - _In_ const std::shared_ptr& temporaryObj); + _Inout_ std::shared_ptr temporaryObj); void checkSwitch( _In_ const AsicView& currentView, diff --git a/syncd/FlexCounter.cpp b/syncd/FlexCounter.cpp index 36d76c003..fd132b536 100644 --- a/syncd/FlexCounter.cpp +++ b/syncd/FlexCounter.cpp @@ -1596,7 +1596,7 @@ void FlexCounter::runPlugins( { std::to_string(counters_db.getDbId()), COUNTERS_TABLE, - std::to_string(m_pollInterval * 1000) + std::to_string(m_pollInterval) }; std::vector portList; diff --git a/syncd/Makefile.am b/syncd/Makefile.am index 757d7766b..aad2e1e68 100644 --- a/syncd/Makefile.am +++ b/syncd/Makefile.am @@ -60,6 +60,7 @@ syncd_CPPFLAGS = $(CODE_COVERAGE_CPPFLAGS) syncd_CXXFLAGS = $(DBGFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS_COMMON) $(CODE_COVERAGE_CXXFLAGS) syncd_LDADD = libSyncd.a $(top_srcdir)/lib/libSaiRedis.a -L$(top_srcdir)/meta/.libs -lsaimetadata -lsaimeta \ -ldl -lhiredis -lswsscommon $(SAILIB) -lpthread -lzmq $(CODE_COVERAGE_LIBS) +syncd_LDFLAGS = -rdynamic if SAITHRIFT libSyncd_a_CXXFLAGS += -DSAITHRIFT=yes diff --git a/syncd/SaiObj.cpp b/syncd/SaiObj.cpp index 27ecec4fa..6695743d0 100644 --- a/syncd/SaiObj.cpp +++ b/syncd/SaiObj.cpp @@ -4,6 +4,30 @@ using namespace syncd; +std::string ObjectStatus::sai_serialize_object_status( + _In_ sai_object_status_t os) +{ + SWSS_LOG_ENTER(); + + switch (os) + { + case SAI_OBJECT_STATUS_NOT_PROCESSED: + return "not-processed"; + + case SAI_OBJECT_STATUS_MATCHED: + return "matched"; + + case SAI_OBJECT_STATUS_REMOVED: + return "removed"; + + case SAI_OBJECT_STATUS_FINAL: + return "final"; + + default: + SWSS_LOG_THROW("unknown object status: %d", os); + } +} + SaiObj::SaiObj(): m_createdObject(false), m_objectStatus(SAI_OBJECT_STATUS_NOT_PROCESSED) diff --git a/syncd/SaiObj.h b/syncd/SaiObj.h index 81618b52e..6d2e4c3b3 100644 --- a/syncd/SaiObj.h +++ b/syncd/SaiObj.h @@ -55,6 +55,19 @@ namespace syncd } sai_object_status_t; + class ObjectStatus + { + private: + + ObjectStatus() = delete; + ~ObjectStatus() = delete; + + public: + + static std::string sai_serialize_object_status( + _In_ sai_object_status_t os); + }; + class SaiObj { private: diff --git a/syncd/scripts/syncd_init_common.sh b/syncd/scripts/syncd_init_common.sh index 3ac813a7c..d450a0429 100644 --- a/syncd/scripts/syncd_init_common.sh +++ b/syncd/scripts/syncd_init_common.sh @@ -161,11 +161,11 @@ config_syncd_bcm() fi fi - - if [ -f "$HWSKU_DIR/context_config.json" ]; then + + if [ -f "$HWSKU_DIR/context_config.json" ]; then CMD_ARGS+=" -x $HWSKU_DIR/context_config.json -g 0" fi - + [ -e /dev/linux-bcm-knet ] || mknod /dev/linux-bcm-knet c 122 0 [ -e /dev/linux-user-bde ] || mknod /dev/linux-user-bde c 126 0 [ -e /dev/linux-kernel-bde ] || mknod /dev/linux-kernel-bde c 127 0 diff --git a/tests/BCM56850.pl b/tests/BCM56850.pl index 9ec2eccc7..842b19bf7 100755 --- a/tests/BCM56850.pl +++ b/tests/BCM56850.pl @@ -697,8 +697,17 @@ sub test_multi_switch_key play("-p", "$utils::DIR/vsprofile_ctx_multi.ini", "multi_switch_key.rec"); } +sub test_buffer_profile_get +{ + fresh_start; + + play "buffer_profile_get_A.rec"; + play "buffer_profile_get_B.rec"; +} + # RUN TESTS +test_buffer_profile_get; test_multi_switch_key; test_ignore_attributes; test_sairedis_client; diff --git a/tests/BCM56850/buffer_profile_get_A.rec b/tests/BCM56850/buffer_profile_get_A.rec new file mode 100644 index 000000000..c28e15986 --- /dev/null +++ b/tests/BCM56850/buffer_profile_get_A.rec @@ -0,0 +1,12 @@ +2021-08-17.04:02:06.218382|a|INIT_VIEW +2021-08-17.04:02:06.219002|A|SAI_STATUS_SUCCESS +2021-08-17.04:02:06.220179|c|SAI_OBJECT_TYPE_SWITCH:oid:0x21000000000000|SAI_SWITCH_ATTR_INIT_SWITCH=true|SAI_SWITCH_ATTR_SRC_MAC_ADDRESS=18:17:25:55:17:67 +2021-08-17.04:02:10.063326|g|SAI_OBJECT_TYPE_SWITCH:oid:0x21000000000000|SAI_SWITCH_ATTR_PORT_LIST=32:oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0 +2021-08-17.04:02:10.066144|G|SAI_STATUS_SUCCESS|SAI_SWITCH_ATTR_PORT_LIST=32:oid:0x1000000000124,oid:0x1000000000125,oid:0x1000000000126,oid:0x1000000000127,oid:0x1000000000128,oid:0x1000000000129,oid:0x100000000012a,oid:0x100000000012b,oid:0x100000000012c,oid:0x100000000012d,oid:0x100000000012e,oid:0x100000000012f,oid:0x1000000000130,oid:0x1000000000131,oid:0x1000000000132,oid:0x1000000000133,oid:0x1000000000134,oid:0x1000000000135,oid:0x1000000000136,oid:0x1000000000137,oid:0x1000000000138,oid:0x1000000000139,oid:0x100000000013a,oid:0x100000000013b,oid:0x100000000013c,oid:0x100000000013d,oid:0x100000000013e,oid:0x100000000013f,oid:0x1000000000140,oid:0x1000000000141,oid:0x1000000000142,oid:0x1000000000143 +2021-08-17.04:02:10.788257|g|SAI_OBJECT_TYPE_PORT:oid:0x100000000013b|SAI_PORT_ATTR_INGRESS_PRIORITY_GROUP_LIST=8:oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0 +2021-08-17.04:02:10.789514|G|SAI_STATUS_SUCCESS|SAI_PORT_ATTR_INGRESS_PRIORITY_GROUP_LIST=8:oid:0x1a000000000039,oid:0x1a000000000059,oid:0x1a000000000079,oid:0x1a000000000099,oid:0x1a0000000000b9,oid:0x1a0000000000d9,oid:0x1a0000000000f9,oid:0x1a000000000119 +2021-08-17.04:02:12.427282|c|SAI_OBJECT_TYPE_BUFFER_POOL:oid:0x1800000000038a|SAI_BUFFER_POOL_ATTR_THRESHOLD_MODE=SAI_BUFFER_POOL_THRESHOLD_MODE_DYNAMIC|SAI_BUFFER_POOL_ATTR_SIZE=47218432|SAI_BUFFER_POOL_ATTR_TYPE=SAI_BUFFER_POOL_TYPE_INGRESS|SAI_BUFFER_POOL_ATTR_XOFF_SIZE=17708800 +2021-08-17.04:11:48.564269|c|SAI_OBJECT_TYPE_BUFFER_PROFILE:oid:0x1900000000044a|SAI_BUFFER_PROFILE_ATTR_POOL_ID=oid:0x1800000000038a|SAI_BUFFER_PROFILE_ATTR_THRESHOLD_MODE=SAI_BUFFER_PROFILE_THRESHOLD_MODE_DYNAMIC|SAI_BUFFER_PROFILE_ATTR_RESERVED_BUFFER_SIZE=6755399441055744|SAI_BUFFER_PROFILE_ATTR_SHARED_DYNAMIC_TH=-8 +2021-08-17.04:13:43.975909|s|SAI_OBJECT_TYPE_INGRESS_PRIORITY_GROUP:oid:0x1a0000000000b9|SAI_INGRESS_PRIORITY_GROUP_ATTR_BUFFER_PROFILE=oid:0x1900000000044a +2021-08-17.04:02:10.210537|a|APPLY_VIEW +2021-08-17.04:02:10.211307|A|SAI_STATUS_SUCCESS diff --git a/tests/BCM56850/buffer_profile_get_B.rec b/tests/BCM56850/buffer_profile_get_B.rec new file mode 100644 index 000000000..303fe4690 --- /dev/null +++ b/tests/BCM56850/buffer_profile_get_B.rec @@ -0,0 +1,13 @@ +2021-08-17.04:19:21.957051|a|INIT_VIEW +2021-08-17.04:19:28.152399|A|SAI_STATUS_SUCCESS +2021-08-17.04:19:28.154608|c|SAI_OBJECT_TYPE_SWITCH:oid:0x21000000000000|SAI_SWITCH_ATTR_INIT_SWITCH=true|SAI_SWITCH_ATTR_SRC_MAC_ADDRESS=18:17:25:55:17:67 +2021-08-17.04:19:28.171193|g|SAI_OBJECT_TYPE_SWITCH:oid:0x21000000000000|SAI_SWITCH_ATTR_PORT_LIST=32:oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0 +2021-08-17.04:19:28.175104|G|SAI_STATUS_SUCCESS|SAI_SWITCH_ATTR_PORT_LIST=32:oid:0x1000000000124,oid:0x1000000000125,oid:0x1000000000126,oid:0x1000000000127,oid:0x1000000000128,oid:0x1000000000129,oid:0x100000000012a,oid:0x100000000012b,oid:0x100000000012c,oid:0x100000000012d,oid:0x100000000012e,oid:0x100000000012f,oid:0x1000000000130,oid:0x1000000000131,oid:0x1000000000132,oid:0x1000000000133,oid:0x1000000000134,oid:0x1000000000135,oid:0x1000000000136,oid:0x1000000000137,oid:0x1000000000138,oid:0x1000000000139,oid:0x100000000013a,oid:0x100000000013b,oid:0x100000000013c,oid:0x100000000013d,oid:0x100000000013e,oid:0x100000000013f,oid:0x1000000000140,oid:0x1000000000141,oid:0x1000000000142,oid:0x1000000000143 +2021-08-17.04:19:29.456685|g|SAI_OBJECT_TYPE_PORT:oid:0x100000000013b|SAI_PORT_ATTR_INGRESS_PRIORITY_GROUP_LIST=8:oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0 +2021-08-17.04:19:29.457560|G|SAI_STATUS_SUCCESS|SAI_PORT_ATTR_INGRESS_PRIORITY_GROUP_LIST=8:oid:0x1a000000000039,oid:0x1a000000000059,oid:0x1a000000000079,oid:0x1a000000000099,oid:0x1a0000000000b9,oid:0x1a0000000000d9,oid:0x1a0000000000f9,oid:0x1a000000000119 +2021-08-17.04:19:31.376976|g|SAI_OBJECT_TYPE_INGRESS_PRIORITY_GROUP:oid:0x1a0000000000b9|SAI_INGRESS_PRIORITY_GROUP_ATTR_BUFFER_PROFILE=oid:0x0 +2021-08-17.04:19:31.379199|G|SAI_STATUS_SUCCESS|SAI_INGRESS_PRIORITY_GROUP_ATTR_BUFFER_PROFILE=oid:0x1900000000044a +2021-08-17.04:19:31.380341|c|SAI_OBJECT_TYPE_BUFFER_PROFILE:oid:0x1900000000051c|SAI_BUFFER_PROFILE_ATTR_POOL_ID=oid:0x0|SAI_BUFFER_PROFILE_ATTR_THRESHOLD_MODE=SAI_BUFFER_PROFILE_THRESHOLD_MODE_DYNAMIC|SAI_BUFFER_PROFILE_ATTR_RESERVED_BUFFER_SIZE=6755399441055744|SAI_BUFFER_PROFILE_ATTR_SHARED_DYNAMIC_TH=-8 +2021-08-17.04:19:31.382246|s|SAI_OBJECT_TYPE_INGRESS_PRIORITY_GROUP:oid:0x1a0000000000b9|SAI_INGRESS_PRIORITY_GROUP_ATTR_BUFFER_PROFILE=oid:0x1900000000051c +2021-08-17.04:19:31.415208|a|APPLY_VIEW +2021-08-17.04:19:32.331089|A|SAI_STATUS_SUCCESS diff --git a/tests/BCM56850/full_ntf.rec b/tests/BCM56850/full_ntf.rec new file mode 100644 index 000000000..436589379 --- /dev/null +++ b/tests/BCM56850/full_ntf.rec @@ -0,0 +1,15 @@ +2017-06-14.01:55:46.543987|a|INIT_VIEW +2017-06-14.01:55:46.551164|A|SAI_STATUS_SUCCESS +2017-06-14.01:55:46.555975|c|SAI_OBJECT_TYPE_SWITCH:oid:0x21000000000000|SAI_SWITCH_ATTR_INIT_SWITCH=true|SAI_SWITCH_ATTR_FDB_EVENT_NOTIFY=0x417890|SAI_SWITCH_ATTR_PORT_STATE_CHANGE_NOTIFY=0x4179f0|SAI_SWITCH_ATTR_SWITCH_SHUTDOWN_REQUEST_NOTIFY=0x417b50 +2017-06-14.01:55:46.558259|s|SAI_OBJECT_TYPE_SWITCH:oid:0x21000000000000|SAI_SWITCH_ATTR_SRC_MAC_ADDRESS=00:11:11:11:11:11 +2017-06-14.01:55:46.559177|g|SAI_OBJECT_TYPE_SWITCH:oid:0x21000000000000|SAI_SWITCH_ATTR_DEFAULT_VIRTUAL_ROUTER_ID=oid:0x0 +2017-06-14.01:56:05.500382|G|SAI_STATUS_SUCCESS|SAI_SWITCH_ATTR_DEFAULT_VIRTUAL_ROUTER_ID=oid:0x3000000000022 +2017-06-14.01:56:05.501109|c|SAI_OBJECT_TYPE_ROUTER_INTERFACE:oid:0x60000000005a3|SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID=oid:0x3000000000022|SAI_ROUTER_INTERFACE_ATTR_TYPE=SAI_ROUTER_INTERFACE_TYPE_LOOPBACK +2017-06-14.01:56:05.508992|g|SAI_OBJECT_TYPE_SWITCH:oid:0x21000000000000|SAI_SWITCH_ATTR_CPU_PORT=oid:0x0 +2017-06-14.01:56:05.516398|G|SAI_STATUS_SUCCESS|SAI_SWITCH_ATTR_CPU_PORT=oid:0x1000000000001 +2017-06-14.01:56:05.516767|g|SAI_OBJECT_TYPE_SWITCH:oid:0x21000000000000|SAI_SWITCH_ATTR_NUMBER_OF_ACTIVE_PORTS=1 +2017-06-14.01:56:05.519973|G|SAI_STATUS_SUCCESS|SAI_SWITCH_ATTR_NUMBER_OF_ACTIVE_PORTS=32 +2017-06-14.01:56:05.520538|g|SAI_OBJECT_TYPE_SWITCH:oid:0x21000000000000|SAI_SWITCH_ATTR_PORT_LIST=32:oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0 +2017-06-14.01:56:05.525938|G|SAI_STATUS_SUCCESS|SAI_SWITCH_ATTR_PORT_LIST=32:oid:0x1000000000002,oid:0x1000000000003,oid:0x1000000000004,oid:0x1000000000005,oid:0x1000000000006,oid:0x1000000000007,oid:0x1000000000008,oid:0x1000000000009,oid:0x100000000000a,oid:0x100000000000b,oid:0x100000000000c,oid:0x100000000000d,oid:0x100000000000e,oid:0x100000000000f,oid:0x1000000000010,oid:0x1000000000011,oid:0x1000000000012,oid:0x1000000000013,oid:0x1000000000014,oid:0x1000000000015,oid:0x1000000000016,oid:0x1000000000017,oid:0x1000000000018,oid:0x1000000000019,oid:0x100000000001a,oid:0x100000000001b,oid:0x100000000001c,oid:0x100000000001d,oid:0x100000000001e,oid:0x100000000001f,oid:0x1000000000020,oid:0x1000000000021 +2017-06-14.01:56:06.151337|a|APPLY_VIEW +2017-06-14.01:56:06.156740|A|SAI_STATUS_SUCCESS diff --git a/tests/aspell.en.pws b/tests/aspell.en.pws index e99b9a373..93c1fef79 100644 --- a/tests/aspell.en.pws +++ b/tests/aspell.en.pws @@ -1,4 +1,5 @@ personal_ws-1.1 en 0 +acl ACL ACLs AES @@ -97,36 +98,55 @@ WRED Werror ZMQ acl +aclaction +aclfield +addr apache api +API apis +APIs +ApplyView arp asic +ASIC asicCreateObject -asicSet asics +ASICs +asicSet asicview +AsicView async attr +ATTR +ATTR +AttrHash attrid attridname attrs attrvalue +BCM bool +Bool booldata brcm broadcom bv candidateObjects +CHARDATA childs +COLDVIDS config const +CONST consts -countOnly counterName +countOnly cout cpp cpu +CreateObject +CRM currentObj currentObject currentView @@ -135,18 +155,24 @@ dbg deallocate decap decrement +Decrement +DEI del deserialize deserialized deserializer dest destructor +Destructor dev didn doesn dscp +EAPOL ecn +ECN eg +EIO encap encodingsa endif @@ -154,47 +180,71 @@ endl enum epoll errno +ETERM eth -ethX ethernet +ethX extern fastfast fd fdb +FDB fdbs +FDBs filename -gSwitchId +FIXME +FlexCounter +GCM genetlink getInstance getQueueSize getSwitchId getVid github +GRE +gSwitchId +GUID hardcoded hasEqualAttribute hostif hpp +HSV +htonl http https hw hwinfo +ICV +ICV idx ifdef +IFF ifindex inattr ini init +INIT inout inseg +Inseg +INSEG insegs ip +IP ipc +ipg +IPG +IPG ipgs +IPGs ipmc +IPv isobjectid isoidattribute json kco +KEYs +KEYs lck lgtm librediscommon @@ -202,31 +252,42 @@ libsairedis libswsscommon linux loadMACsecAttr +LOGLEVEL logrotate lookup +LOOPBACK lua macsec +MACsec +MCAST md +Mellanox memcpy metadata mlnx mpls +MTU multicast mutex mutexes namespace namespaces netdev +NHG nhgm nlog ntf nullptr +OA +ObjectAttrHash objectHash +ObjectHash objectid objectkey objecttype oid oids +OIDs ok orch orchagent @@ -236,59 +297,83 @@ performTransition pfc plaintext pn +PN policer +PORTs pre printf ptr qos queueCounterIds queueId +QUEUEs queueStats rc readonly recv redis +Redis refactor refactored refactoring reimplement reinit removedVidToRid +REQ +RID +RIDs +RIDTOVID rif +RIF rifCounterIds rifId rifStats +RO +RPC runtime rx +RXSC sa sai -saiDiscovery +SaiAttr saibuffer +saiDiscovery +SaiObj sairedis saiswitch +SaiSwitch +SAITHRIFT saivs +SAK sanitycheck +SAs sc scb +SCs sdk +SDK selectable setBuffered setMinPrio setPortCounterList setQueueCounterList sg +SGs shm shmem sleeptime soAll +SONiC splitted src +SRC ss stateful stdint stdlib stdout stp +STP str struct structs @@ -296,22 +381,29 @@ structure subport sw swid +Switch switchid +SwitchState swss swsscommon syncd sys syslog tapfd +TCI tcp temporaryObj temporaryVid temporaryView +TestCase timestamp tmp +TODO torvalds +TPID ttl tx +TXSC typedef uint uncomment @@ -326,23 +418,34 @@ updatable upgradable util utils -vEthernetX versa veth +vEthernetX vid +VID +VIDCOUNTER vidReference -vidToRid vids +VIDs +vidToRid +VIDTORID vlan vlans +VLANS +VOQ vr vslib vxlan +VXLAN +Werror wikipedia workaroung +WRED www xoff xon zero zeromq zmq +ZMQ +ZMQ diff --git a/tests/checkwhitespace.sh b/tests/checkwhitespace.sh index dffbf2239..292d1a31d 100755 --- a/tests/checkwhitespace.sh +++ b/tests/checkwhitespace.sh @@ -2,7 +2,11 @@ echo Checkig for white spaces ... -find .. -type f | grep -v SAI/ |grep -f _wrap.cpp| perl -ne 'print if /\.(c|cpp|h|hpp|am|sh|pl|pm|install|dirs|links|json|ini|yml|pws|md|py|cfg|conf|i|ac)$/' | xargs grep -P "\\s\$" +find .. -type f | +grep -v SAI/ | +grep -v _wrap.cpp | +perl -ne 'print if /\.(c|cpp|h|hpp|am|sh|pl|pm|install|dirs|links|json|ini|yml|pws|md|py|cfg|conf|i|ac)$/' | +xargs grep -P "\\s\$" if [ $? -eq 0 ]; then echo ERROR: some files contain white spaces at the end of line, please fix diff --git a/tests/findcrossinclude.sh b/tests/findcrossinclude.sh index 61afdcdee..f345224cb 100755 --- a/tests/findcrossinclude.sh +++ b/tests/findcrossinclude.sh @@ -38,7 +38,7 @@ find ../meta/.deps -name "*.Plo" -o -name "*.Po"|xargs grep -P "[^r]/lib/|vslib/ echo -- find cross include in lib directory find ../lib/.deps -name "*.Plo" -o -name "*.Po"|xargs grep -P "vslib/|syncd/" - + echo -- find cross include in vslib directory find ../vslib/.deps -name "*.Plo" -o -name "*.Po"|xargs grep -P "[^r]/lib/|syncd/"| \ diff --git a/unittest/lib/Makefile.am b/unittest/lib/Makefile.am index a7d3191a7..6a274bca3 100644 --- a/unittest/lib/Makefile.am +++ b/unittest/lib/Makefile.am @@ -6,7 +6,13 @@ LDADD_GTEST = -L/usr/src/gtest -lgtest -lgtest_main tests_SOURCES = \ main.cpp \ - TestSwitch.cpp + TestSwitch.cpp \ + TestClientConfig.cpp \ + TestClientServerSai.cppa \ + TestContext.cpp \ + TestContextConfig.cpp \ + TestContextConfigContainer.cpp \ + TestUtils.cpp tests_CXXFLAGS = $(DBGFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS_COMMON) tests_LDADD = $(LDADD_GTEST) $(top_srcdir)/lib/libSaiRedis.a -lhiredis -lswsscommon -lpthread -L$(top_srcdir)/meta/.libs -lsaimetadata -lsaimeta -lzmq $(CODE_COVERAGE_LIBS) @@ -62,4 +68,4 @@ testslibsairedis_SOURCES = main_libsairedis.cpp \ testslibsairedis_CXXFLAGS = $(DBGFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS_COMMON) testslibsairedis_LDADD = $(LDADD_GTEST) -L$(top_srcdir)/lib/.libs -lsairedis -lhiredis -lswsscommon -lpthread -L$(top_srcdir)/meta/.libs -lsaimetadata -lsaimeta -lzmq $(CODE_COVERAGE_LIBS) -TESTS = tests testslibsairedis +TESTS = testslibsairedis tests diff --git a/unittest/lib/TestClientConfig.cpp b/unittest/lib/TestClientConfig.cpp new file mode 100644 index 000000000..26a0caeab --- /dev/null +++ b/unittest/lib/TestClientConfig.cpp @@ -0,0 +1,14 @@ +#include "ClientConfig.h" + +#include + +using namespace sairedis; + +TEST(ClientConfig, loadFromFile) +{ + EXPECT_NE(ClientConfig::loadFromFile("non_existing"), nullptr); + + EXPECT_NE(ClientConfig::loadFromFile("files/client_config_bad.txt"), nullptr); + + EXPECT_NE(ClientConfig::loadFromFile("files/client_config_ok.txt"), nullptr); +} diff --git a/unittest/lib/TestClientServerSai.cpp b/unittest/lib/TestClientServerSai.cpp new file mode 100644 index 000000000..ea77661bf --- /dev/null +++ b/unittest/lib/TestClientServerSai.cpp @@ -0,0 +1,83 @@ +#include "ClientServerSai.h" + +#include "swss/logger.h" + +#include + +using namespace sairedis; + +static const char* profile_get_value( + _In_ sai_switch_profile_id_t profile_id, + _In_ const char* variable) +{ + SWSS_LOG_ENTER(); + + if (variable == NULL) + return NULL; + + return nullptr; +} + +static int profile_get_next_value( + _In_ sai_switch_profile_id_t profile_id, + _Out_ const char** variable, + _Out_ const char** value) +{ + SWSS_LOG_ENTER(); + + return 0; +} + +static sai_service_method_table_t test_services = { + profile_get_value, + profile_get_next_value +}; + +TEST(ClientServerSai, ctr) +{ + auto css = std::make_shared(); +} + +TEST(ClientServerSai, initialize) +{ + auto css = std::make_shared(); + + EXPECT_NE(SAI_STATUS_SUCCESS, css->initialize(1, nullptr)); + + EXPECT_NE(SAI_STATUS_SUCCESS, css->initialize(0, nullptr)); + + EXPECT_EQ(SAI_STATUS_SUCCESS, css->initialize(0, &test_services)); + + css = nullptr; // invoke uninitialize in destructor + + css = std::make_shared(); + + EXPECT_EQ(SAI_STATUS_SUCCESS, css->initialize(0, &test_services)); + + EXPECT_NE(SAI_STATUS_SUCCESS, css->initialize(0, &test_services)); +} + +TEST(ClientServerSai, objectTypeQuery) +{ + auto css = std::make_shared(); + + EXPECT_EQ(SAI_OBJECT_TYPE_NULL, css->objectTypeQuery(0x1111111111111111L)); +} + +TEST(ClientServerSai, switchIdQuery) +{ + auto css = std::make_shared(); + + EXPECT_EQ(SAI_NULL_OBJECT_ID, css->switchIdQuery(0x1111111111111111L)); +} + +TEST(ClientServerSai, logSet) +{ + auto css = std::make_shared(); + + EXPECT_NE(SAI_STATUS_SUCCESS, css->logSet(SAI_API_PORT, SAI_LOG_LEVEL_NOTICE)); + + EXPECT_EQ(SAI_STATUS_SUCCESS, css->initialize(0, &test_services)); + + EXPECT_EQ(SAI_STATUS_SUCCESS, css->logSet(SAI_API_PORT, SAI_LOG_LEVEL_NOTICE)); +} diff --git a/unittest/lib/TestContext.cpp b/unittest/lib/TestContext.cpp new file mode 100644 index 000000000..45e9ba446 --- /dev/null +++ b/unittest/lib/TestContext.cpp @@ -0,0 +1,31 @@ +#include "Context.h" + +#include "swss/logger.h" + +#include + +using namespace sairedis; + +static sai_switch_notifications_t handle_notification( + _In_ std::shared_ptr notification, + _In_ Context* context) +{ + SWSS_LOG_ENTER(); + + sai_switch_notifications_t ntf; + + memset(&ntf, 0, sizeof(ntf)); + + return ntf; +} + +TEST(Context, populateMetadata) +{ + auto recorder = std::make_shared(); + + auto cc = std::make_shared(0, "syncd", "ASIC_DB", "COUNTERS_DB","FLEX_DB", "STATE_DB"); + + auto ctx = std::make_shared(cc, recorder,handle_notification); + + ctx->populateMetadata(0x212121212212121L); +} diff --git a/unittest/lib/TestContextConfig.cpp b/unittest/lib/TestContextConfig.cpp new file mode 100644 index 000000000..5851313ef --- /dev/null +++ b/unittest/lib/TestContextConfig.cpp @@ -0,0 +1,31 @@ +#include "ContextConfig.h" + +#include "swss/logger.h" + +#include + +using namespace sairedis; + +TEST(ContextConfig, hasConflict) +{ + auto cc = std::make_shared(0, "syncd", "ASIC_DB", "COUNTERS_DB","FLEX_DB", "STATE_DB"); + + EXPECT_TRUE(cc->hasConflict(std::make_shared(0, "syncd", "ASIC_DB", "COUNTERS_DB","FLEX_DB", "STATE_DB"))); + EXPECT_TRUE(cc->hasConflict(std::make_shared(1, "syncd", "ASIC_DB", "COUNTERS_DB","FLEX_DB", "STATE_DB"))); + EXPECT_TRUE(cc->hasConflict(std::make_shared(1, "syncb", "ASIC_DB", "COUNTERS_DB","FLEX_DB", "STATE_DB"))); + EXPECT_TRUE(cc->hasConflict(std::make_shared(1, "syncb", "ASIC_DD", "COUNTERS_DB","FLEX_DB", "STATE_DB"))); + EXPECT_TRUE(cc->hasConflict(std::make_shared(1, "syncb", "ASIC_DD", "COUNTERS_DD","FLEX_DB", "STATE_DB"))); + EXPECT_TRUE(cc->hasConflict(std::make_shared(1, "syncb", "ASIC_DD", "COUNTERS_DD","FLEX_DD", "STATE_DB"))); + EXPECT_TRUE(cc->hasConflict(std::make_shared(1, "syncb", "ASIC_DD", "COUNTERS_DD","FLEX_DD", "STATE_DD"))); + + auto aa = std::make_shared(1, "syncb", "ASIC_DD", "COUNTERS_DD","FLEX_DD", "STATE_DD"); + + aa->m_zmqEndpoint = "AA"; + + EXPECT_TRUE(cc->hasConflict(aa)); + + aa->m_zmqNtfEndpoint = "AA"; + + EXPECT_FALSE(cc->hasConflict(aa)); +} + diff --git a/unittest/lib/TestContextConfigContainer.cpp b/unittest/lib/TestContextConfigContainer.cpp new file mode 100644 index 000000000..302a0a32b --- /dev/null +++ b/unittest/lib/TestContextConfigContainer.cpp @@ -0,0 +1,32 @@ +#include "ContextConfigContainer.h" + +#include "swss/logger.h" + +#include + +using namespace sairedis; + +TEST(ContextConfigContainer, get) +{ + ContextConfigContainer ccc; + + EXPECT_EQ(ccc.get(0), nullptr); +} + +TEST(ContextConfigContainer, loadFromFile) +{ + ContextConfigContainer ccc; + + EXPECT_NE(ccc.loadFromFile("files/ccc_bad.txt"), nullptr); +} + +TEST(ContextConfigContainer, insert) +{ + ContextConfigContainer ccc; + + auto cc = std::make_shared(0, "syncd", "ASIC_DB", "COUNTERS_DB","FLEX_DB", "STATE_DB"); + + ccc.insert(cc); + + EXPECT_THROW(ccc.insert(cc), std::runtime_error); +} diff --git a/unittest/lib/TestSwitch.cpp b/unittest/lib/TestSwitch.cpp index bd0990cc3..69d9616a1 100644 --- a/unittest/lib/TestSwitch.cpp +++ b/unittest/lib/TestSwitch.cpp @@ -2,9 +2,11 @@ #include +#include + using namespace sairedis; TEST(Switch, ctr) { - EXPECT_THROW(new Switch(SAI_NULL_OBJECT_ID), std::runtime_error); + EXPECT_THROW(std::make_shared(SAI_NULL_OBJECT_ID), std::runtime_error); } diff --git a/unittest/lib/TestUtils.cpp b/unittest/lib/TestUtils.cpp new file mode 100644 index 000000000..3a9e29053 --- /dev/null +++ b/unittest/lib/TestUtils.cpp @@ -0,0 +1,61 @@ +#include "Utils.h" + +#include "swss/logger.h" + +#include + +using namespace sairedis; + +TEST(Utils, clearOidValues) +{ + sai_attribute_t attr; + + sai_object_id_t oids[1]; + + attr.id = 1000; + + EXPECT_THROW(Utils::clearOidValues(SAI_OBJECT_TYPE_NULL, 1, &attr), std::runtime_error); + + attr.id = SAI_ACL_ENTRY_ATTR_FIELD_IN_PORT; + + attr.value.aclfield.data.oid = 1; + + Utils::clearOidValues(SAI_OBJECT_TYPE_ACL_ENTRY, 1, &attr); + + EXPECT_EQ(attr.value.aclfield.data.oid, 0); + + attr.id = SAI_ACL_ENTRY_ATTR_FIELD_IN_PORTS; + + attr.value.aclfield.enable = true; + + attr.value.aclfield.data.objlist.count = 1; + attr.value.aclfield.data.objlist.list = oids; + + oids[0] = 1; + + Utils::clearOidValues(SAI_OBJECT_TYPE_ACL_ENTRY, 1, &attr); + + EXPECT_EQ(oids[0], 0); + + attr.id = SAI_ACL_ENTRY_ATTR_ACTION_COUNTER; + + attr.value.aclaction.parameter.oid = 1; + + Utils::clearOidValues(SAI_OBJECT_TYPE_ACL_ENTRY, 1, &attr); + + EXPECT_EQ(attr.value.aclaction.parameter.oid, 0); + + attr.id = SAI_ACL_ENTRY_ATTR_ACTION_REDIRECT_LIST; + + attr.value.aclaction.enable = true; + + attr.value.aclaction.parameter.objlist.count = 1; + attr.value.aclaction.parameter.objlist.list = oids; + + oids[0] = 1; + + Utils::clearOidValues(SAI_OBJECT_TYPE_ACL_ENTRY, 1, &attr); + + EXPECT_EQ(oids[0], 0); + +} diff --git a/unittest/lib/files/ccc_bad.txt b/unittest/lib/files/ccc_bad.txt new file mode 100644 index 000000000..d675fa44e --- /dev/null +++ b/unittest/lib/files/ccc_bad.txt @@ -0,0 +1 @@ +foo bar diff --git a/unittest/lib/files/client_config_bad.txt b/unittest/lib/files/client_config_bad.txt new file mode 100644 index 000000000..d675fa44e --- /dev/null +++ b/unittest/lib/files/client_config_bad.txt @@ -0,0 +1 @@ +foo bar diff --git a/unittest/lib/files/client_config_ok.txt b/unittest/lib/files/client_config_ok.txt new file mode 100644 index 000000000..21f45e3cc --- /dev/null +++ b/unittest/lib/files/client_config_ok.txt @@ -0,0 +1,4 @@ +{ + "zmq_endpoint": "ipc:///tmp/saiServer", + "zmq_ntf_endpoint": "ipc:///tmp/saiServerNtf" +} diff --git a/unittest/lib/main.cpp b/unittest/lib/main.cpp index e4af24fa3..61f8cd250 100644 --- a/unittest/lib/main.cpp +++ b/unittest/lib/main.cpp @@ -2,7 +2,7 @@ #include -class SwsscommonEnvironment: +class SwsscommonEnvironment: public ::testing::Environment { public: diff --git a/unittest/lib/main_libsairedis.cpp b/unittest/lib/main_libsairedis.cpp index 050c58c55..b6e78370b 100644 --- a/unittest/lib/main_libsairedis.cpp +++ b/unittest/lib/main_libsairedis.cpp @@ -76,12 +76,12 @@ static sai_service_method_table_t test_services = { profile_get_next_value }; -class sairedisEnvironment: +class sairedisEnvironment: public ::testing::Environment { public: - virtual void SetUp() override + virtual void SetUp() override { SWSS_LOG_ENTER(); @@ -91,7 +91,7 @@ class sairedisEnvironment: EXPECT_EQ(status, SAI_STATUS_SUCCESS); } - + virtual void TearDown() override { SWSS_LOG_ENTER(); diff --git a/unittest/lib/test_sai_redis_hostif.cpp b/unittest/lib/test_sai_redis_hostif.cpp index bea9a791d..f1dfaadb3 100644 --- a/unittest/lib/test_sai_redis_hostif.cpp +++ b/unittest/lib/test_sai_redis_hostif.cpp @@ -30,7 +30,7 @@ TEST(libsairedis, hostif) EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_hostif_trap_group(0)); EXPECT_NE(SAI_STATUS_SUCCESS, api->set_hostif_trap_group_attribute(0,0)); EXPECT_NE(SAI_STATUS_SUCCESS, api->get_hostif_trap_group_attribute(0,0,0)); - + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_hostif_trap(&id,0,0,0)); EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_hostif_trap(0)); EXPECT_NE(SAI_STATUS_SUCCESS, api->set_hostif_trap_attribute(0,0)); diff --git a/unittest/meta/Makefile.am b/unittest/meta/Makefile.am index cb186ba88..842b5e661 100644 --- a/unittest/meta/Makefile.am +++ b/unittest/meta/Makefile.am @@ -6,7 +6,39 @@ LDADD_GTEST = -L/usr/src/gtest -lgtest -lgtest_main tests_SOURCES = \ main.cpp \ - TestAttrKeyMap.cpp + ../../meta/DummySaiInterface.cpp \ + ../../meta/MetaTestSaiInterface.cpp \ + ../../lib/VirtualObjectIdManager.cpp \ + ../../lib/SwitchConfig.cpp \ + ../../lib/SwitchConfigContainer.cpp \ + ../../lib/ZeroMQChannel.cpp \ + ../../lib/Channel.cpp \ + TestAttrKeyMap.cpp \ + TestGlobals.cpp \ + TestMetaKeyHasher.cpp \ + TestNotificationFactory.cpp \ + TestNotificationFdbEvent.cpp \ + TestNotificationPortStateChange.cpp \ + TestNotificationQueuePfcDeadlock.cpp \ + TestNotificationSwitchShutdownRequest.cpp \ + TestNotificationSwitchStateChange.cpp \ + TestOidRefCounter.cpp \ + TestPerformanceIntervalTimer.cpp \ + TestPortRelatedSet.cpp \ + TestSaiAttrWrapper.cpp \ + TestSaiAttributeList.cpp \ + TestSaiObject.cpp \ + TestSaiObjectCollection.cpp \ + TestSaiInterface.cpp \ + TestSaiSerialize.cpp \ + TestLegacy.cpp \ + TestLegacyFdbEntry.cpp \ + TestLegacyNeighborEntry.cpp \ + TestLegacyVlan.cpp \ + TestLegacyRouteEntry.cpp \ + TestLegacyOther.cpp \ + TestZeroMQSelectableChannel.cpp \ + TestMeta.cpp tests_CXXFLAGS = $(DBGFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS_COMMON) tests_LDADD = $(LDADD_GTEST) -lhiredis -lswsscommon -lpthread -L$(top_srcdir)/meta/.libs -lsaimetadata -lsaimeta -lzmq $(CODE_COVERAGE_LIBS) diff --git a/unittest/meta/TestAttrKeyMap.cpp b/unittest/meta/TestAttrKeyMap.cpp index 3682ca6bd..75660b9b6 100644 --- a/unittest/meta/TestAttrKeyMap.cpp +++ b/unittest/meta/TestAttrKeyMap.cpp @@ -12,6 +12,8 @@ TEST(AttrKeyMap, constructKey) sai_object_meta_key_t mk; + memset(&mk, 0, sizeof(mk)); + EXPECT_THROW( akm->constructKey(SAI_NULL_OBJECT_ID, mk, 0, nullptr), std::runtime_error); diff --git a/unittest/meta/TestGlobals.cpp b/unittest/meta/TestGlobals.cpp new file mode 100644 index 000000000..8fbab604d --- /dev/null +++ b/unittest/meta/TestGlobals.cpp @@ -0,0 +1,47 @@ +#include "Globals.h" + +#include + +#include + +using namespace saimeta; + +static_assert(SAI_MAX_HARDWARE_ID_LEN <= 256, "max is 256"); + +TEST(Globals, getHardwareInfo) +{ + EXPECT_EQ("", Globals::getHardwareInfo(0, nullptr)); + + EXPECT_EQ("", Globals::getHardwareInfo(1, nullptr)); + + sai_attribute_t attr; + + attr.id = SAI_SWITCH_ATTR_SWITCH_HARDWARE_INFO; + attr.value.s8list.count = 0; + attr.value.s8list.list = nullptr; + + EXPECT_EQ("", Globals::getHardwareInfo(1, &attr)); + + attr.value.s8list.count = 1; + attr.value.s8list.list = nullptr; + + EXPECT_EQ("", Globals::getHardwareInfo(1, &attr)); + + char hwinfo[SAI_MAX_HARDWARE_ID_LEN + 2]; + + memset(hwinfo, '0', SAI_MAX_HARDWARE_ID_LEN + 2); + + hwinfo[SAI_MAX_HARDWARE_ID_LEN + 1] = 0; + + attr.value.s8list.count = SAI_MAX_HARDWARE_ID_LEN + 1; + attr.value.s8list.list = (int8_t*)hwinfo; + + EXPECT_EQ(std::string(SAI_MAX_HARDWARE_ID_LEN, '0'), Globals::getHardwareInfo(1, &attr)); + + attr.value.s8list.count = 10; + attr.value.s8list.list = (int8_t*)hwinfo; + + hwinfo[3] = 0; + + EXPECT_EQ("000", Globals::getHardwareInfo(1, &attr)); +} diff --git a/unittest/meta/TestLegacy.cpp b/unittest/meta/TestLegacy.cpp new file mode 100644 index 000000000..c14b88c10 --- /dev/null +++ b/unittest/meta/TestLegacy.cpp @@ -0,0 +1,230 @@ +#include "TestLegacy.h" + +#include "sai_serialize.h" + +#include + +//using namespace TestLegacy; + +using namespace saimeta; + +namespace TestLegacy +{ + std::shared_ptr g_sai = std::make_shared(); + std::shared_ptr g_meta = std::make_shared(g_sai); + + // STATIC HELPER METHODS + + void clear_local() + { + SWSS_LOG_ENTER(); + + g_sai = std::make_shared(); + g_meta = std::make_shared(g_sai); + } + + sai_object_id_t create_switch() + { + SWSS_LOG_ENTER(); + + sai_attribute_t attr; + + sai_object_id_t switch_id; + + attr.id = SAI_SWITCH_ATTR_INIT_SWITCH; + attr.value.booldata = true; + + auto status = g_meta->create(SAI_OBJECT_TYPE_SWITCH, &switch_id, SAI_NULL_OBJECT_ID, 1, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + return switch_id; + } + + void remove_switch( + _In_ sai_object_id_t switchId) + { + SWSS_LOG_ENTER(); + + EXPECT_TRUE(g_meta->isEmpty() == false); + + SWSS_LOG_NOTICE("removing: %lX", switchId); + + auto status = g_meta->remove(SAI_OBJECT_TYPE_SWITCH, switchId); + + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + if (g_meta->isEmpty() == false) + { + g_meta->dump(); + } + + EXPECT_TRUE(g_meta->isEmpty()); + } + + sai_object_id_t create_bridge( + _In_ sai_object_id_t switch_id) + { + SWSS_LOG_ENTER(); + + sai_object_id_t bridge_id; + + sai_attribute_t attrs[9] = {}; + + attrs[0].id = SAI_BRIDGE_ATTR_TYPE; + attrs[0].value.s32 = SAI_BRIDGE_TYPE_1Q; + + sai_status_t status = g_meta->create(SAI_OBJECT_TYPE_BRIDGE, &bridge_id, switch_id, 1, attrs); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + return bridge_id; + } + + sai_object_id_t create_port( + _In_ sai_object_id_t switch_id) + { + SWSS_LOG_ENTER(); + + sai_object_id_t port; + + static uint32_t id = 1; + id++; + sai_attribute_t attrs[9] = { }; + + uint32_t list[1] = { id }; + + attrs[0].id = SAI_PORT_ATTR_HW_LANE_LIST; + attrs[0].value.u32list.count = 1; + attrs[0].value.u32list.list = list; + + attrs[1].id = SAI_PORT_ATTR_SPEED; + attrs[1].value.u32 = 10000; + + auto status = g_meta->create(SAI_OBJECT_TYPE_PORT, &port, switch_id, 2, attrs); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + return port; + } + + sai_object_id_t create_bridge_port( + _In_ sai_object_id_t switch_id, + _In_ sai_object_id_t bridge_id) + { + SWSS_LOG_ENTER(); + + sai_object_id_t bridge_port; + + sai_attribute_t attrs[9] = { }; + + auto port = create_port(switch_id); + + attrs[0].id = SAI_BRIDGE_PORT_ATTR_TYPE; + attrs[0].value.s32 = SAI_BRIDGE_PORT_TYPE_PORT; + + attrs[1].id = SAI_BRIDGE_PORT_ATTR_PORT_ID; + attrs[1].value.oid = port; + + auto status = g_meta->create(SAI_OBJECT_TYPE_BRIDGE_PORT, &bridge_port, switch_id, 2, attrs); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + return bridge_port; + } + + sai_object_id_t create_dummy_object_id( + _In_ sai_object_type_t object_type, + _In_ sai_object_id_t switch_id) + { + SWSS_LOG_ENTER(); + + sai_object_id_t oid; + + auto status = g_sai->create(object_type, &oid, switch_id, 0, NULL); + + if (status != SAI_STATUS_SUCCESS) + { + SWSS_LOG_THROW("failed to create oid"); + } + + SWSS_LOG_DEBUG("created oid %s", sai_serialize_object_id(oid).c_str()); + + return oid; + } + + sai_object_id_t create_virtual_router( + _In_ sai_object_id_t switch_id) + { + SWSS_LOG_ENTER(); + + sai_object_id_t vr; + + auto status = g_meta->create(SAI_OBJECT_TYPE_VIRTUAL_ROUTER, &vr, switch_id, 0, NULL); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + return vr; + } + + sai_object_id_t create_rif( + _In_ sai_object_id_t switch_id) + { + SWSS_LOG_ENTER(); + + sai_object_id_t rif; + + sai_attribute_t attrs[9] = { }; + + auto port = create_port(switch_id); + + auto vr = create_virtual_router(switch_id); + + attrs[0].id = SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID; + attrs[0].value.oid = vr; + + attrs[1].id = SAI_ROUTER_INTERFACE_ATTR_TYPE; + attrs[1].value.s32 = SAI_ROUTER_INTERFACE_TYPE_PORT; + + attrs[2].id = SAI_ROUTER_INTERFACE_ATTR_PORT_ID; + attrs[2].value.oid = port; + + auto status = g_meta->create(SAI_OBJECT_TYPE_ROUTER_INTERFACE, &rif, switch_id, 3, attrs); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + return rif; + } + + sai_object_id_t create_stp( + _In_ sai_object_id_t switch_id) + { + SWSS_LOG_ENTER(); + + sai_object_id_t stp; + + auto status = g_meta->create(SAI_OBJECT_TYPE_STP, &stp, switch_id, 0, NULL); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + return stp; + } + + sai_object_id_t create_next_hop( + _In_ sai_object_id_t switch_id) + { + SWSS_LOG_ENTER(); + + sai_object_id_t nh; + + sai_attribute_t attrs[9] = { }; + + attrs[0].id = SAI_NEXT_HOP_ATTR_TYPE; + attrs[0].value.s32 = SAI_NEXT_HOP_TYPE_IP; + + attrs[1].id = SAI_NEXT_HOP_ATTR_IP; + + auto rif = create_rif(switch_id); + + attrs[2].id = SAI_NEXT_HOP_ATTR_ROUTER_INTERFACE_ID; + attrs[2].value.oid = rif; + + auto status = g_meta->create(SAI_OBJECT_TYPE_NEXT_HOP, &nh, switch_id, 3, attrs); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + return nh; + } +} diff --git a/unittest/meta/TestLegacy.h b/unittest/meta/TestLegacy.h new file mode 100644 index 000000000..728ce210f --- /dev/null +++ b/unittest/meta/TestLegacy.h @@ -0,0 +1,43 @@ +#include "Meta.h" +#include "MetaTestSaiInterface.h" + +namespace TestLegacy +{ + extern std::shared_ptr g_sai; + extern std::shared_ptr g_meta; + + // STATIC HELPER METHODS + + void clear_local(); + + sai_object_id_t create_switch(); + + void remove_switch( + _In_ sai_object_id_t switchId); + + sai_object_id_t create_bridge( + _In_ sai_object_id_t switch_id); + + sai_object_id_t create_port( + _In_ sai_object_id_t switch_id); + + sai_object_id_t create_bridge_port( + _In_ sai_object_id_t switch_id, + _In_ sai_object_id_t bridge_id); + + sai_object_id_t create_dummy_object_id( + _In_ sai_object_type_t object_type, + _In_ sai_object_id_t switch_id); + + sai_object_id_t create_virtual_router( + _In_ sai_object_id_t switch_id); + + sai_object_id_t create_rif( + _In_ sai_object_id_t switch_id); + + sai_object_id_t create_stp( + _In_ sai_object_id_t switch_id); + + sai_object_id_t create_next_hop( + _In_ sai_object_id_t switch_id); +} diff --git a/unittest/meta/TestLegacyFdbEntry.cpp b/unittest/meta/TestLegacyFdbEntry.cpp new file mode 100644 index 000000000..d9734972b --- /dev/null +++ b/unittest/meta/TestLegacyFdbEntry.cpp @@ -0,0 +1,415 @@ +#include "TestLegacy.h" + +#include + +#include + +using namespace TestLegacy; + +// STATIC HELPERS + +static sai_fdb_entry_t create_fdb_entry() +{ + SWSS_LOG_ENTER(); + + sai_fdb_entry_t fdb_entry; + + sai_mac_t mac = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; + + memcpy(fdb_entry.mac_address, mac, sizeof(mac)); + + auto switch_id = create_switch(); + + fdb_entry.switch_id = switch_id; + sai_object_id_t bridge_id = create_bridge(switch_id); + fdb_entry.bv_id = bridge_id; + + sai_object_id_t port = create_bridge_port(switch_id, bridge_id); + + sai_attribute_t list1[4] = { }; + + sai_attribute_t &attr1 = list1[0]; + sai_attribute_t &attr2 = list1[1]; + sai_attribute_t &attr3 = list1[2]; + sai_attribute_t &attr4 = list1[3]; + + attr1.id = SAI_FDB_ENTRY_ATTR_TYPE; + attr1.value.s32 = SAI_FDB_ENTRY_TYPE_STATIC; + + attr2.id = SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID; + attr2.value.oid = port; + + attr3.id = SAI_FDB_ENTRY_ATTR_PACKET_ACTION; + attr3.value.s32 = SAI_PACKET_ACTION_FORWARD; + + attr4.id = -1; + + sai_attribute_t list2[4] = { attr1, attr2, attr3, attr3 }; + + auto status = g_meta->create(&fdb_entry, 3, list2); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + return fdb_entry; +} + +// TESTS + +TEST(LegacyFdbEntry, fdb_entry_create) +{ + SWSS_LOG_ENTER(); + + clear_local(); + + sai_status_t status; + sai_attribute_t attr; + + sai_object_id_t switch_id = create_switch(); + + sai_fdb_entry_t fdb_entry; + + sai_mac_t mac = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; + + memcpy(fdb_entry.mac_address, mac, sizeof(mac)); + + fdb_entry.switch_id = switch_id; + sai_object_id_t bridge_id = create_bridge(switch_id); + fdb_entry.bv_id = bridge_id; + + sai_object_id_t port = create_bridge_port(switch_id, bridge_id); + + SWSS_LOG_NOTICE("create tests"); + + SWSS_LOG_NOTICE("zero attribute count (but there are mandatory attributes)"); + attr.id = SAI_FDB_ENTRY_ATTR_TYPE; + status = g_meta->create(&fdb_entry, 0, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("attr is null"); + status = g_meta->create(&fdb_entry, 1, NULL); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("fdb entry is null"); + status = g_meta->create((const sai_fdb_entry_t*)NULL, 1, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + sai_attribute_t list1[4] = { }; + + sai_attribute_t &attr1 = list1[0]; + sai_attribute_t &attr2 = list1[1]; + sai_attribute_t &attr3 = list1[2]; + sai_attribute_t &attr4 = list1[3]; + + attr1.id = SAI_FDB_ENTRY_ATTR_TYPE; + attr1.value.s32 = SAI_FDB_ENTRY_TYPE_STATIC; + + attr2.id = SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID; + attr2.value.oid = port; + + attr3.id = SAI_FDB_ENTRY_ATTR_PACKET_ACTION; + attr3.value.s32 = SAI_PACKET_ACTION_FORWARD; + + attr4.id = -1; + + SWSS_LOG_NOTICE("invalid attribute id"); + status = g_meta->create(&fdb_entry, 4, list1); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + +// // packet action is now optional +// SWSS_LOG_NOTICE("passing optional attribute"); +// status = g_meta->create(&fdb_entry, 1, list1); +// EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + attr2.value.oid = create_dummy_object_id(SAI_OBJECT_TYPE_HASH, switch_id); + + SWSS_LOG_NOTICE("invalid attribute value on oid"); + status = g_meta->create(&fdb_entry, 3, list1); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + attr2.value.oid = create_dummy_object_id(SAI_OBJECT_TYPE_PORT, switch_id); + + SWSS_LOG_NOTICE("non existing object on oid"); + status = g_meta->create(&fdb_entry, 3, list1); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + attr2.value.oid = port; + attr3.value.s32 = 0x100; + + SWSS_LOG_NOTICE("invalid attribute value on enum"); + status = g_meta->create(&fdb_entry, 3, list1); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + attr3.value.s32 = SAI_PACKET_ACTION_FORWARD; + + sai_attribute_t list2[4] = { attr1, attr2, attr3, attr3 }; + + SWSS_LOG_NOTICE("repeated attribute id"); + status = g_meta->create(&fdb_entry, 4, list2); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("correct"); + status = g_meta->create(&fdb_entry, 3, list2); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("already exists"); + status = g_meta->create(&fdb_entry, 3, list2); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + remove_switch(switch_id); +} + +TEST(LegacyFdbEntry, fdb_entry_remove) +{ + clear_local(); + + sai_status_t status; + + sai_object_id_t switch_id = create_switch(); + + sai_fdb_entry_t fdb_entry; + + sai_mac_t mac = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; + + memcpy(fdb_entry.mac_address, mac, sizeof(mac)); + fdb_entry.switch_id = switch_id; + sai_object_id_t bridge_id = create_bridge(switch_id); + fdb_entry.bv_id= bridge_id; + + sai_object_id_t port = create_bridge_port(switch_id, bridge_id); + + sai_attribute_t list1[3] = { }; + + sai_attribute_t &attr1 = list1[0]; + sai_attribute_t &attr2 = list1[1]; + sai_attribute_t &attr3 = list1[2]; + + attr1.id = SAI_FDB_ENTRY_ATTR_TYPE; + attr1.value.s32 = SAI_FDB_ENTRY_TYPE_STATIC; + + attr2.id = SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID; + attr2.value.oid = port; + + attr3.id = SAI_FDB_ENTRY_ATTR_PACKET_ACTION; + attr3.value.s32 = SAI_PACKET_ACTION_FORWARD; + + SWSS_LOG_NOTICE("creating fdb entry"); + status = g_meta->create(&fdb_entry, 3, list1); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("remove tests"); + + SWSS_LOG_NOTICE("fdb_entry is null"); + status = g_meta->remove((const sai_fdb_entry_t*)NULL); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + //SWSS_LOG_NOTICE("invalid vlan"); + //status = g_meta->remove(&fdb_entry); + //EXPECT_NE(SAI_STATUS_SUCCESS, status); + + fdb_entry.mac_address[0] = 1; + + SWSS_LOG_NOTICE("invalid mac"); + status = g_meta->remove(&fdb_entry); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + fdb_entry.mac_address[0] = 0x11; + + sai_object_meta_key_t key = { .objecttype = SAI_OBJECT_TYPE_FDB_ENTRY, .objectkey = { .key = { .fdb_entry = fdb_entry } } }; + + EXPECT_TRUE(g_meta->objectExists(key)); + + SWSS_LOG_NOTICE("success"); + status = g_meta->remove(&fdb_entry); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + EXPECT_TRUE(!g_meta->objectExists(key)); + + remove_switch(switch_id); +} + +TEST(LegacyFdbEntry, fdb_entry_set) +{ + clear_local(); + + sai_status_t status; + sai_attribute_t attr; + + memset(&attr, 0, sizeof(attr)); + + sai_fdb_entry_t fdb_entry = create_fdb_entry(); + + //status = g_meta->create(&fdb_entry, 0, 0); + //EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("attr is null"); + status = g_meta->set(&fdb_entry, NULL); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("fdb entry is null"); + status = g_meta->set((const sai_fdb_entry_t*)NULL, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("setting read only object"); + attr.id = SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID; + attr.value.oid = create_dummy_object_id(SAI_OBJECT_TYPE_BRIDGE_PORT, fdb_entry.switch_id); + + status = g_meta->set(&fdb_entry, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("setting invalid attrib id"); + attr.id = -1; + status = g_meta->set(&fdb_entry, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + //SWSS_LOG_NOTICE("invalid vlan"); + //attr.id = SAI_FDB_ENTRY_ATTR_TYPE; + //attr.value.s32 = SAI_FDB_ENTRY_TYPE_STATIC; + //status = g_meta->set(&fdb_entry, &attr); + //EXPECT_NE(SAI_STATUS_SUCCESS, status); + + //SWSS_LOG_NOTICE("vlan outside range"); + //attr.id = SAI_FDB_ENTRY_ATTR_TYPE; + //attr.value.s32 = SAI_FDB_ENTRY_TYPE_STATIC; + //status = g_meta->set(&fdb_entry, &attr); + //EXPECT_NE(SAI_STATUS_SUCCESS, status); + + // correct + attr.id = SAI_FDB_ENTRY_ATTR_TYPE; + attr.value.s32 = SAI_FDB_ENTRY_TYPE_STATIC; + status = g_meta->set(&fdb_entry, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + // TODO check references ? + + remove_switch(fdb_entry.switch_id); +} + +TEST(LegacyFdbEntry, fdb_entry_get) +{ + clear_local(); + + sai_status_t status; + sai_attribute_t attr; + + memset(&attr, 0, sizeof(attr)); + + sai_fdb_entry_t fdb_entry = create_fdb_entry(); + + attr.id = SAI_FDB_ENTRY_ATTR_TYPE; + attr.value.s32 = SAI_FDB_ENTRY_TYPE_STATIC; + status = g_meta->set(&fdb_entry, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("get test"); + + // zero attribute count + attr.id = SAI_FDB_ENTRY_ATTR_TYPE; + status = g_meta->get(&fdb_entry, 0, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + // attr is null + status = g_meta->get(&fdb_entry, 1, NULL); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + // fdb entry is null + status = g_meta->get((sai_fdb_entry_t*)NULL, 1, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + // attr id out of range + attr.id = -1; + status = g_meta->get(&fdb_entry, 1, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + // correct single valid attribute + attr.id = SAI_FDB_ENTRY_ATTR_TYPE; + status = g_meta->get(&fdb_entry, 1, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + // correct 2 attributes + sai_attribute_t attr1; + attr1.id = SAI_FDB_ENTRY_ATTR_TYPE; + + sai_attribute_t attr2; + attr2.id = SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID; + sai_attribute_t list[2] = { attr1, attr2 }; + + status = g_meta->get(&fdb_entry, 2, list); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + remove_switch(fdb_entry.switch_id); +} + +TEST(LegacyFdbEntry, fdb_entry_flow) +{ + SWSS_LOG_TIMER("fdb flow"); + + clear_local(); + + sai_object_id_t switch_id = create_switch(); + sai_status_t status; + sai_attribute_t attr; + + sai_fdb_entry_t fdb_entry; + + sai_mac_t mac = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; + + memcpy(fdb_entry.mac_address, mac, sizeof(mac)); + fdb_entry.switch_id = switch_id; + + sai_object_id_t bridge_id = create_bridge(switch_id); + fdb_entry.bv_id= bridge_id; + + sai_object_id_t lag = create_bridge_port(switch_id, bridge_id); + + sai_attribute_t list[4] = { }; + + sai_attribute_t &attr1 = list[0]; + sai_attribute_t &attr2 = list[1]; + sai_attribute_t &attr3 = list[2]; + sai_attribute_t &attr4 = list[3]; + + attr1.id = SAI_FDB_ENTRY_ATTR_TYPE; + attr1.value.s32 = SAI_FDB_ENTRY_TYPE_STATIC; + + attr2.id = SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID; + attr2.value.oid = lag; + + attr3.id = SAI_FDB_ENTRY_ATTR_PACKET_ACTION; + attr3.value.s32 = SAI_PACKET_ACTION_FORWARD; + + attr4.id = SAI_FDB_ENTRY_ATTR_META_DATA; + attr4.value.u32 = 0x12345678; + + SWSS_LOG_NOTICE("create"); + status = g_meta->create(&fdb_entry, 4, list); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("create existing"); + status = g_meta->create(&fdb_entry, 4, list); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("set"); + attr.id = SAI_FDB_ENTRY_ATTR_TYPE; + attr.value.s32 = SAI_FDB_ENTRY_TYPE_DYNAMIC; + status = g_meta->set(&fdb_entry, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("set"); + attr.id = SAI_FDB_ENTRY_ATTR_META_DATA; + attr.value.u32 = SAI_FDB_ENTRY_TYPE_DYNAMIC; + status = g_meta->set(&fdb_entry, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("get"); + status = g_meta->get(&fdb_entry, 4, list); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("remove"); + status = g_meta->remove(&fdb_entry); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("remove non existing"); + status = g_meta->remove(&fdb_entry); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + remove_switch(switch_id); +} diff --git a/unittest/meta/TestLegacyNeighborEntry.cpp b/unittest/meta/TestLegacyNeighborEntry.cpp new file mode 100644 index 000000000..b23eda496 --- /dev/null +++ b/unittest/meta/TestLegacyNeighborEntry.cpp @@ -0,0 +1,475 @@ +#include "TestLegacy.h" + +#include + +#include + +#include + +using namespace TestLegacy; + +// STATIC HELPERS + +//static sai_neighbor_entry_t create_neighbor_entry() +//{ +// SWSS_LOG_ENTER(); +// +// sai_object_id_t switch_id = create_switch(); +// sai_status_t status; +// +// sai_mac_t mac = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; +// +// sai_neighbor_entry_t neighbor_entry; +// +// sai_object_id_t rif = create_rif(switch_id); +// +// neighbor_entry.ip_address.addr_family = SAI_IP_ADDR_FAMILY_IPV4; +// neighbor_entry.ip_address.addr.ip4 = htonl(0x0a00000f); +// neighbor_entry.rif_id = rif; +// neighbor_entry.switch_id = switch_id; +// +// sai_attribute_t list[3] = { }; +// +// sai_attribute_t &attr1 = list[0]; +// sai_attribute_t &attr2 = list[1]; +// sai_attribute_t &attr3 = list[2]; +// +// attr1.id = SAI_NEIGHBOR_ENTRY_ATTR_DST_MAC_ADDRESS; +// memcpy(attr1.value.mac, mac, 6); +// +// attr2.id = SAI_NEIGHBOR_ENTRY_ATTR_PACKET_ACTION; +// attr2.value.s32 = SAI_PACKET_ACTION_FORWARD; +// +// attr3.id = -1; +// +// attr2.value.s32 = SAI_PACKET_ACTION_FORWARD; +// +// sai_attribute_t list2[4] = { attr1, attr2, attr2 }; +// +// status = g_meta->create(&neighbor_entry, 2, list2); +// EXPECT_EQ(SAI_STATUS_SUCCESS, status); +// +// return neighbor_entry; +//} + +static sai_object_id_t create_hash( + _In_ sai_object_id_t switch_id) +{ + SWSS_LOG_ENTER(); + + sai_object_id_t hash; + + auto status = g_meta->create(SAI_OBJECT_TYPE_HASH, &hash, switch_id, 0, NULL); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + return hash; +} + +// ACTUAL TESTS + +TEST(LegacyNeighborEntry, neighbor_entry_create) +{ + SWSS_LOG_ENTER(); + + clear_local(); + + sai_object_id_t switch_id = create_switch(); + sai_status_t status; + sai_attribute_t attr; + + sai_mac_t mac = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; + + sai_neighbor_entry_t neighbor_entry; + + sai_object_id_t rif = create_rif(switch_id); + + neighbor_entry.ip_address.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + neighbor_entry.ip_address.addr.ip4 = htonl(0x0a00000f); + neighbor_entry.rif_id = rif; + neighbor_entry.switch_id = switch_id; + + SWSS_LOG_NOTICE("create tests"); + + SWSS_LOG_NOTICE("zero attribute count (but there are mandatory attributes)"); + status = g_meta->create(&neighbor_entry, 0, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("attr is null"); + status = g_meta->create(&neighbor_entry, 1, NULL); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("neighbor entry is null"); + status = g_meta->create((sai_neighbor_entry_t*)NULL, 1, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + sai_attribute_t list[3] = { }; + + sai_attribute_t &attr1 = list[0]; + sai_attribute_t &attr2 = list[1]; + sai_attribute_t &attr3 = list[2]; + + attr1.id = SAI_NEIGHBOR_ENTRY_ATTR_DST_MAC_ADDRESS; + memcpy(attr1.value.mac, mac, 6); + + attr2.id = SAI_NEIGHBOR_ENTRY_ATTR_PACKET_ACTION; + attr2.value.s32 = SAI_PACKET_ACTION_FORWARD; + + attr3.id = -1; + + SWSS_LOG_NOTICE("invalid attribute id"); + status = g_meta->create(&neighbor_entry, 3, list); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + attr2.value.s32 = SAI_PACKET_ACTION_FORWARD + 0x100; + SWSS_LOG_NOTICE("invalid attribute value on enum"); + status = g_meta->create(&neighbor_entry, 2, list); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + attr2.value.s32 = SAI_PACKET_ACTION_FORWARD; + + sai_attribute_t list2[4] = { attr1, attr2, attr2 }; + + SWSS_LOG_NOTICE("repeated attribute id"); + status = g_meta->create(&neighbor_entry, 3, list2); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("correct ipv4"); + status = g_meta->create(&neighbor_entry, 2, list2); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + neighbor_entry.ip_address.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + sai_ip6_t ip6 = {0x00, 0x11, 0x22, 0x33,0x44, 0x55, 0x66,0x77, 0x88, 0x99, 0xaa, 0xbb,0xcc,0xdd,0xee,0xff}; + memcpy(neighbor_entry.ip_address.addr.ip6, ip6, 16); + + SWSS_LOG_NOTICE("correct ipv6"); + status = g_meta->create(&neighbor_entry, 2, list2); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("already exists"); + status = g_meta->create(&neighbor_entry, 2, list2); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + remove_switch(switch_id); +} + +TEST(LegacyNeighborEntry, neighbor_entry_remove) +{ + clear_local(); + + sai_status_t status; + + sai_object_id_t switch_id = create_switch(); + sai_neighbor_entry_t neighbor_entry; + + sai_mac_t mac = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; + + sai_attribute_t list[2] = { }; + + sai_attribute_t &attr1 = list[0]; + sai_attribute_t &attr2 = list[1]; + + attr1.id = SAI_NEIGHBOR_ENTRY_ATTR_DST_MAC_ADDRESS; + memcpy(attr1.value.mac, mac, 6); + + attr2.id = SAI_NEIGHBOR_ENTRY_ATTR_PACKET_ACTION; + attr2.value.s32 = SAI_PACKET_ACTION_FORWARD; + + sai_object_id_t rif = create_rif(switch_id); + + neighbor_entry.ip_address.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + neighbor_entry.ip_address.addr.ip4 = htonl(0x0a00000f); + neighbor_entry.rif_id = rif; + neighbor_entry.switch_id = switch_id; + + SWSS_LOG_NOTICE("create"); + + SWSS_LOG_NOTICE("correct ipv4"); + status = g_meta->create(&neighbor_entry, 2, list); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + neighbor_entry.ip_address.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + sai_ip6_t ip6 = {0x00, 0x11, 0x22, 0x33,0x44, 0x55, 0x66,0x77, 0x88, 0x99, 0xaa, 0xbb,0xcc,0xdd,0xee,0xff}; + memcpy(neighbor_entry.ip_address.addr.ip6, ip6, 16); + + SWSS_LOG_NOTICE("correct ipv6"); + status = g_meta->create(&neighbor_entry, 2, list); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("remove tests"); + + SWSS_LOG_NOTICE("neighbor_entry is null"); + status = g_meta->remove((sai_neighbor_entry_t*)NULL); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + neighbor_entry.rif_id = SAI_NULL_OBJECT_ID; + + SWSS_LOG_NOTICE("invalid object id null"); + status = g_meta->remove(&neighbor_entry); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + neighbor_entry.rif_id = create_hash(switch_id); + + SWSS_LOG_NOTICE("invalid object id hash"); + status = g_meta->remove(&neighbor_entry); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + neighbor_entry.rif_id = create_rif(switch_id); + + SWSS_LOG_NOTICE("invalid object id router"); + status = g_meta->remove(&neighbor_entry); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + neighbor_entry.rif_id = rif; + + sai_object_meta_key_t key = { .objecttype = SAI_OBJECT_TYPE_NEIGHBOR_ENTRY, .objectkey = { .key = { .neighbor_entry = neighbor_entry } } }; + + EXPECT_TRUE(g_meta->objectExists(key)); + + SWSS_LOG_NOTICE("success"); + status = g_meta->remove(&neighbor_entry); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + EXPECT_TRUE(!g_meta->objectExists(key)); + + remove_switch(switch_id); +} + +TEST(LegacyNeighborEntry, neighbor_entry_set) +{ + clear_local(); + + sai_status_t status; + + sai_attribute_t attr; + + memset(&attr, 0, sizeof(attr)); + + sai_object_id_t switch_id = create_switch(); + sai_neighbor_entry_t neighbor_entry; + + sai_mac_t mac = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; + + sai_attribute_t list[2] = { }; + + sai_attribute_t &attr1 = list[0]; + sai_attribute_t &attr2 = list[1]; + + attr1.id = SAI_NEIGHBOR_ENTRY_ATTR_DST_MAC_ADDRESS; + memcpy(attr1.value.mac, mac, 6); + + attr2.id = SAI_NEIGHBOR_ENTRY_ATTR_PACKET_ACTION; + attr2.value.s32 = SAI_PACKET_ACTION_FORWARD; + + sai_object_id_t rif = create_rif(switch_id); + + neighbor_entry.ip_address.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + neighbor_entry.ip_address.addr.ip4 = htonl(0x0a00000f); + neighbor_entry.rif_id = rif; + neighbor_entry.switch_id = switch_id; + + SWSS_LOG_NOTICE("create"); + + SWSS_LOG_NOTICE("correct ipv4"); + status = g_meta->create(&neighbor_entry, 2, list); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + neighbor_entry.ip_address.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + sai_ip6_t ip6 = {0x00, 0x11, 0x22, 0x33,0x44, 0x55, 0x66,0x77, 0x88, 0x99, 0xaa, 0xbb,0xcc,0xdd,0xee,0xff}; + memcpy(neighbor_entry.ip_address.addr.ip6, ip6, 16); + + SWSS_LOG_NOTICE("correct ipv6"); + status = g_meta->create(&neighbor_entry, 2, list); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("set tests"); + + SWSS_LOG_NOTICE("attr is null"); + status = g_meta->set(&neighbor_entry, NULL); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("neighbor entry is null"); + status = g_meta->set((sai_neighbor_entry_t*)NULL, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("setting invalid attrib id"); + attr.id = -1; + status = g_meta->set(&neighbor_entry, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("value outside range"); + attr.id = SAI_NEIGHBOR_ENTRY_ATTR_PACKET_ACTION; + attr.value.s32 = 0x100; + status = g_meta->set(&neighbor_entry, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + // correct + attr.id = SAI_NEIGHBOR_ENTRY_ATTR_PACKET_ACTION; + attr.value.s32 = SAI_PACKET_ACTION_DROP; + status = g_meta->set(&neighbor_entry, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + remove_switch(switch_id); +} + +TEST(LegacyNeighborEntry, neighbor_entry_get) +{ + clear_local(); + + sai_status_t status; + + sai_attribute_t attr; + + memset(&attr, 0, sizeof(attr)); + + sai_object_id_t switch_id = create_switch(); + sai_neighbor_entry_t neighbor_entry; + + sai_mac_t mac = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; + + sai_attribute_t list[2] = { }; + + sai_attribute_t &attr1 = list[0]; + sai_attribute_t &attr2 = list[1]; + + attr1.id = SAI_NEIGHBOR_ENTRY_ATTR_DST_MAC_ADDRESS; + memcpy(attr1.value.mac, mac, 6); + + attr2.id = SAI_NEIGHBOR_ENTRY_ATTR_PACKET_ACTION; + attr2.value.s32 = SAI_PACKET_ACTION_FORWARD; + + sai_object_id_t rif = create_rif(switch_id); + + neighbor_entry.ip_address.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + neighbor_entry.ip_address.addr.ip4 = htonl(0x0a00000f); + neighbor_entry.rif_id = rif; + neighbor_entry.switch_id = switch_id; + + SWSS_LOG_NOTICE("create"); + + SWSS_LOG_NOTICE("correct ipv4"); + status = g_meta->create(&neighbor_entry, 2, list); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + neighbor_entry.ip_address.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + sai_ip6_t ip6 = {0x00, 0x11, 0x22, 0x33,0x44, 0x55, 0x66,0x77, 0x88, 0x99, 0xaa, 0xbb,0xcc,0xdd,0xee,0xff}; + memcpy(neighbor_entry.ip_address.addr.ip6, ip6, 16); + + SWSS_LOG_NOTICE("correct ipv6"); + status = g_meta->create(&neighbor_entry, 2, list); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("get test"); + + SWSS_LOG_NOTICE("zero attribute count"); + attr.id = SAI_NEIGHBOR_ENTRY_ATTR_PACKET_ACTION; + status = g_meta->get(&neighbor_entry, 0, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("attr is null"); + status = g_meta->get(&neighbor_entry, 1, NULL); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("neighbor entry is null"); + status = g_meta->get((sai_neighbor_entry_t*)NULL, 1, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("attr id out of range"); + attr.id = -1; + status = g_meta->get(&neighbor_entry, 1, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("correct single valid attribute"); + attr.id = SAI_NEIGHBOR_ENTRY_ATTR_PACKET_ACTION; + status = g_meta->get(&neighbor_entry, 1, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("correct 2 attributes"); + + sai_attribute_t attr3; + sai_attribute_t attr4; + attr3.id = SAI_NEIGHBOR_ENTRY_ATTR_PACKET_ACTION; + attr3.value.s32 = 1; + attr4.id = SAI_NEIGHBOR_ENTRY_ATTR_NO_HOST_ROUTE; + + sai_attribute_t list2[2] = { attr3, attr4 }; + status = g_meta->get(&neighbor_entry, 2, list2); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + remove_switch(switch_id); +} + +TEST(LegacyNeighborEntry, neighbor_entry_flow) +{ + SWSS_LOG_ENTER(); + + clear_local(); + + sai_status_t status; + + sai_object_id_t switch_id = create_switch(); + sai_neighbor_entry_t neighbor_entry; + + sai_mac_t mac = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; + + sai_attribute_t list[4] = { }; + + sai_attribute_t &attr1 = list[0]; + sai_attribute_t &attr2 = list[1]; + sai_attribute_t &attr3 = list[1]; + sai_attribute_t &attr4 = list[1]; + + attr1.id = SAI_NEIGHBOR_ENTRY_ATTR_DST_MAC_ADDRESS; + memcpy(attr1.value.mac, mac, 6); + + attr2.id = SAI_NEIGHBOR_ENTRY_ATTR_PACKET_ACTION; + attr2.value.s32 = SAI_PACKET_ACTION_FORWARD; + + attr3.id = SAI_NEIGHBOR_ENTRY_ATTR_NO_HOST_ROUTE; + attr3.value.booldata = true; + + attr4.id = SAI_NEIGHBOR_ENTRY_ATTR_META_DATA; + attr4.value.u32 = 1; + + sai_object_id_t rif = create_rif(switch_id); + + neighbor_entry.ip_address.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + neighbor_entry.ip_address.addr.ip4 = htonl(0x0a00000f); + neighbor_entry.rif_id = rif; + neighbor_entry.switch_id = switch_id; + + SWSS_LOG_NOTICE("create"); + + SWSS_LOG_NOTICE("correct ipv4"); + status = g_meta->create(&neighbor_entry, 2, list); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("correct ipv4 existing"); + status = g_meta->create(&neighbor_entry, 2, list); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("set"); + status = g_meta->set(&neighbor_entry, &attr1); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("set"); + status = g_meta->set(&neighbor_entry, &attr2); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("set"); + status = g_meta->set(&neighbor_entry, &attr3); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("set"); + status = g_meta->set(&neighbor_entry, &attr4); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("remove"); + status = g_meta->remove(&neighbor_entry); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("remove existing"); + status = g_meta->remove(&neighbor_entry); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + remove_switch(switch_id); +} diff --git a/unittest/meta/TestLegacyOther.cpp b/unittest/meta/TestLegacyOther.cpp new file mode 100644 index 000000000..21f8846ef --- /dev/null +++ b/unittest/meta/TestLegacyOther.cpp @@ -0,0 +1,1038 @@ +#include "TestLegacy.h" +#include "AttrKeyMap.h" + +#include "sai_serialize.h" + +#include +#include + +#include + +#include + +using namespace TestLegacy; +using namespace saimeta; + +// STATIC HELPERS + +static sai_object_id_t create_acl_table( + _In_ sai_object_id_t switch_id) +{ + SWSS_LOG_ENTER(); + + sai_object_id_t at; + + sai_attribute_t attrs[9] = { }; + + attrs[0].id = SAI_ACL_TABLE_ATTR_ACL_STAGE; + attrs[0].value.s32 = SAI_ACL_STAGE_INGRESS; + + auto status = g_meta->create(SAI_OBJECT_TYPE_ACL_TABLE, &at, switch_id, 1, attrs); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + return at; +} + +static sai_object_id_t create_acl_counter( + _In_ sai_object_id_t switch_id) +{ + SWSS_LOG_ENTER(); + + sai_object_id_t ac; + + sai_attribute_t attrs[9] = { }; + + attrs[0].id = SAI_ACL_COUNTER_ATTR_TABLE_ID; + attrs[0].value.oid = create_acl_table(switch_id); + + auto status = g_meta->create(SAI_OBJECT_TYPE_ACL_COUNTER, &ac, switch_id, 1, attrs); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + return ac; +} + +static sai_object_id_t create_policer( + _In_ sai_object_id_t switch_id) +{ + SWSS_LOG_ENTER(); + + sai_object_id_t policer; + + sai_attribute_t attrs[9] = { }; + + attrs[0].id = SAI_POLICER_ATTR_METER_TYPE; + attrs[0].value.s32 = SAI_METER_TYPE_PACKETS; + attrs[1].id = SAI_POLICER_ATTR_MODE; + attrs[1].value.s32 = SAI_POLICER_MODE_SR_TCM; + + auto status = g_meta->create(SAI_OBJECT_TYPE_POLICER, &policer, switch_id, 2, attrs); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + return policer; +} + +static sai_object_id_t create_samplepacket( + _In_ sai_object_id_t switch_id) +{ + SWSS_LOG_ENTER(); + + sai_object_id_t sp; + + sai_attribute_t attrs[9] = { }; + + attrs[0].id = SAI_SAMPLEPACKET_ATTR_SAMPLE_RATE; + attrs[0].value.u32 = 1; + + auto status = g_meta->create(SAI_OBJECT_TYPE_SAMPLEPACKET, &sp, switch_id, 1, attrs); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + return sp; +} + +static sai_object_id_t create_hostif_udt( + _In_ sai_object_id_t switch_id) +{ + SWSS_LOG_ENTER(); + + sai_object_id_t udt; + + sai_attribute_t attrs[9] = { }; + + attrs[0].id = SAI_HOSTIF_USER_DEFINED_TRAP_ATTR_TYPE; + attrs[0].value.s32 = SAI_HOSTIF_USER_DEFINED_TRAP_TYPE_ROUTER; + + auto status = g_meta->create(SAI_OBJECT_TYPE_HOSTIF_USER_DEFINED_TRAP, &udt, switch_id, 1, attrs); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + return udt; +} + +static sai_object_id_t create_ipg( + _In_ sai_object_id_t switch_id) +{ + SWSS_LOG_ENTER(); + + sai_object_id_t ipg; + + sai_attribute_t attrs[9] = { }; + + attrs[0].id = SAI_INGRESS_PRIORITY_GROUP_ATTR_PORT; + attrs[0].value.oid = create_port(switch_id); + attrs[1].id = SAI_INGRESS_PRIORITY_GROUP_ATTR_INDEX; + attrs[1].value.u8 = 0; + + auto status = g_meta->create(SAI_OBJECT_TYPE_INGRESS_PRIORITY_GROUP, &ipg, switch_id, 2, attrs); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + return ipg; +} + +static sai_object_id_t insert_dummy_object( + _In_ sai_object_type_t ot, + _In_ sai_object_id_t switch_id) +{ + SWSS_LOG_ENTER(); + + switch (ot) + { + case SAI_OBJECT_TYPE_PORT: + return create_port(switch_id); + + case SAI_OBJECT_TYPE_ACL_TABLE: + return create_acl_table(switch_id); + + case SAI_OBJECT_TYPE_ACL_COUNTER: + return create_acl_counter(switch_id); + + case SAI_OBJECT_TYPE_POLICER: + return create_policer(switch_id); + + case SAI_OBJECT_TYPE_SAMPLEPACKET: + return create_samplepacket(switch_id); + + case SAI_OBJECT_TYPE_HOSTIF_USER_DEFINED_TRAP: + return create_hostif_udt(switch_id); + + case SAI_OBJECT_TYPE_INGRESS_PRIORITY_GROUP: + return create_ipg(switch_id); + + default: + + SWSS_LOG_THROW("not implemented: %s, FIXME", sai_serialize_object_type(ot).c_str()); + } +} + +static sai_object_id_t create_scheduler_group( + _In_ sai_object_id_t switch_id) +{ + SWSS_LOG_ENTER(); + + sai_object_id_t sg; + + sai_attribute_t attrs[9] = { }; + + attrs[0].id = SAI_SCHEDULER_GROUP_ATTR_PORT_ID; + attrs[0].value.oid = create_port(switch_id); + attrs[1].id = SAI_SCHEDULER_GROUP_ATTR_LEVEL; + attrs[1].value.u8 = 0; + attrs[2].id = SAI_SCHEDULER_GROUP_ATTR_MAX_CHILDS; + attrs[2].value.u8 = 1; + attrs[3].id = SAI_SCHEDULER_GROUP_ATTR_PARENT_NODE; + attrs[3].value.oid = attrs[0].value.oid; + + auto status = g_meta->create(SAI_OBJECT_TYPE_SCHEDULER_GROUP, &sg, switch_id, 4, attrs); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + return sg; +} + +// ACTUAL TESTS + +TEST(Legacy, switch_set) +{ + SWSS_LOG_ENTER(); + + clear_local(); + + sai_status_t status; + sai_attribute_t attr; + + memset(&attr, 0, sizeof(attr)); + + sai_object_id_t switch_id = create_switch(); + + status = g_meta->set(SAI_OBJECT_TYPE_SWITCH, switch_id, NULL); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + status = g_meta->set(SAI_OBJECT_TYPE_SWITCH, switch_id, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + // id outside range + attr.id = -1; + status = g_meta->set(SAI_OBJECT_TYPE_SWITCH, switch_id, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + g_sai->setStatus(SAI_STATUS_FAILURE); + attr.id = SAI_SWITCH_ATTR_PORT_NUMBER; + status = g_meta->set(SAI_OBJECT_TYPE_SWITCH, switch_id, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + g_sai->setStatus(SAI_STATUS_SUCCESS); + + attr.id = SAI_SWITCH_ATTR_PORT_NUMBER; + status = g_meta->set(SAI_OBJECT_TYPE_SWITCH, switch_id, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + attr.id = SAI_SWITCH_ATTR_SWITCHING_MODE; + attr.value.s32 = 0x1000; + status = g_meta->set(SAI_OBJECT_TYPE_SWITCH, switch_id, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + // enum + attr.id = SAI_SWITCH_ATTR_SWITCHING_MODE; + attr.value.s32 = SAI_SWITCH_SWITCHING_MODE_STORE_AND_FORWARD; + status = g_meta->set(SAI_OBJECT_TYPE_SWITCH, switch_id, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + // bool + attr.id = SAI_SWITCH_ATTR_BCAST_CPU_FLOOD_ENABLE; + attr.value.booldata = SAI_SWITCH_SWITCHING_MODE_STORE_AND_FORWARD; + status = g_meta->set(SAI_OBJECT_TYPE_SWITCH, switch_id, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + // mac + sai_mac_t mac = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; + + attr.id = SAI_SWITCH_ATTR_SRC_MAC_ADDRESS; + memcpy(attr.value.mac, mac, sizeof(mac)); + status = g_meta->set(SAI_OBJECT_TYPE_SWITCH, switch_id, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + // uint8 + attr.id = SAI_SWITCH_ATTR_QOS_DEFAULT_TC; + attr.value.u8 = 0x11; + status = g_meta->set(SAI_OBJECT_TYPE_SWITCH, switch_id, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + // object id with not allowed null + + // currently hash is read only + // + // // null oid + + // attr.id = SAI_SWITCH_ATTR_LAG_HASH_IPV6; + // attr.value.oid = SAI_NULL_OBJECT_ID; + // status = g_meta->set(SAI_OBJECT_TYPE_SWITCH, switch_id, &attr); + // EXPECT_NE(SAI_STATUS_SUCCESS, status); + // + // // wrong object type + // attr.id = SAI_SWITCH_ATTR_LAG_HASH_IPV6; + // attr.value.oid = create_dummy_object_id(SAI_OBJECT_TYPE_LAG); + // status = g_meta->set(SAI_OBJECT_TYPE_SWITCH, switch_id, &attr); + // EXPECT_NE(SAI_STATUS_SUCCESS, status); + // + // // valid object (object must exist) + // attr.id = SAI_SWITCH_ATTR_LAG_HASH_IPV6; + // attr.value.oid = create_hash(switch_id); + // + // status = g_meta->set(SAI_OBJECT_TYPE_SWITCH, switch_id, &attr); + // EXPECT_EQ(SAI_STATUS_SUCCESS, status); + // + // EXPECT_TRUE(g_meta->getObjectReferenceCount(attr.value.oid) == 1); + + // object id with allowed null + + // null oid + attr.id = SAI_SWITCH_ATTR_QOS_DOT1P_TO_TC_MAP; + attr.value.oid = SAI_NULL_OBJECT_ID; + status = g_meta->set(SAI_OBJECT_TYPE_SWITCH, switch_id, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + // wrong object + attr.id = SAI_SWITCH_ATTR_QOS_DOT1P_TO_TC_MAP; + status = g_meta->create(SAI_OBJECT_TYPE_LAG, &attr.value.oid, switch_id, 0, NULL); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + status = g_meta->set(SAI_OBJECT_TYPE_SWITCH, switch_id, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + // good object + attr.id = SAI_SWITCH_ATTR_QOS_DOT1P_TO_TC_MAP; + + sai_attribute_t a[2] = { }; + a[0].id = SAI_QOS_MAP_ATTR_TYPE; + a[0].value.s32 = 1; + a[1].id = SAI_QOS_MAP_ATTR_MAP_TO_VALUE_LIST; + status = g_meta->create(SAI_OBJECT_TYPE_QOS_MAP, &attr.value.oid, switch_id, 2, a); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + sai_object_id_t oid = attr.value.oid; + + status = g_meta->set(SAI_OBJECT_TYPE_SWITCH, switch_id, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + EXPECT_TRUE(g_meta->getObjectReferenceCount(attr.value.oid) == 1); + + attr.id = SAI_SWITCH_ATTR_QOS_DOT1P_TO_TC_MAP; + attr.value.oid = SAI_NULL_OBJECT_ID; + status = g_meta->set(SAI_OBJECT_TYPE_SWITCH, switch_id, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + // check if it was decreased + EXPECT_TRUE(g_meta->getObjectReferenceCount(oid) == 0); + + remove_switch(switch_id); +} + +TEST(Legacy, switch_get) +{ + SWSS_LOG_ENTER(); + + clear_local(); + + sai_status_t status; + sai_attribute_t attr; + + memset(&attr, 0, sizeof(attr)); + + sai_object_id_t switch_id = create_switch(); + + attr.id = SAI_SWITCH_ATTR_PORT_NUMBER; + status = g_meta->get(SAI_OBJECT_TYPE_SWITCH, switch_id, 0, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + status = g_meta->get(SAI_OBJECT_TYPE_SWITCH, switch_id, 1000, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + status = g_meta->get(SAI_OBJECT_TYPE_SWITCH, switch_id, 1, NULL); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + status = g_meta->get(SAI_OBJECT_TYPE_SWITCH, switch_id, 1, NULL); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + status = g_meta->get(SAI_OBJECT_TYPE_SWITCH, switch_id, 1, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + attr.id = -1; + status = g_meta->get(SAI_OBJECT_TYPE_SWITCH, switch_id, 1, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + attr.id = SAI_SWITCH_ATTR_PORT_NUMBER; + attr.value.u32 = 0; + status = g_meta->get(SAI_OBJECT_TYPE_SWITCH, switch_id, 1, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + sai_attribute_t attr1; + attr1.id = SAI_SWITCH_ATTR_PORT_NUMBER; + + sai_attribute_t attr2; + attr2.id = SAI_SWITCH_ATTR_DEFAULT_VIRTUAL_ROUTER_ID; + sai_attribute_t list[2] = { attr1, attr2 }; + + status = g_meta->get(SAI_OBJECT_TYPE_SWITCH, switch_id, 2, list); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + remove_switch(switch_id); +} + +TEST(Legacy, serialization_type_vlan_list) +{ + SWSS_LOG_ENTER(); + + clear_local(); + + sai_status_t status; + + SWSS_LOG_NOTICE("create stp"); + sai_object_id_t switch_id = create_switch(); + + sai_object_id_t stp = create_stp(switch_id); + + sai_vlan_id_t list[2] = { 1, 2 }; + + sai_attribute_t attr; + + attr.id = SAI_STP_ATTR_VLAN_LIST; + attr.value.vlanlist.count = 2; + attr.value.vlanlist.list = list; + + SWSS_LOG_NOTICE("set vlan list"); + + status = g_meta->set(SAI_OBJECT_TYPE_STP, stp, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("get vlan list"); + + status = g_meta->get(SAI_OBJECT_TYPE_STP, stp, 1, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("remove stp"); + + status = g_meta->remove(SAI_OBJECT_TYPE_STP, stp); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + remove_switch(switch_id); +} + +TEST(Legacy, serialization_type_bool) +{ + SWSS_LOG_ENTER(); + + clear_local(); + + sai_status_t status; + + sai_object_id_t vr; + + SWSS_LOG_NOTICE("create stp"); + sai_object_id_t switch_id = create_switch(); + + sai_attribute_t attr; + + attr.id = SAI_VIRTUAL_ROUTER_ATTR_ADMIN_V4_STATE; + attr.value.booldata = true; + + status = g_meta->create(SAI_OBJECT_TYPE_VIRTUAL_ROUTER, &vr, switch_id, 1, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("set bool"); + + status = g_meta->set(SAI_OBJECT_TYPE_VIRTUAL_ROUTER, vr, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("get bool"); + + status = g_meta->get(SAI_OBJECT_TYPE_VIRTUAL_ROUTER, vr, 1, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("remove vr"); + + status = g_meta->remove(SAI_OBJECT_TYPE_VIRTUAL_ROUTER, vr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + remove_switch(switch_id); +} + +TEST(Legacy, serialization_type_char) +{ + SWSS_LOG_ENTER(); + + clear_local(); + + sai_status_t status; + + sai_object_id_t hostif; + + SWSS_LOG_NOTICE("create port"); + sai_object_id_t switch_id = create_switch(); + + sai_object_id_t port = create_port(switch_id); + + sai_attribute_t attr, attr2, attr3; + + attr.id = SAI_HOSTIF_ATTR_TYPE; + attr.value.s32 = SAI_HOSTIF_TYPE_NETDEV; + + attr2.id = SAI_HOSTIF_ATTR_OBJ_ID; + attr2.value.oid = port; + + attr3.id = SAI_HOSTIF_ATTR_NAME; + + memcpy(attr3.value.chardata, "foo", sizeof("foo")); + + sai_attribute_t list[3] = { attr, attr2, attr3 }; + + // TODO we need to support conditions here + + SWSS_LOG_NOTICE("create hostif"); + + status = g_meta->create(SAI_OBJECT_TYPE_HOSTIF, &hostif, switch_id, 3, list); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("set char"); + + status = g_meta->set(SAI_OBJECT_TYPE_HOSTIF, hostif, &attr3); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("get char"); + + status = g_meta->get(SAI_OBJECT_TYPE_HOSTIF, hostif, 1, &attr3); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("remove hostif"); + + status = g_meta->remove(SAI_OBJECT_TYPE_HOSTIF, hostif); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + attr.id = SAI_HOSTIF_ATTR_TYPE; + attr.value.s32 = SAI_HOSTIF_TYPE_FD; + + sai_attribute_t list2[1] = { attr }; + + SWSS_LOG_NOTICE("create hostif with non mandatory"); + status = g_meta->create(SAI_OBJECT_TYPE_HOSTIF, &hostif, switch_id, 1, list2); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + // TODO this test should pass, we are doing query here for conditional + // attribute, where condition is not met so this attribute will not be used, so + // metadata should figure out that we can't query this attribute, but there is + // a problem with internal existing objects, since we don't have their values + // then we we can't tell whether attribute was passed or not, we need to get + // switch discovered objects and attributes and populate local db then we need + // to update metadata condition in meta_generic_validation_get method where we + // check if attribute is conditional + // + // SWSS_LOG_NOTICE("get char"); + // + // status = g_meta->get(SAI_OBJECT_TYPE_HOSTIF, hostif, 1, &attr2); + // EXPECT_NE(SAI_STATUS_SUCCESS, status); + + attr.id = SAI_HOSTIF_ATTR_TYPE; + attr.value.s32 = SAI_HOSTIF_TYPE_NETDEV; + + sai_attribute_t list3[1] = { attr }; + + SWSS_LOG_NOTICE("create hostif with mandatory missing"); + status = g_meta->create(SAI_OBJECT_TYPE_HOSTIF, &hostif, switch_id, 1, list3); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + remove_switch(switch_id); +} + +TEST(Legacy, serialization_type_int32_list) +{ + SWSS_LOG_ENTER(); + + clear_local(); + + sai_status_t status; + + sai_object_id_t hash; + + sai_attribute_t attr; + + SWSS_LOG_NOTICE("create hash"); + sai_object_id_t switch_id = create_switch(); + + int32_t list[2] = { SAI_NATIVE_HASH_FIELD_SRC_IP, SAI_NATIVE_HASH_FIELD_VLAN_ID }; + + attr.id = SAI_HASH_ATTR_NATIVE_HASH_FIELD_LIST; + attr.value.s32list.count = 2; + attr.value.s32list.list = list; + + status = g_meta->create(SAI_OBJECT_TYPE_HASH, &hash, switch_id, 1, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("set hash"); + + status = g_meta->set(SAI_OBJECT_TYPE_HASH, hash, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("get hash"); + + status = g_meta->get(SAI_OBJECT_TYPE_HASH, hash, 1, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("remove hash"); + + status = g_meta->remove(SAI_OBJECT_TYPE_HASH, hash); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + remove_switch(switch_id); +} + +TEST(Legacy, test_serialization_type_uint32_list) +{ + SWSS_LOG_ENTER(); + + clear_local(); + + sai_status_t status; + + sai_object_id_t hash; + + sai_attribute_t attr; + + SWSS_LOG_NOTICE("create hash"); + sai_object_id_t switch_id = create_switch(); + + int32_t list[2] = { SAI_NATIVE_HASH_FIELD_SRC_IP, SAI_NATIVE_HASH_FIELD_VLAN_ID }; + + attr.id = SAI_HASH_ATTR_NATIVE_HASH_FIELD_LIST; + attr.value.s32list.count = 2; + attr.value.s32list.list = list; + + status = g_meta->create(SAI_OBJECT_TYPE_HASH, &hash, switch_id, 1, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("set hash"); + + status = g_meta->set(SAI_OBJECT_TYPE_HASH, hash, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("get hash"); + + status = g_meta->get(SAI_OBJECT_TYPE_HASH, hash, 1, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("remove hash"); + + status = g_meta->remove(SAI_OBJECT_TYPE_HASH, hash); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + remove_switch(switch_id); +} + +TEST(Legacy, mask) +{ + SWSS_LOG_ENTER(); + + sai_ip6_t ip6mask1 = {0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff, 0xff,0xff,0xff,0xff,0x00}; + sai_ip6_t ip6mask2 = {0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff, 0xff,0xff,0xff,0xff,0xff}; + sai_ip6_t ip6mask3 = {0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00}; + sai_ip6_t ip6mask4 = {0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff, 0xff,0xff,0xff,0xff,0xfe}; + sai_ip6_t ip6mask5 = {0x80, 0x00, 0x00, 0x00,0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00}; + + sai_ip6_t ip6mask6 = {0x01, 0x00, 0x00, 0x00,0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00}; + sai_ip6_t ip6mask7 = {0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff, 0xff,0xff,0xff,0xff,0x8f}; + sai_ip6_t ip6mask8 = {0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff, 0xff,0xff,0xff,0xff,0x8f}; + sai_ip6_t ip6mask9 = {0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff,0xf1, 0xff, 0xff, 0xff, 0xff,0xff,0xff,0xff,0xff}; + + EXPECT_TRUE(Meta::is_ipv6_mask_valid(ip6mask1)); + EXPECT_TRUE(Meta::is_ipv6_mask_valid(ip6mask2)); + EXPECT_TRUE(Meta::is_ipv6_mask_valid(ip6mask3)); + EXPECT_TRUE(Meta::is_ipv6_mask_valid(ip6mask4)); + EXPECT_TRUE(Meta::is_ipv6_mask_valid(ip6mask5)); + + EXPECT_TRUE(!Meta::is_ipv6_mask_valid(ip6mask6)); + EXPECT_TRUE(!Meta::is_ipv6_mask_valid(ip6mask7)); + EXPECT_TRUE(!Meta::is_ipv6_mask_valid(ip6mask8)); + EXPECT_TRUE(!Meta::is_ipv6_mask_valid(ip6mask9)); +} + +TEST(Legacy, acl_entry_field_and_action) +{ + SWSS_LOG_ENTER(); + + clear_local(); + + sai_object_id_t switch_id = create_switch(); + sai_status_t status; + + sai_object_id_t aclentry; + + int32_t ids[] = { + SAI_ACL_ENTRY_ATTR_TABLE_ID, + SAI_ACL_ENTRY_ATTR_PRIORITY, + SAI_ACL_ENTRY_ATTR_FIELD_SRC_IPV6, + SAI_ACL_ENTRY_ATTR_FIELD_DST_IPV6, + SAI_ACL_ENTRY_ATTR_FIELD_SRC_MAC, + SAI_ACL_ENTRY_ATTR_FIELD_DST_MAC, + SAI_ACL_ENTRY_ATTR_FIELD_SRC_IP, + SAI_ACL_ENTRY_ATTR_FIELD_DST_IP, + SAI_ACL_ENTRY_ATTR_FIELD_IN_PORTS, + SAI_ACL_ENTRY_ATTR_FIELD_OUT_PORTS, + SAI_ACL_ENTRY_ATTR_FIELD_IN_PORT, + SAI_ACL_ENTRY_ATTR_FIELD_OUT_PORT, + SAI_ACL_ENTRY_ATTR_FIELD_SRC_PORT, + SAI_ACL_ENTRY_ATTR_FIELD_OUTER_VLAN_ID, + SAI_ACL_ENTRY_ATTR_FIELD_OUTER_VLAN_PRI, + SAI_ACL_ENTRY_ATTR_FIELD_OUTER_VLAN_CFI, + SAI_ACL_ENTRY_ATTR_FIELD_INNER_VLAN_ID, + SAI_ACL_ENTRY_ATTR_FIELD_INNER_VLAN_PRI, + SAI_ACL_ENTRY_ATTR_FIELD_INNER_VLAN_CFI, + SAI_ACL_ENTRY_ATTR_FIELD_L4_SRC_PORT, + SAI_ACL_ENTRY_ATTR_FIELD_L4_DST_PORT, + SAI_ACL_ENTRY_ATTR_FIELD_ETHER_TYPE, + SAI_ACL_ENTRY_ATTR_FIELD_IP_PROTOCOL, + SAI_ACL_ENTRY_ATTR_FIELD_DSCP, + SAI_ACL_ENTRY_ATTR_FIELD_ECN, + SAI_ACL_ENTRY_ATTR_FIELD_TTL, + SAI_ACL_ENTRY_ATTR_FIELD_TOS, + SAI_ACL_ENTRY_ATTR_FIELD_IP_FLAGS, + SAI_ACL_ENTRY_ATTR_FIELD_TCP_FLAGS, + SAI_ACL_ENTRY_ATTR_FIELD_ACL_IP_FRAG, + SAI_ACL_ENTRY_ATTR_FIELD_IPV6_FLOW_LABEL, + SAI_ACL_ENTRY_ATTR_FIELD_TC, + SAI_ACL_ENTRY_ATTR_FIELD_ICMP_TYPE, + SAI_ACL_ENTRY_ATTR_FIELD_ICMP_CODE, + SAI_ACL_ENTRY_ATTR_FIELD_FDB_DST_USER_META, + SAI_ACL_ENTRY_ATTR_FIELD_ROUTE_DST_USER_META, + SAI_ACL_ENTRY_ATTR_FIELD_NEIGHBOR_DST_USER_META, + SAI_ACL_ENTRY_ATTR_FIELD_PORT_USER_META, + SAI_ACL_ENTRY_ATTR_FIELD_VLAN_USER_META, + SAI_ACL_ENTRY_ATTR_FIELD_ACL_USER_META, + SAI_ACL_ENTRY_ATTR_FIELD_FDB_NPU_META_DST_HIT, + SAI_ACL_ENTRY_ATTR_FIELD_NEIGHBOR_NPU_META_DST_HIT, + SAI_ACL_ENTRY_ATTR_FIELD_ROUTE_NPU_META_DST_HIT, + SAI_ACL_ENTRY_ATTR_ACTION_REDIRECT, + //SAI_ACL_ENTRY_ATTR_ACTION_REDIRECT_LIST, + SAI_ACL_ENTRY_ATTR_ACTION_PACKET_ACTION, + SAI_ACL_ENTRY_ATTR_ACTION_FLOOD, + SAI_ACL_ENTRY_ATTR_ACTION_COUNTER, + SAI_ACL_ENTRY_ATTR_ACTION_MIRROR_INGRESS, + SAI_ACL_ENTRY_ATTR_ACTION_MIRROR_EGRESS, + SAI_ACL_ENTRY_ATTR_ACTION_SET_POLICER, + SAI_ACL_ENTRY_ATTR_ACTION_DECREMENT_TTL, + SAI_ACL_ENTRY_ATTR_ACTION_SET_TC, + SAI_ACL_ENTRY_ATTR_ACTION_SET_PACKET_COLOR, + SAI_ACL_ENTRY_ATTR_ACTION_SET_INNER_VLAN_ID, + SAI_ACL_ENTRY_ATTR_ACTION_SET_INNER_VLAN_PRI, + SAI_ACL_ENTRY_ATTR_ACTION_SET_OUTER_VLAN_ID, + SAI_ACL_ENTRY_ATTR_ACTION_SET_OUTER_VLAN_PRI, + SAI_ACL_ENTRY_ATTR_ACTION_SET_SRC_MAC, + SAI_ACL_ENTRY_ATTR_ACTION_SET_DST_MAC, + SAI_ACL_ENTRY_ATTR_ACTION_SET_SRC_IP, + SAI_ACL_ENTRY_ATTR_ACTION_SET_DST_IP, + SAI_ACL_ENTRY_ATTR_ACTION_SET_SRC_IPV6, + SAI_ACL_ENTRY_ATTR_ACTION_SET_DST_IPV6, + SAI_ACL_ENTRY_ATTR_ACTION_SET_DSCP, + SAI_ACL_ENTRY_ATTR_ACTION_SET_ECN, + SAI_ACL_ENTRY_ATTR_ACTION_SET_L4_SRC_PORT, + SAI_ACL_ENTRY_ATTR_ACTION_SET_L4_DST_PORT, + SAI_ACL_ENTRY_ATTR_ACTION_INGRESS_SAMPLEPACKET_ENABLE, + SAI_ACL_ENTRY_ATTR_ACTION_EGRESS_SAMPLEPACKET_ENABLE, + SAI_ACL_ENTRY_ATTR_ACTION_SET_ACL_META_DATA, + SAI_ACL_ENTRY_ATTR_ACTION_EGRESS_BLOCK_PORT_LIST, + SAI_ACL_ENTRY_ATTR_ACTION_SET_USER_TRAP_ID, + }; + + std::vector vattrs; + + // all lists are empty we need info if that is possible + + for (uint32_t i = 0; i < sizeof(ids)/sizeof(int32_t); ++i) + { + sai_attribute_t attr; + + memset(&attr,0,sizeof(attr)); + + attr.value.aclfield.enable = true; + attr.value.aclaction.enable = true; + + attr.id = ids[i]; + + if (attr.id == SAI_ACL_ENTRY_ATTR_TABLE_ID) + attr.value.oid = insert_dummy_object(SAI_OBJECT_TYPE_ACL_TABLE,switch_id); + + if (attr.id == SAI_ACL_ENTRY_ATTR_FIELD_IN_PORT) + attr.value.aclfield.data.oid = insert_dummy_object(SAI_OBJECT_TYPE_PORT,switch_id); + + if (attr.id == SAI_ACL_ENTRY_ATTR_FIELD_OUT_PORT) + attr.value.aclfield.data.oid = insert_dummy_object(SAI_OBJECT_TYPE_PORT,switch_id); + + if (attr.id == SAI_ACL_ENTRY_ATTR_FIELD_SRC_PORT) + attr.value.aclfield.data.oid = insert_dummy_object(SAI_OBJECT_TYPE_PORT,switch_id); + + if (attr.id == SAI_ACL_ENTRY_ATTR_ACTION_REDIRECT) + attr.value.aclaction.parameter.oid = insert_dummy_object(SAI_OBJECT_TYPE_PORT,switch_id); + + if (attr.id == SAI_ACL_ENTRY_ATTR_ACTION_COUNTER) + attr.value.aclaction.parameter.oid = insert_dummy_object(SAI_OBJECT_TYPE_ACL_COUNTER,switch_id); + + if (attr.id == SAI_ACL_ENTRY_ATTR_ACTION_SET_POLICER) + attr.value.aclaction.parameter.oid = insert_dummy_object(SAI_OBJECT_TYPE_POLICER,switch_id); + + if (attr.id == SAI_ACL_ENTRY_ATTR_ACTION_INGRESS_SAMPLEPACKET_ENABLE) + attr.value.aclaction.parameter.oid = insert_dummy_object(SAI_OBJECT_TYPE_SAMPLEPACKET,switch_id); + + if (attr.id == SAI_ACL_ENTRY_ATTR_ACTION_EGRESS_SAMPLEPACKET_ENABLE) + attr.value.aclaction.parameter.oid = insert_dummy_object(SAI_OBJECT_TYPE_SAMPLEPACKET,switch_id); + + if (attr.id == SAI_ACL_ENTRY_ATTR_ACTION_SET_USER_TRAP_ID) + attr.value.aclaction.parameter.oid = insert_dummy_object(SAI_OBJECT_TYPE_HOSTIF_USER_DEFINED_TRAP,switch_id); + + if (attr.id == SAI_ACL_ENTRY_ATTR_ACTION_REDIRECT_LIST) + { + sai_object_id_t list[1]; + + list[0] = insert_dummy_object(SAI_OBJECT_TYPE_QUEUE,switch_id); + + SWSS_LOG_NOTICE("0x%" PRIx64, list[0]); + + attr.value.aclaction.parameter.objlist.count = 1; + attr.value.aclaction.parameter.objlist.list = list; + } + + vattrs.push_back(attr); + } + + SWSS_LOG_NOTICE("create acl entry"); + + status = g_meta->create(SAI_OBJECT_TYPE_ACL_ENTRY, &aclentry, switch_id, (uint32_t)vattrs.size(), vattrs.data()); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + for (uint32_t i = 0; i < sizeof(ids)/sizeof(int32_t); ++i) + { + if (vattrs[i].id == SAI_ACL_ENTRY_ATTR_TABLE_ID) + continue; + + auto m = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_ACL_ENTRY, vattrs[i].id); + + SWSS_LOG_NOTICE("set aclentry %u %s", i, m->attridname); + + status = g_meta->set(SAI_OBJECT_TYPE_ACL_ENTRY, aclentry, &vattrs[i]); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + } + + SWSS_LOG_NOTICE("get aclentry"); + + status = g_meta->get(SAI_OBJECT_TYPE_ACL_ENTRY, aclentry, (uint32_t)vattrs.size(), vattrs.data()); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("remove aclentry"); + + status = g_meta->remove(SAI_OBJECT_TYPE_ACL_ENTRY, aclentry); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + remove_switch(switch_id); +} + +TEST(Legacy, construct_key) +{ + SWSS_LOG_ENTER(); + + clear_local(); + + sai_attribute_t attr; + + uint32_t list[4] = {1,2,3,4}; + + attr.id = SAI_PORT_ATTR_HW_LANE_LIST; + attr.value.u32list.count = 4; + attr.value.u32list.list = list; + + sai_object_meta_key_t meta_key; + + meta_key.objecttype = SAI_OBJECT_TYPE_PORT; + + sai_object_id_t switchId = 0x21000000000000; + + std::string key = AttrKeyMap::constructKey(switchId, meta_key, 1, &attr); + + SWSS_LOG_NOTICE("constructed key: %s", key.c_str()); + + EXPECT_TRUE(key == "oid:0x21000000000000;SAI_PORT_ATTR_HW_LANE_LIST:1,2,3,4;"); +} + +TEST(Legacy, queue_create) +{ + SWSS_LOG_ENTER(); + + clear_local(); + + sai_object_id_t switch_id = create_switch(); + + sai_status_t status; + sai_object_id_t queue; + + sai_attribute_t attr1; + sai_attribute_t attr2; + sai_attribute_t attr3; + sai_attribute_t attr4; + + attr1.id = SAI_QUEUE_ATTR_TYPE; + attr1.value.s32 = SAI_QUEUE_TYPE_UNICAST; + + attr2.id = SAI_QUEUE_ATTR_INDEX; + attr2.value.u8 = 7; + + attr3.id = SAI_QUEUE_ATTR_PORT; + attr3.value.oid = create_port(switch_id); + + attr4.id = SAI_QUEUE_ATTR_PARENT_SCHEDULER_NODE; + attr4.value.oid = create_scheduler_group(switch_id); + + sai_attribute_t list[4] = { attr1, attr2, attr3, attr4 }; + + SWSS_LOG_NOTICE("create tests"); + + SWSS_LOG_NOTICE("create queue"); + status = g_meta->create(SAI_OBJECT_TYPE_QUEUE, &queue, switch_id, 4, list); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("create queue but key exists"); + status = g_meta->create(SAI_OBJECT_TYPE_QUEUE, &queue, switch_id, 4, list); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("remove queue"); + status = g_meta->remove(SAI_OBJECT_TYPE_QUEUE, queue); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("create queue"); + status = g_meta->create(SAI_OBJECT_TYPE_QUEUE, &queue, switch_id, 4, list); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + remove_switch(switch_id); +} + +TEST(Legacy, null_list) +{ + SWSS_LOG_ENTER(); + + clear_local(); + + sai_status_t status; + + sai_object_id_t hash; + + sai_attribute_t attr; + + int32_t list[2] = { SAI_NATIVE_HASH_FIELD_SRC_IP, SAI_NATIVE_HASH_FIELD_VLAN_ID }; + + attr.id = SAI_HASH_ATTR_NATIVE_HASH_FIELD_LIST; + attr.value.s32list.count = 0; + attr.value.s32list.list = list; + sai_object_id_t switch_id = create_switch(); + + SWSS_LOG_NOTICE("0 count, not null list"); + status = g_meta->create(SAI_OBJECT_TYPE_HASH, &hash, switch_id, 1, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + attr.value.s32list.list = NULL; + + SWSS_LOG_NOTICE("0 count, null list"); + status = g_meta->create(SAI_OBJECT_TYPE_HASH, &hash, switch_id, 1, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + remove_switch(switch_id); +} + +TEST(Legacy, priority_group) +{ + SWSS_LOG_ENTER(); + + clear_local(); + + sai_object_id_t switch_id = create_switch(); + + sai_status_t status; + + sai_attribute_t attr; + + sai_object_id_t pg = insert_dummy_object(SAI_OBJECT_TYPE_INGRESS_PRIORITY_GROUP, switch_id); + + SWSS_LOG_NOTICE("set SAI_INGRESS_PRIORITY_GROUP_ATTR_BUFFER_PROFILE attr"); + + attr.id = SAI_INGRESS_PRIORITY_GROUP_ATTR_BUFFER_PROFILE; + attr.value.oid = SAI_NULL_OBJECT_ID; + status = g_meta->set(SAI_OBJECT_TYPE_INGRESS_PRIORITY_GROUP, pg, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + remove_switch(switch_id); +} + +TEST(Legacy, bulk_route_entry_create) +{ + SWSS_LOG_ENTER(); + + clear_local(); + + int object_count = 1000; + + std::vector routes; + std::vector attr_counts; + std::vector attr_lists; + std::vector statuses(object_count); + + sai_object_id_t switch_id = create_switch(); + + sai_object_id_t vr = create_virtual_router(switch_id); + sai_object_id_t hop = create_next_hop(switch_id); + + sai_attribute_t attr; + + attr.id = SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID; + attr.value.oid = hop; + + int n = 100; + + for (int i = 0; i < object_count * n; i++) + { + sai_route_entry_t re; + + memset(re.destination.mask.ip6, 0xff, sizeof(re.destination.mask.ip6)); + re.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + re.destination.addr.ip4 = htonl(0x0a00000f + i); + re.destination.mask.ip4 = htonl(0xffffff00); + re.vr_id = vr; + re.switch_id = switch_id; + + routes.push_back(re); + + attr_counts.push_back(1); + + // since we use the same attribute every where we can get away with this + + attr_lists.push_back(&attr); + } + + auto start = std::chrono::high_resolution_clock::now(); + + if (getenv("TEST_NO_PERF")) + { + object_count = 10; + + std::cout << "disabling performance tests" << std::endl; + } + + + for (int i = 0; i < n; i++) + { + auto status = g_meta->bulkCreate( + object_count, + routes.data() + i * object_count, + attr_counts.data(), + attr_lists.data(), + SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR, + statuses.data()); + + EXPECT_EQ(status, SAI_STATUS_SUCCESS); + } + + auto end = std::chrono::high_resolution_clock::now(); + auto time = end - start; + auto us = std::chrono::duration_cast(time); + + std::cout << "ms: " << (double)us.count()/1000 << " / " << n << "/" << object_count << std::endl; +} + diff --git a/unittest/meta/TestLegacyRouteEntry.cpp b/unittest/meta/TestLegacyRouteEntry.cpp new file mode 100644 index 000000000..9c5e91cca --- /dev/null +++ b/unittest/meta/TestLegacyRouteEntry.cpp @@ -0,0 +1,544 @@ +#include "TestLegacy.h" + +#include + +#include + +#include + +using namespace TestLegacy; + +// STATIC HELPERS + +// ACTUAL TESTS + +TEST(LegacyRouteEntry, route_entry_create) +{ + SWSS_LOG_ENTER(); + + clear_local(); + + sai_status_t status; + sai_attribute_t attr; + + sai_object_id_t switch_id = create_switch(); + sai_route_entry_t route_entry; + + sai_object_id_t vr = create_virtual_router(switch_id); + + sai_object_id_t hop = create_next_hop(switch_id); + + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + route_entry.destination.addr.ip4 = htonl(0x0a00000f); + route_entry.destination.mask.ip4 = htonl(0xffffff00); + route_entry.vr_id = vr; + route_entry.switch_id = switch_id; + + SWSS_LOG_NOTICE("create tests"); + + // commented out as there is no mandatory attribute + // SWSS_LOG_NOTICE("zero attribute count (but there are mandatory attributes)"); + // attr.id = SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID; + // status = g_meta->create(&route_entry, 0, &attr); + // EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("attr is null"); + status = g_meta->create(&route_entry, 1, NULL); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("route entry is null"); + status = g_meta->create((sai_route_entry_t*)NULL, 1, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + sai_attribute_t list[3] = { }; + + sai_attribute_t &attr1 = list[0]; + sai_attribute_t &attr2 = list[1]; + sai_attribute_t &attr3 = list[2]; + + attr1.id = SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID; + attr1.value.oid = hop; + + attr2.id = SAI_ROUTE_ENTRY_ATTR_PACKET_ACTION; + attr2.value.s32 = SAI_PACKET_ACTION_FORWARD; + + attr3.id = -1; + + SWSS_LOG_NOTICE("invalid attribute id"); + status = g_meta->create(&route_entry, 3, list); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + attr2.value.s32 = SAI_PACKET_ACTION_FORWARD + 0x100; + SWSS_LOG_NOTICE("invalid attribute value on enum"); + status = g_meta->create(&route_entry, 2, list); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + attr2.value.s32 = SAI_PACKET_ACTION_FORWARD; + + sai_attribute_t list2[4] = { attr1, attr2, attr2 }; + + SWSS_LOG_NOTICE("repeated attribute id"); + status = g_meta->create(&route_entry, 3, list2); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("wrong object type"); + attr1.value.oid = create_dummy_object_id(SAI_OBJECT_TYPE_HASH,switch_id); + status = g_meta->create(&route_entry, 2, list); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("non existing object"); + attr1.value.oid = create_dummy_object_id(SAI_OBJECT_TYPE_NEXT_HOP,switch_id); + status = g_meta->create(&route_entry, 2, list); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + int fam = 10; + attr1.value.oid = hop; + route_entry.destination.addr_family = (sai_ip_addr_family_t)fam; + + SWSS_LOG_NOTICE("wrong address family"); + status = g_meta->create(&route_entry, 2, list); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("correct ipv4"); + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + status = g_meta->create(&route_entry, 2, list); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + sai_ip6_t ip62 = {0x00, 0x11, 0x22, 0x33,0x44, 0x55, 0x66,0x77, 0x88, 0x99, 0xaa, 0xbb,0xcc,0xdd,0xee,0x99}; + memcpy(route_entry.destination.addr.ip6, ip62, 16); + + sai_ip6_t ip6mask2 = {0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff, 0xff,0xff,0xff,0xf7,0x00}; + memcpy(route_entry.destination.mask.ip6, ip6mask2, 16); + + SWSS_LOG_NOTICE("invalid mask"); + status = g_meta->create(&route_entry, 2, list); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + sai_ip6_t ip6 = {0x00, 0x11, 0x22, 0x33,0x44, 0x55, 0x66,0x77, 0x88, 0x99, 0xaa, 0xbb,0xcc,0xdd,0xee,0xff}; + memcpy(route_entry.destination.addr.ip6, ip6, 16); + + sai_ip6_t ip6mask = {0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff, 0xff,0xff,0xff,0xff,0x00}; + memcpy(route_entry.destination.mask.ip6, ip6mask, 16); + + SWSS_LOG_NOTICE("correct ipv6"); + status = g_meta->create(&route_entry, 2, list); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("already exists"); + status = g_meta->create(&route_entry, 2, list); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + remove_switch(switch_id); +} + +TEST(LegacyRouteEntry, route_entry_remove) +{ + SWSS_LOG_ENTER(); + + clear_local(); + + sai_status_t status; + sai_object_id_t switch_id = create_switch(); + + sai_route_entry_t route_entry; + + sai_object_id_t vr = create_virtual_router(switch_id); + sai_object_id_t hop = create_next_hop(switch_id); + + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + route_entry.destination.addr.ip4 = htonl(0x0a00000f); + route_entry.destination.mask.ip4 = htonl(0xffffff00); + route_entry.vr_id = vr; + route_entry.switch_id = switch_id; + + SWSS_LOG_NOTICE("create tests"); + + sai_attribute_t list[3] = { }; + + sai_attribute_t &attr1 = list[0]; + sai_attribute_t &attr2 = list[1]; + + attr1.id = SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID; + attr1.value.oid = hop; + + attr2.id = SAI_ROUTE_ENTRY_ATTR_PACKET_ACTION; + attr2.value.s32 = SAI_PACKET_ACTION_FORWARD; + + SWSS_LOG_NOTICE("correct ipv4"); + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + status = g_meta->create(&route_entry, 2, list); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + sai_ip6_t ip6 = {0x00, 0x11, 0x22, 0x33,0x44, 0x55, 0x66,0x77, 0x88, 0x99, 0xaa, 0xbb,0xcc,0xdd,0xee,0xff}; + memcpy(route_entry.destination.addr.ip6, ip6, 16); + + sai_ip6_t ip6mask = {0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff, 0xff,0xff,0xff,0xff,0x00}; + memcpy(route_entry.destination.mask.ip6, ip6mask, 16); + + SWSS_LOG_NOTICE("correct ipv6"); + status = g_meta->create(&route_entry, 2, list); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("remove tests"); + + SWSS_LOG_NOTICE("route_entry is null"); + status = g_meta->remove((sai_route_entry_t*)NULL); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + route_entry.vr_id = SAI_NULL_OBJECT_ID; + + SWSS_LOG_NOTICE("invalid object id null"); + status = g_meta->remove(&route_entry); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + route_entry.vr_id = create_dummy_object_id(SAI_OBJECT_TYPE_HASH,switch_id); + + SWSS_LOG_NOTICE("invalid object id hash"); + status = g_meta->remove(&route_entry); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + route_entry.vr_id = create_dummy_object_id(SAI_OBJECT_TYPE_VIRTUAL_ROUTER,switch_id); + + SWSS_LOG_NOTICE("invalid object id router"); + status = g_meta->remove(&route_entry); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + route_entry.vr_id = vr; + + sai_object_meta_key_t key = { .objecttype = SAI_OBJECT_TYPE_ROUTE_ENTRY, .objectkey = { .key = { .route_entry = route_entry } } }; + + EXPECT_TRUE(g_meta->objectExists(key)); + + SWSS_LOG_NOTICE("success"); + status = g_meta->remove(&route_entry); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + EXPECT_TRUE(!g_meta->objectExists(key)); + + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + route_entry.destination.addr.ip4 = htonl(0x0a00000f); + route_entry.destination.mask.ip4 = htonl(0xffffff00); + + SWSS_LOG_NOTICE("success"); + status = g_meta->remove(&route_entry); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + remove_switch(switch_id); +} + +TEST(LegacyRouteEntry, route_entry_set) +{ + SWSS_LOG_ENTER(); + + clear_local(); + + sai_status_t status; + sai_attribute_t attr; + sai_object_id_t switch_id = create_switch(); + + memset(&attr, 0, sizeof(attr)); + + sai_route_entry_t route_entry; + + sai_object_id_t vr = create_virtual_router(switch_id); + sai_object_id_t hop = create_next_hop(switch_id); + + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + route_entry.destination.addr.ip4 = htonl(0x0a00000f); + route_entry.destination.mask.ip4 = htonl(0xffffff00); + route_entry.vr_id = vr; + route_entry.switch_id = switch_id; + + SWSS_LOG_NOTICE("create tests"); + + sai_attribute_t list[3] = { }; + + sai_attribute_t &attr1 = list[0]; + sai_attribute_t &attr2 = list[1]; + + attr1.id = SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID; + attr1.value.oid = hop; + + attr2.id = SAI_ROUTE_ENTRY_ATTR_PACKET_ACTION; + attr2.value.s32 = SAI_PACKET_ACTION_FORWARD; + + SWSS_LOG_NOTICE("correct ipv4"); + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + status = g_meta->create(&route_entry, 2, list); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + sai_ip6_t ip6 = {0x00, 0x11, 0x22, 0x33,0x44, 0x55, 0x66,0x77, 0x88, 0x99, 0xaa, 0xbb,0xcc,0xdd,0xee,0xff}; + memcpy(route_entry.destination.addr.ip6, ip6, 16); + + sai_ip6_t ip6mask = {0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff, 0xff,0xff,0xff,0xff,0x00}; + memcpy(route_entry.destination.mask.ip6, ip6mask, 16); + + SWSS_LOG_NOTICE("correct ipv6"); + status = g_meta->create(&route_entry, 2, list); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("set tests"); + + SWSS_LOG_NOTICE("attr is null"); + status = g_meta->set(&route_entry, NULL); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("route entry is null"); + status = g_meta->set((sai_route_entry_t*)NULL, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("setting invalid attrib id"); + attr.id = -1; + status = g_meta->set(&route_entry, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("value outside range"); + attr.id = SAI_ROUTE_ENTRY_ATTR_PACKET_ACTION; + attr.value.s32 = 0x100; + status = g_meta->set(&route_entry, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("correct packet action"); + attr.id = SAI_ROUTE_ENTRY_ATTR_PACKET_ACTION; + attr.value.s32 = SAI_PACKET_ACTION_DROP; + status = g_meta->set(&route_entry, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("correct next hop"); + attr.id = SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID; + attr.value.oid = hop; + status = g_meta->set(&route_entry, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("correct metadata"); + attr.id = SAI_ROUTE_ENTRY_ATTR_META_DATA; + attr.value.u32 = 0x12345678; + status = g_meta->set(&route_entry, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + remove_switch(switch_id); +} + +TEST(LegacyRouteEntry, route_entry_get) +{ + SWSS_LOG_ENTER(); + + clear_local(); + + sai_status_t status; + sai_attribute_t attr; + sai_object_id_t switch_id = create_switch(); + + memset(&attr, 0, sizeof(attr)); + + sai_route_entry_t route_entry; + + sai_object_id_t vr = create_virtual_router(switch_id); + sai_object_id_t hop = create_next_hop(switch_id); + + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + route_entry.destination.addr.ip4 = htonl(0x0a00000f); + route_entry.destination.mask.ip4 = htonl(0xffffff00); + route_entry.vr_id = vr; + route_entry.switch_id = switch_id; + + SWSS_LOG_NOTICE("create tests"); + + sai_attribute_t list[3] = { }; + + sai_attribute_t &attr1 = list[0]; + sai_attribute_t &attr2 = list[1]; + + attr1.id = SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID; + attr1.value.oid = hop; + + attr2.id = SAI_ROUTE_ENTRY_ATTR_PACKET_ACTION; + attr2.value.s32 = SAI_PACKET_ACTION_FORWARD; + + SWSS_LOG_NOTICE("correct ipv4"); + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + status = g_meta->create(&route_entry, 2, list); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + sai_ip6_t ip6 = {0x00, 0x11, 0x22, 0x33,0x44, 0x55, 0x66,0x77, 0x88, 0x99, 0xaa, 0xbb,0xcc,0xdd,0xee,0xff}; + memcpy(route_entry.destination.addr.ip6, ip6, 16); + + sai_ip6_t ip6mask = {0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff, 0xff,0xff,0xff,0xff,0x00}; + memcpy(route_entry.destination.mask.ip6, ip6mask, 16); + + SWSS_LOG_NOTICE("correct ipv6"); + status = g_meta->create(&route_entry, 2, list); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("zero attribute count"); + attr.id = SAI_ROUTE_ENTRY_ATTR_PACKET_ACTION; + status = g_meta->get(&route_entry, 0, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("attr is null"); + status = g_meta->get(&route_entry, 1, NULL); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("route entry is null"); + status = g_meta->get((sai_route_entry_t*)NULL, 1, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("attr id out of range"); + attr.id = -1; + status = g_meta->get(&route_entry, 1, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("correct packet action"); + attr.id = SAI_ROUTE_ENTRY_ATTR_PACKET_ACTION; + status = g_meta->get(&route_entry, 1, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("correct next hop"); + attr.id = SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID; + status = g_meta->get(&route_entry, 1, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("correct meta"); + attr.id = SAI_ROUTE_ENTRY_ATTR_META_DATA; + status = g_meta->get(&route_entry, 1, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + remove_switch(switch_id); +} + +TEST(LegacyRouteEntry, route_entry_flow) +{ + SWSS_LOG_ENTER(); + + clear_local(); + + sai_status_t status; + sai_attribute_t attr; + + sai_route_entry_t route_entry; + sai_object_id_t switch_id = create_switch(); + + sai_object_id_t vr = create_virtual_router(switch_id); + sai_object_id_t hop = create_next_hop(switch_id); + + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + route_entry.destination.addr.ip4 = htonl(0x0a00000f); + route_entry.destination.mask.ip4 = htonl(0xffffff00); + route_entry.vr_id = vr; + route_entry.switch_id = switch_id; + + SWSS_LOG_NOTICE("create tests"); + + sai_attribute_t list[3] = { }; + + sai_attribute_t &attr1 = list[0]; + sai_attribute_t &attr2 = list[1]; + + attr1.id = SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID; + attr1.value.oid = hop; + + attr2.id = SAI_ROUTE_ENTRY_ATTR_PACKET_ACTION; + attr2.value.s32 = SAI_PACKET_ACTION_FORWARD; + + SWSS_LOG_NOTICE("correct ipv4"); + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + status = g_meta->create(&route_entry, 2, list); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("already exists ipv4"); + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + status = g_meta->create(&route_entry, 2, list); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + sai_ip6_t ip62 = {0x00, 0x11, 0x22, 0x33,0x44, 0x55, 0x66,0x77, 0x88, 0x99, 0xaa, 0xbb,0xcc,0xdd,0xee,0x99}; + memcpy(route_entry.destination.addr.ip6, ip62, 16); + + sai_ip6_t ip6mask2 = {0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff, 0xff,0xff,0xff,0xf7,0x00}; + memcpy(route_entry.destination.mask.ip6, ip6mask2, 16); + + SWSS_LOG_NOTICE("invalid mask"); + status = g_meta->create(&route_entry, 2, list); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + sai_ip6_t ip6 = {0x00, 0x11, 0x22, 0x33,0x44, 0x55, 0x66,0x77, 0x88, 0x99, 0xaa, 0xbb,0xcc,0xdd,0xee,0xff}; + memcpy(route_entry.destination.addr.ip6, ip6, 16); + + sai_ip6_t ip6mask = {0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff, 0xff,0xff,0xff,0xff,0x00}; + memcpy(route_entry.destination.mask.ip6, ip6mask, 16); + + SWSS_LOG_NOTICE("correct ipv6"); + status = g_meta->create(&route_entry, 2, list); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("already exists"); + status = g_meta->create(&route_entry, 2, list); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("set tests"); + + SWSS_LOG_NOTICE("correct packet action"); + attr.id = SAI_ROUTE_ENTRY_ATTR_PACKET_ACTION; + attr.value.s32 = SAI_PACKET_ACTION_DROP; + status = g_meta->set(&route_entry, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("correct next hop"); + attr.id = SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID; + attr.value.oid = hop; + status = g_meta->set(&route_entry, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("correct metadata"); + attr.id = SAI_ROUTE_ENTRY_ATTR_META_DATA; + attr.value.u32 = 0x12345678; + status = g_meta->set(&route_entry, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("get tests"); + + SWSS_LOG_NOTICE("correct packet action"); + attr.id = SAI_ROUTE_ENTRY_ATTR_PACKET_ACTION; + status = g_meta->get(&route_entry, 1, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("correct next hop"); + attr.id = SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID; + status = g_meta->get(&route_entry, 1, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("correct meta"); + attr.id = SAI_ROUTE_ENTRY_ATTR_META_DATA; + status = g_meta->get(&route_entry, 1, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("remove tests"); + + SWSS_LOG_NOTICE("success"); + status = g_meta->remove(&route_entry); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("non existing"); + status = g_meta->remove(&route_entry); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + route_entry.destination.addr.ip4 = htonl(0x0a00000f); + route_entry.destination.mask.ip4 = htonl(0xffffff00); + + SWSS_LOG_NOTICE("success"); + status = g_meta->remove(&route_entry); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("non existing"); + status = g_meta->remove(&route_entry); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + remove_switch(switch_id); +} diff --git a/unittest/meta/TestLegacyVlan.cpp b/unittest/meta/TestLegacyVlan.cpp new file mode 100644 index 000000000..61005b3d6 --- /dev/null +++ b/unittest/meta/TestLegacyVlan.cpp @@ -0,0 +1,483 @@ +#include "TestLegacy.h" + +#include + +#include + +#include + +using namespace TestLegacy; + +// STATIC HELPERS + +//static sai_object_id_t create_vlan( +// _In_ sai_object_id_t switch_id) +//{ +// SWSS_LOG_ENTER(); +// +// sai_object_id_t vlan; +// +// sai_attribute_t attrs[9] = { }; +// +// attrs[0].id = SAI_VLAN_ATTR_VLAN_ID; +// attrs[0].value.u16 = 1; +// +// auto status = g_meta->create(SAI_OBJECT_TYPE_VLAN, &vlan, switch_id, 1, attrs); +// EXPECT_EQ(SAI_STATUS_SUCCESS, status); +// +// return vlan; +//} + +// ACTUAL TESTS + +TEST(LegacyVlan, vlan_create) +{ + SWSS_LOG_ENTER(); + + clear_local(); + + sai_status_t status; + + sai_attribute_t vlan1_att; + vlan1_att.id = SAI_VLAN_ATTR_VLAN_ID; + vlan1_att.value.u16 = 1; + + sai_object_id_t vlan1_id; + + sai_object_id_t switch_id = create_switch(); + + status = g_meta->create(SAI_OBJECT_TYPE_VLAN, &vlan1_id, switch_id, 1, &vlan1_att); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + sai_attribute_t vlan; + vlan.id = SAI_VLAN_ATTR_VLAN_ID; + vlan.value.u16 = 2; + + sai_object_id_t vlan_id; + + SWSS_LOG_NOTICE("create tests"); + +// SWSS_LOG_NOTICE("existing vlan"); +// status = g_meta->create(SAI_OBJECT_TYPE_VLAN, &vlan_id, switch_id, 1, &vlan); +// EXPECT_NE(SAI_STATUS_SUCCESS, status); + + vlan.value.u16 = MAXIMUM_VLAN_NUMBER + 1; + +// SWSS_LOG_NOTICE("vlan outside range"); +// status = g_meta->create(SAI_OBJECT_TYPE_VLAN, &vlan_id, switch_id, 1, &vlan); +// EXPECT_NE(SAI_STATUS_SUCCESS, status); + + vlan.value.u16 = 2; + + SWSS_LOG_NOTICE("correct"); + status = g_meta->create(SAI_OBJECT_TYPE_VLAN, &vlan_id, switch_id, 1, &vlan); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("existing"); + status = g_meta->create(SAI_OBJECT_TYPE_VLAN, &vlan_id, switch_id, 1, &vlan); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + remove_switch(switch_id); +} + +TEST(LegacyVlan, vlan_remove) +{ + SWSS_LOG_ENTER(); + + clear_local(); + + sai_status_t status; + + sai_attribute_t vlan1_att; + vlan1_att.id = SAI_VLAN_ATTR_VLAN_ID; + vlan1_att.value.u16 = 1; + + sai_object_id_t vlan1_id; + sai_object_id_t switch_id = create_switch(); + + SWSS_LOG_NOTICE("create"); + + status = g_meta->create(SAI_OBJECT_TYPE_VLAN, &vlan1_id, switch_id, 1, &vlan1_att); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + sai_attribute_t vlan; + vlan.id = SAI_VLAN_ATTR_VLAN_ID; + vlan.value.u16 = 2; + + sai_object_id_t vlan_id; + + SWSS_LOG_NOTICE("correct"); + status = g_meta->create(SAI_OBJECT_TYPE_VLAN, &vlan_id, switch_id, 1, &vlan); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("remove tests"); + + SWSS_LOG_NOTICE("invalid vlan"); + status = g_meta->remove(SAI_OBJECT_TYPE_VLAN, SAI_NULL_OBJECT_ID); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + +// SWSS_LOG_NOTICE("default vlan"); +// status = g_meta->remove(SAI_OBJECT_TYPE_VLAN, vlan1_id); +// EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("success"); + status = g_meta->remove(SAI_OBJECT_TYPE_VLAN, vlan_id); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("non existing"); + status = g_meta->remove(SAI_OBJECT_TYPE_VLAN, vlan_id); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + remove_switch(switch_id); +} + +TEST(LegacyVlan, vlan_set) +{ + SWSS_LOG_ENTER(); + + clear_local(); + + sai_status_t status; + + sai_attribute_t attr; + + memset(&attr, 0, sizeof(attr)); + + sai_attribute_t vlan1_att; + vlan1_att.id = SAI_VLAN_ATTR_VLAN_ID; + vlan1_att.value.u16 = 1; + + sai_object_id_t vlan1_id; + sai_object_id_t switch_id = create_switch(); + + sai_object_id_t stp = create_stp(switch_id); + + SWSS_LOG_NOTICE("create"); + + status = g_meta->create(SAI_OBJECT_TYPE_VLAN, &vlan1_id, switch_id, 1, &vlan1_att); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + sai_attribute_t vlan; + vlan.id = SAI_VLAN_ATTR_VLAN_ID; + vlan.value.u16 = 2; + + sai_object_id_t vlan_id; + + SWSS_LOG_NOTICE("correct"); + status = g_meta->create(SAI_OBJECT_TYPE_VLAN, &vlan_id, switch_id, 1, &vlan); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("set tests"); + + SWSS_LOG_NOTICE("invalid vlan"); + status = g_meta->set(SAI_OBJECT_TYPE_VLAN, SAI_NULL_OBJECT_ID, &vlan); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("set is null"); + status = g_meta->set(SAI_OBJECT_TYPE_VLAN, vlan_id, &vlan); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("attr is null"); + status = g_meta->set(SAI_OBJECT_TYPE_VLAN, vlan_id, NULL); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + attr.id = -1; + + SWSS_LOG_NOTICE("invalid attribute"); + status = g_meta->set(SAI_OBJECT_TYPE_VLAN, vlan_id, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + attr.id = SAI_VLAN_ATTR_MEMBER_LIST; + + SWSS_LOG_NOTICE("read only"); + status = g_meta->set(SAI_OBJECT_TYPE_VLAN, vlan_id, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("max learned addresses"); + attr.id = SAI_VLAN_ATTR_MAX_LEARNED_ADDRESSES; + attr.value.u32 = 1; + status = g_meta->set(SAI_OBJECT_TYPE_VLAN, vlan_id, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("null stp instance"); + attr.id = SAI_VLAN_ATTR_STP_INSTANCE; + attr.value.oid = SAI_NULL_OBJECT_ID; + status = g_meta->set(SAI_OBJECT_TYPE_VLAN, vlan_id, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("wrong type on stp instance"); + attr.id = SAI_VLAN_ATTR_STP_INSTANCE; + attr.value.oid = create_dummy_object_id(SAI_OBJECT_TYPE_HASH,switch_id); + status = g_meta->set(SAI_OBJECT_TYPE_VLAN, vlan_id, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("wrong type on stp instance"); + attr.id = SAI_VLAN_ATTR_STP_INSTANCE; + attr.value.oid = create_dummy_object_id(SAI_OBJECT_TYPE_STP,switch_id); + status = g_meta->set(SAI_OBJECT_TYPE_VLAN, vlan_id, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("good stp oid"); + attr.id = SAI_VLAN_ATTR_STP_INSTANCE; + attr.value.oid = stp; + status = g_meta->set(SAI_OBJECT_TYPE_VLAN, vlan_id, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("learn disable"); + attr.id = SAI_VLAN_ATTR_LEARN_DISABLE; + attr.value.booldata = false; + status = g_meta->set(SAI_OBJECT_TYPE_VLAN, vlan_id, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("metadat"); + attr.id = SAI_VLAN_ATTR_META_DATA; + attr.value.u32 = 1; + status = g_meta->set(SAI_OBJECT_TYPE_VLAN, vlan_id, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + remove_switch(switch_id); +} + +TEST(LegacyVlan, vlan_get) +{ + SWSS_LOG_ENTER(); + + clear_local(); + + sai_object_id_t switch_id = create_switch(); + sai_status_t status; + + sai_attribute_t attr; + + memset(&attr, 0, sizeof(attr)); + + sai_attribute_t vlan1_att; + vlan1_att.id = SAI_VLAN_ATTR_VLAN_ID; + vlan1_att.value.u16 = 1; + + sai_object_id_t vlan1_id; + + sai_object_id_t stp = create_stp(switch_id); + + SWSS_LOG_NOTICE("create"); + + status = g_meta->create(SAI_OBJECT_TYPE_VLAN, &vlan1_id, switch_id, 1, &vlan1_att); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + sai_attribute_t vlan; + vlan.id = SAI_VLAN_ATTR_VLAN_ID; + vlan.value.u16 = 2; + + sai_object_id_t vlan_id; + + SWSS_LOG_NOTICE("correct"); + status = g_meta->create(SAI_OBJECT_TYPE_VLAN, &vlan_id, switch_id, 1, &vlan); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("get tests"); + + attr.id = SAI_VLAN_ATTR_MAX_LEARNED_ADDRESSES; + + SWSS_LOG_NOTICE("invalid vlan"); + status = g_meta->get(SAI_OBJECT_TYPE_VLAN, 0, 1, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + +// SWSS_LOG_NOTICE("invalid vlan"); +// status = g_meta->get(SAI_OBJECT_TYPE_VLAN, 3, 1, &attr); +// EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("attr is null"); + status = g_meta->get(SAI_OBJECT_TYPE_VLAN, vlan_id, 1, NULL); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("zero attributes"); + status = g_meta->get(SAI_OBJECT_TYPE_VLAN, vlan_id, 0, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + attr.id = -1; + + SWSS_LOG_NOTICE("invalid attribute"); + status = g_meta->get(SAI_OBJECT_TYPE_VLAN, vlan_id, 1, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + attr.id = SAI_VLAN_ATTR_MEMBER_LIST; + attr.value.objlist.count = 1; + attr.value.objlist.list = NULL; + + SWSS_LOG_NOTICE("read only null list"); + status = g_meta->get(SAI_OBJECT_TYPE_VLAN, vlan_id, 1, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + sai_object_id_t list[5] = { }; + + list[0] = SAI_NULL_OBJECT_ID; + list[1] = create_dummy_object_id(SAI_OBJECT_TYPE_HASH,switch_id); + list[2] = create_dummy_object_id(SAI_OBJECT_TYPE_VLAN_MEMBER,switch_id); + list[3] = stp; + + attr.value.objlist.count = 0; + attr.value.objlist.list = list; + + SWSS_LOG_NOTICE("readonly 0 count and not null"); + status = g_meta->get(SAI_OBJECT_TYPE_VLAN, vlan_id, 1, &attr); +// EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + attr.value.objlist.count = 5; + + SWSS_LOG_NOTICE("readonly count and not null"); + status = g_meta->get(SAI_OBJECT_TYPE_VLAN, vlan_id, 1, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + attr.value.objlist.count = 0; + attr.value.objlist.list = NULL; + + SWSS_LOG_NOTICE("readonly count 0 and null"); + status = g_meta->get(SAI_OBJECT_TYPE_VLAN, vlan_id, 1, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("max learned addresses"); + attr.id = SAI_VLAN_ATTR_MAX_LEARNED_ADDRESSES; + status = g_meta->get(SAI_OBJECT_TYPE_VLAN, vlan_id, 1, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("stp instance"); + attr.id = SAI_VLAN_ATTR_STP_INSTANCE; + status = g_meta->get(SAI_OBJECT_TYPE_VLAN, vlan_id, 1, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("learn disable"); + attr.id = SAI_VLAN_ATTR_LEARN_DISABLE; + status = g_meta->get(SAI_OBJECT_TYPE_VLAN, vlan_id, 1, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("metadata"); + attr.id = SAI_VLAN_ATTR_META_DATA; + status = g_meta->get(SAI_OBJECT_TYPE_VLAN, vlan_id, 1, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + remove_switch(switch_id); +} + +TEST(LegacyVlan, vlan_flow) +{ + SWSS_LOG_ENTER(); + + clear_local(); + + sai_attribute_t attr; + + sai_status_t status; + + sai_object_id_t vlan_id; + + attr.id = SAI_VLAN_ATTR_VLAN_ID; + attr.value.u16 = 2; + sai_object_id_t switch_id = create_switch(); + + sai_object_id_t stp = create_stp(switch_id); + + SWSS_LOG_NOTICE("create"); + + attr.id = SAI_VLAN_ATTR_VLAN_ID; + attr.value.u16 = 2; + + SWSS_LOG_NOTICE("correct"); + status = g_meta->create(SAI_OBJECT_TYPE_VLAN, &vlan_id, switch_id, 1, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("existing"); + status = g_meta->create(SAI_OBJECT_TYPE_VLAN, &vlan_id, switch_id, 1, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("set"); + + SWSS_LOG_NOTICE("max learned addresses"); + attr.id = SAI_VLAN_ATTR_MAX_LEARNED_ADDRESSES; + attr.value.u32 = 1; + status = g_meta->set(SAI_OBJECT_TYPE_VLAN, vlan_id, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("good stp oid"); + attr.id = SAI_VLAN_ATTR_STP_INSTANCE; + attr.value.oid = stp; + status = g_meta->set(SAI_OBJECT_TYPE_VLAN, vlan_id, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("learn disable"); + attr.id = SAI_VLAN_ATTR_LEARN_DISABLE; + attr.value.booldata = false; + status = g_meta->set(SAI_OBJECT_TYPE_VLAN, vlan_id, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("metadata"); + attr.id = SAI_VLAN_ATTR_META_DATA; + attr.value.u32 = 1; + status = g_meta->set(SAI_OBJECT_TYPE_VLAN, vlan_id, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("get"); + + sai_object_id_t list[5] = { }; + + list[0] = SAI_NULL_OBJECT_ID; + list[1] = create_dummy_object_id(SAI_OBJECT_TYPE_HASH,switch_id); + list[2] = create_dummy_object_id(SAI_OBJECT_TYPE_VLAN_MEMBER,switch_id); + list[3] = stp; + + attr.value.objlist.count = 0; + attr.value.objlist.list = list; + + SWSS_LOG_NOTICE("readonly 0 count and not null"); + status = g_meta->get(SAI_OBJECT_TYPE_VLAN, vlan_id, 1, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + attr.value.objlist.count = 5; + + SWSS_LOG_NOTICE("readonly count and not null"); + status = g_meta->get(SAI_OBJECT_TYPE_VLAN, vlan_id, 1, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + attr.value.objlist.count = 0; + attr.value.objlist.list = NULL; + + SWSS_LOG_NOTICE("readonly count 0 and null"); + status = g_meta->get(SAI_OBJECT_TYPE_VLAN, vlan_id, 1, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("max learned addresses"); + attr.id = SAI_VLAN_ATTR_MAX_LEARNED_ADDRESSES; + status = g_meta->get(SAI_OBJECT_TYPE_VLAN, vlan_id, 1, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("stp instance"); + attr.id = SAI_VLAN_ATTR_STP_INSTANCE; + status = g_meta->get(SAI_OBJECT_TYPE_VLAN, vlan_id, 1, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("learn disable"); + attr.id = SAI_VLAN_ATTR_LEARN_DISABLE; + status = g_meta->get(SAI_OBJECT_TYPE_VLAN, vlan_id, 1, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("metadata"); + attr.id = SAI_VLAN_ATTR_META_DATA; + status = g_meta->get(SAI_OBJECT_TYPE_VLAN, vlan_id, 1, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("remove"); + + SWSS_LOG_NOTICE("success"); + status = g_meta->remove(SAI_OBJECT_TYPE_VLAN, vlan_id); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("non existing"); + status = g_meta->remove(SAI_OBJECT_TYPE_VLAN, vlan_id); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + SWSS_LOG_NOTICE("learn disable"); + attr.id = SAI_VLAN_ATTR_LEARN_DISABLE; + status = g_meta->get(SAI_OBJECT_TYPE_VLAN, vlan_id, 1, &attr); + EXPECT_NE(SAI_STATUS_SUCCESS, status); + + remove_switch(switch_id); +} diff --git a/unittest/meta/TestMeta.cpp b/unittest/meta/TestMeta.cpp new file mode 100644 index 000000000..1b2a9eae0 --- /dev/null +++ b/unittest/meta/TestMeta.cpp @@ -0,0 +1,297 @@ +#include "Meta.h" +#include "MetaTestSaiInterface.h" + +#include + +#include + +using namespace saimeta; + +TEST(Meta, initialize) +{ + Meta m(std::make_shared()); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.initialize(0,0)); +} + +TEST(Meta, uninitialize) +{ + Meta m(std::make_shared()); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.uninitialize()); +} + +TEST(Meta, quad_mcast_fdb_entry) +{ + Meta m(std::make_shared()); + + sai_object_id_t switchId = 0; + + sai_attribute_t attr; + + attr.id = SAI_SWITCH_ATTR_INIT_SWITCH; + attr.value.booldata = true; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create(SAI_OBJECT_TYPE_SWITCH, &switchId, SAI_NULL_OBJECT_ID, 1, &attr)); + + sai_object_id_t vlanId = 0; + + attr.id = SAI_VLAN_ATTR_VLAN_ID; + attr.value.u16 = 2; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create(SAI_OBJECT_TYPE_VLAN, &vlanId, switchId, 1, &attr)); + + sai_object_id_t l2mcGroupId = 0; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create(SAI_OBJECT_TYPE_L2MC_GROUP, &l2mcGroupId, switchId, 0, 0)); + + sai_attribute_t attrs[2]; + + attrs[0].id = SAI_MCAST_FDB_ENTRY_ATTR_GROUP_ID; + attrs[0].value.oid = l2mcGroupId; + + attrs[1].id = SAI_MCAST_FDB_ENTRY_ATTR_PACKET_ACTION; + attrs[1].value.s32 = SAI_PACKET_ACTION_FORWARD; + + sai_mcast_fdb_entry_t e; + + memset(&e, 0, sizeof(e)); + + e.bv_id = vlanId; + e.switch_id = switchId; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create(&e, 2, attrs)); + + attr.id = SAI_MCAST_FDB_ENTRY_ATTR_PACKET_ACTION; + attr.value.s32 = SAI_PACKET_ACTION_DROP; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.set(&e, &attr)); + + attr.id = SAI_MCAST_FDB_ENTRY_ATTR_GROUP_ID; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.get(&e, 1, &attr)); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.remove(&e)); +} + +TEST(Meta, quad_l2mc_entry) +{ + Meta m(std::make_shared()); + + sai_object_id_t switchId = 0; + + sai_attribute_t attr; + + attr.id = SAI_SWITCH_ATTR_INIT_SWITCH; + attr.value.booldata = true; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create(SAI_OBJECT_TYPE_SWITCH, &switchId, SAI_NULL_OBJECT_ID, 1, &attr)); + + sai_object_id_t vlanId = 0; + + attr.id = SAI_VLAN_ATTR_VLAN_ID; + attr.value.u16 = 2; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create(SAI_OBJECT_TYPE_VLAN, &vlanId, switchId, 1, &attr)); + + sai_object_id_t l2mcGroupId = 0; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create(SAI_OBJECT_TYPE_L2MC_GROUP, &l2mcGroupId, switchId, 0, 0)); + + + attr.id = SAI_L2MC_ENTRY_ATTR_PACKET_ACTION; + attr.value.s32 = SAI_PACKET_ACTION_FORWARD; + + sai_l2mc_entry_t e; + + memset(&e, 0, sizeof(e)); + + e.bv_id = vlanId; + e.switch_id = switchId; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create(&e, 1, &attr)); + + attr.id = SAI_L2MC_ENTRY_ATTR_PACKET_ACTION; + attr.value.s32 = SAI_PACKET_ACTION_DROP; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.set(&e, &attr)); + + attr.id = SAI_L2MC_ENTRY_ATTR_PACKET_ACTION; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.get(&e, 1, &attr)); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.remove(&e)); +} + +TEST(Meta, quad_inseg_entry) +{ + Meta m(std::make_shared()); + + sai_object_id_t switchId = 0; + + sai_attribute_t attr; + + attr.id = SAI_SWITCH_ATTR_INIT_SWITCH; + attr.value.booldata = true; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create(SAI_OBJECT_TYPE_SWITCH, &switchId, SAI_NULL_OBJECT_ID, 1, &attr)); + + sai_object_id_t vlanId = 0; + + attr.id = SAI_VLAN_ATTR_VLAN_ID; + attr.value.u16 = 2; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create(SAI_OBJECT_TYPE_VLAN, &vlanId, switchId, 1, &attr)); + + attr.id = SAI_L2MC_ENTRY_ATTR_PACKET_ACTION; + attr.value.s32 = SAI_PACKET_ACTION_FORWARD; + + sai_inseg_entry_t e; + + memset(&e, 0, sizeof(e)); + + e.switch_id = switchId; + e.label = 1; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create(&e, 1, &attr)); + + attr.id = SAI_INSEG_ENTRY_ATTR_PACKET_ACTION; + attr.value.s32 = SAI_PACKET_ACTION_DROP; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.set(&e, &attr)); + + attr.id = SAI_INSEG_ENTRY_ATTR_PACKET_ACTION; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.get(&e, 1, &attr)); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.remove(&e)); +} + +TEST(Meta, quad_nat_entry) +{ + Meta m(std::make_shared()); + + sai_object_id_t switchId = 0; + + sai_attribute_t attr; + + attr.id = SAI_SWITCH_ATTR_INIT_SWITCH; + attr.value.booldata = true; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create(SAI_OBJECT_TYPE_SWITCH, &switchId, SAI_NULL_OBJECT_ID, 1, &attr)); + + sai_object_id_t vrId = 0; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create(SAI_OBJECT_TYPE_VIRTUAL_ROUTER, &vrId, switchId, 0, &attr)); + + attr.id = SAI_NAT_ENTRY_ATTR_NAT_TYPE; + attr.value.s32 = SAI_NAT_TYPE_NONE; + + sai_nat_entry_t e; + + memset(&e, 0, sizeof(e)); + + e.switch_id = switchId; + e.vr_id = vrId; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create(&e, 1, &attr)); + + attr.id = SAI_NAT_ENTRY_ATTR_NAT_TYPE; + attr.value.s32 = SAI_NAT_TYPE_NONE; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.set(&e, &attr)); + + attr.id = SAI_NAT_ENTRY_ATTR_NAT_TYPE; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.get(&e, 1, &attr)); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.remove(&e)); +} + +TEST(Meta, quad_impc_entry) +{ + Meta m(std::make_shared()); + + sai_object_id_t switchId = 0; + + sai_attribute_t attr; + + attr.id = SAI_SWITCH_ATTR_INIT_SWITCH; + attr.value.booldata = true; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create(SAI_OBJECT_TYPE_SWITCH, &switchId, SAI_NULL_OBJECT_ID, 1, &attr)); + + sai_object_id_t rpfGroupId = 0; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create(SAI_OBJECT_TYPE_RPF_GROUP, &rpfGroupId, switchId, 0, &attr)); + + sai_object_id_t vrId = 0; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create(SAI_OBJECT_TYPE_VIRTUAL_ROUTER, &vrId, switchId, 0, &attr)); + + sai_attribute_t attrs[2]; + + attrs[0].id = SAI_IPMC_ENTRY_ATTR_PACKET_ACTION; + attrs[0].value.s32 = SAI_PACKET_ACTION_FORWARD; + + attrs[1].id = SAI_IPMC_ENTRY_ATTR_RPF_GROUP_ID; + attrs[1].value.oid = rpfGroupId; + + sai_ipmc_entry_t e; + + memset(&e, 0, sizeof(e)); + + e.switch_id = switchId; + e.vr_id = vrId; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create(&e, 2, attrs)); + + attr.id = SAI_IPMC_ENTRY_ATTR_PACKET_ACTION; + attr.value.s32 = SAI_PACKET_ACTION_DROP; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.set(&e, &attr)); + + attr.id = SAI_IPMC_ENTRY_ATTR_RPF_GROUP_ID; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.get(&e, 1, &attr)); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.remove(&e)); +} + +TEST(Meta, flushFdbEntries) +{ + Meta m(std::make_shared()); + + sai_object_id_t switchId = 0; + + sai_attribute_t attr; + + attr.id = SAI_SWITCH_ATTR_INIT_SWITCH; + attr.value.booldata = true; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create(SAI_OBJECT_TYPE_SWITCH, &switchId, SAI_NULL_OBJECT_ID, 1, &attr)); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.flushFdbEntries(switchId, 0, 0)); + + EXPECT_NE(SAI_STATUS_SUCCESS, m.flushFdbEntries(switchId, 10000, 0)); + + EXPECT_NE(SAI_STATUS_SUCCESS, m.flushFdbEntries(switchId, 1, 0)); + + EXPECT_NE(SAI_STATUS_SUCCESS, m.flushFdbEntries(0, 0, 0)); + + attr.id = 10000; + + EXPECT_NE(SAI_STATUS_SUCCESS, m.flushFdbEntries(switchId, 1, &attr)); + + sai_attribute_t attrs[2]; + + attrs[0].id = SAI_FDB_FLUSH_ATTR_ENTRY_TYPE; + attrs[0].value.s32 = SAI_FDB_FLUSH_ENTRY_TYPE_ALL; + + attrs[1].id = SAI_FDB_FLUSH_ATTR_ENTRY_TYPE; + attrs[1].value.s32 = SAI_FDB_FLUSH_ENTRY_TYPE_ALL; + + EXPECT_NE(SAI_STATUS_SUCCESS, m.flushFdbEntries(switchId, 2, attrs)); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.flushFdbEntries(switchId, 1, attrs)); +} diff --git a/unittest/meta/TestMetaKeyHasher.cpp b/unittest/meta/TestMetaKeyHasher.cpp new file mode 100644 index 000000000..7412900e7 --- /dev/null +++ b/unittest/meta/TestMetaKeyHasher.cpp @@ -0,0 +1,152 @@ +#include "MetaKeyHasher.h" + +#include + +#include + +using namespace saimeta; + +TEST(MetaKeyHasher, operator_eq_route_entry) +{ + sai_route_entry_t ra; + sai_route_entry_t rb; + + memset(&ra, 0, sizeof(ra)); + memset(&rb, 0, sizeof(ra)); + + sai_object_meta_key_t ma = { .objecttype = SAI_OBJECT_TYPE_ROUTE_ENTRY, .objectkey = { .key = { .route_entry = ra } } }; + sai_object_meta_key_t mb = { .objecttype = SAI_OBJECT_TYPE_ROUTE_ENTRY, .objectkey = { .key = { .route_entry = rb } } }; + + MetaKeyHasher mh; + + EXPECT_TRUE(mh.operator()(ma, mb)); +} + +TEST(MetaKeyHasher, operator_eq_nat_entry) +{ + sai_nat_entry_t ra; + sai_nat_entry_t rb; + + memset(&ra, 0, sizeof(ra)); + memset(&rb, 0, sizeof(ra)); + + sai_object_meta_key_t ma = { .objecttype = SAI_OBJECT_TYPE_NAT_ENTRY, .objectkey = { .key = { .nat_entry = ra } } }; + sai_object_meta_key_t mb = { .objecttype = SAI_OBJECT_TYPE_NAT_ENTRY, .objectkey = { .key = { .nat_entry = rb } } }; + + MetaKeyHasher mh; + + EXPECT_TRUE(mh.operator()(ma, mb)); +} + +TEST(MetaKeyHasher, operator_eq_inseg_entry) +{ + sai_inseg_entry_t ra; + sai_inseg_entry_t rb; + + memset(&ra, 0, sizeof(ra)); + memset(&rb, 0, sizeof(ra)); + + sai_object_meta_key_t ma = { .objecttype = SAI_OBJECT_TYPE_INSEG_ENTRY, .objectkey = { .key = { .inseg_entry = ra } } }; + sai_object_meta_key_t mb = { .objecttype = SAI_OBJECT_TYPE_INSEG_ENTRY, .objectkey = { .key = { .inseg_entry = rb } } }; + + MetaKeyHasher mh; + + EXPECT_TRUE(mh.operator()(ma, mb)); +} + +TEST(MetaKeyHasher, operator_eq) +{ + sai_object_meta_key_t ma; + sai_object_meta_key_t mb; + + memset(&ma, 0, sizeof(ma)); + memset(&mb, 0, sizeof(mb)); + + ma.objecttype = SAI_OBJECT_TYPE_ROUTE_ENTRY; + mb.objecttype = SAI_OBJECT_TYPE_INSEG_ENTRY; + + MetaKeyHasher mh; + + EXPECT_FALSE(mh.operator()(ma, mb)); +} + +TEST(MetaKeyHasher, operator_hash) +{ + sai_object_meta_key_t ma; + + memset(&ma, 0, sizeof(ma)); + + MetaKeyHasher mh; + + ma.objecttype = SAI_OBJECT_TYPE_NAT_ENTRY; + + EXPECT_EQ(mh.operator()(ma), 0); + + ma.objecttype = SAI_OBJECT_TYPE_INSEG_ENTRY; + + EXPECT_EQ(mh.operator()(ma), 0); + + ma.objecttype = SAI_OBJECT_TYPE_IPMC_ENTRY; + + EXPECT_EQ(mh.operator()(ma), 0); + + ma.objecttype = SAI_OBJECT_TYPE_L2MC_ENTRY; + + EXPECT_EQ(mh.operator()(ma), 0); + + ma.objecttype = SAI_OBJECT_TYPE_IPMC_ENTRY; + ma.objectkey.key.ipmc_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + ma.objectkey.key.ipmc_entry.source.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + + EXPECT_EQ(mh.operator()(ma), 0); + + ma.objecttype = SAI_OBJECT_TYPE_L2MC_ENTRY; + ma.objectkey.key.l2mc_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + ma.objectkey.key.l2mc_entry.source.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + + EXPECT_EQ(mh.operator()(ma), 0); +} + +TEST(MetaKeyHasher, operator_eq_l2mc) +{ + sai_object_meta_key_t ma; + sai_object_meta_key_t mb; + + memset(&ma, 0, sizeof(ma)); + memset(&mb, 0, sizeof(mb)); + + ma.objecttype = SAI_OBJECT_TYPE_L2MC_ENTRY; + mb.objecttype = SAI_OBJECT_TYPE_L2MC_ENTRY; + + ma.objectkey.key.l2mc_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + ma.objectkey.key.l2mc_entry.source.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + + mb.objectkey.key.l2mc_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + mb.objectkey.key.l2mc_entry.source.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + + MetaKeyHasher mh; + + EXPECT_TRUE(mh.operator()(ma, mb)); +} + +TEST(MetaKeyHasher, operator_eq_ipck) +{ + sai_object_meta_key_t ma; + sai_object_meta_key_t mb; + + memset(&ma, 0, sizeof(ma)); + memset(&mb, 0, sizeof(mb)); + + ma.objecttype = SAI_OBJECT_TYPE_IPMC_ENTRY; + mb.objecttype = SAI_OBJECT_TYPE_IPMC_ENTRY; + + ma.objectkey.key.ipmc_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + ma.objectkey.key.ipmc_entry.source.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + + mb.objectkey.key.ipmc_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + mb.objectkey.key.ipmc_entry.source.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + + MetaKeyHasher mh; + + EXPECT_TRUE(mh.operator()(ma, mb)); +} diff --git a/unittest/meta/TestNotificationFactory.cpp b/unittest/meta/TestNotificationFactory.cpp new file mode 100644 index 000000000..35a354ea8 --- /dev/null +++ b/unittest/meta/TestNotificationFactory.cpp @@ -0,0 +1,78 @@ +#include "NotificationFactory.h" + +#include "sairediscommon.h" +#include "sai_serialize.h" + +#include + +#include + +using namespace sairedis; + +TEST(NotificationFactory, deserialize) +{ + EXPECT_THROW(NotificationFactory::deserialize("foo", "bar"), std::runtime_error); + + EXPECT_THROW(NotificationFactory::deserialize(SAI_SWITCH_NOTIFICATION_NAME_FDB_EVENT, "bar"), std::invalid_argument); +} + +TEST(NotificationFactory, deserialize_fdb_event) +{ + auto ntf = NotificationFactory::deserialize( + SAI_SWITCH_NOTIFICATION_NAME_FDB_EVENT, + "[{\"fdb_entry\":\"{\\\"bvid\\\":\\\"oid:0x260000000005be\\\",\\\"mac\\\":\\\"52:54:00:86:DD:7A\\\",\\\"switch_id\\\":\\\"oid:0x21000000000000\\\"}\"," + "\"fdb_event\":\"SAI_FDB_EVENT_LEARNED\"," + "\"list\":[{\"id\":\"SAI_FDB_ENTRY_ATTR_TYPE\",\"value\":\"SAI_FDB_ENTRY_TYPE_DYNAMIC\"},{\"id\":\"SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID\",\"value\":\"oid:0x3a000000000660\"}]}]"); + + EXPECT_EQ(ntf->getNotificationType(), SAI_SWITCH_NOTIFICATION_TYPE_FDB_EVENT); +} + +TEST(NotificationFactory, deserialize_port_state_change) +{ + auto ntf = NotificationFactory::deserialize( + SAI_SWITCH_NOTIFICATION_NAME_PORT_STATE_CHANGE, + "[{\"port_id\":\"oid:0x100000000001a\",\"port_state\":\"SAI_PORT_OPER_STATUS_UP\"}]"); + + EXPECT_EQ(ntf->getNotificationType(), SAI_SWITCH_NOTIFICATION_TYPE_PORT_STATE_CHANGE); +} + +TEST(NotificationFactory, deserialize_queue_pfc_deadlock) +{ + auto str = "[{\"event\":\"SAI_QUEUE_PFC_DEADLOCK_EVENT_TYPE_DETECTED\",\"queue_id\":\"oid:0x1500000000020a\"}]"; + + auto ntf = NotificationFactory::deserialize( + SAI_SWITCH_NOTIFICATION_NAME_QUEUE_PFC_DEADLOCK, + str); + + EXPECT_EQ(ntf->getNotificationType(), SAI_SWITCH_NOTIFICATION_TYPE_QUEUE_PFC_DEADLOCK); + + EXPECT_EQ(str, ntf->getSerializedNotification()); +} + +TEST(NotificationFactory, deserialize_shutdown_request) +{ + auto ntf = NotificationFactory::deserialize( + SAI_SWITCH_NOTIFICATION_NAME_SWITCH_SHUTDOWN_REQUEST, + "{\"switch_id\":\"oid:0x2100000000\"}"); + + EXPECT_EQ(ntf->getNotificationType(), SAI_SWITCH_NOTIFICATION_TYPE_SWITCH_SHUTDOWN_REQUEST); + + EXPECT_EQ("{\"switch_id\":\"oid:0x2100000000\"}", ntf->getSerializedNotification()); +} + +TEST(NotificationFactory, deserialize_switch_state_change) +{ + sai_switch_oper_status_t status = SAI_SWITCH_OPER_STATUS_UP; + + auto str = sai_serialize_switch_oper_status(0x2100000000, status); + + // {"status":"SAI_SWITCH_OPER_STATUS_UP","switch_id":"oid:0x2100000000"} + + auto ntf = NotificationFactory::deserialize( + SAI_SWITCH_NOTIFICATION_NAME_SWITCH_STATE_CHANGE, + str); + + EXPECT_EQ(ntf->getNotificationType(), SAI_SWITCH_NOTIFICATION_TYPE_SWITCH_STATE_CHANGE); + + EXPECT_EQ(str, ntf->getSerializedNotification()); +} diff --git a/unittest/meta/TestNotificationFdbEvent.cpp b/unittest/meta/TestNotificationFdbEvent.cpp new file mode 100644 index 000000000..c83d447f3 --- /dev/null +++ b/unittest/meta/TestNotificationFdbEvent.cpp @@ -0,0 +1,68 @@ +#include "NotificationFdbEvent.h" +#include "Meta.h" +#include "MetaTestSaiInterface.h" + +#include "sairediscommon.h" +#include "sai_serialize.h" + +#include + +#include + +using namespace sairedis; +using namespace saimeta; + +static std::string s = +"[{\"fdb_entry\":\"{\\\"bvid\\\":\\\"oid:0x260000000005be\\\",\\\"mac\\\":\\\"52:54:00:86:DD:7A\\\",\\\"switch_id\\\":\\\"oid:0x21000000000000\\\"}\"," +"\"fdb_event\":\"SAI_FDB_EVENT_LEARNED\"," +"\"list\":[{\"id\":\"SAI_FDB_ENTRY_ATTR_TYPE\",\"value\":\"SAI_FDB_ENTRY_TYPE_DYNAMIC\"},{\"id\":\"SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID\",\"value\":\"oid:0x3a000000000660\"}]}]"; + +static std::string null = +"[{\"fdb_entry\":\"{\\\"bvid\\\":\\\"oid:0x260000000005be\\\",\\\"mac\\\":\\\"52:54:00:86:DD:7A\\\",\\\"switch_id\\\":\\\"oid:0x0\\\"}\"," +"\"fdb_event\":\"SAI_FDB_EVENT_LEARNED\"," +"\"list\":[{\"id\":\"SAI_FDB_ENTRY_ATTR_TYPE\",\"value\":\"SAI_FDB_ENTRY_TYPE_DYNAMIC\"},{\"id\":\"SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID\",\"value\":\"oid:0x3a000000000660\"}]}]"; + +static std::string fullnull = "[]"; + +TEST(NotificationFdbEvent, ctr) +{ + NotificationFdbEvent n(s); +} + +TEST(NotificationFdbEvent, getSwitchId) +{ + NotificationFdbEvent n(s); + + EXPECT_EQ(n.getSwitchId(), 0x21000000000000); + + NotificationFdbEvent n2(null); + + EXPECT_EQ(n2.getSwitchId(), 0); +} + +TEST(NotificationFdbEvent, getAnyObjectId) +{ + NotificationFdbEvent n(s); + + EXPECT_EQ(n.getAnyObjectId(), 0x21000000000000); + + NotificationFdbEvent n2(null); + + EXPECT_EQ(n2.getAnyObjectId(), 0x260000000005be); + + NotificationFdbEvent n3(fullnull); + + EXPECT_EQ(n3.getSwitchId(), 0x0); + + EXPECT_EQ(n3.getAnyObjectId(), 0x0); +} + +TEST(NotificationFdbEvent, processMetadata) +{ + NotificationFdbEvent n(s); + + auto sai = std::make_shared(); + auto meta = std::make_shared(sai); + + n.processMetadata(meta); +} diff --git a/unittest/meta/TestNotificationPortStateChange.cpp b/unittest/meta/TestNotificationPortStateChange.cpp new file mode 100644 index 000000000..7f0102784 --- /dev/null +++ b/unittest/meta/TestNotificationPortStateChange.cpp @@ -0,0 +1,78 @@ +#include "NotificationPortStateChange.h" +#include "Meta.h" +#include "MetaTestSaiInterface.h" + +#include "sairediscommon.h" +#include "sai_serialize.h" + +#include + +#include + +using namespace sairedis; +using namespace saimeta; + +static std::string s = "[{\"port_id\":\"oid:0x100000000001a\",\"port_state\":\"SAI_PORT_OPER_STATUS_UP\"}]"; +static std::string null = "[{\"port_id\":\"oid:0x0\",\"port_state\":\"SAI_PORT_OPER_STATUS_UP\"}]"; +static std::string fullnull = "[]"; + +TEST(NotificationPortStateChange, ctr) +{ + NotificationPortStateChange n(s); +} + +TEST(NotificationPortStateChange, getSwitchId) +{ + NotificationPortStateChange n(s); + + EXPECT_EQ(n.getSwitchId(), 0); + + NotificationPortStateChange n2(null); + + EXPECT_EQ(n2.getSwitchId(), 0); +} + +TEST(NotificationPortStateChange, getAnyObjectId) +{ + NotificationPortStateChange n(s); + + EXPECT_EQ(n.getAnyObjectId(), 0x100000000001a); + + NotificationPortStateChange n2(null); + + EXPECT_EQ(n2.getAnyObjectId(), 0); + + NotificationPortStateChange n3(fullnull); + + EXPECT_EQ(n3.getSwitchId(), 0); + + EXPECT_EQ(n3.getAnyObjectId(), 0); +} + +TEST(NotificationPortStateChange, processMetadata) +{ + NotificationPortStateChange n(s); + + auto sai = std::make_shared(); + auto meta = std::make_shared(sai); + + n.processMetadata(meta); +} + +static void on_port_state_change_notification( + _In_ uint32_t count, + _In_ const sai_port_oper_status_notification_t *data) +{ + SWSS_LOG_ENTER(); +} + +TEST(NotificationPortStateChange, executeCallback) +{ + NotificationPortStateChange n(s); + + sai_switch_notifications_t ntfs; + + ntfs.on_port_state_change = &on_port_state_change_notification; + + n.executeCallback(ntfs); +} diff --git a/unittest/meta/TestNotificationQueuePfcDeadlock.cpp b/unittest/meta/TestNotificationQueuePfcDeadlock.cpp new file mode 100644 index 000000000..398d8ab39 --- /dev/null +++ b/unittest/meta/TestNotificationQueuePfcDeadlock.cpp @@ -0,0 +1,79 @@ +#include "NotificationQueuePfcDeadlock.h" +#include "Meta.h" +#include "MetaTestSaiInterface.h" + +#include "sairediscommon.h" +#include "sai_serialize.h" + +#include + +#include + +using namespace sairedis; +using namespace saimeta; + +static std::string s = "[{\"event\":\"SAI_QUEUE_PFC_DEADLOCK_EVENT_TYPE_DETECTED\",\"queue_id\":\"oid:0x1500000000020a\"}]"; +static std::string null = "[{\"event\":\"SAI_QUEUE_PFC_DEADLOCK_EVENT_TYPE_DETECTED\",\"queue_id\":\"oid:0x0\"}]"; +static std::string fullnull = "[]"; + +TEST(NotificationQueuePfcDeadlock, ctr) +{ + NotificationQueuePfcDeadlock n(s); +} + +TEST(NotificationQueuePfcDeadlock, getSwitchId) +{ + NotificationQueuePfcDeadlock n(s); + + EXPECT_EQ(n.getSwitchId(), 0); + + NotificationQueuePfcDeadlock n2(null); + + EXPECT_EQ(n2.getSwitchId(), 0); +} + +TEST(NotificationQueuePfcDeadlock, getAnyObjectId) +{ + NotificationQueuePfcDeadlock n(s); + + EXPECT_EQ(n.getAnyObjectId(), 0x1500000000020a); + + NotificationQueuePfcDeadlock n2(null); + + EXPECT_EQ(n2.getAnyObjectId(), 0); + + NotificationQueuePfcDeadlock n3(fullnull); + + EXPECT_EQ(n3.getSwitchId(), 0); + + EXPECT_EQ(n3.getAnyObjectId(), 0); +} + +TEST(NotificationQueuePfcDeadlock, processMetadata) +{ + NotificationQueuePfcDeadlock n(s); + + auto sai = std::make_shared(); + auto meta = std::make_shared(sai); + + n.processMetadata(meta); +} + +static void on_queue_pfc_deadlock_notification( + _In_ uint32_t count, + _In_ const sai_queue_deadlock_notification_data_t *data) +{ + SWSS_LOG_ENTER(); +} + +TEST(NotificationQueuePfcDeadlock, executeCallback) +{ + NotificationQueuePfcDeadlock n(s); + + sai_switch_notifications_t ntfs; + + ntfs.on_queue_pfc_deadlock = &on_queue_pfc_deadlock_notification; + + n.executeCallback(ntfs); +} + diff --git a/unittest/meta/TestNotificationSwitchShutdownRequest.cpp b/unittest/meta/TestNotificationSwitchShutdownRequest.cpp new file mode 100644 index 000000000..d50d48060 --- /dev/null +++ b/unittest/meta/TestNotificationSwitchShutdownRequest.cpp @@ -0,0 +1,70 @@ +#include "NotificationSwitchShutdownRequest.h" +#include "Meta.h" +#include "MetaTestSaiInterface.h" + +#include "sairediscommon.h" +#include "sai_serialize.h" + +#include + +#include + +using namespace sairedis; +using namespace saimeta; + +static std::string s = "{\"switch_id\":\"oid:0x2100000000\"}"; +static std::string null = "{\"switch_id\":\"oid:0x0\"}"; + +TEST(NotificationSwitchShutdownRequest, ctr) +{ + NotificationSwitchShutdownRequest n(s); +} + +TEST(NotificationSwitchShutdownRequest, getSwitchId) +{ + NotificationSwitchShutdownRequest n(s); + + EXPECT_EQ(n.getSwitchId(), 0x2100000000); + + NotificationSwitchShutdownRequest n2(null); + + EXPECT_EQ(n2.getSwitchId(), 0); +} + +TEST(NotificationSwitchShutdownRequest, getAnyObjectId) +{ + NotificationSwitchShutdownRequest n(s); + + EXPECT_EQ(n.getAnyObjectId(), 0x2100000000); + + NotificationSwitchShutdownRequest n2(null); + + EXPECT_EQ(n2.getAnyObjectId(), 0); +} + +TEST(NotificationSwitchShutdownRequest, processMetadata) +{ + NotificationSwitchShutdownRequest n(s); + + auto sai = std::make_shared(); + auto meta = std::make_shared(sai); + + n.processMetadata(meta); +} + +static void on_switch_shutdown_request_notification( + _In_ sai_object_id_t switch_id) +{ + SWSS_LOG_ENTER(); +} + +TEST(NotificationSwitchShutdownRequest, executeCallback) +{ + NotificationSwitchShutdownRequest n(s); + + sai_switch_notifications_t ntfs; + + ntfs.on_switch_shutdown_request = &on_switch_shutdown_request_notification; + + n.executeCallback(ntfs); +} diff --git a/unittest/meta/TestNotificationSwitchStateChange.cpp b/unittest/meta/TestNotificationSwitchStateChange.cpp new file mode 100644 index 000000000..3a7df6e59 --- /dev/null +++ b/unittest/meta/TestNotificationSwitchStateChange.cpp @@ -0,0 +1,71 @@ +#include "NotificationSwitchStateChange.h" +#include "Meta.h" +#include "MetaTestSaiInterface.h" + +#include "sairediscommon.h" +#include "sai_serialize.h" + +#include + +#include + +using namespace sairedis; +using namespace saimeta; + +static std::string s = "{\"status\":\"SAI_SWITCH_OPER_STATUS_UP\",\"switch_id\":\"oid:0x2100000000\"}"; +static std::string null = "{\"status\":\"SAI_SWITCH_OPER_STATUS_UP\",\"switch_id\":\"oid:0x0\"}"; + +TEST(NotificationSwitchStateChange, ctr) +{ + NotificationSwitchStateChange n(s); +} + +TEST(NotificationSwitchStateChange, getSwitchId) +{ + NotificationSwitchStateChange n(s); + + EXPECT_EQ(n.getSwitchId(), 0x2100000000); + + NotificationSwitchStateChange n2(null); + + EXPECT_EQ(n2.getSwitchId(), 0); +} + +TEST(NotificationSwitchStateChange, getAnyObjectId) +{ + NotificationSwitchStateChange n(s); + + EXPECT_EQ(n.getAnyObjectId(), 0x2100000000); + + NotificationSwitchStateChange n2(null); + + EXPECT_EQ(n2.getAnyObjectId(), 0); +} + +TEST(NotificationSwitchStateChange, processMetadata) +{ + NotificationSwitchStateChange n(s); + + auto sai = std::make_shared(); + auto meta = std::make_shared(sai); + + n.processMetadata(meta); +} + +static void on_switch_state_change_notification( + _In_ sai_object_id_t switch_id, + _In_ sai_switch_oper_status_t switch_oper_status) +{ + SWSS_LOG_ENTER(); +} + +TEST(NotificationSwitchStateChange, executeCallback) +{ + NotificationSwitchStateChange n(s); + + sai_switch_notifications_t ntfs; + + ntfs.on_switch_state_change = &on_switch_state_change_notification; + + n.executeCallback(ntfs); +} diff --git a/unittest/meta/TestOidRefCounter.cpp b/unittest/meta/TestOidRefCounter.cpp new file mode 100644 index 000000000..aa9ca81ea --- /dev/null +++ b/unittest/meta/TestOidRefCounter.cpp @@ -0,0 +1,90 @@ +#include "OidRefCounter.h" + +#include + +#include + +using namespace saimeta; + +TEST(OidRefCounter, objectReferenceIncrement) +{ + OidRefCounter c; + + EXPECT_THROW(c.objectReferenceIncrement(1), std::runtime_error); +} + +TEST(OidRefCounter, objectReferenceDecrement) +{ + OidRefCounter c; + + EXPECT_THROW(c.objectReferenceDecrement(1), std::runtime_error); + + c.objectReferenceInsert(2); + + EXPECT_THROW(c.objectReferenceDecrement(2), std::runtime_error); +} + +TEST(OidRefCounter, objectReferenceDecrement_list) +{ + OidRefCounter c; + + sai_object_list_t list; + + sai_object_id_t l[2] = {1, 2}; + + list.count = 2; + list.list = l; + + EXPECT_THROW(c.objectReferenceDecrement(list), std::runtime_error); +} + +TEST(OidRefCounter, objectReferenceInsert) +{ + OidRefCounter c; + + c.objectReferenceInsert(2); + + EXPECT_THROW(c.objectReferenceInsert(2), std::runtime_error); +} + +TEST(OidRefCounter, objectReferenceRemove) +{ + OidRefCounter c; + + c.objectReferenceInsert(2); + + c.objectReferenceIncrement(2); + + EXPECT_THROW(c.objectReferenceRemove(2), std::runtime_error); + + EXPECT_THROW(c.objectReferenceRemove(3), std::runtime_error); +} + +TEST(OidRefCounter, getObjectReferenceCount) +{ + OidRefCounter c; + + EXPECT_THROW(c.getObjectReferenceCount(3), std::runtime_error); +} + + +TEST(OidRefCounter, isObjectInUse) +{ + OidRefCounter c; + + EXPECT_THROW(c.isObjectInUse(3), std::runtime_error); +} + +TEST(OidRefCounter, getAllReferences) +{ + OidRefCounter c; + + EXPECT_EQ(c.getAllReferences().size(), 0); +} + +TEST(OidRefCounter, objectReferenceClear) +{ + OidRefCounter c; + + EXPECT_THROW(c.objectReferenceClear(2), std::runtime_error); +} diff --git a/unittest/meta/TestPerformanceIntervalTimer.cpp b/unittest/meta/TestPerformanceIntervalTimer.cpp new file mode 100644 index 000000000..ed142a783 --- /dev/null +++ b/unittest/meta/TestPerformanceIntervalTimer.cpp @@ -0,0 +1,15 @@ +#include "PerformanceIntervalTimer.h" + +#include + +#include + +using namespace sairediscommon; + +TEST(PerformanceIntervalTimer, inc) +{ + PerformanceIntervalTimer p("foo", 2); + + p.inc(); + p.inc(10); +} diff --git a/unittest/meta/TestPortRelatedSet.cpp b/unittest/meta/TestPortRelatedSet.cpp new file mode 100644 index 000000000..9fbcc69e2 --- /dev/null +++ b/unittest/meta/TestPortRelatedSet.cpp @@ -0,0 +1,18 @@ +#include "PortRelatedSet.h" + +#include + +#include + +using namespace saimeta; + +TEST(PortRelatedSet, inc) +{ + PortRelatedSet set; + + set.insert(0, 0); + + EXPECT_EQ(set.getAllPorts().size(), 0); + + EXPECT_THROW(set.insert(0, 1), std::runtime_error); +} diff --git a/unittest/meta/TestSaiAttrWrapper.cpp b/unittest/meta/TestSaiAttrWrapper.cpp new file mode 100644 index 000000000..f7a9b39a3 --- /dev/null +++ b/unittest/meta/TestSaiAttrWrapper.cpp @@ -0,0 +1,34 @@ +#include "SaiAttrWrapper.h" + +#include + +#include + +using namespace saimeta; + +TEST(SaiAttrWrapper, ctr) +{ + sai_attribute_t attr; + + attr.id = SAI_SWITCH_ATTR_INIT_SWITCH; + attr.value.booldata = true; + + EXPECT_THROW(std::make_shared(nullptr, attr), std::runtime_error); +} + +TEST(SaiAttrWrapper, getAttrId) +{ + sai_attribute_t attr; + + attr.id = SAI_SWITCH_ATTR_INIT_SWITCH; + attr.value.booldata = true; + + auto meta = sai_metadata_get_attr_metadata( + SAI_OBJECT_TYPE_SWITCH, + SAI_SWITCH_ATTR_INIT_SWITCH); + + SaiAttrWrapper w(meta, attr); + + EXPECT_EQ(w.getAttrId(), SAI_SWITCH_ATTR_INIT_SWITCH); +} + diff --git a/unittest/meta/TestSaiAttributeList.cpp b/unittest/meta/TestSaiAttributeList.cpp new file mode 100644 index 000000000..2e2b0ac4c --- /dev/null +++ b/unittest/meta/TestSaiAttributeList.cpp @@ -0,0 +1,46 @@ +#include "SaiAttributeList.h" + +#include + +#include + +using namespace saimeta; + +TEST(SaiAttributeList, ctr_vector) +{ + std::vector vals; + + vals.emplace_back("foo", "bar"); + + EXPECT_THROW(std::make_shared(SAI_OBJECT_TYPE_SWITCH, vals, false), std::runtime_error); + + vals.clear(); + + vals.emplace_back("SAI_SWITCH_ATTR_INIT_SWITCH", "true"); + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" + EXPECT_THROW(std::make_shared((sai_object_type_t)-1, vals, false), std::runtime_error); +#pragma GCC diagnostic pop +} + +TEST(SaiAttributeList, ctr_hash) +{ + std::unordered_map hash; + + hash["foo"] = "bar"; + + EXPECT_THROW(std::make_shared(SAI_OBJECT_TYPE_SWITCH, hash, false), std::runtime_error); + + hash.clear(); + + hash["NULL"] = "NULL"; + hash["SAI_SWITCH_ATTR_INIT_SWITCH"] = "true"; + + SaiAttributeList w(SAI_OBJECT_TYPE_SWITCH, hash, false); + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" + EXPECT_THROW(std::make_shared((sai_object_type_t)-1, hash, false), std::runtime_error); +#pragma GCC diagnostic pop +} diff --git a/unittest/meta/TestSaiInterface.cpp b/unittest/meta/TestSaiInterface.cpp new file mode 100644 index 000000000..b657aa77e --- /dev/null +++ b/unittest/meta/TestSaiInterface.cpp @@ -0,0 +1,125 @@ +#include "SaiInterface.h" +#include "DummySaiInterface.h" + +#include + +#include + +using namespace saimeta; +using namespace sairedis; + +TEST(SaiInterface, create) +{ + DummySaiInterface ds; + + SaiInterface *sai = &ds; + + sai_object_meta_key_t mk = { .objecttype = SAI_OBJECT_TYPE_NULL, .objectkey = { .key = { .object_id = 0 } } }; + + EXPECT_EQ(SAI_STATUS_FAILURE, sai->create(mk, 0, 0, nullptr)); + + mk.objecttype = SAI_OBJECT_TYPE_SWITCH; + EXPECT_EQ(SAI_STATUS_SUCCESS, sai->create(mk, 0, 0, nullptr)); + + mk.objecttype = SAI_OBJECT_TYPE_FDB_ENTRY; + EXPECT_EQ(SAI_STATUS_SUCCESS, sai->create(mk, 0, 0, nullptr)); + + mk.objecttype = SAI_OBJECT_TYPE_NAT_ENTRY; + EXPECT_EQ(SAI_STATUS_SUCCESS, sai->create(mk, 0, 0, nullptr)); + + mk.objecttype = SAI_OBJECT_TYPE_INSEG_ENTRY; + EXPECT_EQ(SAI_STATUS_SUCCESS, sai->create(mk, 0, 0, nullptr)); + + mk.objecttype = SAI_OBJECT_TYPE_L2MC_ENTRY; + EXPECT_EQ(SAI_STATUS_FAILURE, sai->create(mk, 0, 0, nullptr)); +} + +TEST(SaiInterface, remove) +{ + DummySaiInterface ds; + + SaiInterface *sai = &ds; + + sai_object_meta_key_t mk = { .objecttype = SAI_OBJECT_TYPE_NULL, .objectkey = { .key = { .object_id = 0 } } }; + + EXPECT_EQ(SAI_STATUS_FAILURE, sai->remove(mk)); + + mk.objecttype = SAI_OBJECT_TYPE_SWITCH; + EXPECT_EQ(SAI_STATUS_SUCCESS, sai->remove(mk)); + + mk.objecttype = SAI_OBJECT_TYPE_FDB_ENTRY; + EXPECT_EQ(SAI_STATUS_SUCCESS, sai->remove(mk)); + + mk.objecttype = SAI_OBJECT_TYPE_NAT_ENTRY; + EXPECT_EQ(SAI_STATUS_SUCCESS, sai->remove(mk)); + + mk.objecttype = SAI_OBJECT_TYPE_INSEG_ENTRY; + EXPECT_EQ(SAI_STATUS_SUCCESS, sai->remove(mk)); + + mk.objecttype = SAI_OBJECT_TYPE_L2MC_ENTRY; + EXPECT_EQ(SAI_STATUS_FAILURE, sai->remove(mk)); +} + +TEST(SaiInterface, set) +{ + DummySaiInterface ds; + + SaiInterface *sai = &ds; + + sai_object_meta_key_t mk = { .objecttype = SAI_OBJECT_TYPE_NULL, .objectkey = { .key = { .object_id = 0 } } }; + + EXPECT_EQ(SAI_STATUS_FAILURE, sai->set(mk, nullptr)); + + mk.objecttype = SAI_OBJECT_TYPE_SWITCH; + EXPECT_EQ(SAI_STATUS_SUCCESS, sai->set(mk, nullptr)); + + mk.objecttype = SAI_OBJECT_TYPE_FDB_ENTRY; + EXPECT_EQ(SAI_STATUS_SUCCESS, sai->set(mk, nullptr)); + + mk.objecttype = SAI_OBJECT_TYPE_NAT_ENTRY; + EXPECT_EQ(SAI_STATUS_SUCCESS, sai->set(mk, nullptr)); + + mk.objecttype = SAI_OBJECT_TYPE_INSEG_ENTRY; + EXPECT_EQ(SAI_STATUS_SUCCESS, sai->set(mk, nullptr)); + + mk.objecttype = SAI_OBJECT_TYPE_ROUTE_ENTRY; + EXPECT_EQ(SAI_STATUS_SUCCESS, sai->set(mk, nullptr)); + + mk.objecttype = SAI_OBJECT_TYPE_NEIGHBOR_ENTRY; + EXPECT_EQ(SAI_STATUS_SUCCESS, sai->set(mk, nullptr)); + + mk.objecttype = SAI_OBJECT_TYPE_L2MC_ENTRY; + EXPECT_EQ(SAI_STATUS_FAILURE, sai->set(mk, nullptr)); +} + +TEST(SaiInterface, get) +{ + DummySaiInterface ds; + + SaiInterface *sai = &ds; + + sai_object_meta_key_t mk = { .objecttype = SAI_OBJECT_TYPE_NULL, .objectkey = { .key = { .object_id = 0 } } }; + + EXPECT_EQ(SAI_STATUS_FAILURE, sai->get(mk, 0, nullptr)); + + mk.objecttype = SAI_OBJECT_TYPE_SWITCH; + EXPECT_EQ(SAI_STATUS_SUCCESS, sai->get(mk, 0, nullptr)); + + mk.objecttype = SAI_OBJECT_TYPE_FDB_ENTRY; + EXPECT_EQ(SAI_STATUS_SUCCESS, sai->get(mk, 0, nullptr)); + + mk.objecttype = SAI_OBJECT_TYPE_NAT_ENTRY; + EXPECT_EQ(SAI_STATUS_SUCCESS, sai->get(mk, 0, nullptr)); + + mk.objecttype = SAI_OBJECT_TYPE_INSEG_ENTRY; + EXPECT_EQ(SAI_STATUS_SUCCESS, sai->get(mk, 0, nullptr)); + + mk.objecttype = SAI_OBJECT_TYPE_ROUTE_ENTRY; + EXPECT_EQ(SAI_STATUS_SUCCESS, sai->get(mk, 0, nullptr)); + + mk.objecttype = SAI_OBJECT_TYPE_NEIGHBOR_ENTRY; + EXPECT_EQ(SAI_STATUS_SUCCESS, sai->get(mk, 0, nullptr)); + + mk.objecttype = SAI_OBJECT_TYPE_L2MC_ENTRY; + EXPECT_EQ(SAI_STATUS_FAILURE, sai->get(mk, 0, nullptr)); +} diff --git a/unittest/meta/TestSaiObject.cpp b/unittest/meta/TestSaiObject.cpp new file mode 100644 index 000000000..fb4cf2d16 --- /dev/null +++ b/unittest/meta/TestSaiObject.cpp @@ -0,0 +1,43 @@ +#include "SaiObject.h" + +#include + +#include + +using namespace saimeta; + +TEST(SaiObject, ctr) +{ + sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_NULL, .objectkey = { .key = { .object_id = 0 } } }; + + EXPECT_THROW(std::make_shared(meta_key), std::runtime_error); +} + +TEST(SaiObject, hasAttr) +{ + sai_object_meta_key_t mk = { .objecttype = SAI_OBJECT_TYPE_SWITCH, .objectkey = { .key = { .object_id = 0 } } }; + + SaiObject so(mk); + + EXPECT_FALSE(so.hasAttr(1)); +} + +TEST(SaiObject, setAttr) +{ + sai_object_meta_key_t mk = { .objecttype = SAI_OBJECT_TYPE_SWITCH, .objectkey = { .key = { .object_id = 0 } } }; + + SaiObject so(mk); + + sai_attribute_t attr; + + attr.id = SAI_SWITCH_ATTR_INIT_SWITCH; + attr.value.booldata = true; + + auto meta = sai_metadata_get_attr_metadata( + SAI_OBJECT_TYPE_SWITCH, + SAI_SWITCH_ATTR_INIT_SWITCH); + + auto a = std::make_shared(meta, attr); + + so.setAttr(a); +} diff --git a/unittest/meta/TestSaiObjectCollection.cpp b/unittest/meta/TestSaiObjectCollection.cpp new file mode 100644 index 000000000..46931df99 --- /dev/null +++ b/unittest/meta/TestSaiObjectCollection.cpp @@ -0,0 +1,58 @@ +#include "SaiObjectCollection.h" + +#include + +#include + +using namespace saimeta; + +TEST(SaiObjectCollection, createObject) +{ + sai_object_meta_key_t mk = { .objecttype = SAI_OBJECT_TYPE_SWITCH, .objectkey = { .key = { .object_id = 1 } } }; + + SaiObjectCollection oc; + + oc.createObject(mk); + + EXPECT_THROW(oc.createObject(mk), std::runtime_error); +} + +TEST(SaiObjectCollection, removeObject) +{ + sai_object_meta_key_t mk = { .objecttype = SAI_OBJECT_TYPE_SWITCH, .objectkey = { .key = { .object_id = 1 } } }; + + SaiObjectCollection oc; + + EXPECT_THROW(oc.removeObject(mk), std::runtime_error); +} + +TEST(SaiObjectCollection, setObjectAttr) +{ + sai_object_meta_key_t mk = { .objecttype = SAI_OBJECT_TYPE_SWITCH, .objectkey = { .key = { .object_id = 1 } } }; + + SaiObjectCollection oc; + + auto meta = sai_metadata_get_attr_metadata( + SAI_OBJECT_TYPE_SWITCH, + SAI_SWITCH_ATTR_INIT_SWITCH); + + EXPECT_THROW(oc.setObjectAttr(mk, *meta, nullptr), std::runtime_error); +} + +TEST(SaiObjectCollection, getObjectAttr) +{ + sai_object_meta_key_t mk = { .objecttype = SAI_OBJECT_TYPE_SWITCH, .objectkey = { .key = { .object_id = 1 } } }; + + SaiObjectCollection oc; + + EXPECT_EQ(oc.getObjectAttr(mk, 0), nullptr); +} + +TEST(SaiObjectCollection, getObject) +{ + sai_object_meta_key_t mk = { .objecttype = SAI_OBJECT_TYPE_SWITCH, .objectkey = { .key = { .object_id = 1 } } }; + + SaiObjectCollection oc; + + EXPECT_THROW(oc.getObject(mk), std::runtime_error); +} diff --git a/unittest/meta/TestSaiSerialize.cpp b/unittest/meta/TestSaiSerialize.cpp new file mode 100644 index 000000000..e6252774b --- /dev/null +++ b/unittest/meta/TestSaiSerialize.cpp @@ -0,0 +1,1159 @@ +#include "sai_serialize.h" +#include "MetaTestSaiInterface.h" +#include "Meta.h" + +#include "sairedis.h" +#include "sairediscommon.h" + +#include +#include + +#include + +#include + +using namespace saimeta; + +TEST(SaiSerialize, transfer_attributes) +{ + SWSS_LOG_ENTER(); + + sai_attribute_t src; + sai_attribute_t dst; + + memset(&src, 0, sizeof(src)); + memset(&dst, 0, sizeof(dst)); + + EXPECT_EQ(SAI_STATUS_SUCCESS, transfer_attributes(SAI_OBJECT_TYPE_SWITCH, 1, &src, &dst, true)); + + EXPECT_THROW(transfer_attributes(SAI_OBJECT_TYPE_NULL, 1, &src, &dst, true), std::runtime_error); + + src.id = 0; + dst.id = 1; + + EXPECT_THROW(transfer_attributes(SAI_OBJECT_TYPE_SWITCH, 1, &src, &dst, true), std::runtime_error); + + for (size_t idx = 0 ; idx < sai_metadata_attr_sorted_by_id_name_count; ++idx) + { + auto meta = sai_metadata_attr_sorted_by_id_name[idx]; + + src.id = meta->attrid; + dst.id = meta->attrid; + + EXPECT_EQ(SAI_STATUS_SUCCESS, transfer_attributes(meta->objecttype, 1, &src, &dst, true)); + } +} + +TEST(SaiSerialize, sai_serialize_object_meta_key) +{ + sai_object_meta_key_t mk; + + mk.objecttype = SAI_OBJECT_TYPE_NULL; + + EXPECT_THROW(sai_serialize_object_meta_key(mk), std::runtime_error); + + memset(&mk, 0, sizeof(mk)); + + for (int32_t i = SAI_OBJECT_TYPE_NULL+1; i < SAI_OBJECT_TYPE_EXTENSIONS_MAX; i++) + { + mk.objecttype = (sai_object_type_t)i; + + auto s = sai_serialize_object_meta_key(mk); + + sai_deserialize_object_meta_key(s, mk); + } +} + +TEST(SaiSerialize, sai_serialize_attr_value) +{ + sai_attribute_t attr; + + memset(&attr, 0, sizeof(attr)); + + for (size_t idx = 0 ; idx < sai_metadata_attr_sorted_by_id_name_count; ++idx) + { + auto meta = sai_metadata_attr_sorted_by_id_name[idx]; + + switch (meta->attrvaluetype) + { + // values that currently don't have serialization methods + case SAI_ATTR_VALUE_TYPE_TIMESPEC: + case SAI_ATTR_VALUE_TYPE_PORT_ERR_STATUS_LIST: + case SAI_ATTR_VALUE_TYPE_PORT_EYE_VALUES_LIST: + case SAI_ATTR_VALUE_TYPE_FABRIC_PORT_REACHABILITY: + case SAI_ATTR_VALUE_TYPE_PRBS_RX_STATE: + case SAI_ATTR_VALUE_TYPE_SEGMENT_LIST: + case SAI_ATTR_VALUE_TYPE_TLV_LIST: + case SAI_ATTR_VALUE_TYPE_MAP_LIST: + continue; + + default: + break; + } + + attr.id = meta->attrid; + + if (meta->isaclaction) + { + attr.value.aclaction.enable = true; + } + + if (meta->isaclfield) + { + attr.value.aclfield.enable = true; + } + + auto s = sai_serialize_attr_value(*meta, attr, false); + + sai_deserialize_attr_value(s, *meta, attr, false); + + sai_deserialize_free_attribute_value(meta->attrvaluetype, attr); + } +} + +TEST(SaiSerialize, sai_deserialize_redis_communication_mode) +{ + sai_redis_communication_mode_t value; + + sai_deserialize_redis_communication_mode(REDIS_COMMUNICATION_MODE_REDIS_ASYNC_STRING, value); + + EXPECT_EQ(value, SAI_REDIS_COMMUNICATION_MODE_REDIS_ASYNC); + + sai_deserialize_redis_communication_mode(REDIS_COMMUNICATION_MODE_REDIS_SYNC_STRING, value); + + EXPECT_EQ(value, SAI_REDIS_COMMUNICATION_MODE_REDIS_SYNC); + + sai_deserialize_redis_communication_mode(REDIS_COMMUNICATION_MODE_ZMQ_SYNC_STRING, value); + + EXPECT_EQ(value, SAI_REDIS_COMMUNICATION_MODE_ZMQ_SYNC); +} + +TEST(SaiSerialize, sai_deserialize_ingress_priority_group_attr) +{ + auto s = sai_serialize_ingress_priority_group_attr(SAI_INGRESS_PRIORITY_GROUP_ATTR_BUFFER_PROFILE); + + EXPECT_EQ(s, "SAI_INGRESS_PRIORITY_GROUP_ATTR_BUFFER_PROFILE"); + + sai_ingress_priority_group_attr_t attr; + + sai_deserialize_ingress_priority_group_attr(s, attr); +} + +//TEST(SaiSerialize, char_to_int) +//{ +// EXPECT_THROW(char_to_int('g'), std::runtime_error); +// +// EXPECT_EQ(char_to_int('a'), 10); +//} + +TEST(SaiSerialize, transfer_list) +{ + sai_attribute_t src; + sai_attribute_t dst; + + memset(&src, 0, sizeof(src)); + memset(&dst, 0, sizeof(dst)); + + src.id = SAI_PORT_ATTR_HW_LANE_LIST; + dst.id = SAI_PORT_ATTR_HW_LANE_LIST; + + uint32_t list[2] = { 2, 1 }; + + src.value.u32list.count = 2; + src.value.u32list.list = list; + + dst.value.u32list.count = 2; + dst.value.u32list.list = nullptr; + + EXPECT_EQ(SAI_STATUS_FAILURE, transfer_attributes(SAI_OBJECT_TYPE_PORT, 1, &src, &dst, false)); + + src.value.u32list.count = 1; + src.value.u32list.list = nullptr; + + dst.value.u32list.count = 1; + dst.value.u32list.list = list; + + EXPECT_THROW(transfer_attributes(SAI_OBJECT_TYPE_PORT, 1, &src, &dst, false), std::runtime_error); + + src.value.u32list.count = 2; + src.value.u32list.list = list; + + dst.value.u32list.count = 1; + dst.value.u32list.list = list; + + EXPECT_EQ(SAI_STATUS_BUFFER_OVERFLOW, transfer_attributes(SAI_OBJECT_TYPE_PORT, 1, &src, &dst, false)); +} + +TEST(SaiSerialize, sai_deserialize_ip_prefix) +{ + sai_ip_prefix_t p; + + memset(&p, 0, sizeof(p)); + + p.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + + p.addr.ip6[0] = 0x11; + + p.mask.ip6[0] = 0xFF; + p.mask.ip6[1] = 0xF0; + + auto s = sai_serialize_ip_prefix(p); + + EXPECT_EQ(s, "1100::/12"); + + sai_deserialize_ip_prefix(s, p); + + EXPECT_THROW(sai_deserialize_ip_prefix("a/0/c", p), std::runtime_error); + + EXPECT_THROW(sai_deserialize_ip_prefix("12x/0", p), std::runtime_error); + + p.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + + sai_deserialize_ip_prefix("127.0.0.1/8", p); +} + +TEST(SaiSerialize, sai_serialize_ip_prefix) +{ + sai_ip_prefix_t p; + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" + p.addr_family = (sai_ip_addr_family_t)7; +#pragma GCC diagnostic pop + + EXPECT_THROW(sai_serialize_ip_prefix(p), std::runtime_error); +} + +TEST(SaiSerialize, sai_deserialize_ip_address) +{ + sai_ip_address_t a; + + EXPECT_THROW(sai_deserialize_ip_address("123", a), std::runtime_error); +} + +TEST(SaiSerialize, sai_deserialize_ipv4) +{ + sai_ip4_t a; + + EXPECT_THROW(sai_deserialize_ipv4("123", a), std::runtime_error); +} + +TEST(SaiSerialize, sai_deserialize_ipv6) +{ + sai_ip6_t a; + + EXPECT_THROW(sai_deserialize_ipv6("123", a), std::runtime_error); +} + +TEST(SaiSerialize, sai_deserialize_chardata) +{ + sai_attribute_t a; + + EXPECT_THROW(sai_deserialize_chardata(std::string("123456789012345678901234567890123"), a.value.chardata), std::runtime_error); + + EXPECT_THROW(sai_deserialize_chardata(std::string("abc\\"), a.value.chardata), std::runtime_error); + + EXPECT_THROW(sai_deserialize_chardata(std::string("abc\\x"), a.value.chardata), std::runtime_error); + + EXPECT_THROW(sai_deserialize_chardata(std::string("a\\\\bc\\x1"), a.value.chardata), std::runtime_error); + + EXPECT_THROW(sai_deserialize_chardata(std::string("a\\\\bc\\xzg"), a.value.chardata), std::runtime_error); + + sai_deserialize_chardata(std::string("a\\\\\\x22"), a.value.chardata); +} + +TEST(SaiSerialize, sai_serialize_chardata) +{ + sai_attribute_t a; + + a.value.chardata[0] = 'a'; + a.value.chardata[1] = '\\'; + a.value.chardata[2] = 'b'; + a.value.chardata[3] = 7; + a.value.chardata[4] = 0; + + auto s = sai_serialize_chardata(a.value.chardata); + + EXPECT_EQ(s, "a\\\\b\\x07"); +} + +TEST(SaiSerialize, sai_serialize_api) +{ + EXPECT_EQ(sai_serialize_api(SAI_API_VLAN), "SAI_API_VLAN"); +} + +TEST(SaiSerialize, sai_serialize_vlan_id) +{ + EXPECT_EQ(sai_serialize_vlan_id(123), "123"); +} + +TEST(SaiSerialize, sai_deserialize_vlan_id) +{ + sai_vlan_id_t vlan; + + sai_deserialize_vlan_id("123", vlan); +} + +TEST(SaiSerialize, sai_serialize_port_stat) +{ + EXPECT_EQ(sai_serialize_port_stat(SAI_PORT_STAT_IF_IN_OCTETS),"SAI_PORT_STAT_IF_IN_OCTETS"); +} + +TEST(SaiSerialize, sai_serialize_switch_stat) +{ + EXPECT_EQ(sai_serialize_switch_stat(SAI_SWITCH_STAT_IN_CONFIGURED_DROP_REASONS_0_DROPPED_PKTS), + "SAI_SWITCH_STAT_IN_CONFIGURED_DROP_REASONS_0_DROPPED_PKTS"); +} + +TEST(SaiSerialize, sai_serialize_port_pool_stat) +{ + EXPECT_EQ(sai_serialize_port_pool_stat(SAI_PORT_POOL_STAT_IF_OCTETS), "SAI_PORT_POOL_STAT_IF_OCTETS"); +} + +TEST(SaiSerialize, sai_serialize_queue_stat) +{ + EXPECT_EQ(sai_serialize_queue_stat(SAI_QUEUE_STAT_PACKETS), "SAI_QUEUE_STAT_PACKETS"); +} + +TEST(SaiSerialize, sai_serialize_router_interface_stat) +{ + EXPECT_EQ(sai_serialize_router_interface_stat(SAI_ROUTER_INTERFACE_STAT_IN_OCTETS), + "SAI_ROUTER_INTERFACE_STAT_IN_OCTETS"); +} + +TEST(SaiSerialize, sai_serialize_ingress_priority_group_stat) +{ + EXPECT_EQ(sai_serialize_ingress_priority_group_stat(SAI_INGRESS_PRIORITY_GROUP_STAT_PACKETS), + "SAI_INGRESS_PRIORITY_GROUP_STAT_PACKETS"); +} + +TEST(SaiSerialize, sai_serialize_buffer_pool_stat) +{ + EXPECT_EQ(sai_serialize_buffer_pool_stat(SAI_BUFFER_POOL_STAT_CURR_OCCUPANCY_BYTES), + "SAI_BUFFER_POOL_STAT_CURR_OCCUPANCY_BYTES"); +} + +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_queue_attr) +{ + EXPECT_EQ(sai_serialize_queue_attr(SAI_QUEUE_ATTR_TYPE), "SAI_QUEUE_ATTR_TYPE"); +} + +TEST(SaiSerialize, sai_serialize_macsec_sa_attr) +{ + EXPECT_EQ(sai_serialize_macsec_sa_attr(SAI_MACSEC_SA_ATTR_MACSEC_DIRECTION), + "SAI_MACSEC_SA_ATTR_MACSEC_DIRECTION"); +} + +TEST(SaiSerialize, sai_serialize_ingress_drop_reason) +{ + EXPECT_EQ(sai_serialize_ingress_drop_reason(SAI_IN_DROP_REASON_L2_ANY), "SAI_IN_DROP_REASON_L2_ANY"); +} + +TEST(SaiSerialize, sai_serialize_egress_drop_reason) +{ + EXPECT_EQ(sai_serialize_egress_drop_reason(SAI_OUT_DROP_REASON_L2_ANY), "SAI_OUT_DROP_REASON_L2_ANY"); +} + +TEST(SaiSerialize, sai_serialize_switch_shutdown_request) +{ + EXPECT_EQ(sai_serialize_switch_shutdown_request(0x1), "{\"switch_id\":\"oid:0x1\"}"); +} + +TEST(SaiSerialize, sai_serialize_oid_list) +{ + sai_object_list_t list; + + list.count = 2; + list.list = nullptr; + + EXPECT_EQ(sai_serialize_oid_list(list, true), "2"); + + + EXPECT_EQ(sai_serialize_oid_list(list, false), "2:null"); +} + +TEST(SaiSerialize, sai_serialize_hex_binary) +{ + EXPECT_EQ(sai_serialize_hex_binary(nullptr, 0), ""); + + uint8_t buf[1]; + + EXPECT_EQ(sai_serialize_hex_binary(buf, 0), ""); +} + +TEST(SaiSerialize, sai_serialize_system_port_config_list) +{ + sai_system_port_config_t pc; + + memset(&pc, 0, sizeof(pc)); + + sai_system_port_config_list_t list; + + list.count = 1; + list.list = &pc; + + sai_attr_metadata_t *meta = nullptr; + + sai_serialize_system_port_config_list(*meta, list, false); +} + +TEST(SaiSerialize, sai_deserialize_system_port_config_list) +{ + sai_system_port_config_t pc; + + memset(&pc, 0, sizeof(pc)); + + sai_system_port_config_list_t list; + + list.count = 1; + list.list = &pc; + + sai_attr_metadata_t *meta = nullptr; + + auto s = sai_serialize_system_port_config_list(*meta, list, false); + + sai_deserialize_system_port_config_list(s, list, false); +} + +TEST(SaiSerialize, sai_serialize_port_oper_status) +{ + EXPECT_EQ(sai_serialize_port_oper_status(SAI_PORT_OPER_STATUS_UP), "SAI_PORT_OPER_STATUS_UP"); +} + +TEST(SaiSerialize, sai_serialize_queue_deadlock_event) +{ + EXPECT_EQ(sai_serialize_queue_deadlock_event(SAI_QUEUE_PFC_DEADLOCK_EVENT_TYPE_DETECTED), + "SAI_QUEUE_PFC_DEADLOCK_EVENT_TYPE_DETECTED"); +} + +TEST(SaiSerialize, sai_serialize_fdb_event_ntf) +{ + EXPECT_THROW(sai_serialize_fdb_event_ntf(1, nullptr), std::runtime_error); +} + +TEST(SaiSerialize, sai_serialize_port_oper_status_ntf) +{ + sai_port_oper_status_notification_t ntf; + + memset(&ntf, 0, sizeof(ntf)); + + sai_serialize_port_oper_status_ntf(1, &ntf); + + EXPECT_THROW(sai_serialize_port_oper_status_ntf(1, nullptr), std::runtime_error); +} + +TEST(SaiSerialize, sai_serialize_queue_deadlock_ntf) +{ + sai_queue_deadlock_notification_data_t ntf; + + memset(&ntf, 0, sizeof(ntf)); + + sai_serialize_queue_deadlock_ntf(1, &ntf); + + EXPECT_THROW(sai_serialize_queue_deadlock_ntf(1, nullptr), std::runtime_error); +} + +TEST(SaiSerialize, sai_serialize) +{ + sai_redis_notify_syncd_t value = SAI_REDIS_NOTIFY_SYNCD_INSPECT_ASIC; + + EXPECT_EQ(sai_serialize(value), SYNCD_INSPECT_ASIC); +} + +TEST(SaiSerialize, sai_serialize_redis_communication_mode) +{ + EXPECT_EQ(sai_serialize_redis_communication_mode(SAI_REDIS_COMMUNICATION_MODE_REDIS_SYNC), + REDIS_COMMUNICATION_MODE_REDIS_SYNC_STRING); +} + +TEST(SaiSerialize, sai_deserialize_queue_attr) +{ + sai_queue_attr_t attr = SAI_QUEUE_ATTR_PORT; + sai_deserialize_queue_attr("SAI_QUEUE_ATTR_TYPE", attr); + + EXPECT_EQ(attr, SAI_QUEUE_ATTR_TYPE); +} + +TEST(SaiSerialize, sai_deserialize_macsec_sa_attr) +{ + sai_macsec_sa_attr_t attr = SAI_MACSEC_SA_ATTR_SC_ID; + sai_deserialize_macsec_sa_attr("SAI_MACSEC_SA_ATTR_MACSEC_DIRECTION", attr); + + EXPECT_EQ(attr, SAI_MACSEC_SA_ATTR_MACSEC_DIRECTION); +} + +TEST(SaiSerialize, sai_deserialize) +{ + sai_redis_notify_syncd_t value = SAI_REDIS_NOTIFY_SYNCD_APPLY_VIEW; + + sai_deserialize("SYNCD_INSPECT_ASIC", value); + + EXPECT_EQ(value, SAI_REDIS_NOTIFY_SYNCD_INSPECT_ASIC); +} + +// LEGACY TESTS + +TEST(SaiSerialize, serialize_bool) +{ + SWSS_LOG_ENTER(); + + sai_attribute_t attr; + const sai_attr_metadata_t* meta; + std::string s; + + // test bool + + attr.id = SAI_SWITCH_ATTR_ON_LINK_ROUTE_SUPPORTED; + attr.value.booldata = true; + + meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_SWITCH, attr.id); + + EXPECT_EQ(sai_serialize_attr_value(*meta, attr), "true"); + + attr.id = SAI_SWITCH_ATTR_ON_LINK_ROUTE_SUPPORTED; + attr.value.booldata = false; + + EXPECT_EQ(sai_serialize_attr_value(*meta, attr), "false"); + + // deserialize + + attr.id = SAI_SWITCH_ATTR_ON_LINK_ROUTE_SUPPORTED; + + sai_deserialize_attr_value("true", *meta, attr); + + EXPECT_EQ(true, attr.value.booldata); + + sai_deserialize_attr_value("false", *meta, attr); + + EXPECT_EQ(false, attr.value.booldata); + + EXPECT_THROW(sai_deserialize_attr_value("xx", *meta, attr), std::runtime_error); +} + +TEST(SaiSerialize, serialize_chardata) +{ + sai_attribute_t attr; + const sai_attr_metadata_t* meta; + std::string s; + + memset(attr.value.chardata, 0, 32); + + attr.id = SAI_HOSTIF_ATTR_NAME; + memcpy(attr.value.chardata, "foo", sizeof("foo")); + + meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_HOSTIF, attr.id); + + s = sai_serialize_attr_value(*meta, attr); + + EXPECT_EQ(s, "foo"); + + attr.id = SAI_HOSTIF_ATTR_NAME; + memcpy(attr.value.chardata, "f\\oo\x12", sizeof("f\\oo\x12")); + + meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_HOSTIF, attr.id); + + s = sai_serialize_attr_value(*meta, attr); + + EXPECT_EQ(s, "f\\\\oo\\x12"); + + attr.id = SAI_HOSTIF_ATTR_NAME; + memcpy(attr.value.chardata, "\x80\xff", sizeof("\x80\xff")); + + meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_HOSTIF, attr.id); + + s = sai_serialize_attr_value(*meta, attr); + + EXPECT_EQ(s, "\\x80\\xFF"); + + // deserialize + + sai_deserialize_attr_value("f\\\\oo\\x12", *meta, attr); + + SWSS_LOG_NOTICE("des: %s", attr.value.chardata); + + EXPECT_EQ(0, strcmp(attr.value.chardata, "f\\oo\x12")); + + sai_deserialize_attr_value("foo", *meta, attr); + + EXPECT_EQ(0, strcmp(attr.value.chardata, "foo")); + + EXPECT_THROW(sai_deserialize_attr_value("\\x2g", *meta, attr), std::runtime_error); + + EXPECT_THROW(sai_deserialize_attr_value("\\x2", *meta, attr), std::runtime_error); + + EXPECT_THROW(sai_deserialize_attr_value("\\s45", *meta, attr), std::runtime_error); + + EXPECT_THROW(sai_deserialize_attr_value("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", *meta, attr), std::runtime_error); +} + +TEST(SaiSerialize, serialize_uint64) +{ + sai_attribute_t attr; + const sai_attr_metadata_t* meta; + std::string s; + + attr.id = SAI_SWITCH_ATTR_NV_STORAGE_SIZE; + attr.value.u64 = 42; + + meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_SWITCH, attr.id); + + s = sai_serialize_attr_value(*meta, attr); + + EXPECT_EQ(s, "42"); + + attr.value.u64 = 0x87654321aabbccdd; + + attr.id = SAI_SWITCH_ATTR_NV_STORAGE_SIZE; + + meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_SWITCH, attr.id); + + s = sai_serialize_attr_value(*meta, attr); + + char buf[32]; + sprintf(buf, "%" PRIu64, attr.value.u64); + + EXPECT_EQ(s, std::string(buf)); + + // deserialize + + sai_deserialize_attr_value("12345", *meta, attr); + + EXPECT_EQ(12345, attr.value.u64); + + EXPECT_THROW(sai_deserialize_attr_value("22345235345345345435", *meta, attr), std::runtime_error); + + EXPECT_THROW(sai_deserialize_attr_value("2a", *meta, attr), std::runtime_error); +} + +TEST(SaiSerialize, serialize_enum) +{ + sai_attribute_t attr; + const sai_attr_metadata_t* meta; + std::string s; + + attr.id = SAI_SWITCH_ATTR_SWITCHING_MODE; + attr.value.s32 = SAI_SWITCH_SWITCHING_MODE_STORE_AND_FORWARD; + + meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_SWITCH, attr.id); + + s = sai_serialize_attr_value(*meta, attr); + + EXPECT_EQ(s, "SAI_SWITCH_SWITCHING_MODE_STORE_AND_FORWARD"); + + attr.value.s32 = -1; + + attr.id = SAI_SWITCH_ATTR_SWITCHING_MODE; + + meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_SWITCH, attr.id); + + s = sai_serialize_attr_value(*meta, attr); + + EXPECT_EQ(s, "-1"); + + attr.value.s32 = 100; + + attr.id = SAI_SWITCH_ATTR_SWITCHING_MODE; + + meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_SWITCH, attr.id); + + s = sai_serialize_attr_value(*meta, attr); + + EXPECT_EQ(s, "100"); + + // deserialize + + sai_deserialize_attr_value("12345", *meta, attr); + + EXPECT_EQ(12345, attr.value.s32); + + sai_deserialize_attr_value("-1", *meta, attr); + + EXPECT_EQ(-1, attr.value.s32); + + sai_deserialize_attr_value("SAI_SWITCH_SWITCHING_MODE_STORE_AND_FORWARD", *meta, attr); + + EXPECT_EQ(SAI_SWITCH_SWITCHING_MODE_STORE_AND_FORWARD, attr.value.s32); + + EXPECT_THROW(sai_deserialize_attr_value("foo", *meta, attr), std::runtime_error); +} + +TEST(SaiSerialize, serialize_mac) +{ + sai_attribute_t attr; + const sai_attr_metadata_t* meta; + std::string s; + + attr.id = SAI_SWITCH_ATTR_SRC_MAC_ADDRESS; + memcpy(attr.value.mac, "\x01\x22\x33\xaa\xbb\xcc", 6); + + meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_SWITCH, attr.id); + + s = sai_serialize_attr_value(*meta, attr); + + EXPECT_EQ(s, "01:22:33:AA:BB:CC"); + + // deserialize + + sai_deserialize_attr_value("ff:ee:dd:33:44:55", *meta, attr); + + EXPECT_EQ(0, memcmp("\xff\xee\xdd\x33\x44\x55", attr.value.mac, 6)); + + EXPECT_THROW(sai_deserialize_attr_value("foo", *meta, attr), std::runtime_error); +} + +TEST(SaiSerialize, serialize_ip_address) +{ + sai_attribute_t attr; + const sai_attr_metadata_t* meta; + std::string s; + + attr.id = SAI_TUNNEL_ATTR_ENCAP_SRC_IP; + attr.value.ipaddr.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + attr.value.ipaddr.addr.ip4 = htonl(0x0a000015); + + meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_TUNNEL, attr.id); + + s = sai_serialize_attr_value(*meta, attr); + + EXPECT_EQ(s, "10.0.0.21"); + + attr.id = SAI_TUNNEL_ATTR_ENCAP_SRC_IP; + attr.value.ipaddr.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + + uint16_t ip6[] = { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0xaaaa, 0xbbbb }; + + memcpy(attr.value.ipaddr.addr.ip6, ip6, 16); + + meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_TUNNEL, attr.id); + + s = sai_serialize_attr_value(*meta, attr); + + EXPECT_EQ(s, "1111:2222:3333:4444:5555:6666:aaaa:bbbb"); + + uint16_t ip6a[] = { 0x0100, 0 ,0 ,0 ,0 ,0 ,0 ,0xff00 }; + + memcpy(attr.value.ipaddr.addr.ip6, ip6a, 16); + + meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_TUNNEL, attr.id); + + s = sai_serialize_attr_value(*meta, attr); + + EXPECT_EQ(s, "1::ff"); + + uint16_t ip6b[] = { 0, 0 ,0 ,0 ,0 ,0 ,0 ,0x100 }; + + memcpy(attr.value.ipaddr.addr.ip6, ip6b, 16); + + meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_TUNNEL, attr.id); + + s = sai_serialize_attr_value(*meta, attr); + + EXPECT_EQ(s, "::1"); + + int k = 100; + attr.value.ipaddr.addr_family = (sai_ip_addr_family_t)k; + + EXPECT_THROW(sai_serialize_attr_value(*meta, attr), std::runtime_error); + + // deserialize + + sai_deserialize_attr_value("10.0.0.23", *meta, attr); + + EXPECT_EQ(attr.value.ipaddr.addr.ip4, htonl(0x0a000017)); + EXPECT_EQ(attr.value.ipaddr.addr_family, SAI_IP_ADDR_FAMILY_IPV4); + + sai_deserialize_attr_value("1::ff", *meta, attr); + + EXPECT_EQ(0, memcmp(attr.value.ipaddr.addr.ip6, ip6a, 16)); + EXPECT_EQ(attr.value.ipaddr.addr_family, SAI_IP_ADDR_FAMILY_IPV6); + + EXPECT_THROW(sai_deserialize_attr_value("foo", *meta, attr), std::runtime_error); +} + +TEST(SaiSerialize, serialize_uint32_list) +{ + sai_attribute_t attr; + const sai_attr_metadata_t* meta; + std::string s; + + attr.id = SAI_PORT_ATTR_SUPPORTED_SPEED; //SAI_PORT_ATTR_SUPPORTED_HALF_DUPLEX_SPEED; + + uint32_t list[] = {1,2,3,4,5,6,7}; + + attr.value.u32list.count = 7; + attr.value.u32list.list = NULL; + + meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_PORT, attr.id); + + s = sai_serialize_attr_value(*meta, attr); + + EXPECT_EQ(s, "7:null"); + + attr.value.u32list.list = list; + + meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_PORT, attr.id); + + s = sai_serialize_attr_value(*meta, attr); + + EXPECT_EQ(s, "7:1,2,3,4,5,6,7"); + + attr.value.u32list.count = 0; + attr.value.u32list.list = list; + + meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_PORT, attr.id); + + s = sai_serialize_attr_value(*meta, attr); + + EXPECT_EQ(s, "0:null"); + + attr.value.u32list.count = 0; + attr.value.u32list.list = NULL; + + meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_PORT, attr.id); + + s = sai_serialize_attr_value(*meta, attr); + + EXPECT_EQ(s, "0:null"); + + memset(&attr, 0, sizeof(attr)); + + sai_deserialize_attr_value("7:1,2,3,4,5,6,7", *meta, attr, false); + + EXPECT_EQ(attr.value.u32list.count, 7); + EXPECT_EQ(attr.value.u32list.list[0], 1); + EXPECT_EQ(attr.value.u32list.list[1], 2); + EXPECT_EQ(attr.value.u32list.list[2], 3); + EXPECT_EQ(attr.value.u32list.list[3], 4); +} + +TEST(SaiSerialize, serialize_enum_list) +{ + sai_attribute_t attr; + const sai_attr_metadata_t* meta; + std::string s; + + attr.id = SAI_HASH_ATTR_NATIVE_HASH_FIELD_LIST; + + int32_t list[] = { + SAI_NATIVE_HASH_FIELD_SRC_IP, + SAI_NATIVE_HASH_FIELD_DST_IP, + SAI_NATIVE_HASH_FIELD_VLAN_ID, + 77 + }; + + attr.value.s32list.count = 4; + attr.value.s32list.list = NULL; + + meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_HASH, attr.id); + + s = sai_serialize_attr_value(*meta, attr); + + EXPECT_EQ(s, "4:null"); + + attr.value.s32list.list = list; + + meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_HASH, attr.id); + + s = sai_serialize_attr_value(*meta, attr); + + // or for enum: 4:SAI_NATIVE_HASH_FIELD[SRC_IP,DST_IP,VLAN_ID,77] + + EXPECT_EQ(s, "4:SAI_NATIVE_HASH_FIELD_SRC_IP,SAI_NATIVE_HASH_FIELD_DST_IP,SAI_NATIVE_HASH_FIELD_VLAN_ID,77"); + + attr.value.s32list.count = 0; + attr.value.s32list.list = list; + + meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_HASH, attr.id); + + s = sai_serialize_attr_value(*meta, attr); + + EXPECT_EQ(s, "0:null"); + + attr.value.s32list.count = 0; + attr.value.s32list.list = NULL; + + meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_HASH, attr.id); + + s = sai_serialize_attr_value(*meta, attr); + + EXPECT_EQ(s, "0:null"); +} + +TEST(SaiSerialize, serialize_oid) +{ + sai_attribute_t attr; + const sai_attr_metadata_t* meta; + std::string s; + + attr.id = SAI_SWITCH_ATTR_DEFAULT_VIRTUAL_ROUTER_ID; + + attr.value.oid = 0x1234567890abcdef; + + meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_SWITCH, attr.id); + + s = sai_serialize_attr_value(*meta, attr); + + EXPECT_EQ(s, "oid:0x1234567890abcdef"); + + // deserialize + + sai_deserialize_attr_value("oid:0x1234567890abcdef", *meta, attr); + + EXPECT_EQ(0x1234567890abcdef, attr.value.oid); + + EXPECT_THROW(sai_deserialize_attr_value("foo", *meta, attr), std::runtime_error); +} + +TEST(SaiSerialize, serialize_oid_list) +{ + sai_attribute_t attr; + const sai_attr_metadata_t* meta; + std::string s; + + attr.id = SAI_SWITCH_ATTR_PORT_LIST; + + sai_object_id_t list[] = { + 1,0x42, 0x77 + }; + + attr.value.objlist.count = 3; + attr.value.objlist.list = NULL; + + meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_SWITCH, attr.id); + + s = sai_serialize_attr_value(*meta, attr); + + EXPECT_EQ(s, "3:null"); + + attr.value.objlist.list = list; + + meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_SWITCH, attr.id); + + s = sai_serialize_attr_value(*meta, attr); + + // or: 4:[ROUTE:0x1,PORT:0x3,oid:0x77] if we have query function + + EXPECT_EQ(s, "3:oid:0x1,oid:0x42,oid:0x77"); + + attr.value.objlist.count = 0; + attr.value.objlist.list = list; + + meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_SWITCH, attr.id); + + s = sai_serialize_attr_value(*meta, attr); + + EXPECT_EQ(s, "0:null"); + + attr.value.objlist.count = 0; + attr.value.objlist.list = NULL; + + meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_SWITCH, attr.id); + + s = sai_serialize_attr_value(*meta, attr); + + EXPECT_EQ(s, "0:null"); + + memset(&attr, 0, sizeof(attr)); + + // deserialize + + sai_deserialize_attr_value("3:oid:0x1,oid:0x42,oid:0x77", *meta, attr, false); + + EXPECT_EQ(attr.value.objlist.count, 3); + EXPECT_EQ(attr.value.objlist.list[0], 0x1); + EXPECT_EQ(attr.value.objlist.list[1], 0x42); + EXPECT_EQ(attr.value.objlist.list[2], 0x77); +} + +TEST(SaiSerialize, serialize_acl_action) +{ + sai_attribute_t attr; + const sai_attr_metadata_t* meta; + std::string s; + + attr.id = SAI_ACL_ENTRY_ATTR_ACTION_REDIRECT; + + attr.value.aclaction.enable = true; + attr.value.aclaction.parameter.oid = (sai_object_id_t)2; + + meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_ACL_ENTRY, attr.id); + + s = sai_serialize_attr_value(*meta, attr); + + EXPECT_EQ(s, "oid:0x2"); + + attr.value.aclaction.enable = false; + attr.value.aclaction.parameter.oid = (sai_object_id_t)2; + + meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_ACL_ENTRY, attr.id); + + s = sai_serialize_attr_value(*meta, attr); + + EXPECT_EQ(s, "disabled"); + + attr.id = SAI_ACL_ENTRY_ATTR_ACTION_PACKET_ACTION; + + attr.value.aclaction.enable = true; + attr.value.aclaction.parameter.s32 = SAI_PACKET_ACTION_TRAP; + + meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_ACL_ENTRY, attr.id); + + s = sai_serialize_attr_value(*meta, attr); + + EXPECT_EQ(s, "SAI_PACKET_ACTION_TRAP"); + + attr.value.aclaction.enable = true; + attr.value.aclaction.parameter.s32 = 77; + + meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_ACL_ENTRY, attr.id); + + s = sai_serialize_attr_value(*meta, attr); + + EXPECT_EQ(s, "77"); +} + +TEST(SaiSerialize, serialize_qos_map) +{ + sai_attribute_t attr; + const sai_attr_metadata_t* meta; + std::string s; + + attr.id = SAI_QOS_MAP_ATTR_MAP_TO_VALUE_LIST; + + sai_qos_map_t qm = { + .key = { .tc = 1, .dscp = 2, .dot1p = 3, .prio = 4, .pg = 5, .queue_index = 6, .color = SAI_PACKET_COLOR_RED, .mpls_exp = 0 }, + .value = { .tc = 11, .dscp = 22, .dot1p = 33, .prio = 44, .pg = 55, .queue_index = 66, .color = SAI_PACKET_COLOR_GREEN, .mpls_exp = 0 } }; + + attr.value.qosmap.count = 1; + attr.value.qosmap.list = &qm; + + meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_QOS_MAP, attr.id); + + s = sai_serialize_attr_value(*meta, attr); + + std::string ret = "{\"count\":1,\"list\":[{\"key\":{\"color\":\"SAI_PACKET_COLOR_RED\",\"dot1p\":3,\"dscp\":2,\"mpls_exp\":0,\"pg\":5,\"prio\":4,\"qidx\":6,\"tc\":1},\"value\":{\"color\":\"SAI_PACKET_COLOR_GREEN\",\"dot1p\":33,\"dscp\":22,\"mpls_exp\":0,\"pg\":55,\"prio\":44,\"qidx\":66,\"tc\":11}}]}"; + + EXPECT_EQ(s, ret); + + s = sai_serialize_attr_value(*meta, attr, true); + + std::string ret2 = "{\"count\":1,\"list\":null}"; + EXPECT_EQ(s, ret2); + + // deserialize + + memset(&attr, 0, sizeof(attr)); + + sai_deserialize_attr_value(ret, *meta, attr); + + EXPECT_EQ(attr.value.qosmap.count, 1); + + auto &l = attr.value.qosmap.list[0]; + + EXPECT_EQ(l.key.tc, 1); + EXPECT_EQ(l.key.dscp, 2); + EXPECT_EQ(l.key.dot1p, 3); + EXPECT_EQ(l.key.prio, 4); + EXPECT_EQ(l.key.pg, 5); + EXPECT_EQ(l.key.queue_index, 6); + EXPECT_EQ(l.key.color, SAI_PACKET_COLOR_RED); + EXPECT_EQ(l.key.mpls_exp, 0); + + EXPECT_EQ(l.value.tc, 11); + EXPECT_EQ(l.value.dscp, 22); + EXPECT_EQ(l.value.dot1p, 33); + EXPECT_EQ(l.value.prio, 44); + EXPECT_EQ(l.value.pg, 55); + EXPECT_EQ(l.value.queue_index, 66); + EXPECT_EQ(l.value.color, SAI_PACKET_COLOR_GREEN); + EXPECT_EQ(l.value.mpls_exp, 0); +} + +template +static void deserialize_number( + _In_ const std::string& s, + _Out_ T& number, + _In_ bool hex = false) +{ + SWSS_LOG_ENTER(); + + errno = 0; + + char *endptr = NULL; + + number = (T)strtoull(s.c_str(), &endptr, hex ? 16 : 10); + + if (errno != 0 || endptr != s.c_str() + s.length()) + { + SWSS_LOG_THROW("invalid number %s", s.c_str()); + } +} + +template +static std::string serialize_number( + _In_ const T& number, + _In_ bool hex = false) +{ + SWSS_LOG_ENTER(); + + if (hex) + { + char buf[32]; + + snprintf(buf, sizeof(buf), "0x%" PRIx64, (uint64_t)number); + + return buf; + } + + return std::to_string(number); +} + +TEST(SaiSerialize, serialize_number) +{ + SWSS_LOG_ENTER(); + + int64_t sp = 0x12345678; + int64_t sn = -0x12345678; + int64_t u = 0x12345678; + + auto ssp = serialize_number(sp); + auto ssn = serialize_number(sn); + auto su = serialize_number(u); + + EXPECT_EQ(ssp, std::to_string(sp)); + EXPECT_EQ(ssn, std::to_string(sn)); + EXPECT_EQ(su, std::to_string(u)); + + auto shsp = serialize_number(sp, true); + auto shsn = serialize_number(sn, true); + auto shu = serialize_number(u, true); + + EXPECT_EQ(shsp, "0x12345678"); + EXPECT_EQ(shsn, "0xffffffffedcba988"); + EXPECT_EQ(shu, "0x12345678"); + + sp = 0; + sn = 0; + u = 0; + + deserialize_number(ssp, sp); + deserialize_number(ssn, sn); + deserialize_number(su, u); + + EXPECT_EQ(sp, 0x12345678); + EXPECT_EQ(sn, -0x12345678); + EXPECT_EQ(u, 0x12345678); + + deserialize_number(shsp, sp, true); + deserialize_number(shsn, sn, true); + deserialize_number(shu, u, true); + + EXPECT_EQ(sp, 0x12345678); + EXPECT_EQ(sn, -0x12345678); + EXPECT_EQ(u, 0x12345678); +} diff --git a/unittest/meta/TestZeroMQSelectableChannel.cpp b/unittest/meta/TestZeroMQSelectableChannel.cpp new file mode 100644 index 000000000..443b6dc4b --- /dev/null +++ b/unittest/meta/TestZeroMQSelectableChannel.cpp @@ -0,0 +1,89 @@ +#include "ZeroMQSelectableChannel.h" +#include "ZeroMQChannel.h" + +#include "swss/select.h" + +#include + +using namespace sairedis; + +TEST(ZeroMQSelectableChannel, ctr) +{ + EXPECT_THROW(std::make_shared("/dev_not/foo"), std::runtime_error); +} + +TEST(ZeroMQSelectableChannel, empty) +{ + ZeroMQSelectableChannel c("ipc:///tmp/zmq_test"); + + EXPECT_EQ(c.empty(), true); +} + +TEST(ZeroMQSelectableChannel, pop) +{ + ZeroMQSelectableChannel c("ipc:///tmp/zmq_test"); + + swss::KeyOpFieldsValuesTuple kco; + + EXPECT_THROW(c.pop(kco, false), std::runtime_error); +} + +TEST(ZeroMQSelectableChannel, hasData) +{ + ZeroMQSelectableChannel c("ipc:///tmp/zmq_test"); + + EXPECT_EQ(c.hasData(), false); +} + +TEST(ZeroMQSelectableChannel, hasCachedData) +{ + ZeroMQSelectableChannel c("ipc:///tmp/zmq_test"); + + EXPECT_EQ(c.hasCachedData(), false); +} + +TEST(ZeroMQSelectableChannel, set) +{ + ZeroMQSelectableChannel c("ipc:///tmp/zmq_test"); + + std::vector values; + + // wrong state + EXPECT_THROW(c.set("key", values, "op"), std::runtime_error); +} + +static void cb( + _In_ const std::string&, + _In_ const std::string&, + _In_ const std::vector&) +{ + SWSS_LOG_ENTER(); + + // notification callback +} + +TEST(ZeroMQSelectableChannel, readData) +{ + ZeroMQChannel main("ipc:///tmp/zmq_test", "ipc:///tmp/zmq_test_ntf", cb); + + ZeroMQSelectableChannel c("ipc:///tmp/zmq_test"); + + swss::Select ss; + + ss.addSelectable(&c); + + swss::Selectable *sel = NULL; + + std::vector values; + + main.set("key", values, "command"); + + int result = ss.select(&sel); + + EXPECT_EQ(result, swss::Select::OBJECT); + + swss::KeyOpFieldsValuesTuple kco; + + c.pop(kco, false); +} + diff --git a/unittest/meta/main.cpp b/unittest/meta/main.cpp index e4af24fa3..61f8cd250 100644 --- a/unittest/meta/main.cpp +++ b/unittest/meta/main.cpp @@ -2,7 +2,7 @@ #include -class SwsscommonEnvironment: +class SwsscommonEnvironment: public ::testing::Environment { public: diff --git a/unittest/syncd/Makefile.am b/unittest/syncd/Makefile.am index 77b637677..8a76873df 100644 --- a/unittest/syncd/Makefile.am +++ b/unittest/syncd/Makefile.am @@ -1,4 +1,4 @@ -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 bin_PROGRAMS = tests diff --git a/unittest/vslib/TestBuffer.cpp b/unittest/vslib/TestBuffer.cpp index 64e233b49..a1876081a 100644 --- a/unittest/vslib/TestBuffer.cpp +++ b/unittest/vslib/TestBuffer.cpp @@ -8,7 +8,7 @@ using namespace saivs; TEST(Buffer, ctr) { - EXPECT_THROW(new Buffer(0,0), std::runtime_error); + EXPECT_THROW(std::make_shared(nullptr, 0), std::runtime_error); Buffer b((const uint8_t*)"foo", 3); } @@ -22,7 +22,7 @@ TEST(Buffer, dtr) TEST(Buffer, getData) { - EXPECT_THROW(new Buffer(0,0), std::runtime_error); + EXPECT_THROW(std::make_shared(nullptr,0), std::runtime_error); Buffer b((const uint8_t*)"foo", 3); @@ -31,7 +31,7 @@ TEST(Buffer, getData) TEST(Buffer, getSize) { - EXPECT_THROW(new Buffer(0,0), std::runtime_error); + EXPECT_THROW(std::make_shared(nullptr,0), std::runtime_error); Buffer b((const uint8_t*)"foo", 3); @@ -40,7 +40,7 @@ TEST(Buffer, getSize) TEST(Buffer, flow) { - EXPECT_THROW(new Buffer(0,0), std::runtime_error); + EXPECT_THROW(std::make_shared(nullptr,0), std::runtime_error); Buffer b((const uint8_t*)"foo", 3); diff --git a/unittest/vslib/TestFdbInfo.cpp b/unittest/vslib/TestFdbInfo.cpp index 4089b2c70..d1a6ba5cb 100644 --- a/unittest/vslib/TestFdbInfo.cpp +++ b/unittest/vslib/TestFdbInfo.cpp @@ -59,7 +59,7 @@ TEST(FdbInfo, serialize) TEST(FdbInfo, deserialize) { - std::string str = + std::string str = "{\"bridge_port_id\":\"oid:0x1\"," "\"fdb_entry\":\"{\\\"bvid\\\":\\\"oid:0x0\\\",\\\"mac\\\":\\\"00:00:00:00:00:00\\\",\\\"switch_id\\\":\\\"oid:0x0\\\"}\"," "\"port_id\":\"oid:0x0\"," @@ -124,14 +124,14 @@ TEST(FdbInfo, setTimestamp) TEST(FdbInfo, operator_bracket) { - std::string strA = + std::string strA = "{\"bridge_port_id\":\"oid:0x1\"," "\"fdb_entry\":\"{\\\"bvid\\\":\\\"oid:0x0\\\",\\\"mac\\\":\\\"00:00:00:00:00:00\\\",\\\"switch_id\\\":\\\"oid:0x0\\\"}\"," "\"port_id\":\"oid:0x0\"," "\"timestamp\":\"0\"," "\"vlan_id\":\"0\"}"; - std::string strB = + std::string strB = "{\"bridge_port_id\":\"oid:0x1\"," "\"fdb_entry\":\"{\\\"bvid\\\":\\\"oid:0x0\\\",\\\"mac\\\":\\\"00:00:00:00:00:01\\\",\\\"switch_id\\\":\\\"oid:0x0\\\"}\"," "\"port_id\":\"oid:0x0\"," @@ -147,14 +147,14 @@ TEST(FdbInfo, operator_bracket) TEST(FdbInfo, operator_lt) { - std::string strA = + std::string strA = "{\"bridge_port_id\":\"oid:0x1\"," "\"fdb_entry\":\"{\\\"bvid\\\":\\\"oid:0x0\\\",\\\"mac\\\":\\\"00:00:00:00:00:00\\\",\\\"switch_id\\\":\\\"oid:0x0\\\"}\"," "\"port_id\":\"oid:0x0\"," "\"timestamp\":\"0\"," "\"vlan_id\":\"0\"}"; - std::string strB = + std::string strB = "{\"bridge_port_id\":\"oid:0x1\"," "\"fdb_entry\":\"{\\\"bvid\\\":\\\"oid:0x0\\\",\\\"mac\\\":\\\"00:00:00:00:00:01\\\",\\\"switch_id\\\":\\\"oid:0x0\\\"}\"," "\"port_id\":\"oid:0x0\"," @@ -169,14 +169,14 @@ TEST(FdbInfo, operator_lt) EXPECT_EQ(a < a, false); EXPECT_EQ(b < b, false); - std::string strC = + std::string strC = "{\"bridge_port_id\":\"oid:0x1\"," "\"fdb_entry\":\"{\\\"bvid\\\":\\\"oid:0x0\\\",\\\"mac\\\":\\\"00:00:00:00:00:00\\\",\\\"switch_id\\\":\\\"oid:0x0\\\"}\"," "\"port_id\":\"oid:0x0\"," "\"timestamp\":\"0\"," "\"vlan_id\":\"1\"}"; - std::string strD = + std::string strD = "{\"bridge_port_id\":\"oid:0x1\"," "\"fdb_entry\":\"{\\\"bvid\\\":\\\"oid:0x0\\\",\\\"mac\\\":\\\"00:00:00:00:00:00\\\",\\\"switch_id\\\":\\\"oid:0x0\\\"}\"," "\"port_id\":\"oid:0x0\"," diff --git a/unittest/vslib/TestSwitchBCM56850.cpp b/unittest/vslib/TestSwitchBCM56850.cpp index 3aef75f38..6c049259f 100644 --- a/unittest/vslib/TestSwitchBCM56850.cpp +++ b/unittest/vslib/TestSwitchBCM56850.cpp @@ -37,7 +37,7 @@ TEST(SwitchBCM56850, ctr) nullptr); sai_attribute_t attr; - + attr.id = SAI_SWITCH_ATTR_INIT_SWITCH; attr.value.booldata = true; @@ -67,7 +67,7 @@ TEST(SwitchBCM56850, refresh_bridge_port_list) sc); sai_attribute_t attr; - + attr.id = SAI_SWITCH_ATTR_INIT_SWITCH; attr.value.booldata = true; @@ -92,7 +92,7 @@ TEST(SwitchBCM56850, refresh_bridge_port_list) attr.value.objlist.list = list; EXPECT_EQ(sw.get(SAI_OBJECT_TYPE_BRIDGE, sboid, 1, &attr), SAI_STATUS_SUCCESS); - + //std::cout << sw.dump_switch_database_for_warm_restart(); } @@ -242,7 +242,7 @@ TEST(SwitchBCM56850, warm_update_queues) warmBootState); sai_attribute_t attr; - + attr.id = SAI_SWITCH_ATTR_INIT_SWITCH; attr.value.booldata = true; diff --git a/unittest/vslib/TestSwitchBCM81724.cpp b/unittest/vslib/TestSwitchBCM81724.cpp index 4fc854eca..416967615 100644 --- a/unittest/vslib/TestSwitchBCM81724.cpp +++ b/unittest/vslib/TestSwitchBCM81724.cpp @@ -37,7 +37,7 @@ TEST(SwitchBCM81724, ctr) nullptr); sai_attribute_t attr; - + attr.id = SAI_SWITCH_ATTR_INIT_SWITCH; attr.value.booldata = true; @@ -71,7 +71,7 @@ TEST(SwitchBCM81724, refresh_read_only) sc); sai_attribute_t attr; - + attr.id = SAI_SWITCH_ATTR_INIT_SWITCH; attr.value.booldata = true; @@ -98,7 +98,7 @@ TEST(SwitchBCM81724, refresh_read_only) attrs[1].value.u32 = 10000; sai_object_id_t portId = mgr->allocateNewObjectId(SAI_OBJECT_TYPE_PORT, switchId); - + auto strPortId = sai_serialize_object_id(portId); EXPECT_EQ(sw.create(SAI_OBJECT_TYPE_PORT, strPortId, switchId, 2, attrs), SAI_STATUS_SUCCESS); diff --git a/unittest/vslib/TestSwitchMLNX2700.cpp b/unittest/vslib/TestSwitchMLNX2700.cpp index e9bf11508..8086ea692 100644 --- a/unittest/vslib/TestSwitchMLNX2700.cpp +++ b/unittest/vslib/TestSwitchMLNX2700.cpp @@ -37,7 +37,7 @@ TEST(SwitchMLNX2700, ctr) nullptr); sai_attribute_t attr; - + attr.id = SAI_SWITCH_ATTR_INIT_SWITCH; attr.value.booldata = true; @@ -67,7 +67,7 @@ TEST(SwitchMLNX2700, refresh_bridge_port_list) sc); sai_attribute_t attr; - + attr.id = SAI_SWITCH_ATTR_INIT_SWITCH; attr.value.booldata = true; @@ -241,7 +241,7 @@ TEST(SwitchMLNX2700, warm_update_queues) warmBootState); sai_attribute_t attr; - + attr.id = SAI_SWITCH_ATTR_INIT_SWITCH; attr.value.booldata = true; diff --git a/unittest/vslib/TestTrafficForwarder.cpp b/unittest/vslib/TestTrafficForwarder.cpp index 270e54226..d1c9ed43f 100644 --- a/unittest/vslib/TestTrafficForwarder.cpp +++ b/unittest/vslib/TestTrafficForwarder.cpp @@ -47,7 +47,7 @@ TEST(TrafficForwarder, addVlanTag) struct tpacket_auxdata* aux = (struct tpacket_auxdata*)CMSG_DATA(cmsg); // https://en.wikipedia.org/wiki/IEEE_802.1Q - // + // // TPID(16) | TCI(16) // | PCP(3) DEI(1) VID(12) @@ -62,5 +62,5 @@ TEST(TrafficForwarder, addVlanTag) EXPECT_TRUE(TrafficForwarder::addVlanTag(buffer, length, hdr)); - EXPECT_EQ(length, 68); + EXPECT_EQ(length, 68); } diff --git a/unittest/vslib/main_libsaivs.cpp b/unittest/vslib/main_libsaivs.cpp index e83478491..0505f7e59 100644 --- a/unittest/vslib/main_libsaivs.cpp +++ b/unittest/vslib/main_libsaivs.cpp @@ -76,12 +76,12 @@ static sai_service_method_table_t test_services = { profile_get_next_value }; -class VirtualSwitchEnvironment: +class VirtualSwitchEnvironment: public ::testing::Environment { public: - virtual void SetUp() override + virtual void SetUp() override { SWSS_LOG_ENTER(); @@ -93,7 +93,7 @@ class VirtualSwitchEnvironment: EXPECT_EQ(status, SAI_STATUS_SUCCESS); } - + virtual void TearDown() override { SWSS_LOG_ENTER(); diff --git a/unittest/vslib/test_sai_vs_hostif.cpp b/unittest/vslib/test_sai_vs_hostif.cpp index f98a54315..919b0cabd 100644 --- a/unittest/vslib/test_sai_vs_hostif.cpp +++ b/unittest/vslib/test_sai_vs_hostif.cpp @@ -30,7 +30,7 @@ TEST(libsaivs, hostif) EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_hostif_trap_group(0)); EXPECT_NE(SAI_STATUS_SUCCESS, api->set_hostif_trap_group_attribute(0,0)); EXPECT_NE(SAI_STATUS_SUCCESS, api->get_hostif_trap_group_attribute(0,0,0)); - + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_hostif_trap(&id,0,0,0)); EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_hostif_trap(0)); EXPECT_NE(SAI_STATUS_SUCCESS, api->set_hostif_trap_attribute(0,0)); diff --git a/vslib/Switch.cpp b/vslib/Switch.cpp index 1729083f4..874f7767a 100644 --- a/vslib/Switch.cpp +++ b/vslib/Switch.cpp @@ -106,7 +106,7 @@ void Switch::updateNotifications( break; case SAI_SWITCH_ATTR_BFD_SESSION_STATE_CHANGE_NOTIFY: - m_switchNotifications.on_bfd_session_state_change = + m_switchNotifications.on_bfd_session_state_change = (sai_bfd_session_state_change_notification_fn)attr.value.ptr; break; diff --git a/vslib/SwitchStateBaseHostif.cpp b/vslib/SwitchStateBaseHostif.cpp index 219fa22cb..01f44a17b 100644 --- a/vslib/SwitchStateBaseHostif.cpp +++ b/vslib/SwitchStateBaseHostif.cpp @@ -665,14 +665,14 @@ sai_status_t SwitchStateBase::vs_create_hostif_tap_interface( SWSS_LOG_ERROR("failed to get admin state for port %s", sai_serialize_object_id(obj_id).c_str()); - return false; + return status; } if (ifup(vname.c_str(), obj_id, attr.value.booldata, false)) { SWSS_LOG_ERROR("ifup failed on %s", vname.c_str()); - return false; + return SAI_STATUS_FAILURE; } if (!hostif_create_tap_veth_forwarding(name, tapfd, obj_id)) diff --git a/vslib/TrafficForwarder.cpp b/vslib/TrafficForwarder.cpp index 3f077c6eb..0c867a8a9 100644 --- a/vslib/TrafficForwarder.cpp +++ b/vslib/TrafficForwarder.cpp @@ -37,7 +37,7 @@ bool TrafficForwarder::addVlanTag( if (cmsg->cmsg_level != SOL_PACKET || cmsg->cmsg_type != PACKET_AUXDATA) continue; - struct tpacket_auxdata* aux = (struct tpacket_auxdata*)CMSG_DATA(cmsg); + struct tpacket_auxdata* aux = (struct tpacket_auxdata*)(void *)CMSG_DATA(cmsg); if ((aux->tp_status & TP_STATUS_VLAN_VALID) && (aux->tp_status & TP_STATUS_VLAN_TPID_VALID))