vslib/tests.cpp (561 lines of code) (raw):

#include <map> #include <string> #include <vector> #include <unistd.h> #include "swss/logger.h" #include "swss/dbconnector.h" #include "swss/schema.h" #include "swss/notificationproducer.h" #include "meta/sai_serialize.h" extern "C" { #include <sai.h> } #include "saivs.h" const char* profile_get_value( _In_ sai_switch_profile_id_t profile_id, _In_ const char* variable) { SWSS_LOG_ENTER(); SWSS_LOG_NOTICE("request: %s", variable); if (std::string(variable) == SAI_KEY_VS_SWITCH_TYPE) { return SAI_VALUE_VS_SWITCH_TYPE_MLNX2700; } return NULL; } int profile_get_next_value( _In_ sai_switch_profile_id_t profile_id, _Out_ const char** variable, _Out_ const char** value) { SWSS_LOG_ENTER(); if (value == NULL) { SWSS_LOG_INFO("resetting profile map iterator"); return 0; } if (variable == NULL) { SWSS_LOG_WARN("variable is null"); return -1; } SWSS_LOG_INFO("iterator reached end"); return -1; } sai_service_method_table_t test_services = { profile_get_value, profile_get_next_value }; #define SUCCESS(x) \ if ((x) != SAI_STATUS_SUCCESS) \ {\ SWSS_LOG_THROW("expected success on: %s", #x);\ } #define NOT_SUCCESS(x) \ if ((x) == SAI_STATUS_SUCCESS) \ {\ SWSS_LOG_THROW("expected failure, got success on: %s", #x);\ } #define ASSERT_TRUE(x)\ {\ if (!(x))\ {\ SWSS_LOG_THROW("assert true failed %s", #x);\ }\ } void on_switch_state_change( _In_ sai_switch_oper_status_t switch_oper_status) { SWSS_LOG_ENTER(); } void on_fdb_event( _In_ uint32_t count, _In_ sai_fdb_event_notification_data_t *data) { SWSS_LOG_ENTER(); } void on_port_state_change( _In_ uint32_t count, _In_ sai_port_oper_status_notification_t *data) { SWSS_LOG_ENTER(); } void on_switch_shutdown_request() { SWSS_LOG_ENTER(); } void on_packet_event( _In_ const void *buffer, _In_ sai_size_t buffer_size, _In_ uint32_t attr_count, _In_ const sai_attribute_t *attr_list) { SWSS_LOG_ENTER(); } static void clearDB() { SWSS_LOG_ENTER(); auto db = std::make_shared<swss::DBConnector>("ASIC_DB", 0, true); swss::RedisReply r(db.get(), "FLUSHALL", REDIS_REPLY_STATUS); r.checkStatusOK(); } static void sai_reinit() { SWSS_LOG_ENTER(); SUCCESS(sai_api_uninitialize()); clearDB(); SUCCESS(sai_api_initialize(0, (sai_service_method_table_t*)&test_services)); } void test_ports() { SWSS_LOG_ENTER(); sai_reinit(); uint32_t expected_ports = 32; sai_attribute_t attr; sai_object_id_t switch_id; attr.id = SAI_SWITCH_ATTR_INIT_SWITCH; attr.value.booldata = true; SUCCESS(sai_metadata_sai_switch_api->create_switch(&switch_id, 1, &attr)); attr.id = SAI_SWITCH_ATTR_PORT_NUMBER; SUCCESS(sai_metadata_sai_switch_api->get_switch_attribute(switch_id, 1, &attr)); ASSERT_TRUE(attr.value.u32 == expected_ports); std::vector<sai_object_id_t> ports; ports.resize(expected_ports); attr.id = SAI_SWITCH_ATTR_PORT_LIST; attr.value.objlist.count = expected_ports; attr.value.objlist.list = ports.data(); SUCCESS(sai_metadata_sai_switch_api->get_switch_attribute(switch_id, 1, &attr)); ASSERT_TRUE(attr.value.objlist.count == expected_ports); } void test_set_readonly_attribute() { SWSS_LOG_ENTER(); sai_reinit(); sai_attribute_t attr; sai_object_id_t switch_id; attr.id = SAI_SWITCH_ATTR_INIT_SWITCH; attr.value.booldata = true; SUCCESS(sai_metadata_sai_switch_api->create_switch(&switch_id, 1, &attr)); attr.id = SAI_SWITCH_ATTR_PORT_MAX_MTU; attr.value.u32 = 42; ASSERT_TRUE(sai_metadata_sai_switch_api->set_switch_attribute(switch_id, &attr) != SAI_STATUS_SUCCESS); attr.id = SAI_VS_SWITCH_ATTR_META_ENABLE_UNITTESTS; attr.value.booldata = true; ASSERT_TRUE(sai_metadata_sai_switch_api->set_switch_attribute(switch_id, &attr) == SAI_STATUS_SUCCESS); // allow set on readonly attribute attr.id = SAI_VS_SWITCH_ATTR_META_ALLOW_READ_ONLY_ONCE; attr.value.s32 = SAI_SWITCH_ATTR_PORT_MAX_MTU; ASSERT_TRUE(sai_metadata_sai_switch_api->set_switch_attribute(switch_id, &attr) == SAI_STATUS_SUCCESS); attr.id = SAI_SWITCH_ATTR_PORT_MAX_MTU; attr.value.u32 = 42; // set on readonly attribute should pass SUCCESS(sai_metadata_sai_switch_api->set_switch_attribute(switch_id, &attr)); // just scramble value to make sure that GET will succeed attr.value.u32 = 1; SUCCESS(sai_metadata_sai_switch_api->get_switch_attribute(switch_id, 1, &attr)); ASSERT_TRUE(attr.value.u32 == 42); // second SET should fail ASSERT_TRUE(sai_metadata_sai_switch_api->set_switch_attribute(switch_id, &attr) != SAI_STATUS_SUCCESS); } void test_set_readonly_attribute_via_redis() { SWSS_LOG_ENTER(); sai_reinit(); sai_attribute_t attr; sai_object_id_t switch_id; attr.id = SAI_SWITCH_ATTR_INIT_SWITCH; attr.value.booldata = true; SUCCESS(sai_metadata_sai_switch_api->create_switch(&switch_id, 1, &attr)); attr.id = SAI_SWITCH_ATTR_PORT_MAX_MTU; attr.value.u32 = 42; // this set should fail ASSERT_TRUE(sai_metadata_sai_switch_api->set_switch_attribute(switch_id, &attr) != SAI_STATUS_SUCCESS); // this scope contains all operations needed to perform set operation on readonly attribute { swss::DBConnector db("ASIC_DB", 0, true); swss::NotificationProducer vsntf(&db, SAI_VS_UNITTEST_CHANNEL); std::vector<swss::FieldValueTuple> entry; // needs to be done only once vsntf.send(SAI_VS_UNITTEST_ENABLE_UNITTESTS, "true", entry); std::string field = "SAI_SWITCH_ATTR_PORT_MAX_MTU"; std::string value = "42"; // NOTE: normally we need sai_serialize_value() swss::FieldValueTuple fvt(field, value); entry.push_back(fvt); // when using tests from python, user will be required to translate VID2RID here // need RID here in form 0xYYYYYYYYYYYYYYY std::string data = "SAI_OBJECT_TYPE_SWITCH:" + sai_serialize_object_id(switch_id); vsntf.send(SAI_VS_UNITTEST_SET_RO_OP, data, entry); } // give some time for notification to propagate to vs via redis usleep(200*1000); // just scramble value to make sure that GET will succeed attr.value.u32 = 1; SUCCESS(sai_metadata_sai_switch_api->get_switch_attribute(switch_id, 1, &attr)); ASSERT_TRUE(attr.value.u32 == 42); // second SET should fail ASSERT_TRUE(sai_metadata_sai_switch_api->set_switch_attribute(switch_id, &attr) != SAI_STATUS_SUCCESS); } void test_set_stats_via_redis() { SWSS_LOG_ENTER(); sai_reinit(); sai_attribute_t attr; sai_object_id_t switch_id; attr.id = SAI_SWITCH_ATTR_INIT_SWITCH; attr.value.booldata = true; SUCCESS(sai_metadata_sai_switch_api->create_switch(&switch_id, 1, &attr)); std::vector<sai_object_id_t> ports; uint32_t expected_ports = 32; ports.resize(expected_ports); attr.id = SAI_SWITCH_ATTR_PORT_LIST; attr.value.objlist.count = expected_ports; attr.value.objlist.list = ports.data(); SUCCESS(sai_metadata_sai_switch_api->get_switch_attribute(switch_id, 1, &attr)); // this scope contains all operations needed to perform set stats on object { swss::DBConnector db("ASIC_DB", 0, true); swss::NotificationProducer vsntf(&db, SAI_VS_UNITTEST_CHANNEL); std::vector<swss::FieldValueTuple> entry; // needs to be done only once vsntf.send(SAI_VS_UNITTEST_ENABLE_UNITTESTS, "true", entry); std::string field = "SAI_PORT_STAT_IF_IN_ERRORS"; std::string value = "42"; // uint64_t swss::FieldValueTuple fvt(field, value); entry.push_back(fvt); std::string data = sai_serialize_object_id(ports.at(0)); // set on 1st port vsntf.send(SAI_VS_UNITTEST_SET_STATS_OP, data, entry); } // give some time for notification to propagate to vs via redis usleep(200*1000); sai_port_stat_t ids[1] = { SAI_PORT_STAT_IF_IN_ERRORS }; uint64_t counters[1] = { 0 } ; SUCCESS(sai_metadata_sai_port_api->get_port_stats(ports.at(0), 1, (const sai_stat_id_t *)ids, counters)); ASSERT_TRUE(counters[0] == 42); } void sai_fdb_event_notification( _In_ uint32_t count, _In_ const sai_fdb_event_notification_data_t *data) { SWSS_LOG_ENTER(); SWSS_LOG_NOTICE("got fdb notification count %u", count); } sai_fdb_entry_t create_fdb_entry( _In_ sai_object_id_t switch_id, _In_ sai_object_id_t vlan_id, _In_ sai_object_id_t bp_id, _In_ sai_fdb_entry_type_t type, _In_ uint8_t mac_end) { SWSS_LOG_ENTER(); sai_attribute_t attr; attr.id = SAI_FDB_ENTRY_ATTR_TYPE; attr.value.s32 = type; sai_mac_t mac = {1,1,0,0,0,0}; mac[5] = mac_end; sai_fdb_entry_t fe; fe.switch_id = switch_id; fe.bv_id = vlan_id; memcpy(fe.mac_address, mac, sizeof(sai_mac_t)); SUCCESS(sai_metadata_sai_fdb_api->create_fdb_entry(&fe, 1, &attr)); attr.id = SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID; attr.value.oid = bp_id; SUCCESS(sai_metadata_sai_fdb_api->set_fdb_entry_attribute(&fe, &attr)); return fe; } #define ASSERT_FDB_EXISTS(fdb) \ {\ attr.id = SAI_FDB_ENTRY_ATTR_TYPE;\ SUCCESS(sai_metadata_sai_fdb_api->get_fdb_entry_attribute(&fdb, 1, &attr));\ } #define ASSERT_FDB_NOT_EXISTS(fdb) \ {\ attr.id = SAI_FDB_ENTRY_ATTR_TYPE;\ NOT_SUCCESS(sai_metadata_sai_fdb_api->get_fdb_entry_attribute(&fdb, 1, &attr));\ } #define CREATE_ENTRIES()\ SUCCESS(sai_metadata_sai_fdb_api->flush_fdb_entries(switch_id, 0, NULL));\ auto v2bp1d = create_fdb_entry(switch_id, vlan2_id, bp1, SAI_FDB_ENTRY_TYPE_DYNAMIC, 1);\ auto v2bp1s = create_fdb_entry(switch_id, vlan2_id, bp1, SAI_FDB_ENTRY_TYPE_STATIC, 2);\ auto v2bp2d = create_fdb_entry(switch_id, vlan2_id, bp2, SAI_FDB_ENTRY_TYPE_DYNAMIC, 3);\ auto v2bp2s = create_fdb_entry(switch_id, vlan2_id, bp2, SAI_FDB_ENTRY_TYPE_STATIC, 4);\ auto v3bp1d = create_fdb_entry(switch_id, vlan3_id, bp1, SAI_FDB_ENTRY_TYPE_DYNAMIC, 5);\ auto v3bp1s = create_fdb_entry(switch_id, vlan3_id, bp1, SAI_FDB_ENTRY_TYPE_STATIC, 6);\ auto v3bp2d = create_fdb_entry(switch_id, vlan3_id, bp2, SAI_FDB_ENTRY_TYPE_DYNAMIC, 7);\ auto v3bp2s = create_fdb_entry(switch_id, vlan3_id, bp2, SAI_FDB_ENTRY_TYPE_STATIC, 8); void test_fdb_flush() { SWSS_LOG_ENTER(); sai_reinit(); // TODO we need 10 cases, 10th where nothing was removed sai_attribute_t attr; sai_object_id_t switch_id; attr.id = SAI_SWITCH_ATTR_INIT_SWITCH; attr.value.booldata = true; SUCCESS(sai_metadata_sai_switch_api->create_switch(&switch_id, 1, &attr)); // set notification callback attr.id = SAI_SWITCH_ATTR_FDB_EVENT_NOTIFY; attr.value.ptr = (void*)&sai_fdb_event_notification; SUCCESS(sai_metadata_sai_switch_api->set_switch_attribute(switch_id, &attr)); attr.id = SAI_SWITCH_ATTR_DEFAULT_1Q_BRIDGE_ID; SUCCESS(sai_metadata_sai_switch_api->get_switch_attribute(switch_id, 1, &attr)); sai_object_id_t bridge_id = attr.value.oid; sai_object_id_t list[100]; attr.id = SAI_BRIDGE_ATTR_PORT_LIST; attr.value.objlist.count = 100; attr.value.objlist.list = list; SUCCESS(sai_metadata_sai_bridge_api->get_bridge_attribute(bridge_id, 1, &attr)); sai_object_id_t bp1 = list[1]; sai_object_id_t bp2 = list[2]; SWSS_LOG_NOTICE("bridge ports: %s, %s", sai_serialize_object_id(bp1).c_str(), sai_serialize_object_id(bp2).c_str()); // create 2nd vlan attr.id = SAI_VLAN_ATTR_VLAN_ID; attr.value.u16 = 2; sai_object_id_t vlan2_id; SUCCESS(sai_metadata_sai_vlan_api->create_vlan(&vlan2_id, switch_id, 1, &attr)); SWSS_LOG_NOTICE("vlan 2 id: %s", sai_serialize_object_id(vlan2_id).c_str()); // create 3rd vlan attr.id = SAI_VLAN_ATTR_VLAN_ID; attr.value.u16 = 3; sai_object_id_t vlan3_id; SUCCESS(sai_metadata_sai_vlan_api->create_vlan(&vlan3_id, switch_id, 1, &attr)); SWSS_LOG_NOTICE("vlan 3 id: %s", sai_serialize_object_id(vlan3_id).c_str()); SWSS_LOG_NOTICE("1. flush all entries"); { CREATE_ENTRIES(); SUCCESS(sai_metadata_sai_fdb_api->flush_fdb_entries(switch_id, 0, NULL)); ASSERT_FDB_NOT_EXISTS(v2bp1d); ASSERT_FDB_NOT_EXISTS(v2bp1s); ASSERT_FDB_NOT_EXISTS(v2bp2d); ASSERT_FDB_NOT_EXISTS(v2bp2s); ASSERT_FDB_NOT_EXISTS(v3bp1d); ASSERT_FDB_NOT_EXISTS(v3bp1s); ASSERT_FDB_NOT_EXISTS(v3bp2d); ASSERT_FDB_NOT_EXISTS(v3bp2s); } SWSS_LOG_NOTICE("2a. flush dynamic entries"); { CREATE_ENTRIES(); attr.id = SAI_FDB_FLUSH_ATTR_ENTRY_TYPE; attr.value.s32 = SAI_FDB_FLUSH_ENTRY_TYPE_DYNAMIC; SUCCESS(sai_metadata_sai_fdb_api->flush_fdb_entries(switch_id, 1, &attr)); ASSERT_FDB_NOT_EXISTS(v2bp1d); ASSERT_FDB_EXISTS(v2bp1s); ASSERT_FDB_NOT_EXISTS(v2bp2d); ASSERT_FDB_EXISTS(v2bp2s); ASSERT_FDB_NOT_EXISTS(v3bp1d); ASSERT_FDB_EXISTS(v3bp1s); ASSERT_FDB_NOT_EXISTS(v3bp2d); ASSERT_FDB_EXISTS(v3bp2s); } SWSS_LOG_NOTICE("2b. flush static entries"); { CREATE_ENTRIES(); attr.id = SAI_FDB_FLUSH_ATTR_ENTRY_TYPE; attr.value.s32 = SAI_FDB_FLUSH_ENTRY_TYPE_STATIC; SUCCESS(sai_metadata_sai_fdb_api->flush_fdb_entries(switch_id, 1, &attr)); ASSERT_FDB_EXISTS(v2bp1d); ASSERT_FDB_NOT_EXISTS(v2bp1s); ASSERT_FDB_EXISTS(v2bp2d); ASSERT_FDB_NOT_EXISTS(v2bp2s); ASSERT_FDB_EXISTS(v3bp1d); ASSERT_FDB_NOT_EXISTS(v3bp1s); ASSERT_FDB_EXISTS(v3bp2d); ASSERT_FDB_NOT_EXISTS(v3bp2s); } SWSS_LOG_NOTICE("3a. flush vlan 2 entries"); { CREATE_ENTRIES(); attr.id = SAI_FDB_FLUSH_ATTR_BV_ID; attr.value.oid = vlan2_id; SUCCESS(sai_metadata_sai_fdb_api->flush_fdb_entries(switch_id, 1, &attr)); ASSERT_FDB_NOT_EXISTS(v2bp1d); ASSERT_FDB_NOT_EXISTS(v2bp1s); ASSERT_FDB_NOT_EXISTS(v2bp2d); ASSERT_FDB_NOT_EXISTS(v2bp2s); ASSERT_FDB_EXISTS(v3bp1d); ASSERT_FDB_EXISTS(v3bp1s); ASSERT_FDB_EXISTS(v3bp2d); ASSERT_FDB_EXISTS(v3bp2s); } SWSS_LOG_NOTICE("3b. flush vlan 3 entries"); { CREATE_ENTRIES(); attr.id = SAI_FDB_FLUSH_ATTR_BV_ID; attr.value.oid = vlan3_id; SUCCESS(sai_metadata_sai_fdb_api->flush_fdb_entries(switch_id, 1, &attr)); ASSERT_FDB_EXISTS(v2bp1d); ASSERT_FDB_EXISTS(v2bp1s); ASSERT_FDB_EXISTS(v2bp2d); ASSERT_FDB_EXISTS(v2bp2s); ASSERT_FDB_NOT_EXISTS(v3bp1d); ASSERT_FDB_NOT_EXISTS(v3bp1s); ASSERT_FDB_NOT_EXISTS(v3bp2d); ASSERT_FDB_NOT_EXISTS(v3bp2s); } SWSS_LOG_NOTICE("4a. flush bridge port 1 entries"); { CREATE_ENTRIES(); attr.id = SAI_FDB_FLUSH_ATTR_BRIDGE_PORT_ID; attr.value.oid = bp1; SUCCESS(sai_metadata_sai_fdb_api->flush_fdb_entries(switch_id, 1, &attr)); ASSERT_FDB_NOT_EXISTS(v2bp1d); ASSERT_FDB_NOT_EXISTS(v2bp1s); ASSERT_FDB_EXISTS(v2bp2d); ASSERT_FDB_EXISTS(v2bp2s); ASSERT_FDB_NOT_EXISTS(v3bp1d); ASSERT_FDB_NOT_EXISTS(v3bp1s); ASSERT_FDB_EXISTS(v3bp2d); ASSERT_FDB_EXISTS(v3bp2s); } SWSS_LOG_NOTICE("4b. flush vlan 3 entries"); { CREATE_ENTRIES(); attr.id = SAI_FDB_FLUSH_ATTR_BRIDGE_PORT_ID; attr.value.oid = bp2; SUCCESS(sai_metadata_sai_fdb_api->flush_fdb_entries(switch_id, 1, &attr)); ASSERT_FDB_EXISTS(v2bp1d); ASSERT_FDB_EXISTS(v2bp1s); ASSERT_FDB_NOT_EXISTS(v2bp2d); ASSERT_FDB_NOT_EXISTS(v2bp2s); ASSERT_FDB_EXISTS(v3bp1d); ASSERT_FDB_EXISTS(v3bp1s); ASSERT_FDB_NOT_EXISTS(v3bp2d); ASSERT_FDB_NOT_EXISTS(v3bp2s); } sai_attribute_t attrs[3]; SWSS_LOG_NOTICE("5. flush vlan 2 and and type dynamic entries"); { CREATE_ENTRIES(); attrs[0].id = SAI_FDB_FLUSH_ATTR_ENTRY_TYPE; attrs[0].value.s32 = SAI_FDB_FLUSH_ENTRY_TYPE_DYNAMIC; attrs[1].id = SAI_FDB_FLUSH_ATTR_BV_ID; attrs[1].value.oid = vlan2_id; SUCCESS(sai_metadata_sai_fdb_api->flush_fdb_entries(switch_id, 2, attrs)); ASSERT_FDB_NOT_EXISTS(v2bp1d); ASSERT_FDB_EXISTS(v2bp1s); ASSERT_FDB_NOT_EXISTS(v2bp2d); ASSERT_FDB_EXISTS(v2bp2s); ASSERT_FDB_EXISTS(v3bp1d); ASSERT_FDB_EXISTS(v3bp1s); ASSERT_FDB_EXISTS(v3bp2d); ASSERT_FDB_EXISTS(v3bp2s); } SWSS_LOG_NOTICE("6. flush vlan 2 and and bridge port 2 entries"); { CREATE_ENTRIES(); attrs[0].id = SAI_FDB_FLUSH_ATTR_BV_ID; attrs[0].value.oid = vlan2_id; attrs[1].id = SAI_FDB_FLUSH_ATTR_BRIDGE_PORT_ID; attrs[1].value.oid = bp2; SUCCESS(sai_metadata_sai_fdb_api->flush_fdb_entries(switch_id, 2, attrs)); ASSERT_FDB_EXISTS(v2bp1d); ASSERT_FDB_EXISTS(v2bp1s); ASSERT_FDB_NOT_EXISTS(v2bp2d); ASSERT_FDB_NOT_EXISTS(v2bp2s); ASSERT_FDB_EXISTS(v3bp1d); ASSERT_FDB_EXISTS(v3bp1s); ASSERT_FDB_EXISTS(v3bp2d); ASSERT_FDB_EXISTS(v3bp2s); } SWSS_LOG_NOTICE("7. flush type dynamic and and bridge port 2 entries"); { CREATE_ENTRIES(); attrs[0].id = SAI_FDB_FLUSH_ATTR_ENTRY_TYPE; attrs[0].value.s32 = SAI_FDB_FLUSH_ENTRY_TYPE_DYNAMIC; attrs[1].id = SAI_FDB_FLUSH_ATTR_BRIDGE_PORT_ID; attrs[1].value.oid = bp2; SUCCESS(sai_metadata_sai_fdb_api->flush_fdb_entries(switch_id, 2, attrs)); ASSERT_FDB_EXISTS(v2bp1d); ASSERT_FDB_EXISTS(v2bp1s); ASSERT_FDB_NOT_EXISTS(v2bp2d); ASSERT_FDB_EXISTS(v2bp2s); ASSERT_FDB_EXISTS(v3bp1d); ASSERT_FDB_EXISTS(v3bp1s); ASSERT_FDB_NOT_EXISTS(v3bp2d); ASSERT_FDB_EXISTS(v3bp2s); } SWSS_LOG_NOTICE("8. flush type dynamic and and bridge port 2 and vlan 3 entries"); { CREATE_ENTRIES(); attrs[0].id = SAI_FDB_FLUSH_ATTR_ENTRY_TYPE; attrs[0].value.s32 = SAI_FDB_FLUSH_ENTRY_TYPE_DYNAMIC; attrs[1].id = SAI_FDB_FLUSH_ATTR_BRIDGE_PORT_ID; attrs[1].value.oid = bp2; attrs[2].id = SAI_FDB_FLUSH_ATTR_BV_ID; attrs[2].value.oid = vlan3_id; SUCCESS(sai_metadata_sai_fdb_api->flush_fdb_entries(switch_id, 3, attrs)); ASSERT_FDB_EXISTS(v2bp1d); ASSERT_FDB_EXISTS(v2bp1s); ASSERT_FDB_EXISTS(v2bp2d); ASSERT_FDB_EXISTS(v2bp2s); ASSERT_FDB_EXISTS(v3bp1d); ASSERT_FDB_EXISTS(v3bp1s); ASSERT_FDB_NOT_EXISTS(v3bp2d); ASSERT_FDB_EXISTS(v3bp2s); } } void test_get_stats() { SWSS_LOG_ENTER(); sai_reinit(); uint32_t expected_ports = 32; sai_attribute_t attr; sai_object_id_t switch_id; attr.id = SAI_SWITCH_ATTR_INIT_SWITCH; attr.value.booldata = true; SUCCESS(sai_metadata_sai_switch_api->create_switch(&switch_id, 1, &attr)); attr.id = SAI_SWITCH_ATTR_PORT_NUMBER; SUCCESS(sai_metadata_sai_switch_api->get_switch_attribute(switch_id, 1, &attr)); ASSERT_TRUE(attr.value.u32 == expected_ports); std::vector<sai_object_id_t> ports; ports.resize(expected_ports); attr.id = SAI_SWITCH_ATTR_PORT_LIST; attr.value.objlist.count = expected_ports; attr.value.objlist.list = ports.data(); SUCCESS(sai_metadata_sai_switch_api->get_switch_attribute(switch_id, 1, &attr)); ASSERT_TRUE(attr.value.objlist.count == expected_ports); sai_port_stat_t ids[2]; ids[0] = SAI_PORT_STAT_IF_IN_OCTETS; ids[1] = SAI_PORT_STAT_IF_OUT_OCTETS; uint64_t values[2]; values[0] = 42; values[1] = 42; SUCCESS(sai_metadata_sai_port_api->get_port_stats(ports[0], 2, (const sai_stat_id_t *)ids, values)); ASSERT_TRUE(values[0] == 0); ASSERT_TRUE(values[1] == 0); attr.id = SAI_VS_SWITCH_ATTR_META_ENABLE_UNITTESTS; attr.value.booldata = true; ASSERT_TRUE(sai_metadata_sai_switch_api->set_switch_attribute(switch_id, &attr) == SAI_STATUS_SUCCESS); values[0] = 77; values[1] = 127; // setting last bit of count value when unittest are enabled, will cause to perform SET on counters SUCCESS(sai_metadata_sai_port_api->get_port_stats(ports[0], 2 | 0x80000000, (const sai_stat_id_t *)ids, values)); values[0] = 42; values[1] = 42; attr.id = SAI_VS_SWITCH_ATTR_META_ENABLE_UNITTESTS; attr.value.booldata = true; ASSERT_TRUE(sai_metadata_sai_switch_api->set_switch_attribute(switch_id, &attr) == SAI_STATUS_SUCCESS); ids[0] = SAI_PORT_STAT_IF_OUT_OCTETS; ids[1] = SAI_PORT_STAT_IF_IN_OCTETS; SUCCESS(sai_metadata_sai_port_api->get_port_stats(ports[0], 2, (const sai_stat_id_t *)ids, values)); ASSERT_TRUE(values[0] == 127); ASSERT_TRUE(values[1] == 77); } void test_supported_obj_types() { SWSS_LOG_ENTER(); sai_reinit(); uint32_t expected_num_attrs = 8; sai_attribute_t attr; sai_object_id_t switch_id; attr.id = SAI_SWITCH_ATTR_INIT_SWITCH; attr.value.booldata = true; SUCCESS(sai_metadata_sai_switch_api->create_switch(&switch_id, 1, &attr)); std::vector<sai_object_type_t> supported_obj_list; supported_obj_list.resize(expected_num_attrs); attr.id = SAI_SWITCH_ATTR_SUPPORTED_OBJECT_TYPE_LIST; attr.value.s32list.count = expected_num_attrs; attr.value.s32list.list = (int32_t *) supported_obj_list.data(); SUCCESS(sai_metadata_sai_switch_api->get_switch_attribute(switch_id, 1, &attr)); ASSERT_TRUE(attr.value.objlist.count == expected_num_attrs); } int main() { swss::Logger::getInstance().setMinPrio(swss::Logger::SWSS_DEBUG); SWSS_LOG_ENTER(); swss::Logger::getInstance().setMinPrio(swss::Logger::SWSS_NOTICE); SUCCESS(sai_api_initialize(0, (sai_service_method_table_t*)&test_services)); sai_apis_t apis; sai_metadata_apis_query(sai_api_query, &apis); //swss::Logger::getInstance().setMinPrio(swss::Logger::SWSS_INFO); test_ports(); test_set_readonly_attribute(); test_set_readonly_attribute_via_redis(); test_fdb_flush(); test_get_stats(); test_supported_obj_types(); test_set_stats_via_redis(); // make proper uninitialize to close unittest thread sai_api_uninitialize(); return 0; }