diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 9521892a7..e1413cfa5 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -69,8 +69,8 @@ jobs: autoconf-archive \ uuid-dev \ libjansson-dev \ - python \ - nlohmann-json3-dev + nlohmann-json3-dev \ + python - if: matrix.language == 'cpp' name: build-swss-common diff --git a/configure.ac b/configure.ac index b95367ef5..0d25c024b 100644 --- a/configure.ac +++ b/configure.ac @@ -249,6 +249,7 @@ AC_OUTPUT(Makefile unittest/lib/Makefile unittest/vslib/Makefile unittest/syncd/Makefile + unittest/saidump/Makefile pyext/Makefile pyext/py2/Makefile pyext/py3/Makefile) diff --git a/saidump/Makefile.am b/saidump/Makefile.am index 46c51d0fc..104c175d9 100644 --- a/saidump/Makefile.am +++ b/saidump/Makefile.am @@ -7,3 +7,7 @@ saidump_CPPFLAGS = $(CODE_COVERAGE_CPPFLAGS) saidump_CXXFLAGS = $(DBGFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS_COMMON) $(CODE_COVERAGE_CXXFLAGS) saidump_LDADD = -lhiredis -lswsscommon -lpthread -L$(top_srcdir)/meta/.libs -lsaimetadata -lsaimeta \ -L$(top_srcdir)/lib/.libs -lsairedis -lzmq $(CODE_COVERAGE_LIBS) + +noinst_LIBRARIES = libsaidump.a +libsaidump_a_SOURCES = saidump.cpp +AM_CPPFLAGS = -D_UNITTEST_ \ No newline at end of file diff --git a/saidump/saidump.cpp b/saidump/saidump.cpp index 522f5bb40..094de48b1 100644 --- a/saidump/saidump.cpp +++ b/saidump/saidump.cpp @@ -15,28 +15,14 @@ extern "C" { #include "meta/sai_serialize.h" #include "sairediscommon.h" #include "swss/json.hpp" - +#include "saidump.h" #include // TODO split to multiple cpp using namespace swss; using json = nlohmann::json; - -// Default value: 100 MB -constexpr int64_t RDB_JSON_MAX_SIZE = 1024 * 1024 * 100; - -struct CmdOptions -{ - bool skipAttributes; - bool dumpTempView; - bool dumpGraph; - std::string rdbJsonFile; - uint64_t rdbJSonSizeLimit; -}; - - -static CmdOptions g_cmdOptions; +CmdOptions g_cmdOptions; static std::map g_oid_map; void printUsage() @@ -451,7 +437,7 @@ void dumpGraph(const TableDump& td) /** * @brief Process the input JSON file to make sure it's a valid JSON file for the JSON library. */ -static sai_status_t preProcessFile(const std::string file_name) +sai_status_t preProcessFile(const std::string file_name) { SWSS_LOG_ENTER(); @@ -502,7 +488,7 @@ static sai_status_t preProcessFile(const std::string file_name) return SAI_STATUS_SUCCESS; } -static sai_status_t dumpFromRedisRdbJson(const std::string file_name) +sai_status_t dumpFromRedisRdbJson(const std::string file_name) { SWSS_LOG_ENTER(); @@ -592,6 +578,7 @@ static sai_status_t dumpFromRedisRdbJson(const std::string file_name) return SAI_STATUS_FAILURE; } +#ifndef _UNITTEST_ int main(int argc, char **argv) { swss::Logger::getInstance().setMinPrio(swss::Logger::SWSS_DEBUG); @@ -674,3 +661,4 @@ int main(int argc, char **argv) return EXIT_SUCCESS; } +#endif \ No newline at end of file diff --git a/saidump/saidump.h b/saidump/saidump.h new file mode 100755 index 000000000..b6145a87b --- /dev/null +++ b/saidump/saidump.h @@ -0,0 +1,19 @@ +#pragma once +#include + +// Default value: 100 MB +constexpr int64_t RDB_JSON_MAX_SIZE = 1024 * 1024 * 100; + +struct CmdOptions +{ + bool skipAttributes; + bool dumpTempView; + bool dumpGraph; + std::string rdbJsonFile; + uint64_t rdbJSonSizeLimit; +}; + +void printUsage(); +CmdOptions handleCmdLine(int argc, char **argv); +sai_status_t dumpFromRedisRdbJson(const std::string file_name); +sai_status_t preProcessFile(const std::string file_name); \ No newline at end of file diff --git a/unittest/Makefile.am b/unittest/Makefile.am index 9be94ee0a..175555bed 100644 --- a/unittest/Makefile.am +++ b/unittest/Makefile.am @@ -1 +1 @@ -SUBDIRS = meta lib vslib syncd +SUBDIRS = meta lib vslib syncd saidump diff --git a/unittest/saidump/Makefile.am b/unittest/saidump/Makefile.am new file mode 100755 index 000000000..0519d4ca6 --- /dev/null +++ b/unittest/saidump/Makefile.am @@ -0,0 +1,13 @@ +AM_CXXFLAGS = $(SAIINC) -I$(top_srcdir)/saidump -I$(top_srcdir)/lib -I$(top_srcdir)/vslib -I$(top_srcdir)/meta + +bin_PROGRAMS = tests + +LDADD_GTEST = -L/usr/src/gtest -lgtest -lgtest_main + +tests_SOURCES = main.cpp + +tests_CXXFLAGS = $(DBGFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS_COMMON) +tests_LDFLAGS = -D_UNITTEST_ +tests_LDADD = $(LDADD_GTEST) $(top_srcdir)/saidump/libsaidump.a -lhiredis -lswsscommon -lnl-genl-3 -lnl-nf-3 -lnl-route-3 -lnl-3 -lpthread -L$(top_srcdir)/lib/.libs -lsairedis -L$(top_srcdir)/meta/.libs -lsaimetadata -lsaimeta -lzmq $(CODE_COVERAGE_LIBS) + +TESTS = tests \ No newline at end of file diff --git a/unittest/saidump/dump.json b/unittest/saidump/dump.json new file mode 100755 index 000000000..6ab042953 --- /dev/null +++ b/unittest/saidump/dump.json @@ -0,0 +1,73 @@ +[{ +"ROUTE_TABLE:10.1.0.2":{"nexthop":"3.3.3.18,3.3.3.20","ifname":"Ethernet-IB0,Ethernet-IB0","weight":"1,1"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board41:asic0:Ethernet136:5-6":{"profile":"egress_lossy_profile"}, +"SYSTEM_PORT_TABLE:ixre-egl-board41|asic0|Ethernet112":{"core_index":"0","core_port_index":"15","num_voq":"8","speed":"400000","switch_id":"18","system_port_id":"57"}, +"SYSTEM_PORT_TABLE:ixre-egl-board40|asic1|Ethernet280":{"core_index":"0","core_port_index":"18","num_voq":"8","speed":"400000","switch_id":"2","system_port_id":"39"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board41:asic1:Ethernet176:3-4":{"profile":"egress_lossless_profile"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board41:asic0:Ethernet64:5-6":{"profile":"egress_lossy_profile"}, +"SYSTEM_PORT_TABLE:ixre-egl-board40|asic0|Ethernet-IB0":{"core_index":"0","core_port_index":"19","num_voq":"8","speed":"10000","switch_id":"0","system_port_id":"19"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board40:asic1:Ethernet176:3-4":{"profile":"egress_lossless_profile"}, +"SYSTEM_PORT_TABLE:ixre-egl-board40|asic1|Ethernet208":{"core_index":"1","core_port_index":"9","num_voq":"8","speed":"400000","switch_id":"2","system_port_id":"30"}, +"INTF_TABLE:Ethernet136:10.0.0.4/31":{"scope":"global","family":"IPv4"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board40:asic1:Ethernet224:3-4":{"profile":"egress_lossless_profile"}, +"BUFFER_PROFILE_TABLE:egress_lossy_profile":{"dynamic_th":"-1","pool":"ingress_lossless_pool","size":"0"}, +"ROUTE_TABLE:10.0.0.10/31":{"nexthop":"3.3.3.2","ifname":"Ethernet-IB0"}, +"SYSTEM_PORT_TABLE:ixre-egl-board41|asic0|Ethernet-IB0":{"core_index":"0","core_port_index":"19","num_voq":"8","speed":"10000","switch_id":"18","system_port_id":"61"}, +"SYSTEM_PORT_TABLE:ixre-egl-board40|asic0|Ethernet64":{"core_index":"1","core_port_index":"9","num_voq":"8","speed":"400000","switch_id":"0","system_port_id":"9"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board41:asic0:Ethernet0:5-6":{"profile":"egress_lossy_profile"}, +"BUFFER_PG_TABLE:Ethernet80:0":{"profile":"ingress_lossy_profile"}, +"SYSTEM_PORT_TABLE:ixre-egl-board41|asic1|Ethernet-Rec1":{"core_index":"1","core_port_index":"20","num_voq":"8","speed":"10000","switch_id":"20","system_port_id":"83"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board41:asic1:Ethernet224:0-2":{"profile":"egress_lossy_profile"}, +"ROUTE_TABLE:10.0.0.4/31":{"nexthop":"0.0.0.0","ifname":"Ethernet136"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board41:asic0:Ethernet120:3-4":{"profile":"egress_lossless_profile"}, +"PORT_TABLE:Ethernet104":{"alias":"Ethernet14/1","asic_port_name":"Eth104","coreid":"0","coreportid":"14","description":"Ethernet14/1","index":"14","lanes":"32,33,34,35,36,37,38,39","mtu":"9100","numvoq":"8","pfc_asym":"off","role":"Ext","speed":"400000","tpid":"0x8100","admin_status":"down","oper_status":"down"}, +"ROUTE_TABLE:3333::3:1":{"nexthop":"::","ifname":"Ethernet-IB0"}, +"INTF_TABLE:Ethernet-IB0:3.3.3.1/32":{"scope":"global","family":"IPv4"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board41:asic1:Ethernet272:0-2":{"profile":"egress_lossy_profile"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board41:asic0:Ethernet8:5-6":{"profile":"egress_lossy_profile"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board40:asic0:Ethernet104:0-2":{"profile":"egress_lossy_profile"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board41:asic0:Ethernet96:0-2":{"profile":"egress_lossy_profile"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board41:asic0:Ethernet8:3-4":{"profile":"egress_lossless_profile"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board41:asic0:Ethernet72:0-2":{"profile":"egress_lossy_profile"}, +"LAG_MEMBER_TABLE:PortChannel102:Ethernet80":{"status":"disabled"}, +"SYSTEM_PORT_TABLE:ixre-egl-board41|asic1|Ethernet192":{"core_index":"1","core_port_index":"7","num_voq":"8","speed":"400000","switch_id":"20","system_port_id":"70"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board40:asic1:Ethernet160:3-4":{"profile":"egress_lossless_profile"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board40:asic0:Ethernet96:5-6":{"profile":"egress_lossy_profile"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board40:asic1:Ethernet264:3-4":{"profile":"egress_lossless_profile"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board40:asic1:Ethernet272:5-6":{"profile":"egress_lossy_profile"}, +"BUFFER_POOL_TABLE:ingress_lossless_pool":{"mode":"dynamic","size":"6441610000","type":"both","xoff":"11354112"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board41:asic1:Ethernet192:5-6":{"profile":"egress_lossy_profile"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board40:asic1:Ethernet272:3-4":{"profile":"egress_lossless_profile"}, +"LAG_MEMBER_TABLE:PortChannel102:Ethernet32":{"status":"disabled"}, +"SYSTEM_PORT_TABLE:ixre-egl-board41|asic1|Ethernet184":{"core_index":"1","core_port_index":"6","num_voq":"8","speed":"400000","switch_id":"20","system_port_id":"69"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board41:asic1:Ethernet208:0-2":{"profile":"egress_lossy_profile"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board40:asic1:Ethernet248:0-2":{"profile":"egress_lossy_profile"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board40:asic0:Ethernet72:0-2":{"profile":"egress_lossy_profile"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board40:asic0:Ethernet32:3-4":{"profile":"egress_lossless_profile"}, +"INTF_TABLE:PortChannel102:10.0.0.0/31":{"scope":"global","family":"IPv4"}, +"PORT_TABLE:Ethernet32":{"mtu":"9100","admin_status":"up","alias":"Ethernet5/1","asic_port_name":"Eth32","coreid":"1","coreportid":"5","description":"ARISTA01T3:Ethernet1","index":"5","lanes":"104,105,106,107,108,109,110,111","numvoq":"8","pfc_asym":"off","role":"Ext","speed":"400000","tpid":"0x8100","oper_status":"up"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board40:asic1:Ethernet168:5-6":{"profile":"egress_lossy_profile"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board41:asic1:Ethernet176:0-2":{"profile":"egress_lossy_profile"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board41:asic0:Ethernet56:5-6":{"profile":"egress_lossy_profile"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board41:asic0:Ethernet96:3-4":{"profile":"egress_lossless_profile"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board40:asic0:Ethernet120:5-6":{"profile":"egress_lossy_profile"}, +"BUFFER_PROFILE_TABLE:ingress_lossy_profile":{"dynamic_th":"0","pool":"ingress_lossless_pool","size":"1280","xon_offset":"2560"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board41:asic0:Ethernet48:0-2":{"profile":"egress_lossy_profile"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board41:asic1:Ethernet200:0-2":{"profile":"egress_lossy_profile"}, +"COPP_TABLE:queue1_group1":{"cbs":"6000","cir":"6000","meter_type":"packets","mode":"sr_tcm","queue":"1","red_action":"drop","trap_action":"trap","trap_priority":"1","trap_ids":"ip2me"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board40:asic1:Ethernet184:3-4":{"profile":"egress_lossless_profile"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board41:asic1:Ethernet248:5-6":{"profile":"egress_lossy_profile"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board41:asic1:Ethernet256:3-4":{"profile":"egress_lossless_profile"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board40:asic0:Ethernet88:5-6":{"profile":"egress_lossy_profile"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board40:asic0:Ethernet48:3-4":{"profile":"egress_lossless_profile"}, +"SYSTEM_PORT_TABLE:ixre-egl-board40|asic1|Ethernet224":{"core_index":"0","core_port_index":"11","num_voq":"8","speed":"400000","switch_id":"2","system_port_id":"32"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board41:asic0:Ethernet24:0-2":{"profile":"egress_lossy_profile"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board40:asic1:Ethernet168:0-2":{"profile":"egress_lossy_profile"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board41:asic0:Ethernet56:3-4":{"profile":"egress_lossless_profile"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board41:asic1:Ethernet272:5-6":{"profile":"egress_lossy_profile"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board40:asic1:Ethernet208:5-6":{"profile":"egress_lossy_profile"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board41:asic0:Ethernet96:5-6":{"profile":"egress_lossy_profile"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board41:asic1:Ethernet152:3-4":{"profile":"egress_lossless_profile"}, +"BUFFER_QUEUE_TABLE:ixre-egl-board41:asic0:Ethernet40:5-6":{"profile":"egress_lossy_profile"}, +"INTF_TABLE:Loopback0":{"NULL":"NULL","mac_addr":"00:00:00:00:00:00"} +}] \ No newline at end of file diff --git a/unittest/saidump/main.cpp b/unittest/saidump/main.cpp new file mode 100755 index 000000000..06a77b5d9 --- /dev/null +++ b/unittest/saidump/main.cpp @@ -0,0 +1,57 @@ +#include +#include "meta/sai_serialize.h" +#include "saidump.h" +#define ARGVN 5 + +extern CmdOptions g_cmdOptions; + +TEST(SaiDump, printUsage) +{ + SWSS_LOG_ENTER(); + testing::internal::CaptureStdout(); + printUsage(); + std::string output = testing::internal::GetCapturedStdout(); + EXPECT_EQ(true, output.find("Usage: saidump [-t] [-g] [-r] [-m] [-h]") != std::string::npos); +} + +TEST(SaiDump, handleCmdLine) +{ + SWSS_LOG_ENTER(); + const char *arr[] = {"saidump", "-r", "./dump.json", "-m", "100"}; + char **argv = new char *[ARGVN]; + + for (int i = 0; i < ARGVN; ++i) + { + argv[i] = const_cast(arr[i]); + } + + g_cmdOptions = handleCmdLine(ARGVN, argv); + delete[] argv; + EXPECT_EQ(g_cmdOptions.rdbJsonFile, "./dump.json"); + EXPECT_EQ(g_cmdOptions.rdbJSonSizeLimit, RDB_JSON_MAX_SIZE); +} + +TEST(SaiDump, dumpFromRedisRdbJson) +{ + SWSS_LOG_ENTER(); + EXPECT_EQ(SAI_STATUS_FAILURE, dumpFromRedisRdbJson("")); + EXPECT_EQ(SAI_STATUS_FAILURE, dumpFromRedisRdbJson("./dump.json")); +} + +TEST(SaiDump, preProcessFile) +{ + SWSS_LOG_ENTER(); + EXPECT_EQ(SAI_STATUS_FAILURE, preProcessFile("")); + g_cmdOptions.rdbJSonSizeLimit = 0; + EXPECT_EQ(SAI_STATUS_FAILURE, preProcessFile("./dump.json")); + g_cmdOptions.rdbJSonSizeLimit = RDB_JSON_MAX_SIZE; + EXPECT_EQ(SAI_STATUS_SUCCESS, preProcessFile("./dump.json")); + EXPECT_EQ(SAI_STATUS_SUCCESS, dumpFromRedisRdbJson("./dump.json")); +} + +int main(int argc, char *argv[]) +{ + SWSS_LOG_ENTER(); + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} \ No newline at end of file