From 5c88a16a2a59818a30920ac25168702a3ea50af5 Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Sat, 28 Mar 2020 05:33:22 +0000 Subject: [PATCH 1/4] [daemon utils] move platform/check_daemon_status.py to common/platform/daemon_utils.py Signed-off-by: Ying Xie --- .../check_daemon_status.py => common/platform/daemon_utils.py} | 0 tests/platform/test_reboot.py | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename tests/{platform/check_daemon_status.py => common/platform/daemon_utils.py} (100%) diff --git a/tests/platform/check_daemon_status.py b/tests/common/platform/daemon_utils.py similarity index 100% rename from tests/platform/check_daemon_status.py rename to tests/common/platform/daemon_utils.py diff --git a/tests/platform/test_reboot.py b/tests/platform/test_reboot.py index a684f0f053c..84297937e30 100644 --- a/tests/platform/test_reboot.py +++ b/tests/platform/test_reboot.py @@ -22,9 +22,9 @@ from common.reboot import * from common.platform.interface_utils import check_interface_information from common.platform.transceiver_utils import check_transceiver_basic +from common.platform.daemon_utils import check_pmon_daemon_status from check_critical_services import check_critical_services -from check_daemon_status import check_pmon_daemon_status pytestmark = [pytest.mark.disable_loganalyzer] From 3d10574bfe92c7d4d5493325ae6b1c4cde3ae69d Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Fri, 3 Apr 2020 21:47:43 +0000 Subject: [PATCH 2/4] [pmon daemon] refactoring pmon daemon state checking - Refactor get_pmon_daemon_list to get_pmon_daemon_states: returning list of daemon states. not returning daemons that are known short lived. not returning daemons disabled by configuratin. - Refactor daemon state check to check the returned states. Signed-off-by: Ying Xie --- tests/common/devices.py | 32 ++++++++++++++++++--------- tests/common/platform/daemon_utils.py | 24 +++++++------------- 2 files changed, 30 insertions(+), 26 deletions(-) diff --git a/tests/common/devices.py b/tests/common/devices.py index b2b4e0c39d5..2a2a15ab6e0 100644 --- a/tests/common/devices.py +++ b/tests/common/devices.py @@ -232,14 +232,20 @@ def get_crm_resources(self): return result - def get_pmon_daemon_list(self): + def get_pmon_daemon_states(self): """ - @summary: get pmon daemon list from the config file (/usr/share/sonic/device/{platform}/{hwsku}/pmon_daemon_control.json) + @summary: get state list of daemons from pmon docker. + Referencing (/usr/share/sonic/device/{platform}/{hwsku}/pmon_daemon_control.json) if some daemon is disabled in the config file, then remove it from the daemon list. + + @return: dictionary of { service_name1 : state1, ... ... } """ - full_daemon_tup = ('xcvrd', 'ledd', 'psud', 'syseepromd') + # some services are meant to have a short life span or not part of the daemons + exemptions = ('lm-sensors', 'start.sh', 'rsyslogd') + + daemons = self.shell('docker exec pmon supervisorctl status')['stdout_lines'] + daemon_ctl_key_prefix = 'skip_' - daemon_list = [] daemon_config_file_path = os.path.join('/usr/share/sonic/device', self.facts["platform"], 'pmon_daemon_control.json') try: @@ -248,20 +254,26 @@ def get_pmon_daemon_list(self): logging.debug("Original file content is %s" % str(json_data)) for key in full_daemon_tup: if (daemon_ctl_key_prefix + key) not in json_data: - daemon_list.append(key) logging.debug("Daemon %s is enabled" % key) elif not json_data[daemon_ctl_key_prefix + key]: - daemon_list.append(key) logging.debug("Daemon %s is enabled" % key) else: logging.debug("Daemon %s is disabled" % key) + exemptions.append(key) except: # if pmon_daemon_control.json not exist, then it's using default setting, # all the pmon daemons expected to be running after boot up. - daemon_list = list(full_daemon_tup) + pass + + # Collect state of services that are not on the exemption list. + daemon_states = {} + for line in daemons: + words = str(line).split() + if len(words) >= 2 and words[0] not in exemptions: + daemon_states[words[0]] = words[1] - logging.info("Pmon daemon list for this platform is %s" % str(daemon_list)) - return daemon_list + logging.info("Pmon daemon state list for this platform is %s" % str(daemon_states)) + return daemon_states def num_npus(self): """ @@ -321,7 +333,7 @@ def get_image_info(self): ret = {} images = [] for line in lines: - words = line.strip().split(' ') + words = line.strip().split() if len(words) == 2: if words[0] == 'Current:': ret['current'] = words[1] diff --git a/tests/common/platform/daemon_utils.py b/tests/common/platform/daemon_utils.py index fdefbed0c3c..8b3ff66b265 100644 --- a/tests/common/platform/daemon_utils.py +++ b/tests/common/platform/daemon_utils.py @@ -13,19 +13,11 @@ def check_pmon_daemon_status(dut): This function use command "supervisorctl status" inside the container and check the status from the command output. If the daemon status is "RUNNING" then return True, if daemon not exist or status is not "RUNNING", return false. """ - daemon_list = dut.get_pmon_daemon_list() - daemon_status = {} - try: - for daemon in daemon_list: - output = dut.shell('docker exec pmon supervisorctl status | grep %s' % daemon, module_ignore_errors=True) - if bool(output["stdout_lines"]): - expected_line = output["stdout_lines"][0] - expected_line_list = expected_line.split() - daemon_status[daemon] = (daemon in expected_line_list and 'RUNNING' in expected_line_list) - logging.debug("Daemon %s status is %s" % (daemon, str(daemon_status[daemon]))) - else: - logging.debug("Daemon %s does not exist" % daemon) - return False - return all(daemon_status.values()) - except: - return False + daemons = dut.get_pmon_daemon_states() + ret = True + for daemon, state in daemons.items(): + logging.debug("Daemon %s status is %s" % (daemon, state)) + if state != 'RUNNING': + ret = False + + return ret From cff7acc66137a55bf19c4b6fdc895579bc2f4351 Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Sat, 4 Apr 2020 00:28:34 +0000 Subject: [PATCH 3/4] Address review comments --- tests/common/devices.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/common/devices.py b/tests/common/devices.py index 2a2a15ab6e0..5cdab963260 100644 --- a/tests/common/devices.py +++ b/tests/common/devices.py @@ -235,7 +235,7 @@ def get_crm_resources(self): def get_pmon_daemon_states(self): """ @summary: get state list of daemons from pmon docker. - Referencing (/usr/share/sonic/device/{platform}/{hwsku}/pmon_daemon_control.json) + Referencing (/usr/share/sonic/device/{platform}/pmon_daemon_control.json) if some daemon is disabled in the config file, then remove it from the daemon list. @return: dictionary of { service_name1 : state1, ... ... } @@ -245,6 +245,8 @@ def get_pmon_daemon_states(self): daemons = self.shell('docker exec pmon supervisorctl status')['stdout_lines'] + daemon_list = [ line.strip().split()[0] for line in daemons if len(line.strip()) > 0 ] + daemon_ctl_key_prefix = 'skip_' daemon_config_file_path = os.path.join('/usr/share/sonic/device', self.facts["platform"], 'pmon_daemon_control.json') @@ -252,7 +254,7 @@ def get_pmon_daemon_states(self): output = self.shell('cat %s' % daemon_config_file_path) json_data = json.loads(output["stdout"]) logging.debug("Original file content is %s" % str(json_data)) - for key in full_daemon_tup: + for key in daemon_list: if (daemon_ctl_key_prefix + key) not in json_data: logging.debug("Daemon %s is enabled" % key) elif not json_data[daemon_ctl_key_prefix + key]: @@ -268,7 +270,7 @@ def get_pmon_daemon_states(self): # Collect state of services that are not on the exemption list. daemon_states = {} for line in daemons: - words = str(line).split() + words = line.strip().split() if len(words) >= 2 and words[0] not in exemptions: daemon_states[words[0]] = words[1] From 04caa271885a9c70575313b75f36a7cc90f03dbb Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Mon, 6 Apr 2020 17:07:04 +0000 Subject: [PATCH 4/4] change exemptions to list --- tests/common/devices.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/common/devices.py b/tests/common/devices.py index 5cdab963260..44ccdf0e553 100644 --- a/tests/common/devices.py +++ b/tests/common/devices.py @@ -241,7 +241,7 @@ def get_pmon_daemon_states(self): @return: dictionary of { service_name1 : state1, ... ... } """ # some services are meant to have a short life span or not part of the daemons - exemptions = ('lm-sensors', 'start.sh', 'rsyslogd') + exemptions = ['lm-sensors', 'start.sh', 'rsyslogd'] daemons = self.shell('docker exec pmon supervisorctl status')['stdout_lines']