Skip to content

Commit e53489e

Browse files
authored
[syncd] Update log level for bulk api (sonic-net#1532)
[syncd] Update log level for bulk api
1 parent 7ae00e5 commit e53489e

File tree

2 files changed

+296
-3
lines changed

2 files changed

+296
-3
lines changed

syncd/Syncd.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -2019,7 +2019,7 @@ sai_status_t Syncd::processBulkOidCreate(
20192019

20202020
if (status == SAI_STATUS_NOT_IMPLEMENTED || status == SAI_STATUS_NOT_SUPPORTED)
20212021
{
2022-
SWSS_LOG_ERROR("bulkCreate api is not implemented or not supported, object_type = %s",
2022+
SWSS_LOG_WARN("bulkCreate api is not implemented or not supported, object_type = %s",
20232023
sai_serialize_object_type(objectType).c_str());
20242024
return status;
20252025
}
@@ -2095,7 +2095,7 @@ sai_status_t Syncd::processBulkOidSet(
20952095

20962096
if (status == SAI_STATUS_NOT_IMPLEMENTED || status == SAI_STATUS_NOT_SUPPORTED)
20972097
{
2098-
SWSS_LOG_ERROR("bulkSet api is not implemented or not supported, object_type = %s",
2098+
SWSS_LOG_WARN("bulkSet api is not implemented or not supported, object_type = %s",
20992099
sai_serialize_object_type(objectType).c_str());
21002100
}
21012101

@@ -2143,7 +2143,7 @@ sai_status_t Syncd::processBulkOidRemove(
21432143

21442144
if (status == SAI_STATUS_NOT_IMPLEMENTED || status == SAI_STATUS_NOT_SUPPORTED)
21452145
{
2146-
SWSS_LOG_ERROR("bulkRemove api is not implemented or not supported, object_type = %s",
2146+
SWSS_LOG_WARN("bulkRemove api is not implemented or not supported, object_type = %s",
21472147
sai_serialize_object_type(objectType).c_str());
21482148
return status;
21492149
}

unittest/syncd/TestSyncd.cpp

+293
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
using namespace syncd;
2323
using namespace saivs;
24+
using namespace testing;
2425

2526
static void syncd_thread(
2627
_In_ std::shared_ptr<Syncd> syncd)
@@ -230,17 +231,39 @@ void clearDB()
230231
r.checkStatusOK();
231232
}
232233

234+
class MockSaiSwitch : public SaiSwitch {
235+
public:
236+
MockSaiSwitch(sai_object_id_t switchVid, sai_object_id_t switchRid,
237+
std::shared_ptr<RedisClient> client,
238+
std::shared_ptr<VirtualOidTranslator> translator,
239+
std::shared_ptr<MockableSaiInterface> sai, bool warmBoot)
240+
: SaiSwitch(switchVid, switchRid, client, translator, sai, warmBoot) {}
241+
MOCK_METHOD(void, postPortRemove, (sai_object_id_t portRid), (override));
242+
MOCK_METHOD(void, removeExistingObjectReference, (sai_object_id_t rid), (override));
243+
MOCK_METHOD(void, eraseRidAndVid, (sai_object_id_t rid, sai_object_id_t vid));
244+
};
245+
233246
class SyncdTest : public ::testing::Test
234247
{
235248
protected:
236249
void SetUp() override
237250
{
251+
m_sai = std::make_shared<MockableSaiInterface>();
252+
m_opt = std::make_shared<CommandLineOptions>();
253+
m_syncd = std::make_shared<Syncd>(m_sai, m_opt, false);
254+
255+
m_opt->m_enableTempView = true;
256+
m_opt->m_startType = SAI_START_TYPE_FASTFAST_BOOT;
238257
clearDB();
239258
}
240259
void TearDown() override
241260
{
242261
clearDB();
243262
}
263+
264+
std::shared_ptr<MockableSaiInterface> m_sai;
265+
std::shared_ptr<CommandLineOptions> m_opt;
266+
std::shared_ptr<Syncd> m_syncd;
244267
};
245268

246269
TEST_F(SyncdTest, processNotifySyncd)
@@ -259,4 +282,274 @@ TEST_F(SyncdTest, processNotifySyncd)
259282
}));
260283
syncd_object.processEvent(consumer);
261284
}
285+
286+
TEST_F(SyncdTest, BulkCreateTest)
287+
{
288+
m_opt->m_enableSaiBulkSupport = true;
289+
sai_object_id_t switchVid = 0x21000000000000;
290+
sai_object_id_t switchRid = 0x11000000000001;
291+
sai_object_id_t portVid = 0x10000000000002;
292+
sai_object_id_t portRid = 0x11000000000002;
293+
auto translator = m_syncd->m_translator;
294+
translator->insertRidAndVid(switchRid, switchVid);
295+
translator->insertRidAndVid(portRid, portVid);
296+
std::vector<uint32_t> lanes = {52, 53};
297+
m_syncd->m_client->setPortLanes(switchVid, portRid, lanes);
298+
m_sai->mock_objectTypeQuery = [switchRid, portRid](sai_object_id_t oid) {
299+
sai_object_type_t ot = SAI_OBJECT_TYPE_NULL;
300+
if (oid == switchRid)
301+
ot = SAI_OBJECT_TYPE_SWITCH;
302+
else if (oid == portRid)
303+
ot = SAI_OBJECT_TYPE_PORT;
304+
else
305+
ot = SAI_OBJECT_TYPE_QUEUE;
306+
return ot;
307+
};
308+
m_sai->mock_switchIdQuery = [switchVid](sai_object_id_t oid) {
309+
return switchVid;
310+
};
311+
m_sai->mock_get = [switchRid, portVid, portRid](sai_object_type_t objectType, sai_object_id_t objectId, uint32_t attrCount, sai_attribute_t* attrList) -> sai_status_t {
312+
if (attrCount != 1) {
313+
return SAI_STATUS_INVALID_PARAMETER;
314+
}
315+
if (attrList[0].id == SAI_SWITCH_ATTR_PORT_LIST) {
316+
if (objectType == SAI_OBJECT_TYPE_SWITCH && objectId == switchRid) {
317+
attrList[0].value.objlist.count = 1;
318+
attrList[0].value.objlist.list[0] = portRid;
319+
return SAI_STATUS_SUCCESS;
320+
}
321+
return SAI_STATUS_INVALID_PARAMETER;
322+
}
323+
if (attrList[0].id == SAI_SWITCH_ATTR_PORT_NUMBER) {
324+
attrList[0].value.u32 = 1;
325+
return SAI_STATUS_SUCCESS;
326+
}
327+
if (objectType == SAI_OBJECT_TYPE_PORT) {
328+
if (attrList[0].id == SAI_PORT_ATTR_HW_LANE_LIST) {
329+
if (objectId == portRid) {
330+
if (attrList[0].value.u32list.list != nullptr) {
331+
attrList[0].value.u32list.count = 2;
332+
static uint32_t hw_lanes[2] = {52, 53};
333+
memcpy(attrList[0].value.u32list.list, hw_lanes, sizeof(uint32_t) * 2);
334+
} else {
335+
return SAI_STATUS_BUFFER_OVERFLOW;
336+
}
337+
}
338+
}
339+
if (attrList[0].id == SAI_PORT_ATTR_PORT_SERDES_ID) {
340+
attrList[0].value.oid = SAI_NULL_OBJECT_ID;
341+
return SAI_STATUS_SUCCESS;
342+
}
343+
return SAI_STATUS_SUCCESS;
344+
}
345+
if (attrList[0].id == SAI_SWITCH_ATTR_SRC_MAC_ADDRESS) {
346+
if (objectType == SAI_OBJECT_TYPE_SWITCH && objectId == switchRid) {
347+
static sai_mac_t mac = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55};
348+
memcpy(attrList[0].value.mac, mac, sizeof(sai_mac_t));
349+
return SAI_STATUS_SUCCESS;
350+
}
351+
return SAI_STATUS_INVALID_PARAMETER;
352+
}
353+
return SAI_STATUS_NOT_SUPPORTED;
354+
};
355+
// Create a mock switch and set expectations
356+
auto mockSwitch = std::make_shared<MockSaiSwitch>(switchVid, switchRid, m_syncd->m_client, translator, m_sai, false);
357+
m_syncd->m_switches[switchVid] = mockSwitch;
358+
EXPECT_CALL(*mockSwitch, postPortRemove(testing::_))
359+
.WillRepeatedly(testing::Invoke([](sai_object_id_t rid) {
360+
}));
361+
EXPECT_CALL(*mockSwitch, removeExistingObjectReference(testing::_))
362+
.WillRepeatedly(testing::Invoke([](sai_object_id_t rid) {
363+
}));
364+
EXPECT_CALL(*mockSwitch, eraseRidAndVid(testing::_, testing::_))
365+
.WillRepeatedly(testing::Invoke([](sai_object_id_t rid, sai_object_id_t vid) {
366+
}));
367+
swss::KeyOpFieldsValuesTuple kco;
368+
std::string key = "SAI_OBJECT_TYPE_PORT:bulk:1";
369+
std::string op = "bulkcreate";
370+
std::vector<swss::FieldValueTuple> values = {
371+
{"oid:0x10000000000002", "SAI_PORT_ATTR_ADMIN_STATE=true"}
372+
};
373+
kco = std::make_tuple(key, op, values);
374+
auto channel = std::make_shared<MockSelectableChannel>();
375+
int popCallCount = 0;
376+
EXPECT_CALL(*channel, empty())
377+
.WillRepeatedly([&popCallCount]() {
378+
return popCallCount > 0; // Return true after the first pop call
379+
});
380+
EXPECT_CALL(*channel, pop(testing::_, testing::_))
381+
.Times(testing::AnyNumber())
382+
.WillRepeatedly(testing::DoAll(
383+
testing::SetArgReferee<0>(kco),
384+
testing::Invoke([&popCallCount](swss::KeyOpFieldsValuesTuple&, bool) {
385+
popCallCount++;
386+
})
387+
));
388+
m_sai->mock_bulkCreate = [](
389+
sai_object_type_t,
390+
sai_object_id_t,
391+
uint32_t,
392+
const uint32_t*,
393+
const sai_attribute_t**,
394+
sai_bulk_op_error_mode_t,
395+
sai_object_id_t*,
396+
sai_status_t*) -> sai_status_t {
397+
return SAI_STATUS_NOT_IMPLEMENTED;
398+
};
399+
m_syncd->processEvent(*channel);
400+
}
401+
402+
TEST_F(SyncdTest, BulkSetTest)
403+
{
404+
m_opt->m_enableSaiBulkSupport = true;
405+
auto translator = m_syncd->m_translator;
406+
translator->insertRidAndVid(0x11000000000001, 0x21000000000000); // Switch
407+
translator->insertRidAndVid(0x1100000000000d, 0x1000000000000d); // Port 1
408+
translator->insertRidAndVid(0x1100000000000e, 0x1000000000000e); // Port 2
409+
swss::KeyOpFieldsValuesTuple kco;
410+
std::string key = "SAI_OBJECT_TYPE_PORT:bulk:1";
411+
std::string op = "bulkset";
412+
std::vector<swss::FieldValueTuple> values = {
413+
{"oid:0x1000000000000d", "SAI_PORT_ATTR_ADMIN_STATE=true"},
414+
{"oid:0x1000000000000e", "SAI_PORT_ATTR_ADMIN_STATE=false"}
415+
};
416+
kco = std::make_tuple(key, op, values);
417+
auto channel = std::make_shared<MockSelectableChannel>();
418+
EXPECT_CALL(*channel, empty())
419+
.WillOnce(testing::Return(false))
420+
.WillRepeatedly(testing::Return(true));
421+
EXPECT_CALL(*channel, pop(testing::_, testing::_))
422+
.Times(testing::AnyNumber())
423+
.WillRepeatedly(testing::DoAll(
424+
testing::SetArgReferee<0>(kco),
425+
testing::Return()
426+
));
427+
m_sai->mock_bulkSet = [](
428+
sai_object_type_t,
429+
uint32_t,
430+
const sai_object_id_t*,
431+
const sai_attribute_t*,
432+
sai_bulk_op_error_mode_t,
433+
sai_status_t*) -> sai_status_t {
434+
return SAI_STATUS_NOT_IMPLEMENTED;
435+
};
436+
m_syncd->processEvent(*channel);
437+
}
438+
439+
TEST_F(SyncdTest, BulkRemoveTest)
440+
{
441+
m_opt->m_enableSaiBulkSupport = true;
442+
sai_object_id_t switchVid = 0x21000000000000;
443+
sai_object_id_t switchRid = 0x11000000000001;
444+
sai_object_id_t portVid = 0x10000000000002;
445+
sai_object_id_t portRid = 0x11000000000002;
446+
auto translator = m_syncd->m_translator;
447+
translator->insertRidAndVid(switchRid, switchVid);
448+
translator->insertRidAndVid(portRid, portVid);
449+
std::vector<uint32_t> lanes = {52, 53};
450+
m_syncd->m_client->setPortLanes(switchVid, portRid, lanes);
451+
std::set<sai_object_id_t> removedRids;
452+
m_sai->mock_objectTypeQuery = [switchRid, portRid, &removedRids](sai_object_id_t oid) {
453+
sai_object_type_t ot = SAI_OBJECT_TYPE_NULL;
454+
if (removedRids.find(oid) != removedRids.end()) {
455+
return SAI_OBJECT_TYPE_NULL;
456+
}
457+
if (oid == switchRid)
458+
ot = SAI_OBJECT_TYPE_SWITCH;
459+
else if (oid == portRid)
460+
ot = SAI_OBJECT_TYPE_PORT;
461+
else
462+
ot = SAI_OBJECT_TYPE_QUEUE;
463+
return ot;
464+
};
465+
m_sai->mock_switchIdQuery = [switchVid](sai_object_id_t oid) {
466+
return switchVid;
467+
};
468+
m_sai->mock_get = [switchRid, portVid, portRid](sai_object_type_t objectType, sai_object_id_t objectId, uint32_t attrCount, sai_attribute_t* attrList) -> sai_status_t {
469+
if (attrCount != 1) {
470+
return SAI_STATUS_INVALID_PARAMETER;
471+
}
472+
if (attrList[0].id == SAI_SWITCH_ATTR_PORT_LIST) {
473+
if (objectType == SAI_OBJECT_TYPE_SWITCH && objectId == switchRid) {
474+
attrList[0].value.objlist.count = 1;
475+
attrList[0].value.objlist.list[0] = portRid;
476+
return SAI_STATUS_SUCCESS;
477+
}
478+
return SAI_STATUS_INVALID_PARAMETER;
479+
}
480+
if (attrList[0].id == SAI_SWITCH_ATTR_PORT_NUMBER) {
481+
attrList[0].value.u32 = 1;
482+
return SAI_STATUS_SUCCESS;
483+
}
484+
if (objectType == SAI_OBJECT_TYPE_PORT) {
485+
if (attrList[0].id == SAI_PORT_ATTR_HW_LANE_LIST) {
486+
if (objectId == portRid) {
487+
if (attrList[0].value.u32list.list != nullptr) {
488+
attrList[0].value.u32list.count = 2;
489+
static uint32_t hw_lanes[2] = {52, 53};
490+
memcpy(attrList[0].value.u32list.list, hw_lanes, sizeof(uint32_t) * 2);
491+
} else {
492+
return SAI_STATUS_BUFFER_OVERFLOW;
493+
}
494+
}
495+
}
496+
if (attrList[0].id == SAI_PORT_ATTR_PORT_SERDES_ID) {
497+
attrList[0].value.oid = SAI_NULL_OBJECT_ID;
498+
return SAI_STATUS_SUCCESS;
499+
}
500+
return SAI_STATUS_SUCCESS;
501+
}
502+
if (attrList[0].id == SAI_SWITCH_ATTR_SRC_MAC_ADDRESS) {
503+
if (objectType == SAI_OBJECT_TYPE_SWITCH && objectId == switchRid) {
504+
static sai_mac_t mac = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55};
505+
memcpy(attrList[0].value.mac, mac, sizeof(sai_mac_t));
506+
return SAI_STATUS_SUCCESS;
507+
}
508+
return SAI_STATUS_INVALID_PARAMETER;
509+
}
510+
return SAI_STATUS_NOT_SUPPORTED;
511+
};
512+
// Create a mock switch and set expectations
513+
auto mockSwitch = std::make_shared<MockSaiSwitch>(switchVid, switchRid, m_syncd->m_client, translator, m_sai, false);
514+
m_syncd->m_switches[switchVid] = mockSwitch;
515+
EXPECT_CALL(*mockSwitch, postPortRemove(testing::_))
516+
.WillRepeatedly(testing::Invoke([](sai_object_id_t rid) {
517+
}));
518+
EXPECT_CALL(*mockSwitch, removeExistingObjectReference(testing::_))
519+
.WillRepeatedly(testing::Invoke([](sai_object_id_t rid) {
520+
}));
521+
EXPECT_CALL(*mockSwitch, eraseRidAndVid(testing::_, testing::_))
522+
.WillRepeatedly(testing::Invoke([](sai_object_id_t rid, sai_object_id_t vid) {
523+
}));
524+
swss::KeyOpFieldsValuesTuple kco;
525+
std::string key = "SAI_OBJECT_TYPE_PORT:bulk:1";
526+
std::string op = "bulkremove";
527+
std::vector<swss::FieldValueTuple> values = {
528+
{"oid:0x10000000000002", "SAI_PORT_ATTR_ADMIN_STATE=true"}
529+
};
530+
kco = std::make_tuple(key, op, values);
531+
auto channel = std::make_shared<MockSelectableChannel>();
532+
int popCallCount = 0;
533+
EXPECT_CALL(*channel, empty())
534+
.WillRepeatedly([&popCallCount]() {
535+
return popCallCount > 0; // Return true after the first pop call
536+
});
537+
EXPECT_CALL(*channel, pop(testing::_, testing::_))
538+
.Times(testing::AnyNumber())
539+
.WillRepeatedly(testing::DoAll(
540+
testing::SetArgReferee<0>(kco),
541+
testing::Invoke([&popCallCount](swss::KeyOpFieldsValuesTuple&, bool) {
542+
popCallCount++;
543+
})
544+
));
545+
m_sai->mock_bulkRemove = [](
546+
sai_object_type_t,
547+
uint32_t,
548+
const sai_object_id_t*,
549+
sai_bulk_op_error_mode_t,
550+
sai_status_t*) -> sai_status_t {
551+
return SAI_STATUS_NOT_IMPLEMENTED;
552+
};
553+
m_syncd->processEvent(*channel);
554+
}
262555
#endif

0 commit comments

Comments
 (0)