diff --git a/orchagent/main.cpp b/orchagent/main.cpp index 0add517a05..df702e7c3f 100644 --- a/orchagent/main.cpp +++ b/orchagent/main.cpp @@ -505,6 +505,10 @@ int main(int argc, char **argv) attr.value.ptr = (void *)on_switch_shutdown_request; attrs.push_back(attr); + attr.id = SAI_SWITCH_ATTR_PORT_HOST_TX_READY_NOTIFY; + attr.value.ptr = (void *)on_port_host_tx_ready; + attrs.push_back(attr); + if (gMySwitchType != "fabric" && gMacAddress) { attr.id = SAI_SWITCH_ATTR_SRC_MAC_ADDRESS; diff --git a/orchagent/notifications.cpp b/orchagent/notifications.cpp index 2cd46d5cfd..442e93d75a 100644 --- a/orchagent/notifications.cpp +++ b/orchagent/notifications.cpp @@ -47,3 +47,9 @@ void on_switch_shutdown_request(sai_object_id_t switch_id) quick_exit(EXIT_FAILURE); } + +void on_port_host_tx_ready(sai_object_id_t switch_id, sai_object_id_t port_id, sai_port_host_tx_ready_status_t m_portHostTxReadyStatus) +{ + // don't use this event handler, because it runs by libsairedis in a separate thread + // which causes concurrency access to the DB +} diff --git a/orchagent/notifications.h b/orchagent/notifications.h index 61e8422db0..81d49efee0 100644 --- a/orchagent/notifications.h +++ b/orchagent/notifications.h @@ -11,3 +11,4 @@ void on_bfd_session_state_change(uint32_t count, sai_bfd_session_state_notificat // The function prototype information can be found here: // https://github.com/sonic-net/sonic-sairedis/blob/master/meta/NotificationSwitchShutdownRequest.cpp#L49 void on_switch_shutdown_request(sai_object_id_t switch_id); +void on_port_host_tx_ready(sai_object_id_t switch_id, sai_object_id_t port_id, sai_port_host_tx_ready_status_t m_portHostTxReadyStatus); diff --git a/orchagent/portsorch.cpp b/orchagent/portsorch.cpp index 98c13b7dc7..abfa9d5ee9 100755 --- a/orchagent/portsorch.cpp +++ b/orchagent/portsorch.cpp @@ -342,7 +342,7 @@ static void getPortSerdesAttr(PortSerdesAttrMap_t &map, const PortConfig &port) if (port.serdes.ob_m2lp.is_set) { - + map[SAI_PORT_SERDES_ATTR_TX_PAM4_RATIO] = port.serdes.ob_m2lp.value; } @@ -371,7 +371,7 @@ static void getPortSerdesAttr(PortSerdesAttrMap_t &map, const PortConfig &port) map[SAI_PORT_SERDES_ATTR_TX_NMOS_VLTG_REG] = port.serdes.regn_bfm1n.value; } - + } // Port OA ------------------------------------------------------------------------------------------------------------ @@ -532,6 +532,42 @@ PortsOrch::PortsOrch(DBConnector *db, DBConnector *stateDb, vector &portList) attrList.push_back(attr); } + if (m_cmisModuleAsicSyncSupported) + { + attr.id = SAI_PORT_ATTR_HOST_TX_SIGNAL_ENABLE; + attr.value.booldata = false; + attrList.push_back(attr); + } + attrDataList.push_back(attrList); attrCountList.push_back(static_cast(attrDataList.back().size())); attrPtrList.push_back(attrDataList.back().data()); @@ -1386,7 +1436,7 @@ void PortsOrch::initHostTxReadyState(Port &port) if (hostTxReady.empty()) { - m_portStateTable.hset(port.m_alias, "host_tx_ready", "false"); + setHostTxReady(port.m_port_id, "false"); SWSS_LOG_NOTICE("initialize host_tx_ready as false for port %s", port.m_alias.c_str()); } @@ -1400,10 +1450,13 @@ bool PortsOrch::setPortAdminStatus(Port &port, bool state) attr.id = SAI_PORT_ATTR_ADMIN_STATE; attr.value.booldata = state; + // if sync between cmis module configuration and asic is supported, + // do not change host_tx_ready value in STATE DB when admin status is changed. + /* Update the host_tx_ready to false before setting admin_state, when admin state is false */ - if (!state) + if (!state && !m_cmisModuleAsicSyncSupported) { - m_portStateTable.hset(port.m_alias, "host_tx_ready", "false"); + setHostTxReady(port.m_port_id, "false"); SWSS_LOG_NOTICE("Set admin status DOWN host_tx_ready to false for port %s", port.m_alias.c_str()); } @@ -1414,7 +1467,11 @@ bool PortsOrch::setPortAdminStatus(Port &port, bool state) SWSS_LOG_ERROR("Failed to set admin status %s for port %s." " Setting host_tx_ready as false", state ? "UP" : "DOWN", port.m_alias.c_str()); - m_portStateTable.hset(port.m_alias, "host_tx_ready", "false"); + + if (!m_cmisModuleAsicSyncSupported) + { + setHostTxReady(port.m_port_id, "false"); + } task_process_status handle_status = handleSaiSetStatus(SAI_API_PORT, status); if (handle_status != task_success) { @@ -1423,17 +1480,17 @@ bool PortsOrch::setPortAdminStatus(Port &port, bool state) } bool gbstatus = setGearboxPortsAttr(port, SAI_PORT_ATTR_ADMIN_STATE, &state); - if (gbstatus != true) + if (gbstatus != true && !m_cmisModuleAsicSyncSupported) { - m_portStateTable.hset(port.m_alias, "host_tx_ready", "false"); + setHostTxReady(port.m_port_id, "false"); SWSS_LOG_NOTICE("Set host_tx_ready to false as gbstatus is false " "for port %s", port.m_alias.c_str()); } /* Update the state table for host_tx_ready*/ - if (state && (gbstatus == true) && (status == SAI_STATUS_SUCCESS) ) + if (state && (gbstatus == true) && (status == SAI_STATUS_SUCCESS) && !m_cmisModuleAsicSyncSupported) { - m_portStateTable.hset(port.m_alias, "host_tx_ready", "true"); + setHostTxReady(port.m_port_id, "true"); SWSS_LOG_NOTICE("Set admin status UP host_tx_ready to true for port %s", port.m_alias.c_str()); } @@ -1441,6 +1498,20 @@ bool PortsOrch::setPortAdminStatus(Port &port, bool state) return true; } +void PortsOrch::setHostTxReady(sai_object_id_t portId, const std::string &status) +{ + Port p; + + if (!getPort(portId, p)) + { + SWSS_LOG_ERROR("Failed to get port object for port id 0x%" PRIx64, portId); + return; + } + + SWSS_LOG_NOTICE("Setting host_tx_ready status = %s, alias = %s, port_id = 0x%" PRIx64, status.c_str(), p.m_alias.c_str(), portId); + m_portStateTable.hset(p.m_alias, "host_tx_ready", status); +} + bool PortsOrch::getPortAdminStatus(sai_object_id_t id, bool &up) { SWSS_LOG_ENTER(); @@ -1466,6 +1537,25 @@ bool PortsOrch::getPortAdminStatus(sai_object_id_t id, bool &up) return true; } +bool PortsOrch::getPortHostTxReady(const Port& port, bool &hostTxReadyVal) +{ + SWSS_LOG_ENTER(); + + sai_attribute_t attr; + attr.id = SAI_PORT_ATTR_HOST_TX_READY_STATUS; + + sai_status_t status = sai_port_api->get_port_attribute(port.m_port_id, 1, &attr); + if (status != SAI_STATUS_SUCCESS) + { + hostTxReadyVal = false; + return false; + } + + hostTxReadyVal = attr.value.s32; + + return true; +} + bool PortsOrch::getPortMtu(const Port& port, sai_uint32_t &mtu) { SWSS_LOG_ENTER(); @@ -4469,6 +4559,69 @@ void PortsOrch::doVlanMemberTask(Consumer &consumer) } } +void PortsOrch::doTransceiverPresenceCheck(Consumer &consumer) +{ + /* + the idea is to listen to transceiver info table, and also maintain an internal list of plugged modules. + + */ + SWSS_LOG_ENTER(); + + string table_name = consumer.getTableName(); + + auto it = consumer.m_toSync.begin(); + while(it != consumer.m_toSync.end()) + { + auto t = it->second; + string alias = kfvKey(t); + string op = kfvOp(t); + + if (op == SET_COMMAND) + { + SWSS_LOG_DEBUG("TRANSCEIVER_INFO table has changed - SET command for port %s", alias.c_str()); + + if (m_pluggedModulesPort.find(alias) == m_pluggedModulesPort.end()) + { + m_pluggedModulesPort[alias] = m_portList[alias]; + + SWSS_LOG_DEBUG("Setting host_tx_signal allow for port %s", alias.c_str()); + setSaiHostTxSignal(m_pluggedModulesPort[alias], true); + } + } + else if (op == DEL_COMMAND) + { + SWSS_LOG_DEBUG("TRANSCEIVER_INFO table has changed - DEL command for port %s", alias.c_str()); + + Port p; + if (m_pluggedModulesPort.find(alias) != m_pluggedModulesPort.end()) + { + p = m_pluggedModulesPort[alias]; + m_pluggedModulesPort.erase(alias); + SWSS_LOG_DEBUG("Setting host_tx_signal NOT allow for port %s", alias.c_str()); + setSaiHostTxSignal(p, false); + } + } + + it = consumer.m_toSync.erase(it); + } +} + +bool PortsOrch::setSaiHostTxSignal(const Port &port, bool enable) +{ + sai_attribute_t attr; + attr.id = SAI_PORT_ATTR_HOST_TX_SIGNAL_ENABLE; + attr.value.booldata = enable; + sai_status_t status = sai_port_api->set_port_attribute(port.m_port_id, &attr); + + if (status != SAI_STATUS_SUCCESS) + { + SWSS_LOG_ERROR("Could not setSAI_PORT_ATTR_HOST_TX_SIGNAL_ENABLE to port 0x%" PRIx64, port.m_port_id); + return false; + } + + return true; +} + void PortsOrch::doLagTask(Consumer &consumer) { SWSS_LOG_ENTER(); @@ -4867,7 +5020,11 @@ void PortsOrch::doTask(Consumer &consumer) string table_name = consumer.getTableName(); - if (table_name == APP_PORT_TABLE_NAME) + if (table_name == STATE_TRANSCEIVER_INFO_TABLE_NAME) + { + doTransceiverPresenceCheck(consumer); + } + else if (table_name == APP_PORT_TABLE_NAME) { doPortTask(consumer); } @@ -5177,6 +5334,22 @@ bool PortsOrch::initializePort(Port &port) SWSS_LOG_ERROR("Failed to get initial port mtu %d", port.m_mtu); } + /* initialize port host_tx_ready value (only for supporting systems) */ + if (m_cmisModuleAsicSyncSupported) + { + bool hostTxReadyVal; + if (!getPortHostTxReady(port, hostTxReadyVal)) + { + SWSS_LOG_ERROR("Failed to get host_tx_ready value from SAI to Port %" PRIx64 , port.m_port_id); + } + /* set value to state DB */ + + string hostTxReadyStr = hostTxReadyVal ? "true" : "false"; + + SWSS_LOG_DEBUG("Received host_tx_ready current status: port_id: 0x%" PRIx64 " status: %s", port.m_port_id, hostTxReadyStr.c_str()); + setHostTxReady(port.m_port_id, hostTxReadyStr); + } + /* * always initialize Port SAI_HOSTIF_ATTR_OPER_STATUS based on oper_status value in appDB. */ @@ -7281,12 +7454,12 @@ void PortsOrch::doTask(NotificationConsumer &consumer) consumer.pop(op, data, values); - if (&consumer != m_portStatusNotificationConsumer) + if (&consumer != m_portStatusNotificationConsumer && &consumer != m_portHostTxReadyNotificationConsumer) { return; } - if (op == "port_state_change") + if (&consumer == m_portStatusNotificationConsumer && op == "port_state_change") { uint32_t count; sai_port_oper_status_notification_t *portoperstatus = nullptr; @@ -7345,6 +7518,18 @@ void PortsOrch::doTask(NotificationConsumer &consumer) sai_deserialize_free_port_oper_status_ntf(count, portoperstatus); } + else if (&consumer == m_portHostTxReadyNotificationConsumer && op == "port_host_tx_ready") + { + sai_object_id_t port_id; + sai_object_id_t switch_id; + sai_port_host_tx_ready_status_t host_tx_ready_status; + + sai_deserialize_port_host_tx_ready_ntf(data, switch_id, port_id, host_tx_ready_status); + SWSS_LOG_DEBUG("Recieved host_tx_ready notification for port 0x%" PRIx64, port_id); + + setHostTxReady(port_id, host_tx_ready_status == SAI_PORT_HOST_TX_READY_STATUS_READY ? "true" : "false"); + } + } void PortsOrch::updatePortOperStatus(Port &port, sai_port_oper_status_t status) @@ -7937,11 +8122,11 @@ bool PortsOrch::initGearboxPort(Port &port) } attr.value.s32 = sai_fec; attrs.push_back(attr); - + if (fec_override_sup) { attr.id = SAI_PORT_ATTR_AUTO_NEG_FEC_MODE_OVERRIDE; - + attr.value.booldata = m_portHlpr.fecIsOverrideRequired(m_gearboxPortMap[port.m_index].system_fec); attrs.push_back(attr); } @@ -7954,6 +8139,13 @@ bool PortsOrch::initGearboxPort(Port &port) attr.value.booldata = m_gearboxPortMap[port.m_index].system_training; attrs.push_back(attr); + if (m_cmisModuleAsicSyncSupported) + { + attr.id = SAI_PORT_ATTR_HOST_TX_SIGNAL_ENABLE; + attr.value.booldata = false; + attrs.push_back(attr); + } + status = sai_port_api->create_port(&systemPort, phyOid, static_cast(attrs.size()), attrs.data()); if (status != SAI_STATUS_SUCCESS) { @@ -8055,6 +8247,13 @@ bool PortsOrch::initGearboxPort(Port &port) attr.value.u32 = media_type_map[m_gearboxPortMap[port.m_index].line_adver_media_type]; attrs.push_back(attr); + if (m_cmisModuleAsicSyncSupported) + { + attr.id = SAI_PORT_ATTR_HOST_TX_SIGNAL_ENABLE; + attr.value.booldata = false; + attrs.push_back(attr); + } + status = sai_port_api->create_port(&linePort, phyOid, static_cast(attrs.size()), attrs.data()); if (status != SAI_STATUS_SUCCESS) { diff --git a/orchagent/portsorch.h b/orchagent/portsorch.h index 24d7c575f8..cc71c056b4 100755 --- a/orchagent/portsorch.h +++ b/orchagent/portsorch.h @@ -310,6 +310,7 @@ class PortsOrch : public Orch, public Subject map, sai_object_id_t> m_portListLaneMap; map, PortConfig> m_lanesAliasSpeedMap; map m_portList; + map m_pluggedModulesPort; map m_portVlanMember; map> m_port_voq_ids; /* mapping from SAI object ID to Name for faster @@ -326,11 +327,15 @@ class PortsOrch : public Orch, public Subject map m_bridge_port_ref_count; NotificationConsumer* m_portStatusNotificationConsumer; + NotificationConsumer* m_portHostTxReadyNotificationConsumer; + bool fec_override_sup = false; bool oper_fec_sup = false; swss::SelectableTimer *m_port_state_poller = nullptr; + bool m_cmisModuleAsicSyncSupported = false; + void doTask() override; void doTask(Consumer &consumer); void doPortTask(Consumer &consumer); @@ -339,6 +344,7 @@ class PortsOrch : public Orch, public Subject void doVlanMemberTask(Consumer &consumer); void doLagTask(Consumer &consumer); void doLagMemberTask(Consumer &consumer); + void doTransceiverPresenceCheck(Consumer &consumer); void doTask(NotificationConsumer &consumer); void doTask(swss::SelectableTimer &timer); @@ -381,6 +387,7 @@ class PortsOrch : public Orch, public Subject bool setPortAdminStatus(Port &port, bool up); bool getPortAdminStatus(sai_object_id_t id, bool& up); bool getPortMtu(const Port& port, sai_uint32_t &mtu); + bool getPortHostTxReady(const Port& port, bool &hostTxReadyVal); bool setPortMtu(const Port& port, sai_uint32_t mtu); bool setPortTpid(Port &port, sai_uint16_t tpid); bool setPortPvid (Port &port, sai_uint32_t pvid); @@ -392,6 +399,9 @@ class PortsOrch : public Orch, public Subject bool setBridgePortAdminStatus(sai_object_id_t id, bool up); + bool setSaiHostTxSignal(const Port &port, bool enable); + + void setHostTxReady(sai_object_id_t portId, const std::string &status); // Get supported speeds on system side bool isSpeedSupported(const std::string& alias, sai_object_id_t port_id, sai_uint32_t speed); void getPortSupportedSpeeds(const std::string& alias, sai_object_id_t port_id, PortSupportedSpeeds &supported_speeds); diff --git a/tests/test_admin_status.py b/tests/test_admin_status.py index 1b99bf37c7..6aac5cc691 100644 --- a/tests/test_admin_status.py +++ b/tests/test_admin_status.py @@ -8,6 +8,7 @@ class TestAdminStatus(object): def setup_db(self, dvs): self.pdb = swsscommon.DBConnector(0, dvs.redis_sock, 0) self.adb = swsscommon.DBConnector(1, dvs.redis_sock, 0) + self.countdb = swsscommon.DBConnector(2, dvs.redis_sock, 0) self.cdb = swsscommon.DBConnector(4, dvs.redis_sock, 0) self.sdb = swsscommon.DBConnector(6, dvs.redis_sock, 0) @@ -43,6 +44,19 @@ def remove_port_channel_members(self, dvs, lag, members): tbl._del(lag + "|" + member) time.sleep(1) + def update_host_tx_ready_status(self, dvs, port_id, switch_id, admin_state): + host_tx_ready = "SAI_PORT_HOST_TX_READY_STATUS_READY" if admin_state == "up" else "SAI_PORT_HOST_TX_READY_STATUS_NOT_READY" + ntf = swsscommon.NotificationProducer(dvs.adb, "NOTIFICATIONS") + fvp = swsscommon.FieldValuePairs() + ntf_data = "[{\"host_tx_ready_status\":\""+host_tx_ready+"\",\"port_id\":\""+port_id+"\",\"switch_id\":\""+switch_id+"\"}]" + ntf.send("port_host_tx_ready", ntf_data, fvp) + + def get_port_id(self, dvs, port_name): + port_name_map = swsscommon.Table(self.countdb, "COUNTERS_PORT_NAME_MAP") + status, returned_value = port_name_map.hget("", port_name) + assert status == True + return returned_value + def check_admin_status(self, dvs, port, admin_status): assert admin_status == "up" or admin_status == "down" tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_PORT") @@ -91,8 +105,12 @@ def test_PortChannelMemberAdminStatus(self, dvs, testlog): self.remove_port_channel(dvs, "PortChannel6") def test_PortHostTxReadiness(self, dvs, testlog): + dvs.setup_db() self.setup_db(dvs) + #Find switch_id + switch_id = dvs.getSwitchOid() + # configure admin status to interface self.set_admin_status("Ethernet0", "up") self.set_admin_status("Ethernet4", "down") @@ -103,6 +121,11 @@ def test_PortHostTxReadiness(self, dvs, testlog): self.check_admin_status(dvs, "Ethernet4", "down") self.check_admin_status(dvs, "Ethernet8", "up") + self.update_host_tx_ready_status(dvs, self.get_port_id(dvs, "Ethernet0") , switch_id, "up") + self.update_host_tx_ready_status(dvs, self.get_port_id(dvs, "Ethernet4") , switch_id, "down") + self.update_host_tx_ready_status(dvs, self.get_port_id(dvs, "Ethernet8") , switch_id, "up") + time.sleep(3) + # check host readiness status in PORT TABLE of STATE-DB self.check_host_tx_ready_status(dvs, "Ethernet0", "up") self.check_host_tx_ready_status(dvs, "Ethernet4", "down") diff --git a/tests/test_port.py b/tests/test_port.py index 335b0a604b..3853a61ffe 100644 --- a/tests/test_port.py +++ b/tests/test_port.py @@ -289,6 +289,22 @@ def test_PortHostif(self, dvs): hostif_queue = attributes.get("SAI_HOSTIF_ATTR_QUEUE") assert hostif_queue == "7" + def test_PortHostTxSignalSet(self, dvs, testlog): + adb = dvs.get_asic_db() + statedb = dvs.get_state_db() + + transceiver_info_tbl = swsscommon.Table(statedb.db_connection, "TRANSCEIVER_INFO") + fvs = swsscommon.FieldValuePairs([("supported_max_tx_power","N/A")]) + transceiver_info_tbl.set("Ethernet0", fvs) + + port_oid = adb.port_name_map["Ethernet0"] + expected_fields = {"SAI_PORT_ATTR_HOST_TX_SIGNAL_ENABLE":"true"} + adb.wait_for_field_match("ASIC_STATE:SAI_OBJECT_TYPE_PORT", port_oid, expected_fields) + + transceiver_info_tbl.hdel("Ethernet0", "supported_max_tx_power") + expected_fields = {"SAI_PORT_ATTR_HOST_TX_SIGNAL_ENABLE":"false"} + adb.wait_for_field_match("ASIC_STATE:SAI_OBJECT_TYPE_PORT", port_oid, expected_fields) + # Add Dummy always-pass test at end as workaroud # for issue when Flaky fail on final test it invokes module tear-down before retrying diff --git a/tests/test_warm_reboot.py b/tests/test_warm_reboot.py index b2edc42587..718aac9bb5 100644 --- a/tests/test_warm_reboot.py +++ b/tests/test_warm_reboot.py @@ -60,6 +60,31 @@ def check_port_oper_status(appl_db, port_name, state): break assert oper_status == state +def check_port_host_tx_ready_status(state_db, port_name, status): + portTable = swsscommon.Table(state_db, swsscommon.STATE_PORT_TABLE_NAME) + (status, fvs) = portTable.get(port_name) + + assert status == True + + assert "host_tx_ready" in [fv[0] for fv in fvs] + for fv in fvs: + if fv[0] == "host_tx_ready": + assert fv[1] == "true" if status == "up" else "false" + +def update_host_tx_ready_status(dvs, port_id, switch_id, admin_state): + host_tx_ready = "SAI_PORT_HOST_TX_READY_STATUS_READY" if admin_state == "up" else "SAI_PORT_HOST_TX_READY_STATUS_NOT_READY" + ntf = swsscommon.NotificationProducer(dvs.adb, "NOTIFICATIONS") + fvp = swsscommon.FieldValuePairs() + ntf_data = "[{\"host_tx_ready_status\":\""+host_tx_ready+"\",\"port_id\":\""+port_id+"\",\"switch_id\":\""+switch_id+"\"}]" + ntf.send("port_host_tx_ready", ntf_data, fvp) + +def get_port_id(dvs, port_name): + count_db = swsscommon.DBConnector(2, dvs.redis_sock, 0) + port_name_map = swsscommon.Table(count_db, "COUNTERS_PORT_NAME_MAP") + status, returned_value = port_name_map.hget("", port_name) + assert status == True + return returned_value + # function to check the restore count incremented by 1 for a single process def swss_app_check_RestoreCount_single(state_db, restore_count, name): warmtbl = swsscommon.Table(state_db, swsscommon.STATE_WARM_RESTART_TABLE_NAME) @@ -256,6 +281,8 @@ def warm_restart_timer_set(dvs, app, timer, val): class TestWarmReboot(object): def test_PortSyncdWarmRestart(self, dvs, testlog): + dvs.setup_db() + switch_id = dvs.getSwitchOid() conf_db = swsscommon.DBConnector(swsscommon.CONFIG_DB, dvs.redis_sock, 0) appl_db = swsscommon.DBConnector(swsscommon.APPL_DB, dvs.redis_sock, 0) @@ -294,6 +321,13 @@ def test_PortSyncdWarmRestart(self, dvs, testlog): check_port_oper_status(appl_db, "Ethernet16", "up") check_port_oper_status(appl_db, "Ethernet20", "up") + update_host_tx_ready_status(dvs, get_port_id(dvs, "Ethernet16") , switch_id, "up") + update_host_tx_ready_status(dvs, get_port_id(dvs, "Ethernet20") , switch_id, "up") + + # Ethernet port host_tx_ready status should be "true" + check_port_host_tx_ready_status(state_db, "Ethernet16", "up") + check_port_host_tx_ready_status(state_db, "Ethernet20", "up") + # Ping should work between servers via vs vlan interfaces ping_stats = dvs.servers[4].runcmd("ping -c 1 11.0.0.10") time.sleep(1) @@ -337,6 +371,13 @@ def test_PortSyncdWarmRestart(self, dvs, testlog): check_port_oper_status(appl_db, "Ethernet20", "up") check_port_oper_status(appl_db, "Ethernet24", "down") + update_host_tx_ready_status(dvs, get_port_id(dvs, "Ethernet16") , switch_id, "up") + update_host_tx_ready_status(dvs, get_port_id(dvs, "Ethernet20") , switch_id, "up") + update_host_tx_ready_status(dvs, get_port_id(dvs, "Ethernet24") , switch_id, "down") + + check_port_host_tx_ready_status(state_db, "Ethernet16", "up") + check_port_host_tx_ready_status(state_db, "Ethernet20", "up") + check_port_host_tx_ready_status(state_db, "Ethernet24", "down") swss_app_check_RestoreCount_single(state_db, restore_count, "portsyncd") @@ -2397,7 +2438,7 @@ def test_TunnelMgrdWarmRestart(self, dvs): "ecn_mode": "standard", "ttl_mode": "pipe" } - + pubsub = dvs.SubscribeAppDbObject(tunnel_table) dvs.runcmd("config warm_restart enable swss")