Skip to content

Commit 3c485e5

Browse files
[recorder] Fix incorrect attribute enum value capability query (#843)
Recorder was assuming that enum value capability query is executed for an attribute that has a value type of a s32 list. When querying SAI_DEBUG_COUNTER_ATTR_TYPE using sai_query_attribute_enum_values_capability a warning is printed in syslog: "enum value 4 not found in enum sai_debug_counter_type". This happens because SAI_DEBUG_COUNTER_ATTR_TYPE attrvaluetype is int32 (enum value) and sai_s32_list_t structure was casted to int32. Since we initialize sai_s32_list with .count = 4 (the number of values in sai_debug_counter_type_t enum) value 4 is printed in the syslog.
1 parent 677ebca commit 3c485e5

File tree

3 files changed

+171
-17
lines changed

3 files changed

+171
-17
lines changed

lib/src/Recorder.cpp

+18-17
Original file line numberDiff line numberDiff line change
@@ -1032,6 +1032,8 @@ void Recorder::recordQueryAattributeEnumValuesCapability(
10321032
{
10331033
SWSS_LOG_ENTER();
10341034

1035+
std::vector<swss::FieldValueTuple> values;
1036+
10351037
auto meta = sai_metadata_get_attr_metadata(objectType, attrId);
10361038

10371039
if (meta == NULL)
@@ -1041,14 +1043,18 @@ void Recorder::recordQueryAattributeEnumValuesCapability(
10411043
return;
10421044
}
10431045

1044-
auto key = sai_serialize_object_type(SAI_OBJECT_TYPE_SWITCH) + ":" + sai_serialize_object_id(switchId);
1046+
if (!meta->enummetadata)
1047+
{
1048+
SWSS_LOG_ERROR("Attribute %s is not enum/enumlist!", meta->attridname);
1049+
return;
1050+
}
10451051

1046-
sai_attribute_t attr;
1052+
auto key = sai_serialize_object_type(SAI_OBJECT_TYPE_SWITCH) + ":" + sai_serialize_object_id(switchId);
10471053

1048-
attr.id = attrId;
1049-
attr.value.s32list = *enumValuesCapability;
1054+
auto str_attr_id = sai_serialize_attr_id(*meta);
1055+
auto str_enum_list = sai_serialize_enum_list(*enumValuesCapability, meta->enummetadata, true); // we only need to serialize count
10501056

1051-
auto values = SaiAttributeList::serialize_attr_list(objectType, 1, &attr, true); // we only need to serialize count
1057+
values.emplace_back(str_attr_id, str_enum_list);
10521058

10531059
SWSS_LOG_DEBUG("Query arguments: switch %s, attribute: %s, count: %u", key.c_str(), meta->attridname, enumValuesCapability->count);
10541060

@@ -1063,6 +1069,8 @@ void Recorder::recordQueryAattributeEnumValuesCapabilityResponse(
10631069
{
10641070
SWSS_LOG_ENTER();
10651071

1072+
std::vector<swss::FieldValueTuple> values;
1073+
10661074
auto meta = sai_metadata_get_attr_metadata(objectType, attrId);
10671075

10681076
if (meta == NULL)
@@ -1078,20 +1086,13 @@ void Recorder::recordQueryAattributeEnumValuesCapabilityResponse(
10781086
return;
10791087
}
10801088

1081-
std::vector<swss::FieldValueTuple> values;
1082-
1083-
sai_attribute_t attr;
1084-
1085-
attr.id = attrId;
1086-
attr.value.s32list = *enumValuesCapability;
1089+
bool countOnly = (status == SAI_STATUS_BUFFER_OVERFLOW);
10871090

1088-
if (status == SAI_STATUS_SUCCESS)
1089-
{
1090-
values = SaiAttributeList::serialize_attr_list(objectType, 1, &attr, false);
1091-
}
1092-
else if (status == SAI_STATUS_BUFFER_OVERFLOW)
1091+
if (status == SAI_STATUS_SUCCESS || status == SAI_STATUS_BUFFER_OVERFLOW)
10931092
{
1094-
values = SaiAttributeList::serialize_attr_list(objectType, 1, &attr, true);
1093+
auto str_attr_id = sai_serialize_attr_id(*meta);
1094+
auto str_enum_list = sai_serialize_enum_list(*enumValuesCapability, meta->enummetadata, countOnly);
1095+
values.emplace_back(str_attr_id, str_enum_list);
10951096
}
10961097

10971098
recordQueryAttributeEnumValuesCapabilityResponse(status, values);

lib/src/tests.cpp

+148
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ extern "C" {
88
#include "swss/table.h"
99
#include "swss/tokenize.h"
1010

11+
#include "lib/inc/Recorder.h"
12+
1113
#include "meta/sai_serialize.h"
1214
#include "meta/SaiAttributeList.h"
1315

@@ -17,9 +19,13 @@ extern "C" {
1719
#include <chrono>
1820
#include <vector>
1921

22+
#define ASSERT_EQ(a,b) if ((a) != (b)) { SWSS_LOG_THROW("ASSERT EQ FAILED: " #a " != " #b); }
23+
2024
using namespace saimeta;
2125
using namespace sairedis;
2226

27+
const std::string SairedisRecFilename = "sairedis.rec";
28+
2329
sai_object_type_t sai_object_type_query(
2430
_In_ sai_object_id_t objectId)
2531
{
@@ -761,6 +767,144 @@ static sai_object_type_t deserialize_object_type(
761767
return object_type;
762768
}
763769

770+
static std::vector<std::string> parseFirstRecordedAPI()
771+
{
772+
SWSS_LOG_ENTER();
773+
774+
const auto delimiter = '|';
775+
std::ifstream infile(SairedisRecFilename);
776+
std::string line;
777+
// skip first line
778+
std::getline(infile, line);
779+
std::getline(infile, line);
780+
781+
std::vector<std::string> tokens;
782+
std::stringstream sstream(line);
783+
std::string token;
784+
// skip first, it is a timestamp
785+
std::getline(sstream, token, delimiter);
786+
while(std::getline(sstream, token, delimiter)) {
787+
tokens.push_back(token);
788+
}
789+
return tokens;
790+
}
791+
792+
static void test_recorder_enum_value_capability_query_request(
793+
sai_object_id_t switch_id,
794+
sai_object_type_t object_type,
795+
sai_attr_id_t attr_id,
796+
const std::vector<std::string>& expectedOutput)
797+
{
798+
SWSS_LOG_ENTER();
799+
800+
remove(SairedisRecFilename.c_str());
801+
802+
Recorder recorder;
803+
recorder.enableRecording(true);
804+
805+
sai_s32_list_t enum_values_capability {.count = 0, .list = nullptr};
806+
807+
recorder.recordQueryAattributeEnumValuesCapability(
808+
switch_id,
809+
object_type,
810+
attr_id,
811+
&enum_values_capability
812+
);
813+
814+
auto tokens = parseFirstRecordedAPI();
815+
ASSERT_EQ(tokens, expectedOutput);
816+
}
817+
818+
static void test_recorder_enum_value_capability_query_response(
819+
sai_status_t status,
820+
sai_object_type_t object_type,
821+
sai_attr_id_t attr_id,
822+
std::vector<int32_t> enumList,
823+
const std::vector<std::string>& expectedOutput)
824+
{
825+
SWSS_LOG_ENTER();
826+
827+
remove(SairedisRecFilename.c_str());
828+
829+
Recorder recorder;
830+
recorder.enableRecording(true);
831+
832+
sai_s32_list_t enum_values_capability;
833+
enum_values_capability.count = static_cast<int32_t>(enumList.size());
834+
enum_values_capability.list = enumList.data();
835+
836+
recorder.recordQueryAattributeEnumValuesCapabilityResponse(
837+
status,
838+
object_type,
839+
attr_id,
840+
&enum_values_capability
841+
);
842+
843+
auto tokens = parseFirstRecordedAPI();
844+
ASSERT_EQ(tokens, expectedOutput);
845+
}
846+
847+
static void test_recorder_enum_value_capability_query()
848+
{
849+
SWSS_LOG_ENTER();
850+
851+
test_recorder_enum_value_capability_query_request(
852+
1,
853+
SAI_OBJECT_TYPE_DEBUG_COUNTER,
854+
SAI_DEBUG_COUNTER_ATTR_TYPE,
855+
{
856+
"q",
857+
"attribute_enum_values_capability",
858+
"SAI_OBJECT_TYPE_SWITCH:oid:0x1",
859+
"SAI_DEBUG_COUNTER_ATTR_TYPE=0",
860+
}
861+
);
862+
test_recorder_enum_value_capability_query_response(
863+
SAI_STATUS_SUCCESS,
864+
SAI_OBJECT_TYPE_DEBUG_COUNTER,
865+
SAI_DEBUG_COUNTER_ATTR_TYPE,
866+
{
867+
SAI_DEBUG_COUNTER_TYPE_PORT_IN_DROP_REASONS,
868+
SAI_DEBUG_COUNTER_TYPE_PORT_OUT_DROP_REASONS,
869+
SAI_DEBUG_COUNTER_TYPE_SWITCH_IN_DROP_REASONS,
870+
SAI_DEBUG_COUNTER_TYPE_SWITCH_OUT_DROP_REASONS,
871+
},
872+
{
873+
"Q",
874+
"attribute_enum_values_capability",
875+
"SAI_STATUS_SUCCESS",
876+
"SAI_DEBUG_COUNTER_ATTR_TYPE=4:SAI_DEBUG_COUNTER_TYPE_PORT_IN_DROP_REASONS,SAI_DEBUG_COUNTER_TYPE_PORT_OUT_DROP_REASONS,"
877+
"SAI_DEBUG_COUNTER_TYPE_SWITCH_IN_DROP_REASONS,SAI_DEBUG_COUNTER_TYPE_SWITCH_OUT_DROP_REASONS",
878+
}
879+
);
880+
test_recorder_enum_value_capability_query_request(
881+
1,
882+
SAI_OBJECT_TYPE_DEBUG_COUNTER,
883+
SAI_DEBUG_COUNTER_ATTR_IN_DROP_REASON_LIST,
884+
{
885+
"q",
886+
"attribute_enum_values_capability",
887+
"SAI_OBJECT_TYPE_SWITCH:oid:0x1",
888+
"SAI_DEBUG_COUNTER_ATTR_IN_DROP_REASON_LIST=0",
889+
}
890+
);
891+
test_recorder_enum_value_capability_query_response(
892+
SAI_STATUS_SUCCESS,
893+
SAI_OBJECT_TYPE_DEBUG_COUNTER,
894+
SAI_DEBUG_COUNTER_ATTR_IN_DROP_REASON_LIST,
895+
{
896+
SAI_IN_DROP_REASON_L2_ANY,
897+
SAI_IN_DROP_REASON_L3_ANY
898+
},
899+
{
900+
"Q",
901+
"attribute_enum_values_capability",
902+
"SAI_STATUS_SUCCESS",
903+
"SAI_DEBUG_COUNTER_ATTR_IN_DROP_REASON_LIST=2:SAI_IN_DROP_REASON_L2_ANY,SAI_IN_DROP_REASON_L3_ANY"
904+
}
905+
);
906+
}
907+
764908
void test_tokenize_bulk_route_entry()
765909
{
766910
SWSS_LOG_ENTER();
@@ -881,5 +1025,9 @@ int main()
8811025
test_serialize_bulk_create_route_entry(10,10000);
8821026
test_serialize_bulk_create_oid(10,10000);
8831027

1028+
std::cout << " * test recorder" << std::endl;
1029+
1030+
test_recorder_enum_value_capability_query();
1031+
8841032
return 0;
8851033
}

meta/sai_serialize.h

+5
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,11 @@ std::string sai_serialize_enum(
153153
_In_ const int32_t value,
154154
_In_ const sai_enum_metadata_t* meta);
155155

156+
std::string sai_serialize_enum_list(
157+
_In_ const sai_s32_list_t& list,
158+
_In_ const sai_enum_metadata_t* meta,
159+
_In_ bool countOnly);
160+
156161
std::string sai_serialize_number(
157162
_In_ uint32_t number,
158163
_In_ bool hex = false);

0 commit comments

Comments
 (0)