diff --git a/cfgmgr/intfmgr.cpp b/cfgmgr/intfmgr.cpp index f0f4ec97fa..bdfd8ce46c 100644 --- a/cfgmgr/intfmgr.cpp +++ b/cfgmgr/intfmgr.cpp @@ -491,13 +491,24 @@ void IntfMgr::updateSubIntfAdminStatus(const string &alias, const string &admin) std::string IntfMgr::setHostSubIntfAdminStatus(const string &alias, const string &admin_status, const string &parent_admin_status) { stringstream cmd; - string res; + string res, cmd_str; if (parent_admin_status == "up" || admin_status == "down") { SWSS_LOG_INFO("subintf %s admin_status: %s", alias.c_str(), admin_status.c_str()); cmd << IP_CMD " link set " << shellquote(alias) << " " << shellquote(admin_status); - EXEC_WITH_ERROR_THROW(cmd.str(), res); + cmd_str = cmd.str(); + int ret = swss::exec(cmd_str, res); + if (ret && !isIntfStateOk(alias)) + { + // Can happen when a DEL notification is sent by portmgrd immediately followed by a new SET notification + SWSS_LOG_WARN("Setting admin_status to %s netdev failed with cmd:%s, rc:%d, error:%s", + alias.c_str(), cmd_str.c_str(), ret, res.c_str()); + } + else if (ret) + { + throw runtime_error(cmd_str + " : " + res); + } return admin_status; } else diff --git a/tests/mock_tests/Makefile.am b/tests/mock_tests/Makefile.am index cba0212f42..33ecb5e974 100644 --- a/tests/mock_tests/Makefile.am +++ b/tests/mock_tests/Makefile.am @@ -129,7 +129,7 @@ tests_LDADD = $(LDADD_GTEST) $(LDADD_SAI) -lnl-genl-3 -lhiredis -lhiredis -lpthr ## intfmgrd unit tests -tests_intfmgrd_SOURCES = intfmgrd/add_ipv6_prefix_ut.cpp \ +tests_intfmgrd_SOURCES = intfmgrd/intfmgr_ut.cpp \ $(top_srcdir)/cfgmgr/intfmgr.cpp \ $(top_srcdir)/orchagent/orch.cpp \ $(top_srcdir)/orchagent/request_parser.cpp \ diff --git a/tests/mock_tests/intfmgrd/add_ipv6_prefix_ut.cpp b/tests/mock_tests/intfmgrd/intfmgr_ut.cpp similarity index 77% rename from tests/mock_tests/intfmgrd/add_ipv6_prefix_ut.cpp rename to tests/mock_tests/intfmgrd/intfmgr_ut.cpp index f07fa9ccbd..4d84a7d3a0 100644 --- a/tests/mock_tests/intfmgrd/add_ipv6_prefix_ut.cpp +++ b/tests/mock_tests/intfmgrd/intfmgr_ut.cpp @@ -1,6 +1,6 @@ #include "gtest/gtest.h" #include -#include +#include #include #include #include "../mock_table.h" @@ -28,6 +28,9 @@ int cb(const std::string &cmd, std::string &stdout){ else if (cmd.find("/sbin/ip -6 address \"add\"") == 0) { return Ethernet0IPv6Set ? 0 : 2; } + else if (cmd == "/sbin/ip link set \"Ethernet64.10\" \"up\""){ + return 1; + } else { return 0; } @@ -35,7 +38,7 @@ int cb(const std::string &cmd, std::string &stdout){ } // Test Fixture -namespace add_ipv6_prefix_ut +namespace intfmgr_ut { struct IntfMgrTest : public ::testing::Test { @@ -43,14 +46,14 @@ namespace add_ipv6_prefix_ut std::shared_ptr m_app_db; std::shared_ptr m_state_db; std::vector cfg_intf_tables; - + virtual void SetUp() override - { + { testing_db::reset(); m_config_db = std::make_shared("CONFIG_DB", 0); m_app_db = std::make_shared("APPL_DB", 0); m_state_db = std::make_shared("STATE_DB", 0); - + swss::WarmStart::initialize("intfmgrd", "swss"); std::vector tables = { @@ -114,4 +117,22 @@ namespace add_ipv6_prefix_ut } ASSERT_EQ(ip_cmd_called, 1); } + + //This test except no runtime error when the set admin status command failed + //and the subinterface has not ok status (for example not existing subinterface) + TEST_F(IntfMgrTest, testSetAdminStatusFailToNotOkSubInt){ + swss::IntfMgr intfmgr(m_config_db.get(), m_app_db.get(), m_state_db.get(), cfg_intf_tables); + intfmgr.setHostSubIntfAdminStatus("Ethernet64.10", "up", "up"); + } + + //This test except runtime error when the set admin status command failed + //and the subinterface has ok status + TEST_F(IntfMgrTest, testSetAdminStatusFailToOkSubInt){ + swss::IntfMgr intfmgr(m_config_db.get(), m_app_db.get(), m_state_db.get(), cfg_intf_tables); + /* Set portStateTable */ + std::vector values; + values.emplace_back("state", "ok"); + intfmgr.m_statePortTable.set("Ethernet64.10", values, "SET", ""); + EXPECT_THROW(intfmgr.setHostSubIntfAdminStatus("Ethernet64.10", "up", "up"), std::runtime_error); + } }