unittest/syncd/TestMdioIpcServer.cpp (222 lines of code) (raw):

#include "MdioIpcServer.h" #include "MdioIpcClient.h" #include "MdioIpcCommon.h" #include "MockableSaiInterface.h" #include "swss/logger.h" #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <gtest/gtest.h> #define MDIO_MISSING_DEV_ADDR 0x1F #define MDIO_MISSING_REG_ADDR 0xFFFF using namespace syncd; using namespace std; static std::map<uint64_t, uint32_t> mdioDevRegValMap; static std::map<uint64_t, uint32_t> mdioDevCl22RegValMap; static sai_status_t MockMdioRead( _In_ sai_object_id_t switchId, _In_ uint32_t device_addr, _In_ uint32_t start_reg_addr, _In_ uint32_t number_of_registers, _Out_ uint32_t *reg_val) { SWSS_LOG_ENTER(); uint64_t key = device_addr; key <<= 32; key |= start_reg_addr; auto it = mdioDevRegValMap.find(key); if (it == mdioDevRegValMap.end()) { *reg_val = 0; return SAI_STATUS_FAILURE; } else { *reg_val = it->second; } return SAI_STATUS_SUCCESS; } static sai_status_t MockMdioWrite( _In_ sai_object_id_t switchId, _In_ uint32_t device_addr, _In_ uint32_t start_reg_addr, _In_ uint32_t number_of_registers, _In_ const uint32_t *reg_val) { SWSS_LOG_ENTER(); if (MDIO_MISSING_DEV_ADDR == device_addr) { return SAI_STATUS_FAILURE; } uint64_t key = device_addr; key <<= 32; key |= start_reg_addr; mdioDevRegValMap[key] = *reg_val; return SAI_STATUS_SUCCESS; } static sai_status_t MockMdioCl22Read( _In_ sai_object_id_t switchId, _In_ uint32_t device_addr, _In_ uint32_t start_reg_addr, _In_ uint32_t number_of_registers, _Out_ uint32_t *reg_val) { SWSS_LOG_ENTER(); uint64_t key = device_addr; key <<= 32; key |= start_reg_addr; auto it = mdioDevCl22RegValMap.find(key); if (it == mdioDevCl22RegValMap.end()) { *reg_val = 0; return SAI_STATUS_FAILURE; } else { *reg_val = it->second; } return SAI_STATUS_SUCCESS; } static sai_status_t MockMdioCl22Write( _In_ sai_object_id_t switchId, _In_ uint32_t device_addr, _In_ uint32_t start_reg_addr, _In_ uint32_t number_of_registers, _In_ const uint32_t *reg_val) { SWSS_LOG_ENTER(); if (MDIO_MISSING_DEV_ADDR == device_addr) { return SAI_STATUS_FAILURE; } uint64_t key = device_addr; key <<= 32; key |= start_reg_addr; mdioDevCl22RegValMap[key] = *reg_val; return SAI_STATUS_SUCCESS; } TEST(MdioIpcServer, mdioAccess) { SWSS_LOG_ENTER(); std::shared_ptr<MockableSaiInterface> mdio_sai(new MockableSaiInterface()); mdio_sai->mock_switchMdioRead = MockMdioRead; mdio_sai->mock_switchMdioWrite = MockMdioWrite; mdio_sai->mock_switchMdioCl22Read = MockMdioCl22Read; mdio_sai->mock_switchMdioCl22Write = MockMdioCl22Write; char path[64]; strcpy(path, SYNCD_IPC_SOCK_SYNCD); if (open(path, O_DIRECTORY) < 0) { SWSS_LOG_NOTICE("Directory %s does not exist", SYNCD_IPC_SOCK_SYNCD); if (mkdir(SYNCD_IPC_SOCK_SYNCD, 0755) < 0) { SWSS_LOG_WARN("Can not create directory %s", SYNCD_IPC_SOCK_SYNCD); } } std::shared_ptr<MdioIpcServer> mdio_server(new MdioIpcServer(mdio_sai, 0)); mdio_server->setIpcTestMode(); mdio_server->setSwitchId(0x21000000000000); mdio_server->startMdioThread(); sleep(1); uint32_t data; uint64_t key; sai_status_t rc; uint32_t data2[2]; /* MDIO read */ mdioDevRegValMap.clear(); data = 0; key = 0x4; key <<= 32; key |= 0x1A; mdioDevRegValMap[key] = 0xC0DE; rc = mdio_read(0xF0F0F0F0F0F0F0F0, 0x4, 0x1A, 1, &data); SWSS_LOG_NOTICE("rc = %d, data = %x", rc, data); EXPECT_EQ(rc, SAI_STATUS_SUCCESS); EXPECT_EQ(data, 0xC0DE); rc = mdio_read(0xF0F0F0F0F0F0F0F0, MDIO_MISSING_DEV_ADDR, MDIO_MISSING_REG_ADDR, 1, &data); EXPECT_NE(rc, SAI_STATUS_SUCCESS); rc = mdio_read(0xF0F0F0F0F0F0F0F0, 0x4, 0x1A, 2, data2); EXPECT_NE(rc, SAI_STATUS_SUCCESS); /* MDIO write */ mdioDevRegValMap.clear(); data = 0xBEEF; rc = mdio_write(0xF0F0F0F0F0F0F0F0, 0x3, 0x1B, 1, &data); SWSS_LOG_NOTICE("rc = %d", rc); EXPECT_EQ(rc, SAI_STATUS_SUCCESS); key = 0x3; key <<= 32; key |= 0x1B; SWSS_LOG_NOTICE("reg = %x", mdioDevRegValMap[key]); EXPECT_EQ(mdioDevRegValMap[key], 0xBEEF); rc = mdio_write(0xF0F0F0F0F0F0F0F0, MDIO_MISSING_DEV_ADDR, MDIO_MISSING_REG_ADDR, 1, &data); EXPECT_NE(rc, SAI_STATUS_SUCCESS); rc = mdio_write(0xF0F0F0F0F0F0F0F0, 0x3, 0x1B, 2, data2); EXPECT_NE(rc, SAI_STATUS_SUCCESS); /* MDIO CL22 read */ mdioDevCl22RegValMap.clear(); data = 0x0; key = 0x2; key <<= 32; key |= 0x1C; mdioDevCl22RegValMap[key] = 0xFEED; rc = mdio_read_cl22(0xF0F0F0F0F0F0F0F0, 0x2, 0x1C, 1, &data); SWSS_LOG_NOTICE("rc = %d, data = %x", rc, data); EXPECT_EQ(rc, SAI_STATUS_SUCCESS); EXPECT_EQ(data, 0xFEED); rc = mdio_read_cl22(0xF0F0F0F0F0F0F0F0, MDIO_MISSING_DEV_ADDR, MDIO_MISSING_REG_ADDR, 1, &data); EXPECT_NE(rc, SAI_STATUS_SUCCESS); rc = mdio_read_cl22(0xF0F0F0F0F0F0F0F0, 0x2, 0x1C, 2, data2); EXPECT_NE(rc, SAI_STATUS_SUCCESS); /* MDIO CL22 write */ mdioDevCl22RegValMap.clear(); data = 0xCAFE; rc = mdio_write_cl22(0xF0F0F0F0F0F0F0F0, 0x1, 0x1D, 1, &data); SWSS_LOG_NOTICE("rc = %d", rc); EXPECT_EQ(rc, SAI_STATUS_SUCCESS); key = 0x1; key <<= 32; key |= 0x1D; SWSS_LOG_NOTICE("cl22 reg = %x", mdioDevCl22RegValMap[key]); EXPECT_EQ(mdioDevCl22RegValMap[key], 0xCAFE); rc = mdio_write_cl22(0xF0F0F0F0F0F0F0F0, MDIO_MISSING_DEV_ADDR, MDIO_MISSING_REG_ADDR, 1, &data); EXPECT_NE(rc, SAI_STATUS_SUCCESS); rc = mdio_write_cl22(0xF0F0F0F0F0F0F0F0, 0x1, 0x1D, 2, data2); EXPECT_NE(rc, SAI_STATUS_SUCCESS); /* Test ipc client timeout */ sleep(MDIO_CLIENT_TIMEOUT+1); rc = mdio_read_cl22(0xF0F0F0F0F0F0F0F0, 0x1, 0x1D, 1, &data); EXPECT_EQ(rc, SAI_STATUS_SUCCESS); mdio_server->stopMdioThread(); sleep(MDIO_CLIENT_TIMEOUT+1); } TEST(MdioIpcServer, mdioConnect) { SWSS_LOG_ENTER(); std::shared_ptr<MockableSaiInterface> mdio_sai(new MockableSaiInterface()); mdio_sai->mock_switchMdioRead = MockMdioRead; mdio_sai->mock_switchMdioWrite = MockMdioWrite; mdio_sai->mock_switchMdioCl22Read = MockMdioCl22Read; mdio_sai->mock_switchMdioCl22Write = MockMdioCl22Write; char path[64]; strcpy(path, SYNCD_IPC_SOCK_SYNCD); if (open(path, O_DIRECTORY) < 0) { SWSS_LOG_NOTICE("Directory %s does not exist", SYNCD_IPC_SOCK_SYNCD); if (mkdir(SYNCD_IPC_SOCK_SYNCD, 0755) < 0) { SWSS_LOG_WARN("Can not create directory %s", SYNCD_IPC_SOCK_SYNCD); } } std::shared_ptr<MdioIpcServer> mdio_server(new MdioIpcServer(mdio_sai, 0)); mdio_server->setSwitchId(0x21000000000000); mdio_server->startMdioThread(); sleep(1); uint32_t data; uint64_t key; sai_status_t rc; /* ipc connect fail without setIpcTestMode() on non broadcom platform */ mdioDevRegValMap.clear(); data = 0; key = 0x4; key <<= 32; key |= 0x1A; mdioDevRegValMap[key] = 0xC0DE; rc = mdio_read(0xF0F0F0F0F0F0F0F0, 0x4, 0x1A, 1, &data); EXPECT_NE(rc, SAI_STATUS_SUCCESS); mdio_server->stopMdioThread(); }