diff --git a/tests/common/platform/bmc_utils.py b/tests/common/platform/bmc_utils.py index ce70331d02..3a02c2cb7c 100644 --- a/tests/common/platform/bmc_utils.py +++ b/tests/common/platform/bmc_utils.py @@ -1,10 +1,13 @@ """Shared helpers for BMC platform tests (syslog, event.log, Switch-Host).""" import logging +import shlex + from contextlib import contextmanager import pytest + from tests.common.helpers.assertions import pytest_assert from tests.common.helpers.sonic_db import STATE_DB, redis_hget, redis_hset from tests.common.utilities import wait_until @@ -128,10 +131,12 @@ def init(self, log_target=LOG_TARGET_EVENT_LOG): marker = "{}.{}".format(self.marker_prefix, time.strftime("%Y-%m-%d-%H:%M:%S", time.gmtime())) start_line = "start-LogAnalyzer-{}".format(marker) + self.duthost.shell("sync {}".format(shlex.quote(BMC_EVENT_LOG))) self.duthost.shell( "echo '{}' >> {}".format(start_line, BMC_EVENT_LOG), module_ignore_errors=True, ) + self.duthost.shell("sync {}".format(shlex.quote(BMC_EVENT_LOG))) logger.debug("BmcLogAnalyzer: wrote marker '%s' to %s", start_line, BMC_EVENT_LOG) return marker @@ -150,10 +155,13 @@ def analyze(self, marker, fail=False, log_target=LOG_TARGET_EVENT_LOG): return self._get_syslog_analyzer().analyze(marker, fail=fail) start_line = "start-LogAnalyzer-{}".format(marker) + self.duthost.shell("sync {}".format(shlex.quote(BMC_EVENT_LOG))) result = self.duthost.shell( - "awk '/{}/ {{found=1; next}} found' {} 2>/dev/null".format( - start_line.replace("'", r"'\''"), BMC_EVENT_LOG), - module_ignore_errors=True, + "sed -n {} {}".format( + shlex.quote(r"/{}/,$p".format(start_line)), + shlex.quote(BMC_EVENT_LOG) + ), + module_ignore_errors=True ) content = (result.get('stdout', '') or '').strip() diff --git a/tests/common/plugins/pdu_controller/__init__.py b/tests/common/plugins/pdu_controller/__init__.py index 5d49109de4..d10f624c05 100644 --- a/tests/common/plugins/pdu_controller/__init__.py +++ b/tests/common/plugins/pdu_controller/__init__.py @@ -4,6 +4,7 @@ import pytest from .pdu_manager import pdu_manager_factory +from tests.common.fixtures.conn_graph_facts import get_graph_facts from tests.common.utilities import get_host_visible_vars, get_sup_node_or_random_node @@ -111,12 +112,19 @@ def pdu_controller(duthosts, conn_graph_facts): @pytest.fixture(scope="module") -def get_pdu_controller(conn_graph_facts): +def get_pdu_controller(conn_graph_facts, localhost): controller_map = {} def pdu_controller_helper(duthost): if duthost.hostname not in controller_map: - controller = _get_pdu_controller(duthost, conn_graph_facts) + # conn_graph_facts is scoped to the testbed duthosts. When asked for a host + # that is not part of that set (e.g. the paired Switch-Host resolved from a + # BMC DUT), its PDU wiring is absent, so load the graph facts for that host + # on demand instead of returning an empty (None) controller. + facts = conn_graph_facts + if duthost.hostname not in facts.get('device_pdu_links', {}): + facts = get_graph_facts(duthost, localhost, [duthost.hostname]) + controller = _get_pdu_controller(duthost, facts) controller_map[duthost.hostname] = controller return controller_map[duthost.hostname] diff --git a/tests/platform_tests/daemon/test_bmcctld.py b/tests/platform_tests/daemon/test_bmcctld.py index e2bd8d3b1e..c1d4ac54b1 100644 --- a/tests/platform_tests/daemon/test_bmcctld.py +++ b/tests/platform_tests/daemon/test_bmcctld.py @@ -463,20 +463,21 @@ def test_bmcctld_power_on_delay(self, localhost, get_pdu_controller): pytest.skip(f"No PDU controller wired for switch chassis {switch_host.hostname}, " "skipping power-loss scenario") + # PduManager.turn_{off,on}_outlet expects the full outlet dict from + # get_outlet_status() (with psu_name/feed_name/outlet_id), not a bare ID. outlets = pdu_ctrl.get_outlet_status() - outlet_ids = [o['outlet_id'] for o in outlets if 'outlet_id' in o] - pytest_assert(outlet_ids, "PDU controller returned no outlets for switch chassis") + pytest_assert(outlets, "PDU controller returned no outlets for switch chassis") # Set marker in event.log BEFORE power cycle. event.log is persistent; # syslog is tmpfs and is wiped on power loss so cannot be used here. la = make_bmc_loganalyzer(self.duthost, "bmcctld_power_on_delay_scenario_b") marker_b = la.init() - for outlet in outlet_ids: + for outlet in outlets: pdu_ctrl.turn_off_outlet(outlet) wait_until(120, 5, 10, lambda: self.duthost.shell("true", module_ignore_errors=True).get('rc') != 0) - for outlet in outlet_ids: + for outlet in outlets: pdu_ctrl.turn_on_outlet(outlet) wait_until(600, 15, 30, lambda: self.duthost.critical_services_fully_started())