From c860472a3d8c16cad8a44fd7f76e848c39651f2e Mon Sep 17 00:00:00 2001 From: Kamil Cudnik Date: Mon, 26 Mar 2018 22:37:33 +0200 Subject: [PATCH] Add support for "SET" counters values for unittests (#311) --- meta/sai_meta.cpp | 11 +++- vslib/inc/sai_vs.h | 10 +++ vslib/inc/sai_vs_internal.h | 21 ++++++ vslib/inc/sai_vs_state.h | 2 + vslib/src/Makefile.am | 1 + vslib/src/sai_vs_buffer.cpp | 15 +---- vslib/src/sai_vs_generic_get_stats.cpp | 91 ++++++++++++++++++++++++++ vslib/src/sai_vs_port.cpp | 30 +-------- vslib/src/sai_vs_queue.cpp | 15 +---- vslib/src/tests.cpp | 72 ++++++++++++++++++++ 10 files changed, 214 insertions(+), 54 deletions(-) create mode 100644 vslib/src/sai_vs_generic_get_stats.cpp diff --git a/meta/sai_meta.cpp b/meta/sai_meta.cpp index 0195c2615593..101085ee5459 100644 --- a/meta/sai_meta.cpp +++ b/meta/sai_meta.cpp @@ -2416,12 +2416,21 @@ sai_status_t meta_generic_validation_get( template sai_status_t meta_generic_validation_get_stats( _In_ const sai_object_meta_key_t& meta_key, - _In_ const uint32_t count, + _In_ uint32_t count, _In_ const T *counter_id_list, _In_ const uint64_t *counter_list) { SWSS_LOG_ENTER(); + if (meta_unittests_enabled() && (count & 0x80000000)) + { + /* + * If last bit of counters count is set to high, and unittests are enabled, + * then this api can be used to SET counter values by user for debugging purposes. + */ + count = count & ~0x80000000; + } + if (count < 1) { SWSS_LOG_ERROR("expected at least 1 stat when calling get_stats, zero given"); diff --git a/vslib/inc/sai_vs.h b/vslib/inc/sai_vs.h index dd2dc39bdad2..d5a0e2fceb6e 100644 --- a/vslib/inc/sai_vs.h +++ b/vslib/inc/sai_vs.h @@ -173,4 +173,14 @@ sai_status_t vs_generic_get_route_entry( _In_ uint32_t attr_count, _Out_ sai_attribute_t *attr_list); +// STATS + +template +sai_status_t vs_generic_get_stats( + _In_ sai_object_type_t object_type, + _In_ sai_object_id_t object_id, + _In_ uint32_t count, + _In_ const T* counter_id_list, + _Out_ uint64_t *counter_list); + #endif // __SAI_VS__ diff --git a/vslib/inc/sai_vs_internal.h b/vslib/inc/sai_vs_internal.h index 06e11af1b434..05d2eca0525b 100644 --- a/vslib/inc/sai_vs_internal.h +++ b/vslib/inc/sai_vs_internal.h @@ -139,3 +139,24 @@ vs_remove_ ## ot, \ vs_set_ ## ot ##_attribute, \ vs_get_ ## ot ##_attribute, + +// stats + +#define VS_GENERIC_GET_STATS(OBJECT_TYPE,object_type) \ + sai_status_t vs_get_ ## object_type ## _stats( \ + _In_ sai_object_id_t object_type ##_id, \ + _In_ uint32_t count, \ + _In_ const sai_ ## object_type ## _stat_t *counter_id_list, \ + _Out_ uint64_t *counter_list) \ + { \ + MUTEX(); \ + SWSS_LOG_ENTER(); \ + \ + return meta_sai_get_stats_oid( \ + SAI_OBJECT_TYPE_ ## OBJECT_TYPE, \ + object_type ## _id, \ + count, \ + counter_id_list, \ + counter_list, \ + &vs_generic_get_stats); \ + } diff --git a/vslib/inc/sai_vs_state.h b/vslib/inc/sai_vs_state.h index da3b194e5bef..239e0ccea576 100644 --- a/vslib/inc/sai_vs_state.h +++ b/vslib/inc/sai_vs_state.h @@ -174,6 +174,8 @@ class SwitchState ObjectHash objectHash; + std::map> countersMap; + sai_object_id_t getSwitchId() const { SWSS_LOG_ENTER(); diff --git a/vslib/src/Makefile.am b/vslib/src/Makefile.am index ef2b96c30bac..9e1d44023c07 100644 --- a/vslib/src/Makefile.am +++ b/vslib/src/Makefile.am @@ -41,6 +41,7 @@ libsaivs_la_SOURCES = \ sai_vs_generic_get.cpp \ sai_vs_generic_remove.cpp \ sai_vs_generic_set.cpp \ + sai_vs_generic_get_stats.cpp \ sai_vs.cpp \ sai_vs_switch_BCM56850.cpp \ sai_vs_switch_MLNX2700.cpp diff --git a/vslib/src/sai_vs_buffer.cpp b/vslib/src/sai_vs_buffer.cpp index ec6bf8ba3f9f..ece5bcda0f91 100644 --- a/vslib/src/sai_vs_buffer.cpp +++ b/vslib/src/sai_vs_buffer.cpp @@ -1,19 +1,6 @@ #include "sai_vs.h" #include "sai_vs_internal.h" -sai_status_t vs_get_ingress_priority_group_stats( - _In_ sai_object_id_t ingress_pg_id, - _In_ uint32_t number_of_counters, - _In_ const sai_ingress_priority_group_stat_t *counter_ids, - _Out_ uint64_t *counters) -{ - MUTEX(); - - SWSS_LOG_ENTER(); - - return SAI_STATUS_NOT_IMPLEMENTED; -} - sai_status_t vs_clear_ingress_priority_group_stats( _In_ sai_object_id_t ingress_pg_id, _In_ uint32_t number_of_counters, @@ -51,6 +38,8 @@ sai_status_t vs_clear_buffer_pool_stats( return SAI_STATUS_NOT_IMPLEMENTED; } +VS_GENERIC_GET_STATS(INGRESS_PRIORITY_GROUP,ingress_priority_group); + VS_GENERIC_QUAD(BUFFER_POOL,buffer_pool); VS_GENERIC_QUAD(INGRESS_PRIORITY_GROUP,ingress_priority_group); VS_GENERIC_QUAD(BUFFER_PROFILE,buffer_profile); diff --git a/vslib/src/sai_vs_generic_get_stats.cpp b/vslib/src/sai_vs_generic_get_stats.cpp new file mode 100644 index 000000000000..622b7cb8d462 --- /dev/null +++ b/vslib/src/sai_vs_generic_get_stats.cpp @@ -0,0 +1,91 @@ +#include "sai_vs.h" +#include "sai_vs_state.h" +#include "meta/sai_serialize.h" + +template +sai_status_t internal_vs_generic_get_stats( + _In_ sai_object_type_t object_type, + _In_ const std::string &serialized_object_id, + _In_ sai_object_id_t switch_id, + _In_ uint32_t count, + _In_ const T *counter_id_list, + _Out_ uint64_t *counter_list) +{ + SWSS_LOG_ENTER(); + + bool perform_set = false; + + if (meta_unittests_enabled() && (count & 0x80000000)) + { + count = count & ~0x80000000; + + SWSS_LOG_NOTICE("unittests are enabled and counters count MSB is set to 1, performing SET on counters"); + + perform_set = true; + } + + auto &countersMap = g_switch_state_map.at(switch_id)->countersMap; + + auto it = countersMap.find(serialized_object_id); + + if (it == countersMap.end()) + countersMap[serialized_object_id] = std::map(); + + std::map& counters = countersMap[serialized_object_id]; + + for (uint32_t i = 0; i < count; ++i) + { + if (perform_set) + { + counters[ counter_id_list[i] ] = counter_list[i]; + } + else + { + auto itt = counters.find(counter_id_list[i]); + + if (itt == counters.end()) + counter_list[i] = 0; + else + counter_list[i] = itt->second; + } + } + + return SAI_STATUS_SUCCESS; +} + +template +sai_status_t vs_generic_get_stats( + _In_ sai_object_type_t object_type, + _In_ sai_object_id_t object_id, + _In_ uint32_t count, + _In_ const T* counter_id_list, + _Out_ uint64_t *counter_list) +{ + SWSS_LOG_ENTER(); + + std::string str_object_id = sai_serialize_object_id(object_id); + + sai_object_id_t switch_id = sai_switch_id_query(object_id); + + return internal_vs_generic_get_stats( + object_type, + str_object_id, + switch_id, + count, + counter_id_list, + counter_list); +} + +#define DECLARE_VS_GENERIC_GET_STATS(type) \ + template \ + sai_status_t vs_generic_get_stats( \ + _In_ sai_object_type_t object_type, \ + _In_ sai_object_id_t object_id, \ + _In_ uint32_t count, \ + _In_ const sai_ ## type ## _stat_t *counter_id_list, \ + _Out_ uint64_t *counter_list); \ + +DECLARE_VS_GENERIC_GET_STATS(port); +DECLARE_VS_GENERIC_GET_STATS(port_pool); +DECLARE_VS_GENERIC_GET_STATS(queue); +DECLARE_VS_GENERIC_GET_STATS(ingress_priority_group); diff --git a/vslib/src/sai_vs_port.cpp b/vslib/src/sai_vs_port.cpp index 71a3a44fb0ab..6b91dc68f447 100644 --- a/vslib/src/sai_vs_port.cpp +++ b/vslib/src/sai_vs_port.cpp @@ -1,19 +1,6 @@ #include "sai_vs.h" #include "sai_vs_internal.h" -sai_status_t vs_get_port_stats( - _In_ sai_object_id_t port_id, - _In_ uint32_t number_of_counters, - _In_ const sai_port_stat_t *counter_ids, - _Out_ uint64_t *counters) -{ - MUTEX(); - - SWSS_LOG_ENTER(); - - return SAI_STATUS_NOT_IMPLEMENTED; -} - sai_status_t vs_clear_port_stats( _In_ sai_object_id_t port_id, _In_ uint32_t number_of_counters, @@ -36,20 +23,6 @@ sai_status_t vs_clear_port_all_stats( return SAI_STATUS_NOT_IMPLEMENTED; } -sai_status_t vs_get_port_pool_stats( - _In_ sai_object_id_t port_pool_id, - _In_ uint32_t number_of_counters, - _In_ const sai_port_pool_stat_t *counter_ids, - _Out_ uint64_t *counters) -{ - MUTEX(); - - SWSS_LOG_ENTER(); - - return SAI_STATUS_NOT_IMPLEMENTED; -} - - sai_status_t vs_clear_port_pool_stats( _In_ sai_object_id_t port_pool_id, _In_ uint32_t number_of_counters, @@ -63,6 +36,9 @@ sai_status_t vs_clear_port_pool_stats( } +VS_GENERIC_GET_STATS(PORT,port); +VS_GENERIC_GET_STATS(PORT_POOL,port_pool); + VS_GENERIC_QUAD(PORT,port); VS_GENERIC_QUAD(PORT_POOL,port_pool); diff --git a/vslib/src/sai_vs_queue.cpp b/vslib/src/sai_vs_queue.cpp index c455afcc5546..b281a8a31b82 100644 --- a/vslib/src/sai_vs_queue.cpp +++ b/vslib/src/sai_vs_queue.cpp @@ -1,19 +1,6 @@ #include "sai_vs.h" #include "sai_vs_internal.h" -sai_status_t vs_get_queue_stats( - _In_ sai_object_id_t queue_id, - _In_ uint32_t number_of_counters, - _In_ const sai_queue_stat_t *counter_ids, - _Out_ uint64_t *counters) -{ - MUTEX(); - - SWSS_LOG_ENTER(); - - return SAI_STATUS_NOT_IMPLEMENTED; -} - sai_status_t vs_clear_queue_stats( _In_ sai_object_id_t queue_id, _In_ uint32_t number_of_counters, @@ -26,6 +13,8 @@ sai_status_t vs_clear_queue_stats( return SAI_STATUS_NOT_IMPLEMENTED; } +VS_GENERIC_GET_STATS(QUEUE,queue); + VS_GENERIC_QUAD(QUEUE,queue); const sai_queue_api_t vs_queue_api = { diff --git a/vslib/src/tests.cpp b/vslib/src/tests.cpp index ef3392713694..cb6a9e3627b4 100644 --- a/vslib/src/tests.cpp +++ b/vslib/src/tests.cpp @@ -606,6 +606,76 @@ void test_fdb_flush() } } +void test_get_stats() +{ + SWSS_LOG_ENTER(); + + 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 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, ids, values)); + + ASSERT_TRUE(values[0] == 0); + ASSERT_TRUE(values[1] == 0); + + meta_unittests_enable(true); + + 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, ids, values)); + + values[0] = 42; + values[1] = 42; + + meta_unittests_enable(false); + + 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, ids, values)); + + ASSERT_TRUE(values[0] == 127); + ASSERT_TRUE(values[1] == 77); +} + int main() { swss::Logger::getInstance().setMinPrio(swss::Logger::SWSS_DEBUG); @@ -629,6 +699,8 @@ int main() test_fdb_flush(); + test_get_stats(); + // make proper unitinialize to close unittest thread sai_api_uninitialize();